The guard only threw when NODE_ENV==='production' AND resolution came
back empty. But NODE_ENV is exactly what isn't reliably set for the
maintenance scripts this guards (they're run by hand from an operator
shell with no service-definition env and no dotenv), so on the real
prod box the guard never fired: resolution silently returned '', the
script opened a brand-new empty SQLite file under <cwd>/data, and
printed a false "0 project(s) rebuilt" success.
Now the guard fires on the OUTCOME instead: whenever resolution
selects SQLite, refuse to run unless the target file already exists —
a migration/maintenance script must never CREATE a database. Applies
only to requireDbUrlForEnv (the script entry path); server.ts calls
resolveDbUrl directly and is untouched, so first boot still creates
its DB as before.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The test never connects to Postgres, it only asserts resolution
behaviour, so the real prod URL had no reason to be duplicated here.
Swapped for a dummy postgres://u:p@h:5432/db throughout.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
apply-onboarding-pipeline.ts and migrate-onboarding-templates.ts resolved the
engine as `DATABASE_URL ?? ''`, diverging from server.ts's production
fallback. On the prod box (DATABASE_URL unset) each script opened a brand-new
empty SQLite file, "succeeded" against it, and Postgres was never touched.
resolveDbUrl()/requireDbUrlForEnv()/pgTargetDescription() now live in
db-pg.ts as the one place this is decided; server.ts and both scripts call
it. The scripts additionally hard-fail (never fall back to SQLite) when
NODE_ENV=production resolves nothing, log their target engine before doing
any work, and close the DB handle in a finally.
Also lands client_module.created_at (nullable, additive) — schema groundwork
FIX D uses to measure a no-tick project's age from its real creation date
instead of treating a missing done_on as infinitely old.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>