#!/usr/bin/env node // seed-dev.js — Create a demo account + hero for local testing. // Safe to re-run (skips if demo user already exists). // Skipped entirely when NODE_ENV=production. // NOTE: NODE_ENV check must happen before any require() that loads config, // because config throws on placeholder SESSION_SECRET in production. if (process.env.NODE_ENV === 'production') { console.log('seed-dev: NODE_ENV=production — skipping.'); process.exit(0); } const bcrypt = require('bcryptjs'); const { runMigrations } = require('./migrate'); const { getDb } = require('../src/db'); const time = require('../src/utils/time'); const DEMO_USERNAME = 'demo'; const DEMO_PASSWORD = 'demo123'; const DEMO_HERO_NAME = 'Aldric'; const DEMO_CLASS = 'warrior'; // Starter gear: a basic weapon + armor + potion for the demo hero. const STARTER_ITEMS = [ { slug: 'rusty-sword', qty: 1 }, // weapon, common, min_level 1 { slug: 'leather-jerkin', qty: 1 }, // armor, common, min_level 1 { slug: 'minor-healing-potion', qty: 2 }, // consumable, stackable ]; function getOrCreateDemoUser(db) { const stmt = db.prepare( 'SELECT id, username FROM users WHERE username = ? COLLATE NOCASE' ); const existing = stmt.get(DEMO_USERNAME); if (existing) { console.log(` Demo user "${DEMO_USERNAME}" already exists (id=${existing.id}).`); return existing; } const passwordHash = bcrypt.hashSync(DEMO_PASSWORD, 12); const result = db.prepare( 'INSERT INTO users (username, password_hash, created_at) VALUES (?, ?, ?)' ).run(DEMO_USERNAME, passwordHash, time.now()); console.log(` Created demo user "${DEMO_USERNAME}" (id=${result.lastInsertRowid}).`); return { id: result.lastInsertRowid, username: DEMO_USERNAME }; } function getOrCreateDemoHero(db, userId) { const heroCheck = db.prepare( 'SELECT id FROM characters WHERE user_id = ?' ).get(userId); if (heroCheck) { console.log(` Demo hero already exists for user ${userId}.`); return null; } const heroNameCheck = db.prepare( 'SELECT id FROM characters WHERE name = ? COLLATE NOCASE' ).get(DEMO_HERO_NAME); if (heroNameCheck) { console.log(` Hero name "${DEMO_HERO_NAME}" already taken.`); return null; } // Get base stats for the class const { getBaseStats } = require('../src/game/classes'); const { calcDerived } = require('../src/game/stats'); const baseStats = getBaseStats(DEMO_CLASS); const hpCurrent = calcDerived(baseStats, 1, DEMO_CLASS).maxHp; const { ENERGY_MAX } = require('../src/game/stats'); const now = time.now(); const result = db.prepare( `INSERT INTO characters (user_id, name, class, level, xp, gold, str, agi, int, vit, unspent_points, hp_current, energy, energy_updated_at, kills, deaths, created_at) VALUES (?, ?, ?, 1, 0, 100, ?, ?, ?, ?, 0, ?, ?, ?, 0, 0, ?)` ).run( userId, DEMO_HERO_NAME, DEMO_CLASS, baseStats.str, baseStats.agi, baseStats.int, baseStats.vit, hpCurrent, ENERGY_MAX, now, now ); console.log(` Created demo hero "${DEMO_HERO_NAME}" (id=${result.lastInsertRowid}, class=${DEMO_CLASS}).`); return { id: result.lastInsertRowid }; } function giveStarterGear(db, characterId) { const itemIds = []; for (const { slug, qty } of STARTER_ITEMS) { const item = db.prepare('SELECT id FROM items WHERE slug = ?').get(slug); if (!item) { console.warn(` WARNING: item "${slug}" not found in database.`); continue; } itemIds.push({ itemId: item.id, qty }); } const insertInv = db.prepare( 'INSERT INTO inventory (character_id, item_id, quantity, acquired_at) VALUES (?, ?, ?, ?)' ); for (const { itemId, qty } of itemIds) { insertInv.run(characterId, itemId, qty, time.now()); } console.log(` Granted ${itemIds.length} starter item(s) to hero ${characterId}.`); } function seedDev() { console.log('seed-dev: running migrations...'); runMigrations(); const db = getDb(); console.log('seed-dev: seeding demo account...'); const user = getOrCreateDemoUser(db); const hero = getOrCreateDemoHero(db, user.id); if (hero) { giveStarterGear(db, hero.id); } console.log(''); console.log('═══════════════════════════════════════'); console.log(' Demo account ready!'); console.log(` Username: ${DEMO_USERNAME}`); console.log(` Password: ${DEMO_PASSWORD}`); console.log('═══════════════════════════════════════'); console.log(''); } // Run if called directly if (require.main === module) { seedDev(); process.exit(0); } module.exports = { seedDev };