Files
simbarag/docs/development.md
T
ryan de88679f25
CI / backend (pull_request) Successful in 1m23s
CI / frontend (pull_request) Failing after 37s
CI / backend (push) Successful in 36s
CI / frontend (push) Failing after 7s
Validate production config, add CI, and build from locked dependencies
- Fail startup on unsafe or malformed production settings (scripts/validate_config.py),
  run it before migrations, and stop on a failed `aerich upgrade`.
- Forward the context-budget, timeout and metrics settings through Compose; accept
  the historical TAVILIY_API_KEY spelling.
- Build the image from uv.lock and yarn.lock in a multi-stage Dockerfile.
- Add Gitea Actions CI: Ruff, unit tests, context evaluation, frontend tests,
  typecheck and build.
- Update README and deployment/development docs to match the current stack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:09:22 -04:00

77 lines
4.4 KiB
Markdown

# Development
The repository uses Python 3.13 with `uv.lock`, React 19 with Rsbuild, and PostgreSQL with pgvector. There is no `docker-compose.dev.yml` or `requirements.txt` workflow. Run the backend locally against the Compose PostgreSQL service.
## Local setup
Install uv 0.7.2, Python 3.13, Node 22.14.0, and Docker Compose v2.
```bash
cp .env.example .env
uv sync --frozen --extra test
cd raggr-frontend
npm ci
npm run build
cd ..
docker compose up -d postgres
```
Edit `.env` before starting the database. Set `POSTGRES_USER`, `POSTGRES_PASSWORD`, and `POSTGRES_DB`; use the same credentials in `DATABASE_URL`, but point its host at `localhost` for local Python. Use `postgres://` so both Tortoise and the pgvector URL conversion work. The PostgreSQL image creates the `vector` extension on an empty data volume using `docker/init-pgvector.sql`.
The backend needs `OPENAI_API_KEY` even with llama-server configured, a `JWT_SECRET_KEY`, and `FERNET_KEY` for encrypted model fields. Configure local writable paths, for example `CHECKPOINT_DB_PATH=/tmp/raggr/checkpoints.db` and `CONVERSATION_SUMMARY_DB_PATH=/tmp/raggr/summaries.db`, and create the parent directory. Keep optional integration credentials empty until needed.
The backend loads `.env` with python-dotenv; exported process variables take precedence. Do not use `export $(cat .env | xargs)` to load secrets. Validate production policy with `make validate-config`, or check provided settings with relaxed development requirements:
```bash
uv run --frozen python scripts/validate_config.py --development
uv run --frozen aerich upgrade
uv run --frozen python app.py
```
The local entry point serves on `http://localhost:8080` in debug mode. A truly new database without Aerich metadata needs an explicit, reviewed `uv run --frozen aerich init-db` first. Do not use `init-db` or fake migrations as a routine repair for an existing database.
## Frontend
```bash
cd raggr-frontend
npm ci
npm run dev
```
Rsbuild serves the development UI. The current Rsbuild configuration does not define an API proxy; use the combined build served by Quart for same-origin backend integration, or configure a development proxy before using API-backed flows. `npm run build` writes `dist`, which Quart serves in the combined application. TypeScript and renderer tests run independently of the bundler:
```bash
node --test tests/*.test.cjs
npx --no-install tsc --noEmit
npm run build
```
## Backend checks
```bash
make test
make evaluate
make lint
make frontend-check
```
Test commands supply synthetic OpenAI/Tavily keys to satisfy existing client constructors; no live API calls are needed. Unit tests use the existing test fixtures and generate an ephemeral Fernet key when needed. They do not invoke startup validation globally or require every integration secret. Configuration tests validate explicit synthetic environments, malformed settings, context budgets, signature policy, Compose forwarding, and startup failure ordering. Compose interpolation tests run when the Docker Compose CLI is installed; they neither start services nor contact a database.
`make evaluate` runs local context-compaction fixtures without LLM calls. Gitea CI pins uv/Ruff/Python/Node and uses frozen Python dependencies and `npm ci`; TypeScript comes from the frontend lockfile. A lock/manifest mismatch must be fixed by the dependency owner rather than resolved during CI.
## Changes and migrations
Backend routes and models live in `blueprints/`; chat/tool routing and context management live in `blueprints/conversation/`. `config/db.py` holds the Tortoise config used by Aerich. Retrieval is in `blueprints/rag/`, and integration clients are in `utils/`.
```bash
make migrate-new # interactive script: container if running, local DB otherwise
# Or, against your explicitly configured local database:
uv run --frozen aerich migrate --name describe_your_change
uv run --frozen aerich upgrade
uv run --frozen aerich history
```
Review generated files in `migrations/models/`. Production blue/green rollouts require migrations compatible with both old and new code. See [deployment.md](deployment.md).
For dependency changes, use `uv add package-name` for backend dependencies and `npm install package-name` in `raggr-frontend` for frontend dependencies. Review and include the corresponding lockfile changes. Use npm consistently for the frontend CI/build path; a `yarn.lock` also exists, but is not used by production or CI.