v0.15.1
## Changed
- `GET /api/health` returns 503 until minion registration, the round info cache and the
scheduler have each come up once. While starting, the body lists what it is still waiting on.
After that it returns 503 with `Status: Degraded` whenever Postgres is unreachable or RabbitMQ
is disconnected. The body now includes `Database` and `RabbitMQ` lines
- `/api/health` no longer goes through the transaction middleware, so a database outage shows
up as a 503 from the health check instead of a 500
- `/minion/health` returns the version, `Status` and `RabbitMQ`, and returns 503 while the minion
is unregistered or has no RabbitMQ connection. Docker's healthcheck retries cover a short
reconnect
- The backend, frontend and minion images no longer have the `entrypoint.sh` that waited on
Postgres and RabbitMQ. The processes already retry both on their own
- In the compose override, the minion waits for a healthy backend instead of the database, and
the frontend waits for a healthy backend instead of the database and RabbitMQ
- Frontend is on TypeScript 7, and npm dependencies are updated
## Fixed
- A check or team deleted mid-round (a database reset, for example) made that round's ledger
insert fail, and every team lost the round's results. The ledger write now skips results for
deleted checks and teams, logs a warning with their ids, and writes the rest. A delete that
lands during the write waits for it to finish, then cascades over the new rows
- The scheduler published checks in the same order every round, and RabbitMQ's round-robin gave
each team the same minion, and so the same source IP, every round. Checks are now shuffled
before publishing
- `just check-nodes` showed no IP range on Docker 29, which reports no IPAM config for the
config-only `minion_lan_config` network. It reads the range from `minion_lan` now. That network
only exists on a node while a minion runs there, so a node without one shows "range shows once
a minion runs here""