Deployment Validation
Maintainer-only operator runbook. These checks govern the hosted service and do not grant a customer permission to deploy or operate the SPAPS backend.
Deployment validation should prove three things: the Python package still passes its code-quality gates, startup safety checks accept the target environment, and operational health endpoints can answer after the service boots. Keep this sequence boring; production auth and billing code should not depend on manual heroics.
Local Gate
make pytest
make lint
make typecheck
make pytest-cov
make testRuntime Gate
make local-proof-up
curl -fsS http://localhost:3301/health
curl -fsS http://localhost:3301/health/ready
curl -fsS http://localhost:3301/api/metricsUse local-proof-up for a portable checkout. make local-up is reserved for internal operator
workspaces that provide ../.env-manager/sync.sh.
Release Checklist
| Surface | Command | Expected signal | Docs to refresh when it changes |
|---|---|---|---|
| Python test path | make pytest | Repo-owned test wrapper runs affected tests | Testing and TDD |
| Runtime health | curl -fsS http://localhost:3301/health | Process health responds | Endpoint reference |
| Readiness invariants | curl -fsS http://localhost:3301/health/ready | Dependency and PII checks are named | Security invariants |
| Local persona mode | curl -fsS http://localhost:3301/health/local-mode | Local mode state is explicit | Auth and local mode |
| Metrics | curl -fsS http://localhost:3301/api/metrics | Metrics endpoint responds | Endpoint reference |
| Docs drift | npm run docs-contract:validate | Endpoint, package, env, and CLI refs match fixture | Release governance |
Migration Gate
make migrate
make new-migration MSG="describe_change"What Startup Checks Catch
| Check family | Example failure |
|---|---|
| Required settings | Missing DATABASE_URL, JWT secret, refresh secret |
| Production URLs | Non-HTTPS SPAPS_API_URL or CFO_API_URL |
| Legacy API keys | LEGACY_API_KEY_AUTH_ENABLED=true in production |
| CORS | Wildcard origin with credentials |
| Webhooks | Missing destination allowlist policy |
| Self-service | Missing allowed IP/CIDR boundary |
The production app also checks PII and email-recipient invariants during lifespan startup before serving traffic.