Skip to content

Repository files navigation

BriefBoard — multi-tenant AI document workspace

BriefBoard is a small but complete AI SaaS: tenants upload documents, then ask questions or get summaries over their own documents. It demonstrates the concerns a real AI product has beyond the model — API-key auth, per-tenant data isolation, streaming responses, usage metering, and a cost guardrail — with a working web UI.

  • Multi-tenant: every request is scoped to the tenant resolved from its API key; one tenant can never see another's documents.
  • Streaming: answers stream token-by-token over Server-Sent Events.
  • Metered + budgeted: every call records input/output tokens and cost; a per-tenant monthly budget hard-stops spending (HTTP 402).
  • Real model: Claude via the Anthropic SDK; RAG over the tenant's own docs.

Architecture

flowchart LR
UI[Web UI / API client] -->|X-API-Key| AUTH[auth: resolve tenant]
AUTH --> G{cost guardrail}
G -->|over budget| B[402]
G -->|ok| R[per-tenant RAG retrieval]
R --> LLM[Claude stream]
LLM -->|SSE tokens| UI
LLM --> M[record usage + cost]
M --> DB[(SQLite: tenants · documents · usage)]
Loading

The multi-tenancy boundary is row-level: documents and usage are always queried with WHERE tenant_id = ?. See docs/architecture.md.

Endpoints

MethodPathPurpose
POST/documentsUpload a document (tenant-scoped)
GET/documentsList the tenant's documents
POST/askAsk across the tenant's docs — streams SSE
POST/summarizeSummarize one of the tenant's docs
GET/usageMonth-to-date tokens, cost, budget remaining
GET/Web UI

All except / and /health require the X-API-Key header.

Quickstart

make setup
make test# full suite — no API key needed (fake LLM)
cp .env.example .env # add ANTHROPIC_API_KEY to actually answer/summarize
make run # UI at http://localhost:8000

Seeded demo tenants: demo-acme-key and demo-globex-key (each with a $5/mo budget).

curl -s -X POST localhost:8000/documents -H 'X-API-Key: demo-acme-key' \
-H 'content-type: application/json' -d '{"title":"Notes","text":"The launch is in March."}'
curl -N -X POST localhost:8000/ask -H 'X-API-Key: demo-acme-key' \
-H 'content-type: application/json' -d '{"question":"When is the launch?"}'

Project structure

briefboard/
├── app/
│ ├── main.py # FastAPI app + endpoints
│ ├── auth.py # API-key -> tenant
│ ├── db.py # SQLite, tenant-scoped queries
│ ├── metering.py # cost calc + budget guardrail
│ ├── retrieval.py # per-tenant TF-IDF RAG
│ ├── llm.py # Claude streaming + summarize (Anthropic SDK)
│ ├── schemas.py · config.py · seed.py
├── static/index.html # web UI (vanilla JS, consumes the SSE stream)
├── tests/test_api.py # auth, isolation, streaming, metering, budget
└── docs/architecture.md

Notes

  • The UI is a self-contained functional demo (vanilla JS). A production build would typically be a Next.js frontend against the same API; the backend contract is identical.
  • SQLite keeps the demo one-command-runnable; the data layer is small enough to port to Postgres (with a tenant_id FK and row-level security) without changing the API.

License

MIT — see LICENSE.

About

Multi-tenant AI SaaS: document Q&A + summarization with auth, streaming, and usage metering

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages