Architecture Overview
Runtime topology, inter-service communication, and the key design decisions behind the Aurea monorepo.
Monorepo structure
Aurea uses Bun workspaces for package management and Turborepo 2 for task orchestration.
All apps live under apps/, all shared libraries under packages/.
aurea/
├── apps/
│ ├── web/ # Next.js 15 + Payload CMS
│ ├── dashboard/ # Vite 6 + React Router 7 SPA
│ ├── api/ # NestJS 11 + GraphQL + MCP
│ └── docs/ # Fumadocs (Next.js 15)
└── packages/
├── ui/
├── shared/
└── tooling/
├── eslint-config/
└── typescript-config/The root turbo.json defines the task graph (build depends on ^build, etc.) so Turborepo
can parallelise and cache correctly.
Runtime topology
Browser / AI Agent
│
├─► GET :3000 apps/web (Next.js SSR + Payload CMS headless)
├─► GET :3001 apps/dashboard (Vite SPA → GraphQL at :4000)
├─► GET :3002 apps/docs (Fumadocs static/SSR)
└─► POST :4000 apps/api
│
├─► /graphql (Apollo GraphQL)
└─► /mcp (Streamable HTTP — Model Context Protocol)Inter-service communication
Dashboard → API (GraphQL)
The Vite SPA (apps/dashboard) fetches data by sending GraphQL queries to
http://localhost:4000/graphql (configured via NEXT_PUBLIC_API_URL / Vite env vars).
Current operations:
| Operation | Type | Description |
|---|---|---|
cases | Query | List all active cases |
case(id) | Query | Fetch a single case by ID |
advanceCaseStatus(id) | Mutation | Move a case to its next lifecycle status |
Web → Payload CMS
apps/web uses Payload CMS 3 as an embedded headless CMS. Payload runs inside the Next.js
process and persists to a dedicated PostgreSQL database (PAYLOAD_DATABASE_URL). There is no
separate Payload server; the Next.js app IS the CMS.
API → Database
apps/api uses Drizzle ORM with the postgres driver. The schema lives in
apps/api/src/database/schema/. In development, CasesService falls back to an in-memory
seed when DATABASE_URL is not set.
Agent → API (MCP)
AI agents connect to POST http://localhost:4000/mcp using the Streamable HTTP transport
defined in the MCP SDK. See the MCP Server docs for available tools.
Dependency direction
apps/* → packages/ui → (no internal deps)
apps/* → packages/shared → (no internal deps)
packages/* → packages/tooling/* (config only, never runtime)Apps may depend on packages but packages must never depend on apps.