docs(18): create initiative detail phase plan
Phase 18: Initiative Detail - 4 plans in 2 waves - 3 parallel (wave 1), 1 sequential (wave 2) - Ready for execution
This commit is contained in:
170
.planning/phases/18-initiative-detail/18-04-PLAN.md
Normal file
170
.planning/phases/18-initiative-detail/18-04-PLAN.md
Normal file
@@ -0,0 +1,170 @@
|
||||
---
|
||||
phase: 18-initiative-detail
|
||||
plan: 04
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on: ["18-01", "18-02", "18-03"]
|
||||
files_modified:
|
||||
- packages/web/src/routes/initiatives/$id.tsx
|
||||
autonomous: true
|
||||
---
|
||||
|
||||
<objective>
|
||||
Assemble the Initiative Detail page by wiring all Phase 18 components into the $id.tsx route with tRPC data fetching, queue actions, and build verification.
|
||||
|
||||
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.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
|
||||
# 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
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Wire Initiative Detail page with data fetching and all components</name>
|
||||
<files>packages/web/src/routes/initiatives/$id.tsx</files>
|
||||
<action>
|
||||
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.
|
||||
|
||||
1. `trpc.getInitiative.useQuery({ id })` — fetch initiative by route param `$id`
|
||||
2. `trpc.listPhases.useQuery({ initiativeId: id })` — fetch all phases
|
||||
3. 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. Use `trpc.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.length
|
||||
- `tasksComplete/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.
|
||||
</action>
|
||||
<verify>npx tsc --noEmit -p packages/web/tsconfig.app.json passes AND npx vite build in packages/web succeeds</verify>
|
||||
<done>Initiative Detail page renders with header, progress, decisions placeholder, phase accordion with tasks, and task detail modal. Build passes.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Verify full build and integration</name>
|
||||
<files>packages/web/src/routes/initiatives/$id.tsx</files>
|
||||
<action>
|
||||
Run full verification:
|
||||
1. `npx tsc --noEmit -p packages/web/tsconfig.app.json` — TypeScript check
|
||||
2. `npx vite build` in packages/web — production build
|
||||
3. `npm run build` in root — backend build (ensure no regressions)
|
||||
4. Verify the route is accessible by checking routeTree.gen.ts includes the $id route
|
||||
|
||||
Fix any TypeScript errors or build failures discovered.
|
||||
|
||||
No new code unless fixing build issues.
|
||||
</action>
|
||||
<verify>All three build commands pass with zero errors</verify>
|
||||
<done>Full project builds cleanly. Initiative detail page compiles and bundles correctly.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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
|
||||
</verification>
|
||||
|
||||
<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>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/18-initiative-detail/18-04-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user