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:
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -477,7 +477,9 @@ 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
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue([
|
||||||
{ data: rawVeventWithValarm, etag: '"etag-valarm"', url: '/cal/valarm.ics' },
|
{ data: rawVeventWithValarm, etag: '"etag-valarm"', url: '/cal/valarm.ics' },
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
@@ -505,7 +507,9 @@ 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
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue([
|
||||||
{ data: rawVeventNoValarm, etag: '"etag-no-valarm"', url: '/cal/no-valarm.ics' },
|
{ data: rawVeventNoValarm, etag: '"etag-no-valarm"', url: '/cal/no-valarm.ics' },
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
@@ -619,7 +623,9 @@ 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
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue([
|
||||||
{ data: rawVeventWithValarm, etag: '"etag-upsert"', url: '/cal/upsert.ics' },
|
{ data: rawVeventWithValarm, etag: '"etag-upsert"', url: '/cal/upsert.ics' },
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user