141 lines
4.6 KiB
JavaScript
141 lines
4.6 KiB
JavaScript
#!/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 };
|