Zazz Board is a Kanban-style orchestration app for coordinating AI agents and owners — the people who define what to build, approve PLANs, and review results. Work is organized by project; each project contains deliverables (features, bug fixes, refactors) that group tasks. Owners manage SPECs and deliverable flow; agents execute implementation work and board updates. Only deliverables are PR’d — never individual tasks.
Current initiative focus: spec-builder, planner, and worker agent flows. Coordinator/QA agent flows are not the current release focus.
Stack: Fastify API (JavaScript, ESM) · React client (Vite) · PostgreSQL 15 (Docker) · Drizzle ORM · Docker Compose
Framework: Zazz Board is the tool that enables teams to practice the Zazz Framework — a spec-driven methodology for multi-agent software development. The framework doc defines terminology (SPEC, PLAN, deliverables, tasks), workflow stages, agent roles, and how owners (Project Owners and Deliverable Owners) and agents collaborate.
- Main views and features
- Quick start
- Contributor setup
- Running in the cloud
- Running tests
- API docs (Swagger)
- API authentication
- Common issues
- Reference
- About this repository
- Documentation
- Updating skills from zazz-skills
| View | Purpose |
|---|---|
| Project list | Create/edit projects; configure task and deliverable workflows. |
| Deliverable list | Sortable table of deliverables per project; SPEC/PLAN/PRD paths with copy-to-clipboard; PR links. |
| Deliverable Kanban | Columns from project’s deliverable workflow (Planning, In Progress, In Review, Staged, Done). Drag-and-drop deliverable cards; task progress and PR URL on cards. |
| Task Kanban | Columns from project’s task workflow (To Do, Ready, In Progress, QA, Completed). Tasks show deliverable name in card footer. Drag-and-drop. |
| Task graph | Task Graph — one deliverable’s task graph at a time; select deliverable via dropdown. Readiness and coordination types (e.g. TEST_TOGETHER, DEPLOY_TOGETHER) supported. |
- Deliverable creation: Owner works with the spec builder agent to create the deliverable specification (SPEC). During that dialogue, the agent drafts the SPEC document and creates the deliverable card on the Kanban board via the API — both with sufficient clarity and correct metadata (SPEC path, worktree, branch).
- Planning: The Planner agent decomposes the SPEC into the PLAN — phased sequence of tasks with per-task acceptance criteria, test requirements, and file assignments. Owner approves PLAN (sets
approved_by/approved_at), sets PLAN path. Owner or system moves deliverable to In Progress (guard: PLAN approved + PLAN path set). - Execution: The Worker agent realizes plan tasks just-in-time on the board, creates required relations, and implements with TDD while keeping statuses and block flags current via API. Owner-managed orchestration can run this flow directly without coordinator/QA agent personas in the current release.
- Review & release: Owner reviews PR, merges to staging (Staged) then to main (Done or Prod for projects with a release-pipeline workflow). Status history is stored for lead-time and reporting.
- API: Fastify,
TB_TOKEN(or Bearer) auth, JSON Schema validation. All DB access viadatabaseService; schema inapi/lib/db/schema.js(Drizzle). See AGENTS.md for full route list. - API docs: OpenAPI 3.1 (Swagger UI) at /docs — see API docs (Swagger) below.
- Client: React, Vite, Mantine, react-router-dom v7, @dnd-kit, react-i18next. Token in localStorage.
- DB: Schema-first; no migrations in this phase —
npm run db:resetdrops and recreates from schema then seeds. Separate dev and test DBs.
Seed data includes a sample project (e.g. ZAZZ) so you can explore deliverables, task Kanban, deliverable Kanban, and the task graph with realistic data. SPECs and PLANs live in .zazz/deliverables/ per the Zazz Framework; project standards live in .zazz/standards/. See the canonical zazz-framework.md for the full structure.
Production/self-hosted Docker setup with two flows.
docker compose up --buildOptional non-destructive seed attempt:
npm run docker:seedExpected result:
- PostgreSQL on
localhost:5433 - API on
localhost:3030 - Client on
localhost:3001 - First-run schema + seed happens automatically
Wait for the API to be ready (schema created and seed applied) before running psql queries:
# Health check (wait until this returns OK)
curl http://localhost:3030/healthExpected response: {"status":"ok"}
Once healthy, you can safely query the database. Example:
set -a && source .env && set +a
docker compose --env-file .env exec postgres psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT COUNT(*) AS task_count FROM \"TASKS\";"Run this as a second step from terminal (with containers running):
npm run docker:reset:seedThen re-run the health check above before running DB queries.
docker compose up --build -dNotes:
- Do not run
docker compose down -vfor normal upgrades (that deletes Postgres data). - If schema has changed and data must be preserved, run:
docker compose exec api npm run db:pushYou can skip env files and use defaults. To customize DB settings, copy .env.example to .env and change values.
Default credentials (from docker-compose.yml):
POSTGRES_DB=zazz_board_db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=passwordAgent skills and zazzctl read ZAZZ_API_TOKEN from root .env:
ZAZZ_API_TOKEN=550e8400-e29b-41d4-a716-446655440000| Service | Container name | Host port | Container port | Notes |
|---|---|---|---|---|
| postgres | zazz_board_postgres | 5433 | 5432 | DB: zazz_board_db |
| api | zazz_board_api | 3030 | 3030 | Fastify API |
| client | zazz_board_client | 3001 | 80 | React app (Nginx) |
- API: http://localhost:3030
- Client: http://localhost:3001
- Postgres (from host):
localhost:5433, databasezazz_board_db
Contributor/committer instructions are in CONTRIBUTOR_SETUP.md.
- Open
http://localhost:3001 - Click the Zazz Board menu in the header
- Click Set Access Token
- Paste this token and submit:
550e8400-e29b-41d4-a716-446655440000
If that token does not work, fetch a valid one from your local DB:
set -a && source .env && set +a
docker compose --env-file .env exec postgres psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT email, access_token FROM \"USERS\";"- API: http://localhost:3030
- Client: http://localhost:3001
For a single-node deployment, use docker-compose.prod.yml:
export POSTGRES_PASSWORD=your_secure_password
docker compose -f docker-compose.prod.yml up -d- Postgres: port 5432 (internal)
- API: http://localhost:3030
- Client: http://localhost:80 (Nginx)
Set API_BASE_URL in the API container if the client needs to reach the API at a different host (e.g. a public URL).
| Component | AWS service |
|---|---|
| Database | RDS PostgreSQL 15 |
| API | ECS Fargate (container from api/Dockerfile) |
| Client | S3 + CloudFront (static build) |
| Task images | S3 (in work — see Cloud deployment notes) |
Flow: Create RDS instance → build and push API image to ECR → deploy ECS task with DATABASE_URL pointing at RDS → build client with VITE_API_URL set to your API URL → upload to S3, configure CloudFront. Use Application Load Balancer in front of ECS for the API.
| Component | GCP service |
|---|---|
| Database | Cloud SQL (PostgreSQL 15) |
| API | Cloud Run (container from api/Dockerfile) |
| Client | Cloud Storage + Cloud CDN (or Firebase Hosting) |
| Task images | Cloud Storage (in work — see Cloud deployment notes) |
Step 1 — Cloud SQL
- Create a Cloud SQL instance (PostgreSQL 15).
- Create database
zazz_board_dband user. - Enable Cloud SQL Admin API and (optionally) Private IP for VPC connectivity.
Step 2 — API on Cloud Run
- Build and push the API image to Artifact Registry:
gcloud builds submit --tag gcr.io/YOUR_PROJECT/zazz-board-api ./api
- Deploy to Cloud Run:
gcloud run deploy zazz-board-api \ --image gcr.io/YOUR_PROJECT/zazz-board-api \ --platform managed \ --region us-central1 \ --set-env-vars "DATABASE_URL=postgres://USER:PASS@/zazz_board_db?host=/cloudsql/PROJECT:REGION:INSTANCE" \ --add-cloudsql-instances PROJECT:REGION:INSTANCE - Use Cloud SQL Auth Proxy connection name in
DATABASE_URLwhen using Unix socket, or configure VPC connector for private IP.
Step 3 — Client
- Build the client with the API URL:
cd client && VITE_API_URL=https://your-api-url.run.app npm run build
- Upload
dist/to a Cloud Storage bucket and enable static website hosting, or use Firebase Hosting. - Optionally put Cloud CDN in front for caching.
Step 4 — Seed the database
Run the seed script once against Cloud SQL (e.g. from Cloud Shell or a one-off Cloud Run job with npm run db:reset), or use a local connection through the Cloud SQL Auth Proxy.
Image storage: For cloud deployments, task images should be stored in object storage rather than the database:
- AWS: S3 — upload images to a bucket; store metadata and object keys in the DB.
- GCP: Cloud Storage — same pattern; store metadata and
gs://URLs or object names in the DB.
Configuration: The API will need environment or config to distinguish cloud vs local (e.g. STORAGE_BACKEND=s3 or STORAGE_BACKEND=gcs vs database). This allows the image service to route uploads and serves to the correct backend. This functionality is in work.
Tests use a separate database (zazz_board_test). One-time setup (from project root):
set -a && source .env && set +a
docker compose exec postgres psql -U postgres -c "CREATE DATABASE zazz_board_test;" 2>/dev/null || true
cd api && DATABASE_URL=postgres://postgres:$POSTGRES_PASSWORD@localhost:5433/zazz_board_test npm run db:resetThen run tests (from api/):
set -a && source .env && set +a && NODE_ENV=test npm run testSee api/tests/README.md for details.
The API serves OpenAPI 3.1 interactive docs (Swagger UI) at http://localhost:3030/docs when the API is running. The spec is generated from Fastify route schemas (single source of truth; no separate YAML to maintain). It includes all routes, request/response shapes, and security: TB_TOKEN (header) and Bearer (Authorization header). Access to /docs is token-protected so only authenticated users and agents can view it in production.
| URL | Purpose |
|---|---|
| /openapi.json | Raw OpenAPI 3.1 JSON spec — no auth. Use for agents, codegen, tooling. |
| /docs | Swagger UI — interactive docs. Use Authorize for try-it-out. |
- Tags: core, users, projects, deliverables, task-graph, tags, translations, status-definitions, images.
- Security: Global auth via
TB_TOKENor Bearer; the UI has an Authorize button to set your token for “Try it out” requests. - Try it out: You can run requests from the browser; once authorized, the token is sent automatically and persisted for the session.
You need a valid access token (UUID from USERS.access_token; seed example: 550e8400-e29b-41d4-a716-446655440000).
Option A — Browser (easiest)
- Start the API (
npm run devornpm run dev:api). - Open http://localhost:3030/docs (the
?token=query string does not work; use Authorize instead) - Click Authorize, enter
550e8400-e29b-41d4-a716-446655440000in the TB_TOKEN field, then Authorize → Close - Use “Try it out” on any route; the token is sent on every request.
Option B — Browser (no token in URL)
If you can send a header with the first request (e.g. a REST client or extension), open http://localhost:3030/docs with header TB_TOKEN: <your-uuid>. Then use Authorize in the UI as above for try-it-out.
Option C — Raw OpenAPI JSON (for agents and codegen)
The spec is available at /openapi.json (no auth required). Agents and tooling can fetch it directly:
curl http://localhost:3030/openapi.jsonFor authenticated requests, use the token header: curl -H "TB_TOKEN: 550e8400-e29b-41d4-a716-446655440000" http://localhost:3030/openapi.json
Which routes require a token?
All API routes except: GET /health, GET /, GET /db-test, GET /token-info, GET /openapi.json. The docs at GET /docs (and /docs/*) also require a valid token.
How is the access token set for API calls?
Send one of:
- Header:
TB_TOKEN: <uuid>(fromUSERS.access_token). - Header:
Authorization: Bearer <uuid>.
Example (seed user): TB_TOKEN: 550e8400-e29b-41d4-a716-446655440000
For Swagger UI, see How to access the docs with your access token above.
- Port in use:
lsof -ti:3030 | xargs kill -9(API),lsof -ti:3001 | xargs kill -9(client),lsof -ti:3031 | xargs kill -9(test server). - drizzle-kit “please install drizzle-orm”: From repo root,
ln -sf ./api/node_modules/drizzle-orm ./node_modules/drizzle-orm. - Tests: Always source
api/.envand setNODE_ENV=test; see AGENTS.md and api/tests/README.md.
| Action | Command (project root unless noted) |
|---|---|
| Run API + client | npm run dev |
| Run API only | npm run dev:api |
| Run client only | npm run dev:client |
Reset dev DB (from api/) |
npm run db:reset |
Seed only (from api/) |
npm run db:seed |
| Reset + reseed Docker DB (containers running) | npm run docker:reset:seed |
Run tests (from api/) |
set -a && source .env && set +a && NODE_ENV=test npm run test |
Env: api/.env — DATABASE_URL (dev), DATABASE_URL_TEST (tests). Port 5433. Test DB setup: AGENTS.md. Test guide: api/tests/README.md.
This repository is developed using the Zazz framework (dogfooding). Zazz Board is built with Zazz Board — we use our own deliverables, SPECs, PLANs, and workflow to evolve the product.
- zazz-framework.md (canonical) — Full framework overview: terminology (SPEC, PLAN), workflow stages, agent roles, two kanban boards, TDD, and how to follow the methodology.
- AGENTS.md — Primary reference for agents and developers: repo layout, full API route list, DB setup, test strategy (Vitest + PactumJS + test DB), troubleshooting.
- API docs (Swagger UI): http://localhost:3030/docs — OpenAPI 3.1, token-protected. See API docs (Swagger) and How to access the docs with your access token.
- api/tests/README.md — Writing and running API tests (PactumJS, helpers, safety guards).
.zazz/— Zazz Framework structure:project.md,standards/(atomic project standards),deliverables/(SPECs and PLANs). See zazz-framework.md for repository structure guidance..agents/skills/— Agent skills. Framework skills are sourced from zazz-skills; this repo keeps the reference-implementation copy plus the local-onlydatabase-baseline-refreshskill..zazz/deliverables/deliverables-feature-SPEC.md— Full Deliverable Specification for the deliverables feature. Also in docs/deliverables_feature_SPEC.md (legacy path).
zazz-skills is the canonical source for framework skill names and markdown content. This repo should treat its .agents/skills/ copy as a downstream mirror of that source, except for local-only skills such as database-baseline-refresh.
Typical update flow:
- Review the upstream changes in
zazz-skillsfirst so any renames or new skills are understood before syncing. - Run
./scripts/sync-skills-from-zazz-skills.sh /absolute/path/to/zazz-skills. - Review the diff in this repo, especially
README.md,AGENTS.md, and.zazz/deliverables/, because renamed skills often leave stale references outside the skill folders. - Run
rg -n 'proposal-builder|feature-doc-builder|pr-builder|spec-builder-agent|planner-agent|coordinator-agent|worker-agent|qa-agent' README.md AGENTS.md .zazz .agents/skillsto catch old names or missing follow-up edits.
Notes:
- The sync script mirrors the canonical framework-managed skills:
coordinator,feature-doc-builder,planner,pr-builder,proposal-builder,qa,qa-backend,qa-frontend,spec-builder,worker, andzazz-board-api. - The script intentionally does not touch
.agents/skills/database-baseline-refresh/. - A rename-heavy update like this one still needs a manual documentation sweep after the file sync.