docs: correct the SYNC_MODE deploy section after #14 added health checks - #16
Conversation
#14 added an http_service check on /api/health, which makes a claim I wrote in #12 false: docs/ops.md said "fly.toml defines no health checks". It now does. The conclusion was right for the wrong reason, and the wrong reason is the dangerous part — a reader who checks fly.toml now sees a health check and reasonably concludes config errors are covered. They are not: /api/health never calls getConfig(). getDb() reads process.env.DATABASE_URL directly (src/db/index.ts) and checkLiveness only runs `select 1` (src/services/health.ts). With SYNC_MODE unset the endpoint returns 200 and the machine stays in rotation while every real page 500s. Replaced the paragraph with a per-component table that says exactly which layer catches what, and names /api/health's 200 as the trap. Also switched the example to `fly secrets set --stage`, which avoids restarting machines for a value the running code does not yet read. Separately, notes .nvmrc and scripts/check-node-version.sh from #13 alongside the existing engines/.npmrc mention, so a future Node bump knows all three pins must agree.
📝 WalkthroughWalkthroughThe operations guide now documents ChangesOperations documentation
Estimated code review effort: 1 (Trivial) | ~5 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/ops.md`:
- Around line 222-237: Revise the opening statement in the “missing SYNC_MODE”
section to scope the issue to automatic deployment gating: state that a missing
SYNC_MODE does not automatically fail or roll back the deploy, and that
/api/health does not detect it. Preserve the existing component behavior table
and supporting explanation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 02b33686-53eb-43a6-8d5f-6dff6dbfb6b7
📒 Files selected for processing (1)
docs/ops.md
| **A missing `SYNC_MODE` is not caught by anything, including the health check.** | ||
| Per component: | ||
|
|
||
| | Component | Behavior | Why | | ||
| |---|---|---| | ||
| | Release command | **succeeds** | `src/db/migrate.ts` reads `DATABASE_URL` directly, never `getConfig()` | | ||
| | `worker` | **crash-loops** | `getConfig()` runs at `src/worker/index.ts` startup | | ||
| | `web` | **boots, then 500s on every page** | `getConfig()` is lazily cached (`src/config.ts`) and every caller is inside a route handler or page | | ||
| | `/api/health` | **returns 200 — healthy** | it never calls `getConfig()`: `getDb()` reads `process.env.DATABASE_URL` directly (`src/db/index.ts`) and `checkLiveness` only runs `select 1` | | ||
|
|
||
| That last row is the trap. `fly.toml` *does* define an `http_service` check on | ||
| `/api/health`, and that check genuinely gates deploys — but only on database | ||
| reachability. A config error leaves it reporting healthy while every real page | ||
| is broken, so the machine stays in rotation and the deploy is never gated. | ||
|
|
||
| Setting the secret first is the safety net. There is no automatic one. |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Scope the “not caught” claim to automatic deployment gating.
The table states that worker crash-loops and web returns 500s. Therefore, “not caught by anything” is too broad. State that missing SYNC_MODE does not automatically fail or roll back the deploy, and that /api/health does not detect it.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/ops.md` around lines 222 - 237, Revise the opening statement in the
“missing SYNC_MODE” section to scope the issue to automatic deployment gating:
state that a missing SYNC_MODE does not automatically fail or roll back the
deploy, and that /api/health does not detect it. Preserve the existing component
behavior table and supporting explanation.
Small docs-only correction. Not part of the local-dev stage sequence — it fixes a claim I wrote in #12 that #14 made false.
The stale claim
docs/ops.mdsaid:fly.tomlnow defines anhttp_servicecheck on/api/health(#14).Why the wrong reason matters more than the wrong fact
The conclusion — no automatic rollback for a missing
SYNC_MODE— is still correct. But the stated reason is now false in a way that actively misleads: someone who reads that line, opensfly.toml, and sees a health check will reasonably conclude the gap was closed. It wasn't./api/healthnever callsgetConfig():getDb()readsprocess.env.DATABASE_URLdirectly (src/db/index.ts), not through configcheckLivenessonly runsselect 1(src/services/health.ts)So with
SYNC_MODEunset,/api/healthreturns 200 healthy while every real page 500s. The machine stays in rotation and the deploy is never gated. The new check genuinely gates deploys — but only on database reachability, which is exactly what #14 designed it for.The fix
Replaced the paragraph with a per-component table stating which layer catches what:
migrate.tsreadsDATABASE_URLdirectlyworkergetConfig()at startupwebgetConfig()is lazy, called per request/api/healthgetConfig()with the last row called out as the trap.
Two smaller updates while in there:
fly secrets set --stage, which avoids restarting machines for a value the running code doesn't read yet. (Plainfly secrets setstill works; noted.).nvmrcandscripts/check-node-version.shfrom ci: GitHub Actions workflow, Node pin, and version-drift guard #13 next to the existingengines/.npmrcmention, so a future Node bump knows all three pins must agree.Verification
Docs-only; no source, no test changes.
🤖 Generated with Claude Code
Summary by CodeRabbit