- pnpm 10 workspace + TypeScript strict + ESLint flat + Prettier - CLAUDE.md as canonical brief - docs/tasks/ — 22 task briefs broken out by phase for sub-sessions - docs/decisions/ — ADR scaffold Implements task 01 (repo-init).
2.0 KiB
2.0 KiB
10 — Calendar module
Goal
Implement the calendar module: shared events with month/week/day views and CRUD.
Depends on
- 04 (module loader), 07 (household)
Scope
Schema (src/modules/calendar/schema.ts)
calendar_events:iduuid pkhousehold_idfktitletextstart_attimestamptz,end_attimestamptzall_daybooleanlocationtext nullablenotestext nullablecolortext nullableowner_idfk usersrruletext nullable (reserved; no UI)external_sourcetext nullable,external_idtext nullable (reserved)created_at,updated_at
Server (src/modules/calendar/server/)
listEvents({ from, to })— household-scoped, range query.createEvent,updateEvent,deleteEvent— server actions, validate with Zod.
UI (src/modules/calendar/components/)
/calendarpage with month / week / day toggle. Recommended lib: FullCalendar (@fullcalendar/react+ day/week/month plugins) — handles the heavy lifting; we own only the data layer.- Click a day cell → create-event dialog. Click an event → edit dialog. Drag-resize updates
end_at.
Manifest
- Registers entity type
calendar.eventwithshareenabled (read-only by default),reminderenabled,searchenabled (title + notes + location). - Registers nav entry
/calendar. - Dashboard widget: next 3 days (built in task 20, but expose the data fetcher here).
- Quick-add: "New event" → opens create dialog.
Out of scope
- Recurrence UI (rrule column reserved, ignored on read).
- External calendar sync.
- Free/busy aggregation across users.
Acceptance criteria
- CRUD works end-to-end with optimistic updates.
- All queries scoped to
household_id; cross-household leakage is impossible (verify with a second seeded household in a test). - Manifest registers all four capabilities (entity, nav, widget data, quick-add).
- One Playwright happy-path test: create → see on calendar → edit → delete.