From 5b606ea56ca2fc04336d7b72e22e2e1d85f9d719 Mon Sep 17 00:00:00 2001 From: anandani4136 Date: Wed, 17 Sep 2025 18:30:38 -0500 Subject: [PATCH 1/5] Update Priority Logic --- src/services/checkin/checkin-router.test.ts | 84 ++++++++++++++++++++- src/services/checkin/checkin-utils.ts | 19 ++++- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/src/services/checkin/checkin-router.test.ts b/src/services/checkin/checkin-router.test.ts index f804c35b..3d2849ef 100644 --- a/src/services/checkin/checkin-router.test.ts +++ b/src/services/checkin/checkin-router.test.ts @@ -57,6 +57,21 @@ const REGULAR_EVENT_FOR_CHECKIN = { attendanceCount: 0, }; +const SPECIAL_EVENT_FOR_CHECKIN = { + eventId: uuidv4(), + name: "Second Regular Event", + startTime: new Date((NOW_SECONDS - 600) * 1000).toISOString(), + endTime: new Date((NOW_SECONDS + ONE_HOUR_SECONDS) * 1000).toISOString(), + points: 50, + description: "A second regular event.", + isVirtual: false, + imageUrl: null, + location: "Siebel 2405", + eventType: EventType.enum.SPECIAL, + isVisible: true, + attendanceCount: 0, +}; + const MEALS_EVENT = { eventId: uuidv4(), name: "Lunch Time", @@ -338,7 +353,7 @@ describe("POST /checkin/scan/staff", () => { expect(attendeeError).toBeNull(); expect(updatedAttendee).toMatchObject({ points: TEST_ATTENDEE_1.points + REGULAR_EVENT_FOR_CHECKIN.points, - [`hasPriority${currentDay}`]: true, + [`hasPriority${currentDay}`]: false, // No priority on first check-in }); }, 100000); @@ -573,7 +588,7 @@ describe("POST /checkin/event", () => { .single(); expect(updatedAttendee).toMatchObject({ points: TEST_ATTENDEE_1.points + REGULAR_EVENT_FOR_CHECKIN.points, - [`hasPriority${currentDay}`]: true, + [`hasPriority${currentDay}`]: false, // No priority on first check-in }); }); @@ -744,6 +759,71 @@ describe("POST /checkin/event", () => { expect(attendeeAfter).toEqual(attendeeBefore); expect(attendanceCountAfter).toBe(attendanceCountBefore); }); + + it("should give priority after second check-in to regular event", async () => { + // First check-in - should not get priority + payload.eventId = REGULAR_EVENT_FOR_CHECKIN.eventId; + payload.userId = TEST_ATTENDEE_1.userId; + + const firstResponse = await postAsAdmin("/checkin/event") + .send(payload) + .expect(StatusCodes.OK); + + // Verify no priority after first check-in + const { data: attendeeAfterFirst } = await SupabaseDB.ATTENDEES.select() + .eq("userId", payload.userId) + .single(); + expect(attendeeAfterFirst).toMatchObject({ + [`hasPriority${currentDay}`]: false, + }); + + // Verify first event is in attendance record + const { data: attendeeAttendanceAfterFirst } = + await SupabaseDB.ATTENDEE_ATTENDANCES.select("eventsAttended") + .eq("userId", payload.userId) + .single(); + expect(attendeeAttendanceAfterFirst?.eventsAttended).toContain( + REGULAR_EVENT_FOR_CHECKIN.eventId + ); + expect(attendeeAttendanceAfterFirst?.eventsAttended).toHaveLength(1); + + await SupabaseDB.EVENTS.insert([SPECIAL_EVENT_FOR_CHECKIN]); + + // Second check-in - should get priority + payload.eventId = SPECIAL_EVENT_FOR_CHECKIN.eventId; + + const secondResponse = await postAsAdmin("/checkin/event") + .send(payload) + .expect(StatusCodes.OK); + + // Verify priority is given after second check-in + const { data: attendeeAfterSecond } = + await SupabaseDB.ATTENDEES.select() + .eq("userId", payload.userId) + .single(); + expect(attendeeAfterSecond).toMatchObject({ + [`hasPriority${currentDay}`]: true, + }); + + // Verify both events are in the eventsAttended array + const { data: attendeeAttendance } = + await SupabaseDB.ATTENDEE_ATTENDANCES.select("eventsAttended") + .eq("userId", payload.userId) + .single(); + expect(attendeeAttendance?.eventsAttended).toContain( + SPECIAL_EVENT_FOR_CHECKIN.eventId + ); + expect(attendeeAttendance?.eventsAttended).toContain( + SPECIAL_EVENT_FOR_CHECKIN.eventId + ); + expect(attendeeAttendance?.eventsAttended).toHaveLength(2); + + // Clean up + await SupabaseDB.EVENTS.delete().eq( + "eventId", + SPECIAL_EVENT_FOR_CHECKIN.eventId + ); + }); }); describe("POST /checkin/scan/merch", () => { diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index 79aba7f7..28143f16 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -121,14 +121,29 @@ export async function checkInUserToEvent(eventId: string, userId: string) { .single() .throwOnError(); + // Update attendance records first + await updateAttendanceRecords(eventId, userId); + + // Check if user should get priority (only for non-meal/checkin events and if they have attended >1 event) if ( event.eventType !== EventType.Enum.MEALS && event.eventType !== EventType.Enum.CHECKIN ) { - await updateAttendeePriority(userId); + // Check how many events the user has attended (including the current one) + const { data: attendeeAttendance } = + await SupabaseDB.ATTENDEE_ATTENDANCES.select("eventsAttended") + .eq("userId", userId) + .maybeSingle() + .throwOnError(); + + const eventsAttended = attendeeAttendance?.eventsAttended || []; + + // Only give priority if they have attended more than 1 event + if (eventsAttended.length > 1) { + await updateAttendeePriority(userId); + } } - await updateAttendanceRecords(eventId, userId); await assignPixelsToUser(userId, event.points); } From 173579c0d617981a035029f44c9c671792eb365d Mon Sep 17 00:00:00 2001 From: anandani4136 Date: Wed, 17 Sep 2025 18:42:26 -0500 Subject: [PATCH 2/5] Update Test Format --- src/services/checkin/checkin-router.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/checkin/checkin-router.test.ts b/src/services/checkin/checkin-router.test.ts index 3d2849ef..8fdb27d9 100644 --- a/src/services/checkin/checkin-router.test.ts +++ b/src/services/checkin/checkin-router.test.ts @@ -765,7 +765,7 @@ describe("POST /checkin/event", () => { payload.eventId = REGULAR_EVENT_FOR_CHECKIN.eventId; payload.userId = TEST_ATTENDEE_1.userId; - const firstResponse = await postAsAdmin("/checkin/event") + await postAsAdmin("/checkin/event") .send(payload) .expect(StatusCodes.OK); @@ -792,7 +792,7 @@ describe("POST /checkin/event", () => { // Second check-in - should get priority payload.eventId = SPECIAL_EVENT_FOR_CHECKIN.eventId; - const secondResponse = await postAsAdmin("/checkin/event") + await postAsAdmin("/checkin/event") .send(payload) .expect(StatusCodes.OK); From d3d0d6c8b303ff18fe1dfe2698387c9565eddb9a Mon Sep 17 00:00:00 2001 From: anandani4136 Date: Thu, 18 Sep 2025 01:54:48 -0500 Subject: [PATCH 3/5] Update priority --- src/services/checkin/checkin-router.test.ts | 22 ----------- src/services/checkin/checkin-utils.ts | 41 +++++++++++++++------ 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/services/checkin/checkin-router.test.ts b/src/services/checkin/checkin-router.test.ts index 78fd2b6d..8fdb27d9 100644 --- a/src/services/checkin/checkin-router.test.ts +++ b/src/services/checkin/checkin-router.test.ts @@ -355,17 +355,6 @@ describe("POST /checkin/scan/staff", () => { points: TEST_ATTENDEE_1.points + REGULAR_EVENT_FOR_CHECKIN.points, [`hasPriority${currentDay}`]: false, // No priority on first check-in }); - - const { data: subscription } = await SupabaseDB.SUBSCRIPTIONS.select( - "*" - ) - .eq("userId", TEST_ATTENDEE_1.userId) - .eq("mailingList", payload.eventId) - .single() - .throwOnError(); - expect(subscription).not.toBeNull(); - expect(subscription!.userId).toBe(TEST_ATTENDEE_1.userId); - expect(subscription!.mailingList).toBe(payload.eventId); }, 100000); it("should successfully check-in user to a CHECKIN type event and update records", async () => { @@ -601,17 +590,6 @@ describe("POST /checkin/event", () => { points: TEST_ATTENDEE_1.points + REGULAR_EVENT_FOR_CHECKIN.points, [`hasPriority${currentDay}`]: false, // No priority on first check-in }); - - const { data: subscription } = await SupabaseDB.SUBSCRIPTIONS.select( - "*" - ) - .eq("userId", TEST_ATTENDEE_1.userId) - .eq("mailingList", payload.eventId) - .single() - .throwOnError(); - expect(subscription).not.toBeNull(); - expect(subscription.userId!).toBe(TEST_ATTENDEE_1.userId); - expect(subscription.mailingList!).toBe(payload.eventId); }); it("should successfully check-in to a check in event and update records", async () => { diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index 6974dbcb..5b9b0b7b 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -138,19 +138,38 @@ export async function checkInUserToEvent(eventId: string, userId: string) { const eventsAttended = attendeeAttendance?.eventsAttended || []; - // Only give priority if they have attended more than 1 event - if (eventsAttended.length > 1) { - await updateAttendeePriority(userId); + if (eventsAttended.length > 0) { + // Get details of all attended events to filter by type and day + const { data: attendedEvents } = await SupabaseDB.EVENTS.select( + "eventId, eventType, startTime" + ) + .in("eventId", eventsAttended) + .throwOnError(); + + const currentDay = getCurrentDay(); + + // Filter events: exclude MEALS and CHECKIN, and only count events from current day + const filteredEvents = + attendedEvents?.filter((eventData) => { + const eventDate = new Date(eventData.startTime); + const eventDay = new Intl.DateTimeFormat("en-US", { + timeZone: "America/Chicago", + weekday: "short", + }).format(eventDate) as DayKey; + + return ( + eventData.eventType !== EventType.Enum.MEALS && + eventData.eventType !== EventType.Enum.CHECKIN && + eventDay === currentDay + ); + }) || []; + + // Only give priority if they have attended 2 more than 1 qualifying event today + if (filteredEvents.length >= 2) { + await updateAttendeePriority(userId); + } } } - - - await SupabaseDB.SUBSCRIPTIONS.insert({ - userId: userId, - mailingList: eventId, - }).throwOnError(); - - await updateAttendanceRecords(eventId, userId); await assignPixelsToUser(userId, event.points); } From 404f4a15fde89bad6411cd609d07d54b997cca27 Mon Sep 17 00:00:00 2001 From: Bahl-Aryan <150870091+Bahl-Aryan@users.noreply.github.com> Date: Thu, 18 Sep 2025 04:08:32 -0500 Subject: [PATCH 4/5] Update src/services/checkin/checkin-router.test.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/services/checkin/checkin-router.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/checkin/checkin-router.test.ts b/src/services/checkin/checkin-router.test.ts index 8fdb27d9..8dc8b230 100644 --- a/src/services/checkin/checkin-router.test.ts +++ b/src/services/checkin/checkin-router.test.ts @@ -814,7 +814,7 @@ describe("POST /checkin/event", () => { SPECIAL_EVENT_FOR_CHECKIN.eventId ); expect(attendeeAttendance?.eventsAttended).toContain( - SPECIAL_EVENT_FOR_CHECKIN.eventId + REGULAR_EVENT_FOR_CHECKIN.eventId ); expect(attendeeAttendance?.eventsAttended).toHaveLength(2); From ca3d5b773008232081f78f5613b1c33ca107f9f3 Mon Sep 17 00:00:00 2001 From: Ronit Anandani <56076011+anandani4136@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:19:17 -0500 Subject: [PATCH 5/5] Update src/services/checkin/checkin-utils.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/services/checkin/checkin-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index 5b9b0b7b..cfd3f4b9 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -164,7 +164,7 @@ export async function checkInUserToEvent(eventId: string, userId: string) { ); }) || []; - // Only give priority if they have attended 2 more than 1 qualifying event today + // Only give priority if they have attended 2 or more qualifying events today if (filteredEvents.length >= 2) { await updateAttendeePriority(userId); }