convex/dashboard/ that serve as the exclusive data interface for UI consumers. Burgundy — and any future frontend — never imports internal Convex modules directly. All reads return domain-complete objects (no client-side joins), all writes check auth at the boundary, and a CI script enforces the contract.
Why It Exists
- Schema coupling. Without a boundary, UI components imported internal table helpers directly — any schema change risked breaking the dashboard.
- Client-side joins. Pages assembled objects by fetching multiple tables and joining in React — slow, error-prone, and duplicated across routes.
- No enforced contract. Nothing prevented a new page from importing any internal Convex module — the “boundary” was a naming convention.
- Multi-UI fragility. Adding a second frontend (mobile, CLI, partner portal) would require duplicating all the scattered data-fetching logic.
Architecture
Abstraction Boundary
Burgundy (Next.js 15), future UIs. Import only from convex/dashboard/*.
Auth boundary. Domain-complete reads. Frequency-split queries. convex/dashboard/
Schema, interpreter, governance engine, agents, chat, memory, budgets, and all other internals.
Domain Modules
| Module | Covers |
|---|---|
session | Current user, entitlements, notifications |
gateways | Gateway registry, stats, configuration |
workflows | Definitions, versions, documents, deployments |
runs | Execution, steps, timeline, live state, checkpoints |
org | Org tree, departments, teams, positions, workers |
agents | Definitions, deployments, templates |
resources | Skills, models, step library |
analytics | Token events, cost aggregation, pricing |
settings | Alert rules, webhooks, feature flags |
governance | Policies, approvals, audit log |
chat | Channels, sessions, messages |
factories | Factories, blueprints, dev tasks |
ops | Attention items, traces, knowledge, notifications |
Design Principles
Design Principles
Every query returns fully composed objects. A workflow includes its run count, deployment status, and pending approvals. No client-side joins.
Dashboard functions check auth once. Reads use requireAuth. Writes use requirePermission with domain-specific scopes. Internal modules are truly internal.
Queries split by update frequency. Run data (moderate) is separate from timeline events (high-frequency) and live state (low-frequency). Prevents unnecessary re-computation.
A CI script (check-dashboard-boundary.sh) fails the build if any Burgundy file imports an internal Convex module directly. The boundary is structural, not aspirational.
In Burgundy: The dashboard is the primary consumer of this API. See the Burgundy Overview for operator guides.

