Repository navigation
v0.2.0
Breaking release. Do the update steps before you run the app again.
Update steps
docker compose stop, thenuvx copier update --truston a clean tree.- Rename in your own code:
ARCHITECTURE.md→BACKEND-API.mdAppError.status→status_codelog.exception(...)andlog.emit(..., exception=True)→log.emit_with_current_traceback(...);log.emit(..., exception=error)→log.emit_with_traceback(..., exception=error)app.infrastructure.postgres.base→.models;app.infrastructure.rate_limit.limiter→.limiter_storeapi_lifespan→run_api_lifespan;find_route_template→read_route_template;username_exists→is_username_taken- e2e:
HttpReply.status→status_code,expected_status→expected_status_code
- Set
<PREFIX>_ALLOWED_HOSTSin production. Without accounts, every proxied request gets 400host_not_alloweduntil the public host is listed. - Existing database: in your first own revision set
down_revision = "app_0001", thenBuild before the stamp: with the old image it exits 0 and changes nothing. Scripts that rundocker compose up -d --wait postgres docker compose build docker compose run --rm --no-deps migrate alembic stamp --purge heads docker compose up -d --build --wait
alembic upgrade headnow needheads. - Run
uvx prek run --stage pre-push --all-files, fix what the new gates find in your code, and commit, including the rewrittenbackend/openapi.jsonanduv.lockfiles. Commit subjects and PR titles are nowtype(scope): sentence. - Postgres hosts:
systemctl enable --now <checkout>/deploy/postgres/<slug>-postgres-backup-schedule.service. Until it runs,deploy/deploy.shdeploys, warns and exits 1. - A host with its own Caddy config adds
lb_try_duration 30sandlb_try_interval 250mstoreverse_proxy.
What's new
- Security: a passkey challenge works once; request bodies are capped at 64 KB (413); a foreign
Hostgets 400; trusted proxies can be CIDR networks. (#5) - Worker: optional
include_workeradds a Postgres job queue, arun-workercommand and aworkerservice. Off by default. (#12) - Migrations: separate Alembic lines for the template, each option and the app, so revisions can't collide and an option turned on later just applies. (#11)
- Deploy:
/readychecks the database and the healthcheck uses it; Caddy retries through an api restart; backups run under a systemd unit thatdeploy.shwatches. (#9, #11) - Local dev: compose watch and
serve-api --reload, so a code change needs no image rebuild. (#6) - Gates: no complexity gate; new checks for comments, names, function verbs, file kinds, dead code, setting keys and migrations; every semgrep and ty rule has a fixture that must fire; commit runs only the fast hooks. (#8, #10)
- CI and process: every app gets CI, a Conventional title check, Dependabot, a weekly image scan, issue forms, a
mainruleset,README.mdandAGENTS.md. (#4) - Docs:
BACKEND-API.mdis a tree, Mermaid diagrams, then the rules. (#1, #13) - Template CI: updates an app from the newest release and boots the Postgres option sets with their e2e flows. (#3, #14)
Known gaps
- The database move in step 4 was tested by hand; CI runs no database through an update.
- The app's workflows and first-push commands have not run on a real app repository yet.
- Caddy does not retry a POST that failed after it was sent. One API replica only.
- The worker has no scheduler, priorities or dedupe key, and nothing prunes
failedrows. - The backup unit expects the checkout at
/opt/<slug>and env files in/etc/<slug>.