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.
9.4 KiB
phase, plan, type, wave, depends_on, gap_closure, autonomous, requirements, files_modified, must_haves
| phase | plan | type | wave | depends_on | gap_closure | autonomous | requirements | files_modified | must_haves | |||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 03-event-write-back-pwa-install | 09 | tdd | 1 | true | true |
|
|
|
Purpose: make the events router accept real client requests under real Authelia auth.
Output: an events router whose schema matches CreateEventPayload and whose OIDC
path resolves authenticated members to a DB user via the existing upsertUser helper.
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/03-event-write-back-pwa-install/03-REVIEW.md @.planning/phases/03-event-write-back-pwa-install/03-CONTEXT.md @apps/api/src/routes/events.ts @apps/api/src/auth/user.ts @apps/api/src/routes/me.ts @apps/pwa/src/api/client.ts<artifacts_this_phase_produces>
This gap plan introduces NO new exported symbols. It changes the in-module
eventFieldsSchema field names and converts the private resolveUserId(c) helper
into an async resolveUserId(c): Promise<number | null> that consults upsertUser.
Downstream gap plans (03-10) read the new field names (title/start/end) out of
calendarOutbox.payload.
</artifacts_this_phase_produces>
In events.ts rename `eventFieldsSchema` fields to exactly:
`title: z.string().min(1).max(255)`, `allDay: z.boolean()`,
`start: z.string().min(1).max(64)`, `end: z.string().min(1).max(64)`,
`location: z.string().max(2000).optional()`, `description: z.string().max(2000).optional()`,
`recurrence: z.enum(['none','daily','weekly','monthly','yearly']).optional()`,
`calendarUrl: z.string().url().max(1024).optional()`.
Keep `recurrence` `.optional()` server-side (the client always sends it, but the
contract drift the review noted resolves either way once names match).
The route still stores `payload: JSON.stringify(payload)` unchanged — the worker
(plan 03-10) now parses `title/start/end` from it. Do NOT introduce summary/dtstart/dtend
anywhere; do NOT add an internal rename map (the review's "map internally" alternative is
rejected to keep one canonical name set end-to-end).
Add the two contract tests described in <behavior>. Commit RED then GREEN
(`test(03-09): ...` then `feat(03-09): ...`).
In each of the 5 handlers (create, edit, delete, sync-status, writable-calendars)
replace the `resolveUserId(...)` call + inline getAuth/401 stub block with:
`const currentUserId = await resolveUserId(c)` then `if (currentUserId === null) return c.json({ error: 'Unauthorized' }, 401)`.
Remove every `// For now return 401` stub and the now-redundant inner `getAuth` calls in the handlers.
Per D-10 identity is oidc_iss+oidc_sub; upsertUser keys on `uniq_oidc_identity`. Return 401 ONLY when no session exists (covered by upsertUser path).
Add the two tests in <behavior>. Commit RED then GREEN.
<success_criteria> The events router accepts the real PWA payload and resolves real OIDC members. The write path is no longer dead-on-arrival at the route boundary (CR-01, CR-06 closed). </success_criteria>
Create `.planning/phases/03-event-write-back-pwa-install/03-09-SUMMARY.md` when done.