Reliability gaps found while investigating today's suppliers 500 (which I
only learned about because the user reported it — nothing in the app
itself said anything):
- New bober_bbq/utils/error_alerts.py: notifies OWNER_IDS via the existing
Telegram send_message pattern (already used by gdrive_backup/
reconciliation/checkbox_prro) on ANY unhandled request exception, via
Flask's got_request_exception signal — purely observational, doesn't
change the actual error response. Same helper now also wraps every
APScheduler job in run_web.py, closing the one job (reconcile_payments)
that had no failure handling at all and could die silently. A 15-minute
per-(exception type, source) cooldown keeps a repeating failure from
spamming the chat.
- gdrive_backup.py: verifies each local DB backup with PRAGMA
integrity_check before it's ever uploaded (a corrupt copy now fails
loudly instead of silently becoming an unusable "backup"), and now also
archives+uploads static/uploads/ (product photos) alongside the DB —
previously never backed up at all.
Also, per the earlier per-client template-readiness pass: provision_client.sh
automates docs/DEPLOYMENT.md's clone/.env/nginx/TLS/systemd steps for a
NEW client deployment (confirmation prompt before every irreversible
step; refuses to run against an existing install-dir). Not executed
anywhere this session — no target VPS yet, verified via `bash -n` and a
step-by-step review against the runbook it automates.
All of this is additive and was smoke-tested to confirm zero behavior
change for the live instance: same error responses, same backup content,
same scheduler behavior when nothing is actually broken.