style(11-04): apply prettier to phase-11 modified files

- apps/pwa/src/components/EventForm.tsx (Task 2)
- apps/api/src/broker/{expand,reminderScheduler,sync,vevent}.ts (Plans 11-01/11-03)
- apps/api/tests/broker/{reminderScheduler,sync}.test.ts (Plans 11-01/11-03)
This commit is contained in:
Lucas Berger
2026-06-14 06:54:11 -04:00
parent fe549ef2b0
commit b9b3191b5b
7 changed files with 24 additions and 28 deletions
+1 -3
View File
@@ -243,9 +243,7 @@ export function expandOccurrences(
// classifyValarms wraps ICAL.parse in try/catch (T-11-07 safe); safe on parse failure → null. // classifyValarms wraps ICAL.parse in try/catch (T-11-07 safe); safe on parse failure → null.
const alarmClass = classifyValarms(rawVevent); const alarmClass = classifyValarms(rawVevent);
const reminderLeadMinutes: number | null = const reminderLeadMinutes: number | null =
alarmClass.kind === 'preset' || alarmClass.kind === 'offlist' alarmClass.kind === 'preset' || alarmClass.kind === 'offlist' ? alarmClass.leadMinutes : null;
? alarmClass.leadMinutes
: null;
// --- 4. Non-recurring event: single occurrence check --- // --- 4. Non-recurring event: single occurrence check ---
if (!isRecurring) { if (!isRecurring) {
+3 -3
View File
@@ -183,8 +183,8 @@ export async function runReminderCheck(now = new Date()): Promise<void> {
{ {
uid: string; uid: string;
title: string | null; title: string | null;
dtstartMs: number; // key component — used for compound dedup key dtstartMs: number; // key component — used for compound dedup key
pruneMs: number; // when to prune: dtstartUtc for timed; end-of-event-date for all-day pruneMs: number; // when to prune: dtstartUtc for timed; end-of-event-date for all-day
reminderLeadMinutes: number; reminderLeadMinutes: number;
dateStr: string; dateStr: string;
subs: SubRow[]; subs: SubRow[];
@@ -233,7 +233,7 @@ export async function runReminderCheck(now = new Date()): Promise<void> {
const serverTz = process.env.TZ ?? Intl.DateTimeFormat().resolvedOptions().timeZone; const serverTz = process.env.TZ ?? Intl.DateTimeFormat().resolvedOptions().timeZone;
for (const row of allDayRows) { for (const row of allDayRows) {
// Drizzle's date() column type is Date|null in TS but mysql2 returns ISO string at runtime // Drizzle's date() column type is Date|null in TS but mysql2 returns ISO string at runtime
const dtstartDate = (row.dtstartDate as unknown) as string; // 'YYYY-MM-DD' const dtstartDate = row.dtstartDate as unknown as string; // 'YYYY-MM-DD'
const lead = row.reminderLeadMinutes as number; const lead = row.reminderLeadMinutes as number;
// D-06: all-day 0 is valid (same-day 9 AM) — do NOT skip // D-06: all-day 0 is valid (same-day 9 AM) — do NOT skip
+1 -3
View File
@@ -136,9 +136,7 @@ export async function syncCalendar(
// none → null (no VALARM present). // none → null (no VALARM present).
const alarmClass = classifyValarms(obj.data as string); const alarmClass = classifyValarms(obj.data as string);
const reminderLeadMinutesValue: number | null = const reminderLeadMinutesValue: number | null =
alarmClass.kind === 'preset' || alarmClass.kind === 'offlist' alarmClass.kind === 'preset' || alarmClass.kind === 'offlist' ? alarmClass.leadMinutes : null;
? alarmClass.leadMinutes
: null;
// NOTIF-03: look up the existing row so we can classify add vs update. // NOTIF-03: look up the existing row so we can classify add vs update.
// One indexed lookup on (calendarId, uid) — cheap, covered by uniq_calendar_uid. // One indexed lookup on (calendarId, uid) — cheap, covered by uniq_calendar_uid.
+1 -5
View File
@@ -230,11 +230,7 @@ export function extractValarms(rawVevent: string): ICAL.Component[] {
* @param leadDays — days before event date (0 = same day, 1 = 1 day before, etc.) * @param leadDays — days before event date (0 = same day, 1 = 1 day before, etc.)
* @param tz — IANA timezone identifier (e.g. 'America/New_York') * @param tz — IANA timezone identifier (e.g. 'America/New_York')
*/ */
export function computeAlertInstantUtc( export function computeAlertInstantUtc(eventDateStr: string, leadDays: number, tz: string): Date {
eventDateStr: string,
leadDays: number,
tz: string,
): Date {
// Parse event date as UTC midnight, then subtract lead days to get alert date // Parse event date as UTC midnight, then subtract lead days to get alert date
const [y, m, d] = eventDateStr.split('-').map(Number) as [number, number, number]; const [y, m, d] = eventDateStr.split('-').map(Number) as [number, number, number];
const alertDateUtcMs = Date.UTC(y, m - 1, d - leadDays); const alertDateUtcMs = Date.UTC(y, m - 1, d - leadDays);
@@ -97,7 +97,8 @@ function makeEventRow(overrides: {
dtstartDate: overrides.dtstartDate !== undefined ? overrides.dtstartDate : null, dtstartDate: overrides.dtstartDate !== undefined ? overrides.dtstartDate : null,
allDay: overrides.allDay ?? false, allDay: overrides.allDay ?? false,
isShared: overrides.isShared ?? true, isShared: overrides.isShared ?? true,
reminderLeadMinutes: overrides.reminderLeadMinutes !== undefined ? overrides.reminderLeadMinutes : 15, reminderLeadMinutes:
overrides.reminderLeadMinutes !== undefined ? overrides.reminderLeadMinutes : 15,
subId: overrides.subId ?? 1, subId: overrides.subId ?? 1,
subUserId: overrides.subUserId ?? 1, subUserId: overrides.subUserId ?? 1,
subEndpoint: overrides.subEndpoint ?? 'https://push.example.com/1', subEndpoint: overrides.subEndpoint ?? 'https://push.example.com/1',
+15 -9
View File
@@ -477,9 +477,11 @@ describe('syncCalendar — reminderLeadMinutes from VALARM (Phase 11 Plan 03 Tas
].join('\r\n'); ].join('\r\n');
const mockClient = { const mockClient = {
fetchCalendarObjects: vi.fn().mockResolvedValue([ fetchCalendarObjects: vi
{ data: rawVeventWithValarm, etag: '"etag-valarm"', url: '/cal/valarm.ics' }, .fn()
]), .mockResolvedValue([
{ data: rawVeventWithValarm, etag: '"etag-valarm"', url: '/cal/valarm.ics' },
]),
}; };
await syncCalendar(mockClient as never, MOCK_DAV_CAL as never, 1); await syncCalendar(mockClient as never, MOCK_DAV_CAL as never, 1);
@@ -505,9 +507,11 @@ describe('syncCalendar — reminderLeadMinutes from VALARM (Phase 11 Plan 03 Tas
].join('\r\n'); ].join('\r\n');
const mockClient = { const mockClient = {
fetchCalendarObjects: vi.fn().mockResolvedValue([ fetchCalendarObjects: vi
{ data: rawVeventNoValarm, etag: '"etag-no-valarm"', url: '/cal/no-valarm.ics' }, .fn()
]), .mockResolvedValue([
{ data: rawVeventNoValarm, etag: '"etag-no-valarm"', url: '/cal/no-valarm.ics' },
]),
}; };
await syncCalendar(mockClient as never, MOCK_DAV_CAL as never, 1); await syncCalendar(mockClient as never, MOCK_DAV_CAL as never, 1);
@@ -619,9 +623,11 @@ describe('syncCalendar — reminderLeadMinutes from VALARM (Phase 11 Plan 03 Tas
].join('\r\n'); ].join('\r\n');
const mockClient = { const mockClient = {
fetchCalendarObjects: vi.fn().mockResolvedValue([ fetchCalendarObjects: vi
{ data: rawVeventWithValarm, etag: '"etag-upsert"', url: '/cal/upsert.ics' }, .fn()
]), .mockResolvedValue([
{ data: rawVeventWithValarm, etag: '"etag-upsert"', url: '/cal/upsert.ics' },
]),
}; };
await syncCalendar(mockClient as never, MOCK_DAV_CAL as never, 1); await syncCalendar(mockClient as never, MOCK_DAV_CAL as never, 1);
+1 -4
View File
@@ -80,10 +80,7 @@ function humanizeReminderLead(minutes: number): string {
* string for an off-list value (synthetic option will be rendered for this case). * string for an off-list value (synthetic option will be rendered for this case).
* There is no '__custom__' path here — the occurrence only carries number|null. * There is no '__custom__' path here — the occurrence only carries number|null.
*/ */
function deriveReminderValue( function deriveReminderValue(leadMinutes: number | null, isAllDay: boolean): string {
leadMinutes: number | null,
isAllDay: boolean,
): string {
if (leadMinutes === null) return '__none__'; if (leadMinutes === null) return '__none__';
const presets = isAllDay ? ALLDAY_REMINDER_PRESETS : TIMED_REMINDER_PRESETS; const presets = isAllDay ? ALLDAY_REMINDER_PRESETS : TIMED_REMINDER_PRESETS;
if (presets.has(leadMinutes)) return String(leadMinutes); if (presets.has(leadMinutes)) return String(leadMinutes);