feat(11-04): add reminderLeadMinutes to CreateEventPayload + CalendarOccurrence
- CalendarOccurrence: required reminderLeadMinutes: number | null (atomic mirror of expand.ts, Plan 11-03) - CreateEventPayload: optional reminderLeadMinutes?: number | null with absent/null/0/positive contract (D-08) - Update CalendarOccurrence fixtures in EventForm.test.tsx + EventDetailPopover.test.tsx to include the new required field (reminderLeadMinutes: null) - pwa tsc --noEmit exits 0
This commit is contained in:
@@ -131,6 +131,14 @@ export interface CalendarOccurrence {
|
|||||||
* stay in sync with the server type (Pitfall 4 — atomic mirror, Plan 06-05).
|
* stay in sync with the server type (Pitfall 4 — atomic mirror, Plan 06-05).
|
||||||
*/
|
*/
|
||||||
hasRrule: boolean;
|
hasRrule: boolean;
|
||||||
|
/**
|
||||||
|
* Per-event reminder lead in minutes. NULL = no reminder. 0 = same-day all-day
|
||||||
|
* (fire 9 AM on event date). Positive integer = N minutes before event start.
|
||||||
|
* D-06: NULL and 0 are semantically distinct.
|
||||||
|
* Mirrors CalendarOccurrence.reminderLeadMinutes in apps/api/src/broker/expand.ts
|
||||||
|
* (atomic mirror, Plan 11-03).
|
||||||
|
*/
|
||||||
|
reminderLeadMinutes: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OccurrencesResponse {
|
export interface OccurrencesResponse {
|
||||||
@@ -194,6 +202,14 @@ export interface CreateEventPayload {
|
|||||||
recurrenceCount?: number;
|
recurrenceCount?: number;
|
||||||
location?: string;
|
location?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
/**
|
||||||
|
* Per-event reminder lead in minutes.
|
||||||
|
* absent/undefined = no-change (edit omits field so server preserves existing VALARM, D-08)
|
||||||
|
* null = explicit "None" (clear any VALARM)
|
||||||
|
* 0 = same-day all-day (fire 9 AM on event date, D-05)
|
||||||
|
* positive integer = N minutes before event start
|
||||||
|
*/
|
||||||
|
reminderLeadMinutes?: number | null;
|
||||||
calendarUrl?: string; // omit to use the member's default writable calendar (D-01)
|
calendarUrl?: string; // omit to use the member's default writable calendar (D-01)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ const TIMED_OCCURRENCE: CalendarOccurrence = {
|
|||||||
location: 'Conference Room B',
|
location: 'Conference Room B',
|
||||||
description: 'Daily team sync meeting',
|
description: 'Daily team sync meeting',
|
||||||
hasRrule: false,
|
hasRrule: false,
|
||||||
|
reminderLeadMinutes: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const OCCURRENCE_WITH_HTML: CalendarOccurrence = {
|
const OCCURRENCE_WITH_HTML: CalendarOccurrence = {
|
||||||
@@ -86,6 +87,7 @@ const ALLDAY_OCCURRENCE: CalendarOccurrence = {
|
|||||||
location: null,
|
location: null,
|
||||||
description: null,
|
description: null,
|
||||||
hasRrule: false,
|
hasRrule: false,
|
||||||
|
reminderLeadMinutes: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ── Import component (after mocks are declared) ───────────────────────────────
|
// ── Import component (after mocks are declared) ───────────────────────────────
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ const EDIT_OCCURRENCE: CalendarOccurrence = {
|
|||||||
location: 'Office',
|
location: 'Office',
|
||||||
description: 'Weekly sync',
|
description: 'Weekly sync',
|
||||||
hasRrule: false,
|
hasRrule: false,
|
||||||
|
reminderLeadMinutes: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ── Import component (after mocks) ────────────────────────────────────────────
|
// ── Import component (after mocks) ────────────────────────────────────────────
|
||||||
@@ -506,6 +507,7 @@ const RECURRING_OCCURRENCE: CalendarOccurrence = {
|
|||||||
location: null,
|
location: null,
|
||||||
description: null,
|
description: null,
|
||||||
hasRrule: true,
|
hasRrule: true,
|
||||||
|
reminderLeadMinutes: null,
|
||||||
// @ts-expect-error — recurrence is not on CalendarOccurrence type yet; the reset
|
// @ts-expect-error — recurrence is not on CalendarOccurrence type yet; the reset
|
||||||
// effect reads it if present and defaults to 'none' when absent (WR-03, v1 comment)
|
// effect reads it if present and defaults to 'none' when absent (WR-03, v1 comment)
|
||||||
recurrence: 'weekly',
|
recurrence: 'weekly',
|
||||||
@@ -532,6 +534,7 @@ const LATE_OCCURRENCE: CalendarOccurrence = {
|
|||||||
location: null,
|
location: null,
|
||||||
description: null,
|
description: null,
|
||||||
hasRrule: false,
|
hasRrule: false,
|
||||||
|
reminderLeadMinutes: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('EventForm — Plan 03-12 gap closures', () => {
|
describe('EventForm — Plan 03-12 gap closures', () => {
|
||||||
@@ -779,6 +782,7 @@ const ALL_DAY_OCCURRENCE: CalendarOccurrence = {
|
|||||||
location: null,
|
location: null,
|
||||||
description: null,
|
description: null,
|
||||||
hasRrule: false,
|
hasRrule: false,
|
||||||
|
reminderLeadMinutes: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('EventForm — Plan 06-06 end-tracking + recurrence-bound', () => {
|
describe('EventForm — Plan 06-06 end-tracking + recurrence-bound', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user