docs(20-02): create summary and update state for frontend subscriptions
Phase 20 (Real-Time Subscriptions) is now complete. Both plans delivered: - 20-01: SSE backend with subscription procedures - 20-02: Frontend splitLink + subscription hooks on all 3 UI pages
This commit is contained in:
@@ -9,19 +9,19 @@ See: .planning/PROJECT.md (updated 2026-02-04)
|
||||
|
||||
## Current Position
|
||||
|
||||
Phase: 20 of 21 (Real-Time Subscriptions) - IN PROGRESS
|
||||
Plan: 1 of 2 in current phase
|
||||
Status: Completed 20-01 (SSE Streaming & Subscription Procedures)
|
||||
Last activity: 2026-02-04 - Completed 20-01-PLAN.md (SSE backend)
|
||||
Phase: 20 of 21 (Real-Time Subscriptions) - COMPLETE
|
||||
Plan: 2 of 2 in current phase (all complete)
|
||||
Status: Completed 20-02 (Frontend SSE Subscription Hooks)
|
||||
Last activity: 2026-02-04 - Completed 20-02-PLAN.md (frontend subscriptions)
|
||||
|
||||
Progress: █████████░ 99%
|
||||
|
||||
## Performance Metrics
|
||||
|
||||
**Velocity:**
|
||||
- Total plans completed: 71
|
||||
- Total plans completed: 72
|
||||
- Average duration: 3 min
|
||||
- Total execution time: 201 min
|
||||
- Total execution time: 204 min
|
||||
|
||||
**By Phase (v1.0):**
|
||||
|
||||
@@ -229,6 +229,10 @@ Recent decisions affecting current work:
|
||||
- 20-01: tracked() wrapper on each event for client-side reconnection via lastEventId
|
||||
- 20-01: Fallback AbortSignal (new AbortController().signal) when opts.signal is undefined
|
||||
- 20-01: Vite proxy works for SSE without changes (http-proxy streams chunked responses by default)
|
||||
- 20-02: httpSubscriptionLink (stable export) over unstable_ prefix — both available in @trpc/client v11
|
||||
- 20-02: Subscription-driven invalidation (not local state) — simplest approach, reuses existing React Query cache
|
||||
- 20-02: Silent onError callbacks — pages degrade to manual refresh when backend is not running
|
||||
- 20-02: No new packages needed — splitLink and httpSubscriptionLink ship with @trpc/client v11
|
||||
|
||||
### Pending Todos
|
||||
|
||||
@@ -251,5 +255,5 @@ None.
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-02-04
|
||||
Stopped at: Completed 20-01 (SSE Streaming & Subscription Procedures)
|
||||
Stopped at: Completed 20-02 (Frontend SSE Subscription Hooks) — Phase 20 complete
|
||||
Resume file: None
|
||||
|
||||
112
.planning/phases/20-real-time-subscriptions/20-02-SUMMARY.md
Normal file
112
.planning/phases/20-real-time-subscriptions/20-02-SUMMARY.md
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
phase: 20-real-time-subscriptions
|
||||
plan: 02
|
||||
subsystem: frontend
|
||||
tags: [trpc, sse, subscriptions, react-query, live-updates, splitLink]
|
||||
|
||||
requires:
|
||||
- phase: 20-real-time-subscriptions
|
||||
plan: 01
|
||||
provides: SSE subscription procedures (onEvent, onAgentUpdate, onTaskUpdate)
|
||||
- phase: 16-frontend-scaffold
|
||||
provides: tRPC client and React Query setup
|
||||
|
||||
provides:
|
||||
- splitLink routing subscriptions to httpSubscriptionLink (SSE)
|
||||
- Live update hooks on all three UI pages (dashboard, detail, inbox)
|
||||
- Automatic React Query cache invalidation on domain events
|
||||
|
||||
affects: [21-frontend-polish]
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: [splitLink for operation-type routing, subscription-driven cache invalidation]
|
||||
|
||||
key-files:
|
||||
modified:
|
||||
- packages/web/src/lib/trpc.ts
|
||||
- packages/web/src/routes/initiatives/index.tsx
|
||||
- packages/web/src/routes/initiatives/$id.tsx
|
||||
- packages/web/src/routes/inbox.tsx
|
||||
|
||||
key-decisions:
|
||||
- "httpSubscriptionLink (stable export) over unstable_ prefix — both available in @trpc/client v11"
|
||||
- "Subscription-driven invalidation (not local state) — simplest approach, reuses existing React Query cache"
|
||||
- "Silent onError callbacks — pages degrade to manual refresh when backend is not running"
|
||||
- "No new packages needed — splitLink and httpSubscriptionLink ship with @trpc/client v11"
|
||||
|
||||
patterns-established:
|
||||
- "useSubscription + useUtils().invalidate for live updates on any page"
|
||||
|
||||
duration: 3min
|
||||
completed: 2026-02-04
|
||||
---
|
||||
|
||||
# Plan 20-02: Frontend SSE Subscription Hooks Summary
|
||||
|
||||
**Wire frontend tRPC client with SSE subscriptions and live update hooks on all three UI pages**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 3 min
|
||||
- **Started:** 2026-02-04
|
||||
- **Completed:** 2026-02-04
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 4
|
||||
|
||||
## Accomplishments
|
||||
- Replaced single httpBatchLink with splitLink routing subscriptions to httpSubscriptionLink (SSE)
|
||||
- Added onTaskUpdate subscription to dashboard page (invalidates listInitiatives + listPhases)
|
||||
- Added onTaskUpdate + onAgentUpdate subscriptions to initiative detail page (invalidates phases, tasks, plans, agents)
|
||||
- Added onAgentUpdate subscription to inbox page (invalidates listWaitingAgents + listMessages)
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: Update tRPC client with splitLink for SSE subscriptions** - `eaf3f10` (feat)
|
||||
2. **Task 2: Add live update hooks to all three UI pages** - `170ac55` (feat)
|
||||
|
||||
## Files Modified
|
||||
- `packages/web/src/lib/trpc.ts` - splitLink routing subscriptions to httpSubscriptionLink
|
||||
- `packages/web/src/routes/initiatives/index.tsx` - onTaskUpdate subscription for dashboard
|
||||
- `packages/web/src/routes/initiatives/$id.tsx` - onTaskUpdate + onAgentUpdate subscriptions for detail
|
||||
- `packages/web/src/routes/inbox.tsx` - onAgentUpdate subscription for inbox
|
||||
|
||||
## Decisions Made
|
||||
- 20-02: httpSubscriptionLink (stable export) used over unstable_ prefix variant
|
||||
- 20-02: Subscription-driven invalidation pattern — no local event state, just invalidate React Query caches
|
||||
- 20-02: Silent onError callbacks so pages degrade gracefully without backend
|
||||
- 20-02: No new packages — splitLink and httpSubscriptionLink are core @trpc/client v11 exports
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 3 - Blocking] Duplicate useUtils() declaration in inbox.tsx**
|
||||
- **Found during:** Task 2 (inbox page)
|
||||
- **Issue:** Adding `const utils = trpc.useUtils()` for the subscription created a duplicate declaration (already existed lower in the function for mutations)
|
||||
- **Fix:** Moved the existing `useUtils()` call above the subscription hook and removed the duplicate
|
||||
- **Files modified:** packages/web/src/routes/inbox.tsx
|
||||
- **Verification:** `npm run build` succeeds
|
||||
- **Committed in:** 170ac55 (Task 2 commit)
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 1 auto-fixed (1 blocking)
|
||||
**Impact on plan:** Trivial reorder of existing code. No scope creep.
|
||||
|
||||
## Issues Encountered
|
||||
None
|
||||
|
||||
## User Setup Required
|
||||
None - SSE works over standard HTTP through the existing Vite dev proxy.
|
||||
|
||||
## Next Phase Readiness
|
||||
- Phase 20 (Real-Time Subscriptions) is now complete
|
||||
- All three UI pages receive live updates via SSE when domain events fire
|
||||
- Phase 21 (Frontend Polish) can proceed
|
||||
|
||||
---
|
||||
*Phase: 20-real-time-subscriptions*
|
||||
*Completed: 2026-02-04*
|
||||
Reference in New Issue
Block a user