de88679f25
- 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>
77 lines
4.4 KiB
Markdown
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.
|