docs(03): finalize phase plan (8 plans, verified)
This commit is contained in:
@@ -811,23 +811,26 @@ const isInstalled = window.matchMedia('(display-mode: standalone)').matches
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
## Open Questions (RESOLVED)
|
||||
|
||||
1. **Fastmail object URL format**
|
||||
- What we know: `tsdav` `fetchCalendarObjects` returns `DAVCalendarObject` with a `url` field; Fastmail CalDAV URLs follow the pattern `https://caldav.fastmail.com/dav/calendars/user/<email>/<calendar-slug>/<uid>.ics`
|
||||
- What's unclear: Whether the URL is returned verbatim by `fetchCalendarObjects` or constructed — and whether the `calendarObjectUrl` stored in the outbox is stable across syncs
|
||||
- Recommendation: At worker time, fetch fresh object URLs from the DB `calendarEvents.url` column (which does not exist yet — the schema needs a `url` column added to `calendarEvents` for the CalDAV object URL). Alternatively, construct it from `calendars.url + uid + '.ics'` — verify against a real REPORT response in Wave 0.
|
||||
- **Action for planner:** Add `objectUrl varchar(1024)` to `calendarEvents` schema OR document URL construction convention.
|
||||
- **Resolution:** RESOLVED — `objectUrl` column added to `calendarEvents` in plan 03-01 Task 2 and populated from `obj.url` in `sync.ts` (03-01 Task 3); the worker reads the stored object URL rather than reconstructing it.
|
||||
|
||||
2. **`calendarEvents` schema missing object URL**
|
||||
- What we know: Current `calendarEvents` schema has `uid`, `etag`, `rawVevent` but no `url` field. The object URL is needed for `updateCalendarObject` and `deleteCalendarObject`.
|
||||
- What's unclear: Whether `tsdav` `fetchCalendarObjects` returns a `url` field in the `DAVCalendarObject` (it does — the tsdav type shows `url: string`). So the URL can be stored at sync time.
|
||||
- Recommendation: Add `objectUrl varchar(1024)` to `calendarEvents` in the schema migration. Populate it from `obj.url` in `sync.ts` alongside `etag`.
|
||||
- **Resolution:** RESOLVED — same as Q1: `calendarEvents.objectUrl` (`object_url varchar(1024)`) added in plan 03-01 Task 2 and set from `obj.url` in `sync.ts` (03-01 Task 3).
|
||||
|
||||
3. **Writable calendar set resolution (D-03)**
|
||||
- What we know: D-03 says writable = own personal + shared Family; D-16 says shared calendar not yet created; `calendars.isShared` marks the shared one.
|
||||
- What's unclear: How the API knows which calendars belong to the current user vs being read-only overlays from other members. Currently, `calendars` rows are owned by `userId` — the current user's writable set is simply `WHERE userId = currentUser.id`.
|
||||
- Recommendation: Writable set = `SELECT * FROM calendars WHERE user_id = :userId` (personal) UNION the row where `is_shared = 1` (shared family). This matches D-03 with no additional schema changes.
|
||||
- **Resolution:** RESOLVED via Option A (server-side endpoint) — `GET /api/events/writable-calendars` (plan 03-03 Task 3) is the authoritative owner of the D-03 writable set (`userId = currentUser.id OR isShared = true`); the PWA picker consumes it verbatim (03-05 Task 1) and never derives writability client-side.
|
||||
|
||||
---
|
||||
|
||||
@@ -877,6 +880,7 @@ const isInstalled = window.matchMedia('(display-mode: standalone)').matches
|
||||
| CAL-07 | `buildVeventString` with `rruleString` produces VCALENDAR with RRULE property | unit | same | ❌ Wave 0 |
|
||||
| CAL-04/05/06 | Outbox worker transitions status: pending→done on mock 204, pending→failed on mock 412, pending→backoff on mock 500 | unit | `pnpm --filter @familysync/api test -- broker/outboxWorker` | ❌ Wave 0 |
|
||||
| CAL-04/05/06 | GET /api/events/sync-status returns correct status from outbox row | unit | same events test | ❌ Wave 0 |
|
||||
| CAL-04/05/07 | GET /api/events/writable-calendars returns D-03 writable set; never another member's read-only personal (V4) | unit | `pnpm --filter @familysync/api test -- routes/events` | ❌ Wave 0 |
|
||||
| D-08 | 412 response routes to conflict (not retry), marks failed, triggers re-sync | unit | same outboxWorker test | ❌ Wave 0 |
|
||||
| D-04 | Edit-as-move creates DELETE + CREATE pair; create runs first | unit | same outboxWorker test | ❌ Wave 0 |
|
||||
| PWA-01 | `vite.config.ts` produces a valid `manifest.webmanifest` with required fields | smoke (build output check) | `pnpm --filter @familysync/pwa build && node -e "..."` | ❌ Wave 0 |
|
||||
|
||||
Reference in New Issue
Block a user