docs: write the backend conventions + a development guide (E3 S3, B-core-20)
The layering rule ("request-only logic in routes/; scheduler+worker-shared logic
in the plex|downloads|sync packages; cross-cutting primitives as flat core
modules; extract at the SECOND consumer") was real but unwritten — it lived only
in three module docstrings and a one-line README mention. Collect it, plus the
transaction-ownership rule (a mid-operation helper stages, the caller commits),
the atomic-counter / JobStatus-StrEnum conventions, and the one-home-per-config
rule, into backend/app/README.md. Add docs/development.md (run locally + the gate
commands + branching), so a new session/contributor has one place to look instead
of copying whichever pattern they happen to find first.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# Development
|
||||
|
||||
How to run Siftlode locally and pass the gate. Conventions for the backend code itself live in
|
||||
[`backend/app/README.md`](../backend/app/README.md).
|
||||
|
||||
## Run it locally
|
||||
|
||||
The whole stack (Postgres + API + worker) comes up from the localdev compose file:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.localdev.yml up --build
|
||||
```
|
||||
|
||||
Browse at **http://localhost:8080** (Google login works — the OAuth redirect is
|
||||
`http://localhost:8080/auth/callback`). The API runs `alembic upgrade head` on startup, so the schema
|
||||
is always current.
|
||||
|
||||
For a fast frontend edit loop, run the Vite dev server with HMR against that API:
|
||||
|
||||
```bash
|
||||
cd frontend && npm install && npm run dev # http://localhost:5173, proxying the API on :8080
|
||||
```
|
||||
|
||||
## The gate
|
||||
|
||||
A change is done when all of this is green. CI runs the same checks server-side
|
||||
(`.gitea/workflows/check.yml`), so "main is always green".
|
||||
|
||||
**Backend**
|
||||
|
||||
```bash
|
||||
# lint
|
||||
python -m ruff check --config backend/ruff.toml backend scripts
|
||||
|
||||
# tests — pure-logic + the DB-backed integration lane, against an ephemeral Postgres.
|
||||
# The backend tree is bind-mounted, so it always tests your working files.
|
||||
docker compose -f backend/docker-compose.test.yml up --build --abort-on-container-exit --exit-code-from test
|
||||
docker compose -f backend/docker-compose.test.yml down -v
|
||||
```
|
||||
|
||||
The test compose sets `SIFTLODE_TEST_REQUIRE_DB=1`, which turns a would-be silent skip (no DB, or no
|
||||
ffmpeg) into a hard failure — so the gate can't print green while the DB-backed tests were quietly not
|
||||
run. Tests that need a database take the `db` fixture (`backend/tests/conftest.py`); the rest are
|
||||
pure-logic and run without one.
|
||||
|
||||
**Frontend** (from `frontend/`)
|
||||
|
||||
```bash
|
||||
npm run typecheck # tsc x3 (app / node / e2e)
|
||||
npm run lint # eslint
|
||||
npm run format:check # prettier
|
||||
npm run knip # unused exports/deps
|
||||
npm run test # vitest
|
||||
```
|
||||
|
||||
## Branching
|
||||
|
||||
Trunk-based: branch off `main`, keep the branch gate-green, and land the whole change back to `main`
|
||||
in one reviewed step. Migrations are Alembic revisions under `backend/alembic/versions`; the API
|
||||
applies them on startup, and the DB-lane rebuilds the schema via `alembic upgrade head`, so a broken
|
||||
migration chain fails the tests.
|
||||
Reference in New Issue
Block a user