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

Method Path Purpose
POST /documents Upload a document (tenant-scoped)
GET /documents List the tenant's documents
POST /ask Ask across the tenant's docs — streams SSE
POST /summarize Summarize one of the tenant's docs
GET /usage Month-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