feat(seed): require ADMIN_INITIAL_PASSWORD + convert setup-db to ESM (drop-public-setup) #13
No reviewers
Labels
No labels
agent-context-drift
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: rstillwell/deckhearth#13
Loading…
Reference in a new issue
No description provided.
Delete branch "convoy/drop-public-setup"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes P0 #3 from
.convoys/ship-readiness.md. Removes the last hardcoded admin credential from the source tree and fixes a pre-existing Node 22.x compatibility bug in the seed script so the new env-var gate actually fires.scripts/setup-neon-db.jsnow requiresADMIN_INITIAL_PASSWORDenv var (fails loudly with an actionable message +process.exit(1)before any DB connection if unset).README.mdenv-example block lists the new var; the "Default Admin Account" section is replaced with "First-time admin setup" copy that documents the env var, generation suggestion (openssl rand -base64 24), CI-secret alternative, and operator-rotation note for envs that pre-date this change. Zero occurrences ofadmin123remain in source or README.scripts/setup-neon-db.jsconverted from CommonJS (require()) to native ES modules (import). Brief 1's env-var gate is theatrical without this becausepackage.jsonhas"type": "module"(frombump-next-jsfor ESLint v9 flat config) andnpm run setup-dbwas throwingReferenceError: require is not defined in ES module scopeon Node 22.x. Pure module-system conversion — no functional changes, same DDL, same env-var gate, sameON CONFLICT DO NOTHING.Diff is 2 source files (
scripts/setup-neon-db.js+21/-7,README.md+27/-5) plus 3 convoy planning docs (.convoys/drop-public-setup.md+ 2 briefs) for the audit trail.Decisions
fix-auth-bypass(JWT_SECRET) — fix-loud the input, don't sweep data. Operators rotate manually via the app post-merge. Queuerotate-default-adminif a real audit demands it..cursor/rules/no-go-zones.mdcprohibits schema edits tosetup-neon-db.js. Env-var gate + 2console.logremovals are operational. Zero DDL touched.process.exit(1); manual smoke catches regressions. Unit-testing would require either extractinglib/seed-admin.js(scope creep) or spawning the script from vitest (slow, brittle). Same heuristic the existing 16-test suite uses.Full decision rationale lives in
.convoys/drop-public-setup.md§ Decisions A-D.Smoke verification (Node 22.14.0, local)
Brief 1 + 2: fail-loud path
✅ Exit 1, no DB connection opened (no
✅ Connecting to Neon database...), brief-1 actionable stderr, noReferenceError: require is not defined(the brief-2 fix).Brief 1 + 2: happy path
✅ Exit 0,
admin123andtemporary-strong-pw-for-smokeboth absent from stdout (R3 — stdout-leak prevention).Admin user ready (email: admin@tcgvault.com)replaces the two old credential-echoconsole.loglines.End-to-end login (R1 case A — going-forward behavior)
Local DB has an admin row created 2025-07-23 with
bcrypt.hash('admin123', 12).ON CONFLICT (email) DO NOTHINGdid not rotate it.This is the documented Decision A behavior — re-running setup-db with the new env var does not rotate existing admin rows. See § Pre-merge operator checklist below.
Lint + tests
npm run lint→ exit 0; matches pre-existing baseline (128 problems / 81 errors / 47 warnings, all pre-existing in React/pages files, none inscripts/setup-neon-db.js). Tracked byfix-lint-baseline(P1 #11.5 in ship-readiness).npm run test:run→ 3 test files, 16 tests, all passing (no test touches the files in this PR).Pre-merge operator checklist
admin123hashes are NOT rotated by this PR. Any environment (production, staging, dev branches) that currently hasadmin@tcgvault.com / admin123in its database keeps that password after merge. Operators must rotate manually: log in withadmin123, change the password via profile settings, verify the new hash. The queuedrotate-default-adminfollow-up convoy will ship an idempotent rotation script if a real audit finds a deploy still on the weak hash.ADMIN_INITIAL_PASSWORDmust be set as a Vercel project secret before merging if any branch runsnpm run setup-dbfrom CI. Today none do (it is a manualpackage.jsonscript), but if a future CI step adds it, the secret must be in place first or the build will exit 1.admin123working. Reviewer should rotate via the app before deploying any preview from this branch.Resolved gotchas (
AGENTS.md)admin@tcgvault.com/admin123)" → RESOLVED by brief 1. To be reflected inAGENTS.mdby the doc-writer pass post-merge.Flagged but deferred
scripts/reset-db.js,scripts/create-test-users.js, andTESTING_GUIDE.md— convoy out-of-scope per the no-go-zones rule (historical scripts) + the convoy spec. Queuepurge-weak-creds-from-helpers(or fold intopick-a-name).admin@tcgvault.comhardcoded email in the SQLINSERT— not a credential issue; branding decision belongs to the queuedpick-a-nameconvoy (P1 #12).continue-on-error: trueuntilfix-lint-baselineruns. Implementer confirmed this PR adds zero new lint issues.Test plan (for reviewer)
unset ADMIN_INITIAL_PASSWORD, runnpm run setup-db. Confirm exit 1 + actionable stderr + noReferenceError.export ADMIN_INITIAL_PASSWORD=<your-test-value>, runnpm run setup-db. Confirm exit 0 +✅ Connecting to Neon database...+ your value does not appear anywhere in stdout.npm run test:run— all 16 tests pass.README.mdrendering on the GitHub preview tab — confirm the "First-time admin setup" section reads clearly and the operator-rotation blockquote is visible.🤖 Generated with Cursor
Made with Cursor
The latest updates on your projects. Learn more about Vercel for GitHub.
Pipeline Health
Build + CI gates
Build runs on Vercel; this CI runs lint and schema-map drift only (no duplicate build).
Role reports
See individual comments above for details. This rollup updates automatically.