docs(intel): refresh codebase intelligence at 99f59c3 — capture Phase 4 lists + live-sync

Stale intel reflected commit 01f7456 (pre-Phase-4). Refresh adds the shared-lists
+ SSE subsystem: 21 API endpoints (was 10), lists/sse routes, listEmitter/listAccess/rank
libs, PWA lists surface, 7 new arch decisions, and Phase 4 deps (react-router, @dnd-kit,
fractional-indexing). Canonical filenames preserved; API-SURFACE.md + .last-refresh.json regenerated.
This commit is contained in:
Lucas Berger
2026-06-09 14:57:27 -04:00
parent 99f59c3999
commit d521839a40
6 changed files with 779 additions and 132 deletions
+92 -1
View File
@@ -102,4 +102,95 @@
- **auth:** oidcAuthMiddleware
- **file:** apps/api/src/routes/sse.ts
- **response:** text/event-stream — event: heartbeat, data: { ts, id } every 10s
- **description:** SSE smoke-test endpoint for Pangolin tunnel validation. Phase 4 list-sync events not yet wired.
- **description:** SSE smoke-test endpoint for Pangolin tunnel validation.
## `GET /api/sse/lists`
- **method:** GET
- **path:** /api/sse/lists
- **auth:** oidcAuthMiddleware
- **file:** apps/api/src/routes/sse.ts
- **response:** text/event-stream — events: item:added | item:updated | item:deleted | list:updated | list:deleted, plus heartbeat every 30s
- **description:** Scoped live-list fan-out stream (LIST-04, D-04). Subscribes only to list channels accessible to the caller (owner + shares). Event payload triggers client-side query invalidation (D-10). 30s keepalive heartbeat for Pangolin tunnel.
## `GET /api/lists`
- **method:** GET
- **path:** /api/lists
- **auth:** oidcAuthMiddleware
- **file:** apps/api/src/routes/lists.ts
- **response:** { lists: [{ id, name, isShared, ownerId, activeCount, doneCount, createdAt, updatedAt }] }
- **description:** Scoped list index. Returns only lists the caller owns or has a list_shares row for (T-04-02, D-04). Includes per-list item counts.
## `POST /api/lists`
- **method:** POST
- **path:** /api/lists
- **auth:** oidcAuthMiddleware
- **body:** { name: string, isShared?: boolean (default true) }
- **file:** apps/api/src/routes/lists.ts
- **response:** 201 { id, name, isShared, ownerId, activeCount, doneCount, createdAt, updatedAt }
- **description:** Create a named list. isShared=true (default) auto-inserts list_shares for all other members (D-01/D-02). Shares are server-managed only — no client shares endpoint (T-04-08).
## `PATCH /api/lists/:id`
- **method:** PATCH
- **path:** /api/lists/:id
- **auth:** oidcAuthMiddleware
- **params:** id (path)
- **body:** { name?: string, isShared?: boolean } — at least one field required
- **file:** apps/api/src/routes/lists.ts
- **response:** { id, name, isShared, ownerId, createdAt, updatedAt }
- **description:** Update name and/or isShared. Caller must be owner or sharee. isShared mutations owner-only (T-04-07/T-04-08). Visibility change reconciles list_shares (false→true inserts; true→false deletes all non-owner shares).
## `DELETE /api/lists/:id`
- **method:** DELETE
- **path:** /api/lists/:id
- **auth:** oidcAuthMiddleware
- **params:** id (path)
- **file:** apps/api/src/routes/lists.ts
- **response:** { id }
- **description:** Owner-only delete. Cascade via FK onDelete:cascade removes items and shares. Non-owner sharees receive 403.
## `GET /api/lists/:id/items`
- **method:** GET
- **path:** /api/lists/:id/items
- **auth:** oidcAuthMiddleware
- **params:** id (path)
- **file:** apps/api/src/routes/lists.ts
- **response:** { items: [{ id, listId, text, checked, rank, createdAt, updatedAt }] }
- **description:** Returns all items for the list ordered by rank ASC. Access-gated: owner or sharee only (T-04-05).
## `POST /api/lists/:id/items`
- **method:** POST
- **path:** /api/lists/:id/items
- **auth:** oidcAuthMiddleware
- **params:** id (path)
- **body:** { text: string (1..500) }
- **file:** apps/api/src/routes/lists.ts
- **response:** 201 { id, listId, text, checked, rank, createdAt, updatedAt }
- **description:** Add item to list. Rank assigned via rankForAppend(lastActiveRank) — appends after last unchecked item. Access-gated (T-04-05). publishListEvent item:added fan-out.
## `PATCH /api/list-items/:itemId`
- **method:** PATCH
- **path:** /api/list-items/:itemId
- **auth:** oidcAuthMiddleware
- **params:** itemId (path)
- **body:** exactly one of: { checked: boolean } | { text: string } | { position: string }
- **file:** apps/api/src/routes/lists.ts
- **response:** { id, listId, text, checked, rank, createdAt, updatedAt }
- **description:** Per-field last-write-wins item update (D-08). Exactly one field enforced by Zod (T-04-07). uncheck (checked:false) recomputes rank to active-bottom. 404 if item missing (T-04-09, no upsert). publishListEvent item:updated fan-out.
## `DELETE /api/list-items/:itemId`
- **method:** DELETE
- **path:** /api/list-items/:itemId
- **auth:** oidcAuthMiddleware
- **params:** itemId (path)
- **file:** apps/api/src/routes/lists.ts
- **response:** { id }
- **description:** Delete item instantly (D-06). Delete-wins semantics (D-09): no rollback path. Access-gated: owner or sharee. publishListEvent item:deleted fan-out.