Files
overseerandClaude Opus 5.5 ba0b2032cc Correct retirement docs: deactivation clears future open instances
Retirement preserves the definition row, schedule rule, assignees,
windows and all durable completion history, but like any deactivation
it regenerates, so future uncompleted instances are cleared and none
are recreated while inactive. Fixes the "deletes nothing / all
instances preserved" wording in the core docstrings, the admin DELETE
route description, ADMIN-SPEC and the retire test's docstring
(review finding NQ-262-1). No behavioural change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:40:44 -04:00
..

NestQuest API

Standalone FastAPI service owning the NestQuest database (Feature 16). Served with uvicorn --factory api.app:create_app; configuration is environment-supplied (api/config.py) and every variable is required.

Runtime dependencies

api/requirements.txt is the API deployable's OWN dependency manifest (fastapi, uvicorn, pyjwt[crypto], httpx) — deliberately kept out of the integration's pyproject.toml dev group, which exists only so the monorepo test venv can run the API tests.

Container deployment (scaffold)

The image is built from the repository ROOT context (the API loads the bundled domain core from custom_components/nestquest/core/ by file location, so both trees must be in the build context):

docker build -t nestquest-api:latest .

Run it with compose — the SQLite file lives on the named volume nestquest-db so recreating the container keeps household data:

cp deploy/.env.example deploy/.env   # then fill in real values
docker compose -f deploy/compose.yaml up -d --build

deploy/.env is git-ignored and supplies the secrets (panel service token, Authentik OIDC settings); NESTQUEST_DB_PATH is fixed to /var/lib/nestquest/nestquest.db by compose.

The published port binds NESTQUEST_BIND_ADDRESS from deploy/.env and defaults to 127.0.0.1 (localhost only). In production TLS is terminated by the shared Traefik reverse proxy, which serves https://nestquest.cubecraftlabs.com (Let's Encrypt, auto-renewed, HTTP redirected to HTTPS) and forwards to the API box on port 8080 — so on that box set NESTQUEST_BIND_ADDRESS to its LAN address (10.60.1.14). Traefik only allows /api/v1/panel from the Home Assistant host. The full deployment, restore and verification procedure is in deploy/RUNBOOK.md.

Continuous backup (Litestream)

Compose also runs a litestream sidecar (litestream/litestream:0.5.17, config deploy/litestream.yml). It mounts the same nestquest-db volume and continuously replicates /var/lib/nestquest/nestquest.db over SFTP to the Synology NAS CubeCraft-SRVR1 (joshua@10.60.1.50), directory /volume1/homes/Joshua/nestquest-backups (/homes/Joshua/... in the NAS's chrooted SFTP view) — so the backup is outside the Docker host and its volume. A snapshot is taken daily and a week of snapshots plus incremental changes is retained; the NAS host key is pinned in the config.

The SFTP login uses a dedicated keypair that lives only on the API box and is git-ignored. Create it once, before up:

ssh-keygen -t ed25519 -N "" -C nestquest-litestream -f deploy/litestream_key

then append restrict + the contents of deploy/litestream_key.pub to joshua@10.60.1.50:~/.ssh/authorized_keys. Compose mounts the private key read-only at /etc/litestream/sftp_key. The sidecar runs as uid/gid 999 (the API's nestquest user), so give it the key:

sudo chown 999:999 deploy/litestream_key && chmod 600 deploy/litestream_key

The sidecar needs WRITE access to the database volume: Litestream adds its own _litestream_seq/_litestream_lock tables to the database, writes the -wal/-shm files and checkpoints the WAL, and fails with "unable to open database file" on a read-only mount. That access is contained rather than removed — the sidecar runs as the non-root volume owner with a read-only root filesystem, no-new-privileges and all Linux capabilities dropped.

Check replication with docker compose -f deploy/compose.yaml logs litestream or docker compose -f deploy/compose.yaml exec litestream litestream ltx /var/lib/nestquest/nestquest.db. To restore (high level): stop the api service, run litestream restore -config /etc/litestream.yml -o <new path> /var/lib/nestquest/nestquest.db from a litestream container with the same mounts, verify the restored file, move it into place on the volume (removing any stale -wal/-shm files), and start api again.