deckhearth/scripts/reset-db.js

182 lines
5.9 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* Reset Database Script
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
*
* This script drops and recreates all tables in your Neon database, then
* seeds an admin user. DESTRUCTIVE never run against production.
*
* Required env (in .env.local):
* POSTGRES_URL Neon connection string
* ADMIN_INITIAL_PASSWORD strong password for the seeded admin user
* (generate with `openssl rand -base64 24`)
*
* Mirrors the post-`drop-public-setup` shape of `setup-neon-db.js`
* (commit b63b509) same ESM imports, same fail-loud env-var check,
* same no-password-echo convention. Convoy: `fix-reset-db-script`
* (2026-05-25).
*/
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
import { sql } from '@vercel/postgres';
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
import bcrypt from 'bcryptjs';
async function resetDatabase() {
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
const adminPassword = process.env.ADMIN_INITIAL_PASSWORD;
if (!adminPassword || !adminPassword.trim()) {
console.error(
'❌ ADMIN_INITIAL_PASSWORD environment variable is not set.\n' +
'\n' +
' Set it in .env.local for local dev, or as a CI secret if you run reset from CI.\n' +
' Generate a strong password with: openssl rand -base64 24\n' +
' See README.md → "First-time admin setup" for the full flow.\n'
);
process.exit(1);
}
try {
console.log('✅ Connecting to Neon database...');
console.log('🗑️ Dropping existing tables...');
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
await sql`DROP TABLE IF EXISTS deck_cards CASCADE`;
await sql`DROP TABLE IF EXISTS decks CASCADE`;
await sql`DROP TABLE IF EXISTS collection_cards CASCADE`;
await sql`DROP TABLE IF EXISTS collections CASCADE`;
await sql`DROP TABLE IF EXISTS user_cards CASCADE`;
await sql`DROP TABLE IF EXISTS cards CASCADE`;
await sql`DROP TABLE IF EXISTS users CASCADE`;
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
console.log('✅ Dropped all tables');
await sql`
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`;
console.log('✅ Created users table');
await sql`
CREATE TABLE cards (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
set_name VARCHAR(255),
set_code VARCHAR(50),
card_number VARCHAR(50),
rarity VARCHAR(50),
game VARCHAR(50) NOT NULL,
mana_cost VARCHAR(50),
cmc INTEGER,
card_type VARCHAR(255),
colors JSONB,
oracle_text TEXT,
power VARCHAR(10),
toughness VARCHAR(10),
image_url TEXT,
stock_image_url TEXT,
current_price DECIMAL(10,2),
market_price DECIMAL(10,2),
scryfall_id VARCHAR(255) UNIQUE,
verified BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`;
console.log('✅ Created cards table');
await sql`
CREATE TABLE user_cards (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
card_id INTEGER REFERENCES cards(id) ON DELETE CASCADE,
quantity INTEGER DEFAULT 1,
condition VARCHAR(50) DEFAULT 'NM',
is_foil BOOLEAN DEFAULT false,
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_id, card_id, is_foil)
)
`;
console.log('✅ Created user_cards table');
await sql`
CREATE TABLE collections (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
description TEXT,
is_public BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`;
console.log('✅ Created collections table');
await sql`
CREATE TABLE collection_cards (
id SERIAL PRIMARY KEY,
collection_id INTEGER REFERENCES collections(id) ON DELETE CASCADE,
card_id INTEGER REFERENCES cards(id) ON DELETE CASCADE,
quantity INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(collection_id, card_id)
)
`;
console.log('✅ Created collection_cards table');
await sql`
CREATE TABLE decks (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
description TEXT,
game VARCHAR(50),
is_public BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`;
console.log('✅ Created decks table');
await sql`
CREATE TABLE deck_cards (
id SERIAL PRIMARY KEY,
deck_id INTEGER REFERENCES decks(id) ON DELETE CASCADE,
card_id INTEGER REFERENCES cards(id) ON DELETE CASCADE,
quantity INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(deck_id, card_id)
)
`;
console.log('✅ Created deck_cards table');
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
const hashedPassword = await bcrypt.hash(adminPassword, 12);
await sql`
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
INSERT INTO users (email, password, role)
feat(brand): unify on Deck Hearth across in-repo strings + infra (P1 brand decision) Resolves the launch-blocking 'TCG Vault vs Deck Hearth' inconsistency called out in AGENTS.md line 5 since project setup. Operator gate-0 decision: Deck Hearth wins. Two briefs applied serially. B1 (mechanical): 7-file display + comment sweep. B2 (infrastructure): Redis prefix rename in lib/rate-limit.js (5 prefixes, accept one-time counter reset), package.json + lockfile regen (STOP-on-churn confirmed only name lines changed), admin/alice/bob email rename in seed scripts + login pre-fill + NEW idempotent migration script scripts/migrations/2026-05-24-rename-admin-email.js. Risk 4 PRESERVE applied: test/lib/permission-middleware.test.js retains admin@tcgvault.com literal with 7-line architect-authored why comment (documents pre-fix-auth-bypass bug shape; preserves historical truth per project's gotcha-documentation convention). All 5 D-decisions ratified at gate-1 (Deck Hearth / deck-hearth / deckhearth / admin@deckhearth.com / full deckhearth Redis prefix). Local: lint 128 baseline (B1 + B2), vitest 21/21 (B1 + B2). CI all green: Playwright smoke 3/3 against rebranded preview in 1m4s, forbidden-cors-headers pass, forbidden-endpoints pass, Screenshot diff pass, Vercel deployment complete. Cross-validation lineage: 4th convoy where the same 3-test smoke spec defends auth surface through sweeping change (after PR #15 Layout default-user, PR #19 CORS, PR #20 rate-limit, now this PR #21 brand rename). OPERATOR POST-MERGE ACTION REQUIRED: run 'node scripts/migrations/2026-05-24-rename-admin-email.js' against prod Neon DB before next admin login (ordering: migration FIRST, then any subsequent setup-db invocation). Migration is ESM, idempotent, UNIQUE-collision-safe. PR #21 architect-commit 50ce9ab, B1 ac8c998, B2 1c18d21.
2026-05-25 03:28:29 -04:00
VALUES (${'admin@deckhearth.com'}, ${hashedPassword}, ${'admin'})
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
ON CONFLICT (email) DO NOTHING
`;
console.log('✅ Created admin user');
console.log('🎉 Database reset completed successfully!');
console.log('');
console.log('📋 Database Details:');
console.log(' Database: Neon PostgreSQL');
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
console.log(' Admin user ready (email: admin@deckhearth.com)');
} catch (error) {
console.error('❌ Database reset failed:', error.message);
process.exit(1);
}
}
fix(scripts): convert reset-db.js to ESM + require ADMIN_INITIAL_PASSWORD (#25) Fold of two queued follow-ups from pick-a-name architect audit (convert-reset-db-to-esm + purge-weak-creds-from-helpers). Three bugs in one file; all three fixed atomically by mirroring the proven post- drop-public-setup setup-neon-db.js shape (commit b63b509). Bugs fixed: 1. CJS-in-ESM (lines 10, 12, 142): require('dotenv'), require('@neon...'), inline require('bcryptjs'). package.json has "type": "module" since bump-next-js, so npm run reset-db threw ReferenceError on Node 22.x. Same bug pattern that hit setup-neon-db.js pre-drop-public-setup B2. 2. Hardcoded weak admin password (line 143: bcrypt.hash('admin123', 12)). Same anti-pattern drop-public-setup B1 removed from setup-neon-db.js. 3. Password echoed to stdout (line 156: console.log('Admin Password: admin123')). Security anti-pattern; setup-neon-db.js post-DPS does NOT echo passwords. Fix shape (verbatim mirror of setup-neon-db.js): - ESM top-level imports (dotenv, neon, bcrypt) - Fail-loud ADMIN_INITIAL_PASSWORD env-var check at function top with helpful error message pointing to README "First-time admin setup" - bcrypt.hash(adminPassword, 12) instead of literal - ON CONFLICT (email) DO NOTHING on INSERT (defensive against double-run, matches setup-neon-db.js line 149) - No password echo in success block; admin email logged for confirmation - Updated docstring to flag DESTRUCTIVE + reference required env Convoy file: .convoys/fix-reset-db-script.md (P2 hygiene, parent-owned, no architect — this is a proven-pattern fold with no new decisions to ratify). Verification: - node --check scripts/reset-db.js: exit 0 - npm run lint: 128 problems (baseline preserved, no regression) - npm run test:run: 21/21 pass - Grep: 0 require( | 0 admin123 | 0 'Admin Password' in scripts/reset-db.js - Grep: 3 ADMIN_INITIAL_PASSWORD references (docstring, const, error msg) NOT live-tested (script is destructive — drops all tables). Operator can optionally run npm run reset-db against a non-prod Neon branch post-merge to verify end-to-end. Surfaces follow-up: lint-against-cjs-in-esm-scripts (P3 polish — add ESLint rule to prevent any future require() in scripts/** under "type": "module"). Surfaced for future convoy queue. Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:08:45 -04:00
resetDatabase();