- Fix race condition: guard useEffect when workspaceId is null, prevent
infinite loading state by setting isLoading=false on null workspace
- Fix TypeScript strict typing: @Workspace() returns string|undefined,
controller now matches with BadRequestException guard
- Narrow details DTO type from unknown to Record<string, unknown>|null
- Add error state UI for API fetch failures
- Add error-path test with static mock import pattern
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create dashboard API client with TypeScript interfaces
- Update page.tsx to fetch from GET /api/dashboard/summary on mount
- DashboardMetrics: accept metrics prop, map to 6 cells with real data
- ActivityFeed: accept items prop, map actions to icons/timestamps
- OrchestratorSessions: accept jobs prop, render steps as agent nodes
- TokenBudget: accept budgets prop, compute percentages
- All widgets have empty/zero fallback states
- Update page tests to mock API fetch
Task: MS-P2-002
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create GET /api/dashboard/summary aggregating 10 parallel Prisma
queries: task metrics, active agents, project counts, error rate,
recent activity, active runner jobs with steps, token budget entries.
Guarded by AuthGuard + WorkspaceGuard + PermissionGuard.
Includes DTO classes and unit tests.
Task: MS-P2-001
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>