Phase 18: Initiative Detail - 4 plans in 2 waves - 3 parallel (wave 1), 1 sequential (wave 2) - Ready for execution
7.1 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous
| phase | plan | type | wave | depends_on | files_modified | autonomous | ||||
|---|---|---|---|---|---|---|---|---|---|---|
| 18-initiative-detail | 04 | execute | 2 |
|
|
true |
Purpose: Replace the placeholder detail page with a fully functional initiative detail view that fetches data from the backend, renders the phase/task hierarchy, and provides queue action buttons. Output: Working Initiative Detail page matching the wireframe specification.
<execution_context>
@/.claude/get-shit-done/workflows/execute-plan.md
@/.claude/get-shit-done/templates/summary.md
</execution_context>
Prior plan summaries — need to know what components were created
@.planning/phases/18-initiative-detail/18-01-SUMMARY.md @.planning/phases/18-initiative-detail/18-02-SUMMARY.md @.planning/phases/18-initiative-detail/18-03-SUMMARY.md
Wireframe spec
@docs/wireframes/initiative-detail.md
Existing page pattern to follow
@packages/web/src/routes/initiatives/index.tsx
Components created in plans 01-03
@packages/web/src/components/InitiativeHeader.tsx @packages/web/src/components/ProgressPanel.tsx @packages/web/src/components/PhaseAccordion.tsx @packages/web/src/components/TaskRow.tsx @packages/web/src/components/DependencyIndicator.tsx @packages/web/src/components/DecisionList.tsx @packages/web/src/components/TaskDetailModal.tsx
tRPC client and types
@packages/web/src/lib/trpc.ts @packages/shared/src/types.ts
tRPC router — need exact procedure signatures
@src/trpc/router.ts
Task 1: Wire Initiative Detail page with data fetching and all components packages/web/src/routes/initiatives/$id.tsx Replace the placeholder content with the full initiative detail page.Data fetching strategy:
The page needs to assemble a nested data structure (initiative → phases → tasks) from multiple tRPC calls. Use React Query's useQuery hooks with proper enabled chaining.
trpc.getInitiative.useQuery({ id })— fetch initiative by route param$idtrpc.listPhases.useQuery({ initiativeId: id })— fetch all phases- For each phase, fetch plans:
trpc.listPlans.useQuery({ phaseId })— but since hooks can't be called conditionally, use a pattern where the page fetches all plans for all phases. Usetrpc.useQueries()if available, or fetch plans in a child component.
Recommended approach for nested fetching:
Create a helper component PhaseWithTasks that:
- Receives a phase
- Calls
trpc.listPlans.useQuery({ phaseId: phase.id })to get plans - For each plan, calls
trpc.listTasks.useQuery({ planId: plan.id })to get tasks - Flattens all tasks from all plans into a single array (hiding the Plan layer per decision 15-02)
- Calls
trpc.getPhaseDependencies.useQuery({ phaseId: phase.id })for phase-level deps - Renders PhaseAccordion with the assembled task data
This avoids the conditional hooks problem — each PhaseWithTasks instance has a stable hook call count.
Page layout (matching wireframe):
InitiativeHeader (back button, name, status, dates)
↓
Two-column layout on desktop (grid-cols-1 lg:grid-cols-[1fr_340px]):
Left: PHASES section with PhaseWithTasks for each phase
Right: ProgressPanel + DecisionList (stacked)
↓
TaskDetailModal (controlled by selectedTask state)
State management:
selectedTask:string | null— ID of task with open modal- For the modal, when a task is selected, look it up from the fetched data
Back button:
Use useNavigate from TanStack Router to navigate to /initiatives.
Queue actions:
- "Queue All" button in the PHASES section header — calls
trpc.queuePhase.useMutation()for each pending phase (disabled if no pending phases) - In TaskDetailModal, "Queue Task" calls
trpc.queueTask.useMutation()with task ID - After successful queue mutation, invalidate relevant queries
Loading/error states:
- Show skeleton/spinner while initiative loads (follow InitiativeList pattern)
- Show "Initiative not found" if getInitiative returns 404/error
- Individual PhaseWithTasks components show their own loading states
DecisionList:
Pass empty array for decisions: decisions={[]} — no backend endpoint exists yet.
Progress calculation: Compute from phases data:
phasesComplete: count phases with status 'completed'phasesTotal: phases.lengthtasksComplete/tasksTotal: sum across all PhaseWithTasks (or compute at page level by fetching all)
Since task counts require fetching all tasks (which happens in PhaseWithTasks children), lift the counts up via a callback or compute from the phase-level data. Simplest approach: use the phase statuses for the progress panel and skip exact task counts initially. Or pass task count via a state aggregation pattern.
Pragmatic approach: ProgressPanel shows phase-level progress only (phasesComplete/phasesTotal). Task counts show as "—" until the phase components have loaded their tasks. This avoids overcomplicating the initial implementation. If you find a clean way to aggregate task counts, do it, but don't over-engineer.
npx tsc --noEmit -p packages/web/tsconfig.app.json passes AND npx vite build in packages/web succeeds
Initiative Detail page renders with header, progress, decisions placeholder, phase accordion with tasks, and task detail modal. Build passes.
Fix any TypeScript errors or build failures discovered.
No new code unless fixing build issues. All three build commands pass with zero errors Full project builds cleanly. Initiative detail page compiles and bundles correctly.
Before declaring plan complete: - [ ] `npx tsc --noEmit -p packages/web/tsconfig.app.json` passes - [ ] `npx vite build` in packages/web succeeds - [ ] `npm run build` in root succeeds - [ ] Navigating from dashboard card to /initiatives/$id renders the detail page - [ ] Phase accordion expand/collapse works - [ ] Task detail modal opens on task click<success_criteria>
- Initiative Detail page replaces placeholder with full implementation
- Data fetched from backend via tRPC (getInitiative, listPhases, listPlans, listTasks)
- Phase hierarchy renders with expand/collapse
- Task detail modal functional
- Queue actions wired to tRPC mutations
- All builds pass </success_criteria>