style(13-03): apply Prettier formatting across repo
Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
This commit is contained in:
@@ -3,7 +3,7 @@ phase: 03-event-write-back-pwa-install
|
||||
plan: 05
|
||||
type: execute
|
||||
wave: 3
|
||||
depends_on: ["03-03"]
|
||||
depends_on: ['03-03']
|
||||
files_modified:
|
||||
- apps/pwa/src/api/client.ts
|
||||
- apps/pwa/src/store/calendarStore.ts
|
||||
@@ -16,29 +16,29 @@ user_setup: []
|
||||
must_haves:
|
||||
truths:
|
||||
- "A member can tap 'New Event', fill the form, and save — POST /api/events/create fires and the form closes"
|
||||
- "The form supports timed and all-day events, a recurrence preset (None/Daily/Weekly/Monthly/Yearly), title/location/description"
|
||||
- "The calendar picker is hidden when the member has exactly one writable calendar (D-02)"
|
||||
- "Edit mode pre-populates the form and calls PATCH /api/events/:uid/edit"
|
||||
- 'The form supports timed and all-day events, a recurrence preset (None/Daily/Weekly/Monthly/Yearly), title/location/description'
|
||||
- 'The calendar picker is hidden when the member has exactly one writable calendar (D-02)'
|
||||
- 'Edit mode pre-populates the form and calls PATCH /api/events/:uid/edit'
|
||||
artifacts:
|
||||
- path: "apps/pwa/src/components/EventForm.tsx"
|
||||
provides: "create/edit modal form (bottom sheet on phone, dialog on desktop)"
|
||||
- path: 'apps/pwa/src/components/EventForm.tsx'
|
||||
provides: 'create/edit modal form (bottom sheet on phone, dialog on desktop)'
|
||||
min_lines: 80
|
||||
- path: "apps/pwa/src/api/client.ts"
|
||||
provides: "createEvent, updateEvent, fetchWritableCalendars typed calls"
|
||||
exports: ["createEvent", "updateEvent", "fetchWritableCalendars"]
|
||||
- path: 'apps/pwa/src/api/client.ts'
|
||||
provides: 'createEvent, updateEvent, fetchWritableCalendars typed calls'
|
||||
exports: ['createEvent', 'updateEvent', 'fetchWritableCalendars']
|
||||
key_links:
|
||||
- from: "apps/pwa/src/components/EventForm.tsx"
|
||||
to: "/api/events/create"
|
||||
via: "createEvent mutation"
|
||||
pattern: "createEvent"
|
||||
- from: "apps/pwa/src/api/client.ts"
|
||||
to: "/api/events/writable-calendars"
|
||||
via: "fetchWritableCalendars GET"
|
||||
pattern: "writable-calendars"
|
||||
- from: "apps/pwa/src/components/CalendarShell.tsx"
|
||||
to: "EventForm"
|
||||
via: "New Event FAB toggles eventFormOpen"
|
||||
pattern: "eventFormOpen"
|
||||
- from: 'apps/pwa/src/components/EventForm.tsx'
|
||||
to: '/api/events/create'
|
||||
via: 'createEvent mutation'
|
||||
pattern: 'createEvent'
|
||||
- from: 'apps/pwa/src/api/client.ts'
|
||||
to: '/api/events/writable-calendars'
|
||||
via: 'fetchWritableCalendars GET'
|
||||
pattern: 'writable-calendars'
|
||||
- from: 'apps/pwa/src/components/CalendarShell.tsx'
|
||||
to: 'EventForm'
|
||||
via: 'New Event FAB toggles eventFormOpen'
|
||||
pattern: 'eventFormOpen'
|
||||
---
|
||||
|
||||
<objective>
|
||||
@@ -95,6 +95,7 @@ Output: EventForm + client write calls + store keys + FAB, all wired to the Plan
|
||||
In client.ts add exported interfaces `CreateEventPayload` (title, allDay, start, end, optional location, description, recurrence: 'none'|'daily'|'weekly'|'monthly'|'yearly', calendarUrl?), `CreateEventResponse` ({ uid }), `WritableCalendar` ({ url, displayName, color, isShared }). Add `createEvent(payload): Promise<CreateEventResponse>` (POST), `updateEvent(uid, payload): Promise<CreateEventResponse>` (PATCH `/api/events/${uid}/edit`), and `fetchWritableCalendars(): Promise<WritableCalendar[]>` (GET `/api/events/writable-calendars`, added by Plan 03 Task 3 — call it unconditionally; parse the JSON `{ calendars }` envelope and return `body.calendars`). The server is the authoritative owner of the D-03 writable set; do NOT derive the writable set on the client. All follow the existing fetch shape with credentials:'include' and `if (!res.ok) throw`.
|
||||
|
||||
In calendarStore.ts extend `CalendarStore` with `eventFormOpen: boolean`, `eventFormMode: 'create'|'edit'`, `eventFormUid: string|null`, plus setters `setEventForm(open, mode?, uid?)`. Defaults: closed, mode 'create', uid null. Keep all server data out of Zustand (D — server state stays in TanStack Query).
|
||||
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/luc/Projects/familysync && pnpm --filter @familysync/pwa exec tsc --noEmit && grep -q "createEvent" apps/pwa/src/api/client.ts && grep -q "writable-calendars" apps/pwa/src/api/client.ts && grep -q "eventFormOpen" apps/pwa/src/store/calendarStore.ts && pnpm --filter @familysync/pwa test</automated>
|
||||
@@ -158,18 +159,20 @@ Output: EventForm + client write calls + store keys + FAB, all wired to the Plan
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| Boundary | Description |
|
||||
| ---------------- | ------------------------------------------------ |
|
||||
| form input → API | Member-typed event fields cross to the write API |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-03-15 | Tampering | XSS via event title/location/description in the form | mitigate | All values rendered as plain-text JSX children; never dangerouslySetInnerHTML (Phase 2 T-02e-01 pattern); server re-validates with zod (Plan 03) |
|
||||
| T-03-16 | Elevation of Privilege | client offering a non-writable calendar in the picker | mitigate | Picker is populated only from the authoritative `GET /api/events/writable-calendars` set (Plan 03, D-03 enforced server-side); the client never derives writability, and the write endpoints re-enforce D-03 ownership on enqueue regardless |
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
| --------- | ---------------------- | ----------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| T-03-15 | Tampering | XSS via event title/location/description in the form | mitigate | All values rendered as plain-text JSX children; never dangerouslySetInnerHTML (Phase 2 T-02e-01 pattern); server re-validates with zod (Plan 03) |
|
||||
| T-03-16 | Elevation of Privilege | client offering a non-writable calendar in the picker | mitigate | Picker is populated only from the authoritative `GET /api/events/writable-calendars` set (Plan 03, D-03 enforced server-side); the client never derives writability, and the write endpoints re-enforce D-03 ownership on enqueue regardless |
|
||||
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
@@ -179,9 +182,10 @@ Output: EventForm + client write calls + store keys + FAB, all wired to the Plan
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- CAL-04 and CAL-07 create paths are user-reachable through EventForm → POST /api/events/create.
|
||||
- Edit mode pre-populates and PATCHes; calendar picker honors D-01/D-02, sourced from the Plan 03 writable-calendars endpoint.
|
||||
</success_criteria>
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/03-event-write-back-pwa-install/03-05-SUMMARY.md` when done.
|
||||
|
||||
Reference in New Issue
Block a user