Developer reference: Dashboard (home + summary API)
This document covers the authenticated dashboard route /dashboard, the primary GET /api/dashboard/summary contract, and how the client loads and augments that data. It does not document every sub-page linked from dashboard cards (frameworks, projects, risks, approvals list, incidents list, etc.) beyond navigation entry points.
Repository layout
- Web client:
gaicc-app/Clients - API server:
gaicc-app/Servers
Routing and layout
| Item | Location |
|---|---|
| Dashboard page | gaicc-app/Clients/src/presentation/pages/Dashboard.tsx |
| Route | path: "/dashboard" in gaicc-app/Clients/src/App.tsx, wrapped with sidebar layout via withLayout(<Dashboard />) |
| "No workspace yet" | path: "/create-workspace" → RequireAuth + WorkspaceRequired (gaicc-app/Clients/src/presentation/pages/WorkspaceRequired.tsx) which embeds CreateWorkspaceModal (allowDismiss={false}) |
Client data loading
| Concern | Location |
|---|---|
| Summary query | gaicc-app/Clients/src/application/queries/dashboard.queries.ts — useDashboardSummary (@tanstack/react-query) |
| Query key | gaicc-app/Clients/src/application/queryKeys.ts — qk.dashboard → ["dashboard"] |
| HTTP | gaicc-app/Clients/src/infrastructure/repositories/dashboard.repository.ts — getDashboardSummary() → GET /api/dashboard/summary |
| DTO | gaicc-app/Clients/src/domain/types/dashboard.types.ts — DashboardSummary |
| Refetch policy | useDashboardSummary: staleTime: 0 (refetch on mount), refetchInterval: 60_000 |
Pending approvals badge
usePendingApprovalsCountingaicc-app/Clients/src/application/queries/approval.queries.tsloadsgetPendingApprovals()(GET /api/approvals/pendingviaapproval.repository) and useslist.lengthas the count.- Dashboard prefers that live count when available:
pendingApprovalsDisplay = data ? (pendingCount.data ?? data.pendingApprovals) : 0inDashboard.tsx(so the approvals card can reflect the dedicated pending query).
Dashboard UI behavior (Dashboard.tsx)
- Cards: Configured in
DEFAULT_CARD_ORDER(program-health,use-cases,risks,approvals,incidents,framework-progress,activity-feed,recent-incidents). Each maps to arenderCardbranch with navigation (e.g. program health →/setup/frameworks, use-cases →/projects, risks →/risks). - Drag-and-drop:
@dnd-kitSortableContext/useSortable; activation distance on pointer sensor 8px. - Persistence: Card order JSON in
localStoragekeydashboard-card-order.resetLayoutclears that key and resets toDEFAULT_CARD_ORDER. - Role gating:
rolefrom Redux (auth.role) is read for some UI (e.g. approvals / AI-related affordances); grepDashboard.tsxforrolewhen extending.
API
| Method | Path | Auth / tenant |
|---|---|---|
GET | /api/dashboard/summary | authenticateJWT, attachOrganizationId, enforceMutationBillingCompliance (router-level middleware on all /api/dashboard routes — including this GET) |
Router — gaicc-app/Servers/src/routes/dashboard.routes.ts
- Registers middleware chain then
GET /summary→getSummary.
Controller — gaicc-app/Servers/src/controllers/dashboard.controller.ts
getSummary:getDashboardSummary(req.organizationId!)→ 200 JSON; errors log and return 500{ message: "Internal server error" }.
Service — gaicc-app/Servers/src/services/dashboard.service.ts
getDashboardSummary(organizationId)aggregates Prisma counts and lists (frameworks, controls across legacy + ISO shapes, policies, members, invites, projects, risks, evidence, approvals, vendors, models, tasks, incidents, audit logs), computescomplianceScorefrom assessment answers + ISO slot progress, buildsframeworkProgressperorgFramework, and returns aDashboardSummaryobject.
Server mount — gaicc-app/Servers/src/index.ts: app.use("/api/dashboard", dashboardRoutes).
Related: framework setup
Program health navigates to /setup/frameworks. See the published User guide: Framework setup and Developer: Framework setup (GET /api/frameworks, GET/POST /api/frameworks/projects, etc.).
Related: create workspace (no memberships)
Users with no workspace in the session are redirected to /create-workspace (RequireAuth). See User guide: Create a workspace and Developer: Create workspace — separate from GET /api/dashboard/summary.
Testing notes (TestSprite / external)
- Backend contract for the dashboard surface is primarily
GET /api/dashboard/summarywith a valid JWT and organization context. - The UI also calls
GET /api/approvals/pendingfor the live pending count; include it if testing approval badge behavior. - Configure scope and cases in the TestSprite web portal when you run tests; this file is the implementation reference.