Lead pipeline: local SQLite store as source of truth

Form submissions now land in /data/scout73.db before anything leaves the
box. The Google Sheet and the ntfy push become mirrors whose per-record
outcome is recorded, so a failed sheet write is replayable instead of
surviving only as a push telling you to retype it.

The table is a generic record store keyed by 'kind', with workflow columns
and an audit trail, so RSVPs and other forms can land in the same place
later without a migration. Admin panel talks to /api/admin over HTTP and
never opens the DB file.

- app/store.py     schema, writes, reads, one-time leads.jsonl backfill
- app/admin_api.py token-gated API; fails closed when ADMIN_TOKEN is unset
- app/app.py       three hunks: imports, boot init, join_post
- compose          ADMIN_TOKEN passed through from the Portainer stack env
This commit is contained in:
Mike Wichers
2026-08-26 19:38:33 -04:00
parent 5331e38d62
commit be2d81b3ab
4 changed files with 506 additions and 0 deletions
+1
View File
@@ -24,6 +24,7 @@ services:
- NTFY_BASE=${NTFY_BASE}
- NTFY_TOPIC=${NTFY_TOPIC}
- NTFY_TOKEN=${NTFY_TOKEN}
- ADMIN_TOKEN=${ADMIN_TOKEN}
volumes:
- /srv/scout-website/data:/data
- /srv/scout-website/secrets/service_account.json:/app/service_account.json:ro