c4f0c7ad49
- Introduce async priority queue service in ai-service; all /chat calls now route through it - Refactor chat router to separate execute_chat (core logic) from the HTTP handler - Add /queue endpoints (status, pause, resume, cancel) for queue management - Update ai-service config to use Pydantic v2 model_config style - Add STATUS.md files for backend, ai-service, doc-service, and frontend - Document STATUS.md workflow in CLAUDE.md - Update doc-service documents router and schemas; frontend DocumentsPage and API client Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
201 lines
6.8 KiB
Markdown
201 lines
6.8 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Stack
|
|
|
|
| Layer | Tech |
|
|
|---|---|
|
|
| Backend | FastAPI (async), SQLAlchemy 2 (async), Alembic, PostgreSQL |
|
|
| Auth | JWT via `python-jose`, bcrypt via `bcrypt` (direct, no passlib) |
|
|
| Frontend | React 18, TypeScript, Vite, React Router v6, TanStack Query, Axios |
|
|
| Dev DB | PostgreSQL 16 via Docker Compose |
|
|
|
|
## Commands
|
|
|
|
### Backend (run from `backend/`)
|
|
|
|
```bash
|
|
# Install
|
|
python -m venv .venv && source .venv/bin/activate
|
|
pip install -e ".[dev]"
|
|
|
|
# Run dev server
|
|
uvicorn app.main:app --reload
|
|
|
|
# Lint / format
|
|
ruff check . && ruff format .
|
|
|
|
# Tests
|
|
pytest
|
|
pytest tests/test_auth.py # single file
|
|
|
|
# Migrations
|
|
alembic revision --autogenerate -m "describe change"
|
|
alembic upgrade head
|
|
alembic downgrade -1
|
|
```
|
|
|
|
### Frontend (run from `frontend/`)
|
|
|
|
```bash
|
|
npm install
|
|
npm run dev # Vite dev server at :5173, proxies /api → :8000
|
|
npm run build
|
|
npm run typecheck
|
|
npm run lint
|
|
```
|
|
|
|
### Full stack via Docker
|
|
|
|
```bash
|
|
cp .env.example backend/.env
|
|
docker compose up --build
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Request flow
|
|
|
|
```
|
|
Browser → Vite dev server (:5173)
|
|
/api/* → proxy → FastAPI (:8000)
|
|
→ router → dependency injection (get_db, get_current_user)
|
|
→ SQLAlchemy async session → PostgreSQL
|
|
```
|
|
|
|
### Backend layout
|
|
|
|
- `app/main.py` — FastAPI app, CORS, router registration
|
|
- `app/core/config.py` — all settings via `pydantic-settings` (reads `.env`)
|
|
- `app/core/security.py` — password hashing and JWT encode/decode
|
|
- `app/database.py` — async engine, `AsyncSessionLocal`, `Base` (all models inherit from here)
|
|
- `app/models/` — SQLAlchemy ORM models; import them all in `__init__.py` so Alembic detects them
|
|
- `app/schemas/` — Pydantic request/response models (separate from ORM models)
|
|
- `app/routers/` — one file per resource; mount in `main.py`
|
|
- `app/deps.py` — FastAPI dependencies: `get_current_user` validates JWT and returns `User`
|
|
|
|
### Frontend layout
|
|
|
|
- `src/api/client.ts` — single Axios instance; all API calls live here, token injected via interceptor
|
|
- `src/hooks/useAuth.ts` — token state (localStorage), `login`, `logout`; consumed by pages and `App.tsx`
|
|
- `src/pages/` — one file per route; data fetching via TanStack Query
|
|
- `src/App.tsx` — route tree; `PrivateRoute` wrapper redirects to `/login` when no token
|
|
|
|
### Auth flow
|
|
|
|
1. `POST /api/auth/login` returns a JWT bearer token
|
|
2. Token stored in `localStorage`, attached to every request by the Axios interceptor
|
|
3. Protected routes call `GET /api/users/me`; `get_current_user` dep validates the token on the server
|
|
|
|
## STATUS.md workflow
|
|
|
|
Every directory that contains runnable code, a feature service, or significant logic has a `STATUS.md` file. These files are the canonical **resume point** for development — they describe what the component is, what it currently does, its limitations, and what is planned next.
|
|
|
|
### At the start of every conversation
|
|
|
|
1. Read the `STATUS.md` for every directory you will touch.
|
|
2. If the file does not yet exist for a directory you are working in, create one using the structure below.
|
|
|
|
This applies equally to subagents — always read the relevant `STATUS.md` before starting work.
|
|
|
|
### After making changes
|
|
|
|
Update any `STATUS.md` that is affected:
|
|
- Add new endpoints / models / routes to the **Current functionality** tables.
|
|
- Move completed items off the **Future work** checklist.
|
|
- Add new items to **Known limitations** or **Future work** as appropriate.
|
|
- Keep the **What it is** summary accurate (port, DB, storage, etc.).
|
|
|
|
### STATUS.md structure
|
|
|
|
Each file must contain these sections (add/remove sub-sections as needed):
|
|
|
|
```markdown
|
|
# <Service Name> — Status
|
|
|
|
## What it is
|
|
One paragraph: purpose, internal port, database/storage, how traffic arrives.
|
|
|
|
## Current functionality
|
|
Subsections per router / feature area. Use tables for endpoints.
|
|
|
|
## Architecture
|
|
ASCII diagram showing the call graph / data flow.
|
|
|
|
## Known limitations / not implemented
|
|
Bullet list of gaps that are known but not yet addressed.
|
|
|
|
## Future work
|
|
- [ ] Checklist of planned improvements
|
|
```
|
|
|
|
Root-level services and directories to maintain STATUS.md in:
|
|
- `backend/` — FastAPI gateway
|
|
- `features/ai-service/` — AI intermediary
|
|
- `features/doc-service/` — document microservice
|
|
- `frontend/` — React SPA
|
|
|
|
---
|
|
|
|
## Git convention
|
|
|
|
Always run `git push` immediately after every `git commit`.
|
|
|
|
## Infrastructure change protocol
|
|
|
|
After **any** change to Dockerfiles, `docker-compose*.yml`, `nginx.conf`, setup scripts, or installation / usage procedures:
|
|
|
|
1. **Update `README.md`** — keep the Containers table, ports, image names, and Current State section accurate.
|
|
2. **Spin up the dev stack** and verify that login and registration work end-to-end:
|
|
```bash
|
|
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build
|
|
```
|
|
3. **Spin up the prod stack** and run the same checks:
|
|
```bash
|
|
docker compose up --build -d
|
|
```
|
|
4. Confirm each container is running as a non-root user (`docker inspect <container> --format '{{.Config.User}}'`).
|
|
5. **Tear down after testing** — stop and remove all containers, networks, and volumes:
|
|
```bash
|
|
docker compose down --volumes --remove-orphans
|
|
# or for dev stack:
|
|
docker compose -f docker-compose.yml -f docker-compose.dev.yml down --volumes --remove-orphans
|
|
```
|
|
|
|
## Security hook
|
|
|
|
A pre-commit hook lives in `.githooks/pre-commit` and runs `scripts/security_check.py` inside a Docker container. It is registered via `git config core.hooksPath .githooks` (already set in this repo).
|
|
|
|
The hook checks staged files for:
|
|
- Hardcoded credentials / secrets
|
|
- Dangerous patterns (`eval`, `exec`, `shell=True`, `pickle`)
|
|
- Weak cryptography (MD5, SHA1, DES)
|
|
- SQL injection risk
|
|
- Debug flags left in code
|
|
- `bandit` static analysis on all Python files
|
|
|
|
New clones must run `git config core.hooksPath .githooks` to activate the hook.
|
|
|
|
## Changelog convention
|
|
|
|
Every time files are added or modified, append an entry to the relevant file in `changelog/` (one file per date, named `YYYY-MM-DD_<slug>.md`). If a file for today already exists, append to it rather than creating a new one.
|
|
|
|
Each entry must include:
|
|
- A heading with the date and a short description
|
|
- `**Timestamp:**` in ISO-8601 format
|
|
- A **Summary** sentence
|
|
- A **Files Added / Modified / Deleted** list with one-line descriptions
|
|
|
|
The `README.md` **Current State** section should be kept up to date whenever significant features are added or removed.
|
|
|
|
---
|
|
|
|
### Adding a new resource
|
|
|
|
1. Add ORM model in `app/models/`, import it in `app/models/__init__.py`
|
|
2. Run `alembic revision --autogenerate -m "add <resource>"` + `alembic upgrade head`
|
|
3. Add Pydantic schemas in `app/schemas/`
|
|
4. Add router in `app/routers/`, mount it in `app/main.py`
|
|
5. Add API function(s) to `src/api/client.ts`, add page/component, register route in `App.tsx`
|