feat: Replace initiative card N+1 queries with server-computed activity indicator

listInitiatives now returns an activity object (state, activePhase, phase
counts) derived server-side from phases, eliminating per-card listPhases
queries. Initiative cards show a StatusDot with pulse animation + label
instead of a static StatusBadge. Removed redundant View and Spawn Architect
buttons from cards. Added variant override prop to StatusDot.
This commit is contained in:
Lukas May
2026-03-03 12:49:07 +01:00
parent b74b59b906
commit 96386e1c3d
11 changed files with 167 additions and 96 deletions

View File

@@ -59,6 +59,7 @@ The initiative detail page has three tabs managed via local state (not URL param
### Core Components (`src/components/`)
| Component | Purpose |
|-----------|---------|
| `InitiativeCard` | Initiative list card with activity indicator (dot + label + phase progress), overflow menu |
| `InitiativeHeader` | Initiative name, project badges, inline-editable execution mode & branch |
| `InitiativeContent` | Content tab with page tree + editor |
| `StatusDot` | Small colored dot using status tokens, with pulse animation |
@@ -172,4 +173,11 @@ Configured in `src/lib/trpc.ts`. Uses `@trpc/react-query` with TanStack Query fo
`packages/shared/` exports:
- `sortByPriorityAndQueueTime()` — priority-based task sorting
- `topologicalSort()` / `groupByPipelineColumn()` — phase DAG layout
- `InitiativeActivity` / `InitiativeActivityState` — server-computed activity state for initiative cards
- Shared type re-exports from `packages/shared/src/types.ts` (which re-exports from `apps/server/`)
## Initiative Activity Indicator
`listInitiatives` returns an `activity` field on each initiative, computed server-side from phase statuses via `deriveInitiativeActivity()` in `apps/server/trpc/routers/initiative-activity.ts`. This eliminates per-card N+1 `listPhases` queries.
Activity states (priority order): `pending_review` > `executing` > `blocked` > `complete` > `ready` > `planning` > `idle` > `archived`. Each state maps to a `StatusVariant` + pulse animation in `InitiativeCard`'s `activityVisual()` function.