Monorepo boilerplate for AI SaaS apps. See PRD.md for the full spec and TODO.md for progress.
uv(installs Python 3.12 automatically)- Node.js 20+ and
npm - Git
# Backend deps (creates .venv and installs dev group)
uv sync --project backend
# Frontend deps
npm --prefix frontend install
# Install git hooks (one-time)
uv run --project backend pre-commit installuv run --project backend uvicorn app.main:app --reload --app-dir backendRuns at http://localhost:8000.
Backend API
| Method | Endpoint | Description |
|---|---|---|
| GET | /healthz |
Liveness check |
| POST | /api/v1/documents |
Upload a .txt, .md, or .pdf (⤠5 MB) |
| GET | /api/v1/documents |
List uploaded documents (metadata only) |
| DELETE | /api/v1/documents/{id} |
Remove a document |
| POST | /api/v1/threads |
Create a thread (optionally attach documents) |
| GET | /api/v1/threads |
List threads |
| GET | /api/v1/threads/{id} |
Get thread with messages |
| DELETE | /api/v1/threads/{id} |
Delete a thread |
| POST | /api/v1/chat/stream |
Stream chat response (Vercel AI SDK data-stream format) |
See client.py for a CLI tool to upload, list, and delete documents:
uv run --project backend python client.py upload file.txt
uv run --project backend python client.py list
uv run --project backend python client.py delete <doc-id>npm --prefix frontend run devVisit http://localhost:3000.
uv run --project backend pre-commit run --all-files && npm --prefix frontend run typecheckThis covers: YAML/JSON validation, ruff check + ruff format, ESLint, backend pytest, and frontend TypeScript typecheck (tsc isn't in pre-commit because it's too slow to run on every commit).
# Backend
uv run --project backend pytest
uv run --project backend ruff check backend
uv run --project backend ruff format backend
# Frontend
npm --prefix frontend run lint
npm --prefix frontend run typecheckPre-commit runs automatically on git commit. If a hook fails, fix the issue, re-stage, and commit again.
Copy .env.example to .env and fill in your keys. AI_PROVIDER + MODEL_NAME control which LLM is used (ollama, openai, or anthropic).
The backend exposes an OpenAPI schema at http://localhost:8000/openapi.json. The frontend can generate typed clients from it using openapi-typescript.
.
āāā PRD.md # Product requirements
āāā TODO.md # Progress tracker
āāā README.md # You are here
āāā .env.example # Environment variables template
āāā .pre-commit-config.yaml # yaml/json/ruff/eslint/pytest hooks
āāā backend/
ā āāā pyproject.toml # uv-managed deps, pytest config
ā āāā client.py # CLI tool to upload/list/delete documents
ā āāā app/
ā ā āāā main.py # FastAPI app, CORS, router mounts
ā ā āāā schemas.py # Pydantic request/response models
ā ā āāā state.py # In-memory dataclasses (Document, Thread, etc.)
ā ā āāā core/
ā ā ā āāā config.py # Env-driven settings
ā ā āāā routers/
ā ā ā āāā health.py # GET /healthz
ā ā ā āāā documents.py # Upload, list, delete documents
ā ā ā āāā threads.py # Create, list, get, delete threads
ā ā ā āāā chat.py # Streaming chat endpoint
ā ā āāā services/
ā ā āāā parse.py # Text extraction (txt/md/pdf)
ā ā āāā llm.py # get_llm() provider factory
ā ā āāā graph.py # LangGraph single-node workflow
ā ā āāā sse.py # Vercel AI SDK data-stream encoder
ā āāā tests/ # pytest (asyncio_mode = "auto")
āāā frontend/
āāā package.json
āāā src/app/ # Next.js App Router
āāā ...
