Quorum is the AI-native product development platform described in prd.md. This document is the technical single source of truth for implementing the Quorum application (not the BMAD tooling repo that hosts these artifacts).
Functional requirements (architectural lens): The PRD defines FR1–FR46 as the capability contract. Architecturally they cluster as:
| Cluster | FR range | Architectural demand |
|---|---|---|
| Tenancy & RBAC | FR1–FR6, FR42–FR45 | Hard workspace isolation, role-aware APIs, auditable admin actions |
| Team room & pipeline | FR7–FR13, FR32 | Conversational UI, checkpoint/resume, artifact sidebar, incremental agent feedback |
| Vision → filter | FR14–FR25, FR46 | Structured vision model, generated concept variations (scroll/select), refine + breakout with carry-back, organize handoff bundle (designs + concept labels + core needs from ideation), live linkage to concept visuals, heavy LLM/analysis jobs |
| Document outputs | FR26–FR31 | Same-source HTML + .docx (FR26), diagram/visual artifacts, narrative generation |
| Build handoff | FR33–FR41 | Versioned story export schema, progress tracking, QA/security gates |
| Integrations | FR43 | One primary external work-tracker/knowledge import (Jira or Notion) for V1 |
Non-functional requirements: Performance (NFR-P1–P4), security and isolation (NFR-S1–S6), reliability and concurrency (NFR-R1–R4), accessibility (NFR-A1–A2), integrations (NFR-I1–I3), observability (NFR-O1–O2) bound hosting, data plane, job execution, and client UX.
Product-specific architecture decisions (from PRD):
buildArchitecture in PRD)._gen_prd_exports.py; product implementation may use Node or a small Python sidecar — decision below).Full-stack web application (rich authenticated UI + API + background work). Next.js matches PRD alignment with modern React, Jaymes-led frontend work, and deployability to managed edge/serverless hosts.
| Option | Fit | Notes |
|---|---|---|
| create-next-app@latest | Selected | App Router, TypeScript default, Tailwind default in current CLI generation paths; large ecosystem for B2B SaaS. |
| T3 Stack | Strong alternative | Adds tRPC + opinionated structure; good if team wants end-to-end types without REST. Defer unless team standardizes on tRPC. |
| Remix | Viable | Excellent forms/actions; less default mindshare for “Vercel + jobs” patterns. |
Verified via current Next.js documentation and create-next-app CLI behavior: npx create-next-app@latest defaults include TypeScript, ESLint, Tailwind CSS, App Router, and Turbopack for dev — exact prompts evolve; use --help for flags at init time.
Rationale: Fastest path to production-grade React SSR/SSG hybrid, Route Handlers for APIs, and alignment with common AI-assisted frontend implementation (Jaymes). Keeps one primary language (TypeScript) for the web tier.
Initialization command (non-interactive example — adjust name and flags to match current CLI):
npx create-next-app@latest quorum-web --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
Architectural decisions provided by the starter:
src/app.@/* for absolute imports.Note: Repository layout may be a monorepo (apps/web, packages/*) in a later refactor; the starter establishes the web app slice.
Critical (block implementation without these):
Important (shape the system):
Deferred (explicit post-MVP / V2):
| Decision | Choice | Rationale |
|---|---|---|
| Primary database | PostgreSQL | Row-level multi-tenancy patterns, JSON for flexible artifact metadata, mature ops story. |
| ORM & migrations | Prisma (or Drizzle if team prefers SQL-first) | Default recommendation: Prisma for Next.js team velocity; migrations in repo. |
| Tenant isolation | workspace_id on all tenant rows + middleware enforcement |
Matches FR5; optional PostgreSQL RLS later for defense-in-depth. |
| Caching | Redis (managed) for sessions, rate limits, job dedupe | Supports NFR-P1 cached reads and queue backing if not using a fully managed job product. |
| Full-text / vectors | pgvector extension where needed | Aligns with technical research notes on agent memory; scope minimally until memory stories are prioritized. |
| Decision | Choice | Rationale |
|---|---|---|
| Auth provider | Supabase Auth via @supabase/ssr (chosen 2026-04-16) |
PRD baseline (NFR-S3); managed auth with generous free tier, already installed in quorum-app. Alternatives considered: Clerk / Auth0 (accelerate enterprise SSO), Better Auth (self-hosted data residency). Reassess if enterprise SSO needs grow beyond Supabase's offering. Our Prisma users table mirrors auth.users via upsert in getCurrentUser(). |
| Authorization | RBAC in application layer | Maps to FR3–FR4; permissions expressed as roles → policy checks on every mutating route. |
| Transport | TLS everywhere in production | NFR-S2. |
| Secrets | Managed secret store or platform env + no secrets in client bundles | NFR-S2; Cipher audit expectations (FR39–FR41). |
| Decision | Choice | Rationale |
|---|---|---|
| Client ↔ backend | HTTPS JSON via Next.js Route Handlers (/api/... or app/**/route.ts) |
Simple deployment; clear boundaries for Jaymes/Damien stories. |
| Internal orchestration | LangGraph-based workflows | technical-research.md recommends LangGraph for checkpoints, HITL, durable runs. |
| LangGraph runtime placement | TypeScript (@langchain/langgraph) in the Node server process for V1 |
Single-language primary stack. If a capability gap appears, carve out services/orchestrator (Python) as V1.5/V2. |
| Real-time UX | SSE (preferred) or polling for sidebar updates; WebSocket only if justified | Satisfies incremental progress (NFR-P2) without premature complexity. |
| Webhooks (integrations) | Signed webhook endpoints + idempotent handlers | NFR-I2 retry-safe behavior. |
| Decision | Choice | Rationale |
|---|---|---|
| UI framework | React 19 / Next default | Matches starter. |
| State | Server state: TanStack Query (or equivalent); UI state: React context or lightweight store | Avoids over-centralizing ephemeral chat UI state. |
| Forms | React Hook Form + Zod | Fast iteration for workspace settings, imports, admin. |
| Accessibility | WCAG 2.1 AA target on conductor flows | NFR-A1; test with axe + manual keyboard passes. |
| Motion | CSS + reduced-motion media query; Luca specs as data | NFR-A2; avoid hard-coding animation without tokens/specs. |
| Decision | Choice | Rationale |
|---|---|---|
| Hosting | Vercel or similar managed Node host for Next.js; managed Postgres (Neon, RDS, Supabase PG, etc.) | Horizontal scale of stateless web tier (NFR-R1). |
| Background jobs | Managed job runner (e.g. Inngest, Trigger.dev, or Graphile Worker on Postgres) | Durable queued/running/failed (NFR-P3); avoid “fire-and-forget” only. |
| Object storage | S3-compatible (R2, S3, GCS) for large artifacts & exports | Scales artifact volume; clean pre-signed URL access pattern. |
| Observability | OpenTelemetry-compatible tracing + structured JSON logs | NFR-O1–O2; tenant id on log context, never log raw secrets. |
| CI/CD | GitHub Actions (or equivalent): lint, typecheck, test, preview deploy | Cipher can extend with SAST/dependency audit steps. |
| Decision | Choice | Rationale |
|---|---|---|
| Canonical PRD source | Structured internal model (JSON/MDX/DB-backed sections) | Single source for HTML + DOCX. |
| HTML rendering | React server render or template render to static HTML | In-app preview + export parity. |
| DOCX generation | Library (e.g. docx npm) or controlled Pandoc sidecar |
Match PRD pairing requirement; pick one implementation and forbid divergent copy paths. |
| Decision | Choice | Rationale |
|---|---|---|
| API style | Provider interface in packages/ai (Anthropic, OpenAI, others) |
Tiered models per technical research; swap models without rewriting orchestration. |
| Observability | Trace IDs per workspace session; token usage persisted for metering | NFR-R3, cost guardrails in PRD vision notes. |
Workspace, User, Membership, Role, core artifact tables.Without these rules, multiple AI agents will invent incompatible APIs, schemas, and folder layouts.
| Area | Convention | Example |
|---|---|---|
| DB tables | snake_case, plural |
workspace_members |
| DB columns | snake_case |
workspace_id, created_at |
| TypeScript identifiers | camelCase |
workspaceId |
| React components | PascalCase file + export |
TeamRoomPanel.tsx |
| API routes | kebab-case path segments, plural resources | /api/workspaces, /api/workspaces/:id/artifacts |
| JSON API fields | camelCase in outward JSON |
{ "workspaceId": "..." } (convert at DB boundary in one place) |
| Env vars | SCREAMING_SNAKE_CASE |
DATABASE_URL |
| Area | Rule |
|---|---|
| Feature code | Prefer src/features/<feature>/ (ui, hooks, server actions colocated) over type-only folders for large domains. |
| Shared UI | src/components/ui for primitives; src/components/domain for cross-feature composites. |
| Server-only code | src/server/** or *.server.ts files — never import server modules into client components. |
| Tests | Co-located *.test.ts or tests/ mirror — pick one per repo and never mix (recommend co-located for unit, tests/e2e for Playwright). |
| Area | Rule |
|---|---|
| API success | { "data": T } wrapper for non-collection responses; collections { "data": T[], "nextCursor?": string } |
| API errors | { "error": { "code": string, "message": string, "details?": unknown } } with stable code enums |
| Dates | ISO 8601 strings in JSON (toISOString()); store UTC in DB (timestamptz) |
| IDs | UUIDv7 or ULID for public IDs (time-sortable, URL-safe) |
| Area | Rule |
|---|---|
| Loading UX | Named states: idle, loading, streaming, success, error — NFR-P2 incremental feedback |
| Errors | Log internal cause server-side; return safe message + code to client |
| Authorization | Deny by default; every mutation checks workspace + role |
workspace_id (or equivalent) from session — never from raw client input alone.Good: assertWorkspaceRole(user, workspaceId, 'admin') in a shared guard used by all admin routes.
Anti-Pattern: Separate GET /api/getWorkspace and POST /api/workspaceUpdate with inconsistent naming and no shared types.
| FR cluster | Primary location (conceptual) |
|---|---|
| FR1–FR6, FR42–FR45 | src/server/auth, src/server/rbac, src/features/workspaces, admin API routes |
| FR7–FR13, FR32 | src/features/team-room, src/features/artifacts, orchestration hooks |
| FR14–FR25 | src/features/pipeline, packages/orchestration (LangGraph graphs), job definitions |
| FR26–FR31 | src/features/exports, src/server/export, job workers |
| FR33–FR41 | src/features/stories, src/features/qa, Cipher hook points |
| FR43 | src/features/integrations/<vendor> |
quorum/
├── apps/
│ └── web/ # Next.js application
│ ├── src/
│ │ ├── app/ # App Router routes + layouts
│ │ ├── components/ # Shared UI
│ │ ├── features/ # Domain features
│ │ ├── server/ # Server-only helpers, auth, db
│ │ └── lib/ # Shared utilities
│ ├── prisma/
│ │ ├── schema.prisma
│ │ └── migrations/
│ ├── public/
│ ├── package.json
│ └── next.config.ts
├── packages/
│ ├── ai/ # LLM provider adapters
│ ├── orchestration/ # LangGraph graphs, checkpoints
│ ├── export/ # HTML/DOCX builders (shared)
│ └── config/ # ESLint, TSConfig extends
├── services/ # optional future Python orchestrator
├── .github/workflows/
└── README.md
| Area | Coverage |
|---|---|
| FR1–FR46 | Supported at subsystem level; detailed story breakdown still required (separate epics workflow). |
| NFR-P* | Addressed via caching, streaming UX, async jobs, export time budgets. |
| NFR-S* | TLS, RBAC, audit logging hooks, isolation discipline. |
| NFR-R* | Stateless web tier, Postgres partitioning path, concurrency via optimistic locking or version columns (exact UX per PRD TBD). |
| NFR-A* | WCAG workflow + reduced-motion consumption of Luca specs. |
| NFR-I* | Versioned story schema, integration error model, Figma URL stability fields. |
| NFR-O* | OTel + structured logs + job alerts. |
| Priority | Gap | Mitigation |
|---|---|---|
| Critical | No UX spec file yet in planning artifacts | Run UX workflow; architecture assumes conductor + sidebar — screens need UX source of truth. |
| Important | ~~Exact auth vendor not locked~~ Resolved 2026-04-16: Supabase Auth via @supabase/ssr chosen during Story 1.2. Pattern (managed auth, RBAC in app layer) unchanged. |
|
| Important | Conflict resolution UX (NFR-R2) | Document as product decision; architecture provides versioning/ETag hooks. |
| Nice | Eval harness for agent distinguishability | Add packages/quality with offline eval fixtures when ready. |
Overall status: READY to drive implementation with the explicit dependency that UX specifications and epics/stories still be produced for screen-level and sprint-level detail.
Confidence: Medium-high — orchestration and tenancy are the hardest parts; choices align with internal technical research.
Strengths: Clear tenant boundary, LangGraph alignment, export duality (HTML + DOCX), job-first thinking for long analyses.
Future enhancement: Dedicated orchestrator service, RLS at DB, real-time collaboration engine.
prd.md as the architecture contract.create-next-app command (or equivalent) and land workspace + auth + empty team room shell before deep LangGraph graphs.James — this architecture encodes Quorum as a Next.js-centered multi-tenant SaaS with Postgres, Prisma, managed auth, LangGraph-style orchestration in TypeScript, async jobs, object storage, and a dual HTML/DOCX export path from one canonical source. It respects the PRD’s build orchestration model (stories to external coding tools) and the technical research preference for LangGraph with checkpointing.
Suggested next workflows: bmad-create-ux-design (or equivalent), then bmad-create-epics-and-stories, then re-run bmad-check-implementation-readiness.
For navigation inside BMAD, invoke bmad-help when you want the menu of follow-on skills.