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:
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"_meta": {
|
||||
"updated_at": "2026-06-09T00:00:00Z",
|
||||
"commit": "01f7456b81dd55d477d0bd7530df818f61a873c2",
|
||||
"version": 1
|
||||
"updated_at": "2026-06-09T18:56:37.459Z",
|
||||
"commit": "99f59c3999f4ef992f01ef8f8a38c1d86d2f2a0f",
|
||||
"version": 3
|
||||
},
|
||||
"entries": {
|
||||
"GET /health": {
|
||||
@@ -38,7 +38,10 @@
|
||||
"method": "GET",
|
||||
"path": "/api/events",
|
||||
"auth": "oidcAuthMiddleware",
|
||||
"params": ["start (YYYY-MM-DD, required)", "end (YYYY-MM-DD, required)"],
|
||||
"params": [
|
||||
"start (YYYY-MM-DD, required)",
|
||||
"end (YYYY-MM-DD, required)"
|
||||
],
|
||||
"file": "apps/api/src/routes/events.ts",
|
||||
"response": "{ occurrences: CalendarOccurrence[] }",
|
||||
"description": "Windowed calendar events. Max 90-day window. Reads only from MariaDB cache; never hits Fastmail. Expands RRULEs server-side."
|
||||
@@ -56,7 +59,9 @@
|
||||
"method": "PATCH",
|
||||
"path": "/api/events/:uid/edit",
|
||||
"auth": "oidcAuthMiddleware",
|
||||
"params": ["uid (path)"],
|
||||
"params": [
|
||||
"uid (path)"
|
||||
],
|
||||
"body": "CreateEventPayload",
|
||||
"file": "apps/api/src/routes/events.ts",
|
||||
"response": "202 { uid: string }",
|
||||
@@ -66,7 +71,9 @@
|
||||
"method": "DELETE",
|
||||
"path": "/api/events/:uid",
|
||||
"auth": "oidcAuthMiddleware",
|
||||
"params": ["uid (path)"],
|
||||
"params": [
|
||||
"uid (path)"
|
||||
],
|
||||
"file": "apps/api/src/routes/events.ts",
|
||||
"response": "202 { uid: string }",
|
||||
"description": "Enqueues delete to calendarOutbox with cached etag (If-Match). Async write-back."
|
||||
@@ -75,7 +82,9 @@
|
||||
"method": "GET",
|
||||
"path": "/api/events/sync-status",
|
||||
"auth": "oidcAuthMiddleware",
|
||||
"params": ["uid (query, required)"],
|
||||
"params": [
|
||||
"uid (query, required)"
|
||||
],
|
||||
"file": "apps/api/src/routes/events.ts",
|
||||
"response": "{ uid: string, status: 'pending'|'done'|'failed'|'dead', error?: string }",
|
||||
"description": "Outbox status poll for a given event UID, scoped to current member. Used by SyncStateToast."
|
||||
@@ -94,7 +103,101 @@
|
||||
"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."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user