|
1 | 1 | import type { DBHandle } from "@dotkomonline/db" |
| 2 | +import { findFeaturedEvents } from "@dotkomonline/db" |
2 | 3 | import { |
3 | 4 | type AttendanceId, |
| 5 | + type BaseEvent, |
| 6 | + BaseEventSchema, |
4 | 7 | type CompanyId, |
5 | 8 | type DeregisterReason, |
6 | 9 | DeregisterReasonSchema, |
@@ -41,6 +44,8 @@ const INCLUDE_COMPANY_AND_GROUPS = { |
41 | 44 | export interface EventRepository { |
42 | 45 | create(handle: DBHandle, data: EventWrite): Promise<Event> |
43 | 46 | update(handle: DBHandle, eventId: EventId, data: Partial<EventWrite>): Promise<Event> |
| 47 | + updateEventAttendance(handle: DBHandle, eventId: EventId, attendanceId: AttendanceId): Promise<Event> |
| 48 | + updateEventParent(handle: DBHandle, eventId: EventId, parentEventId: EventId | null): Promise<Event> |
44 | 49 | /** |
45 | 50 | * Soft-delete an event by setting its status to "DELETED". |
46 | 51 | */ |
@@ -81,15 +86,17 @@ export interface EventRepository { |
81 | 86 | page: Pageable |
82 | 87 | ): Promise<Event[]> |
83 | 88 | findByParentEventId(handle: DBHandle, parentEventId: EventId): Promise<Event[]> |
| 89 | + findEventsWithUnansweredFeedbackFormByUserId(handle: DBHandle, userId: UserId): Promise<Event[]> |
| 90 | + findManyDeregisterReasonsWithEvent(handle: DBHandle, page: Pageable): Promise<DeregisterReasonWithEvent[]> |
| 91 | + // This cannot use `Pageable` due to raw query needing numerical offset and not cursor based pagination |
| 92 | + findFeaturedEvents(handle: DBHandle, offset: number, limit: number): Promise<BaseEvent[]> |
| 93 | + |
84 | 94 | addEventHostingGroups(handle: DBHandle, eventId: EventId, hostingGroupIds: Set<GroupId>): Promise<void> |
85 | | - addEventCompanies(handle: DBHandle, eventId: EventId, companyIds: Set<CompanyId>): Promise<void> |
86 | 95 | deleteEventHostingGroups(handle: DBHandle, eventId: EventId, hostingGroupIds: Set<GroupId>): Promise<void> |
| 96 | + addEventCompanies(handle: DBHandle, eventId: EventId, companyIds: Set<CompanyId>): Promise<void> |
87 | 97 | deleteEventCompanies(handle: DBHandle, eventId: EventId, companyIds: Set<CompanyId>): Promise<void> |
88 | | - updateEventAttendance(handle: DBHandle, eventId: EventId, attendanceId: AttendanceId): Promise<Event> |
89 | | - updateEventParent(handle: DBHandle, eventId: EventId, parentEventId: EventId | null): Promise<Event> |
90 | | - findEventsWithUnansweredFeedbackFormByUserId(handle: DBHandle, userId: UserId): Promise<Event[]> |
| 98 | + |
91 | 99 | createDeregisterReason(handle: DBHandle, data: DeregisterReasonWrite): Promise<DeregisterReason> |
92 | | - findManyDeregisterReasonsWithEvent(handle: DBHandle, page: Pageable): Promise<DeregisterReasonWithEvent[]> |
93 | 100 | } |
94 | 101 |
|
95 | 102 | export function getEventRepository(): EventRepository { |
@@ -310,6 +317,25 @@ export function getEventRepository(): EventRepository { |
310 | 317 | ) |
311 | 318 | }, |
312 | 319 |
|
| 320 | + async findFeaturedEvents(handle, offset, limit) { |
| 321 | + // Events will primarily be ranked by their type in the following order (lower number is higher ranking): |
| 322 | + // 1. GENERAL_ASSEMBLY |
| 323 | + // 2. COMPANY, ACADEMIC |
| 324 | + // 3. SOCIAL, INTERNAL, OTHER, WELCOME |
| 325 | + // |
| 326 | + // Within each bucket they will be ranked like this: |
| 327 | + // 1. Event in future, registration open and not full AND attendance capacity is limited (>0) |
| 328 | + // 2. Event in future, registration not started yet (attendance capacity does not matter) |
| 329 | + // 3. Event in future, no attendance registration OR attendance capacity is unlimited (=0) |
| 330 | + // 4. Event in future, registration full (registration status does not matter) |
| 331 | + // |
| 332 | + // Past events are not featured. We would rather have no featured events than "stale" events. |
| 333 | + const events = await handle.$queryRawTyped(findFeaturedEvents(offset, limit)) |
| 334 | + |
| 335 | + // FeaturedEventSchema includes attendance, so we pick just the event shape here |
| 336 | + return parseOrReport(BaseEventSchema.array(), events) |
| 337 | + }, |
| 338 | + |
313 | 339 | async addEventHostingGroups(handle, eventId, hostingGroupIds) { |
314 | 340 | await handle.eventHostingGroup.createMany({ |
315 | 341 | data: hostingGroupIds |
|
0 commit comments