diff --git a/prisma/migrations/20260901180000_move_remaining_umbral_sessions_to_1400_argentina/migration.sql b/prisma/migrations/20260901180000_move_remaining_umbral_sessions_to_1400_argentina/migration.sql new file mode 100644 index 00000000..60b19a3d --- /dev/null +++ b/prisma/migrations/20260901180000_move_remaining_umbral_sessions_to_1400_argentina/migration.sql @@ -0,0 +1,37 @@ +-- Sai moved the two remaining public-cycle sessions to 14:00 Argentina +-- (America/Argentina/Cordoba, UTC-3), which is 17:00 UTC. Historical sessions +-- keep their actual times. Access, facilitator and room state remain intact. +WITH corrected_sessions ("id", "scheduled_at") AS ( + VALUES + ('50000000-0000-4000-8000-202609050001'::uuid, '2026-09-05 17:00:00'::timestamp), + ('50000000-0000-4000-8000-202609120001'::uuid, '2026-09-12 17:00:00'::timestamp) +) +UPDATE "scheduled_sessions" AS session +SET + "scheduled_at" = corrected_sessions."scheduled_at", + "updated_at" = CURRENT_TIMESTAMP +FROM corrected_sessions +WHERE session."id" = corrected_sessions."id" + AND session."status" = 'SCHEDULED'::"ScheduledSessionStatus"; + +DO $$ +DECLARE + initialized_count integer; + corrected_count integer; +BEGIN + SELECT count(*) INTO initialized_count FROM "users"; + + SELECT count(*) INTO corrected_count + FROM "scheduled_sessions" + WHERE ("id", "scheduled_at") IN ( + ('50000000-0000-4000-8000-202609050001'::uuid, '2026-09-05 17:00:00'::timestamp), + ('50000000-0000-4000-8000-202609120001'::uuid, '2026-09-12 17:00:00'::timestamp) + ) + AND "status" = 'SCHEDULED'::"ScheduledSessionStatus"; + + IF initialized_count = 0 AND corrected_count <> 0 THEN + RAISE EXCEPTION 'Empty installation contains a partial remaining Umbral cycle'; + ELSIF initialized_count > 0 AND corrected_count <> 2 THEN + RAISE EXCEPTION 'Remaining Umbral sessions must both start at 17:00 UTC'; + END IF; +END $$; diff --git a/src/lib/__tests__/public-cycle.test.ts b/src/lib/__tests__/public-cycle.test.ts index cdc849ee..2a546df4 100644 --- a/src/lib/__tests__/public-cycle.test.ts +++ b/src/lib/__tests__/public-cycle.test.ts @@ -14,7 +14,7 @@ describe('public four-Saturday cycle', () => { expect(isPublicCycleSession('10000000-0000-4000-8000-000000000001')).toBe(false); }); - it('keeps the final migration contract at the confirmed 16:00 UTC', () => { + it('preserves the historical four-session correction at 16:00 UTC', () => { const migration = readFileSync( new URL( '../../../prisma/migrations/20260821194000_correct_four_saturday_cycle_start/migration.sql', @@ -31,6 +31,22 @@ describe('public four-Saturday cycle', () => { expect(migration).not.toContain('14:00:00'); }); + it('moves only the two remaining sessions to 14:00 Argentina / 17:00 UTC', () => { + const migration = readFileSync( + new URL( + '../../../prisma/migrations/20260901180000_move_remaining_umbral_sessions_to_1400_argentina/migration.sql', + import.meta.url, + ), + 'utf8', + ); + + expect(migration).toContain("'2026-09-05 17:00:00'::timestamp"); + expect(migration).toContain("'2026-09-12 17:00:00'::timestamp"); + expect(migration).not.toContain('2026-08-22 17:00:00'); + expect(migration).not.toContain('2026-08-29 17:00:00'); + expect(migration).toContain('corrected_count <> 2'); + }); + it('recognizes only an entirely anonymous COMP entitlement for a reviewed public room', () => { const candidate = { staffUser: null,