feat: add SQLite schema and seed data
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
import Database from 'better-sqlite3';
|
||||
import path from 'path';
|
||||
import { seedDatabase } from './seed';
|
||||
|
||||
const DB_PATH = process.env.DB_PATH || path.join(process.cwd(), 'data', 'zombie_invasion.db');
|
||||
|
||||
let db: Database.Database;
|
||||
|
||||
export function getDb(): Database.Database {
|
||||
if (!db) {
|
||||
const fs = require('fs');
|
||||
const dir = path.dirname(DB_PATH);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
db = new Database(DB_PATH);
|
||||
db.pragma('journal_mode = WAL');
|
||||
db.pragma('foreign_keys = ON');
|
||||
initSchema(db);
|
||||
seedDatabase();
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
function initSchema(db: Database.Database) {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS players (
|
||||
steam_id TEXT PRIMARY KEY,
|
||||
player_name TEXT NOT NULL,
|
||||
profile_level INTEGER DEFAULT 1,
|
||||
free_currency INTEGER DEFAULT 0,
|
||||
donate_currency INTEGER DEFAULT 0,
|
||||
dust_currency INTEGER DEFAULT 0,
|
||||
arcade_pack_credits TEXT DEFAULT '{"standard":0,"premium":0}',
|
||||
sounds_wheel TEXT DEFAULT '{}',
|
||||
created_at TEXT DEFAULT (datetime('now')),
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS game_sessions (
|
||||
game_id TEXT PRIMARY KEY,
|
||||
match_id INTEGER,
|
||||
session_id TEXT,
|
||||
status TEXT DEFAULT 'active',
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS game_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
steam_id TEXT NOT NULL,
|
||||
game_id TEXT,
|
||||
match_id INTEGER,
|
||||
result TEXT,
|
||||
hero TEXT,
|
||||
hero_level INTEGER,
|
||||
difficulty TEXT,
|
||||
duration INTEGER,
|
||||
kills INTEGER DEFAULT 0,
|
||||
deaths INTEGER DEFAULT 0,
|
||||
score INTEGER DEFAULT 0,
|
||||
outgoing_damage REAL DEFAULT 0,
|
||||
incoming_damage REAL DEFAULT 0,
|
||||
items TEXT,
|
||||
modifiers TEXT,
|
||||
aghanim_scepter INTEGER DEFAULT 0,
|
||||
aghanim_shard INTEGER DEFAULT 0,
|
||||
gold_earned INTEGER DEFAULT 0,
|
||||
session_id TEXT,
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS battle_passes (
|
||||
steam_id TEXT PRIMARY KEY,
|
||||
level INTEGER DEFAULT 0,
|
||||
experience INTEGER DEFAULT 0,
|
||||
has_premium INTEGER DEFAULT 0,
|
||||
claimed_rewards TEXT DEFAULT '[]',
|
||||
claimed_premium_rewards TEXT DEFAULT '[]',
|
||||
created_at TEXT DEFAULT (datetime('now')),
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS battle_pass_quests (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
steam_id TEXT NOT NULL,
|
||||
quest_id TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
name TEXT,
|
||||
description TEXT,
|
||||
progress INTEGER DEFAULT 0,
|
||||
target INTEGER DEFAULT 1,
|
||||
completed INTEGER DEFAULT 0,
|
||||
claimed INTEGER DEFAULT 0,
|
||||
reward_exp INTEGER DEFAULT 0,
|
||||
reward_free_currency INTEGER DEFAULT 0,
|
||||
quality TEXT,
|
||||
npc TEXT,
|
||||
target_item TEXT,
|
||||
created_at TEXT DEFAULT (datetime('now')),
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS purchases (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
steam_id TEXT NOT NULL,
|
||||
item_id TEXT NOT NULL,
|
||||
item_category TEXT,
|
||||
card_id INTEGER,
|
||||
price_free INTEGER DEFAULT 0,
|
||||
price_donate INTEGER DEFAULT 0,
|
||||
price_dust INTEGER DEFAULT 0,
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS active_effects (
|
||||
steam_id TEXT PRIMARY KEY,
|
||||
effects TEXT DEFAULT '{}',
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS promo_codes (
|
||||
code TEXT PRIMARY KEY,
|
||||
free_currency INTEGER DEFAULT 0,
|
||||
donate_currency INTEGER DEFAULT 0,
|
||||
dust_currency INTEGER DEFAULT 0,
|
||||
max_uses INTEGER DEFAULT 1,
|
||||
current_uses INTEGER DEFAULT 0,
|
||||
expires_at TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS promo_redemptions (
|
||||
steam_id TEXT,
|
||||
code TEXT,
|
||||
redeemed_at TEXT DEFAULT (datetime('now')),
|
||||
PRIMARY KEY (steam_id, code)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS card_levels (
|
||||
steam_id TEXT PRIMARY KEY,
|
||||
card_levels TEXT DEFAULT '{}',
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS decks (
|
||||
steam_id TEXT,
|
||||
deck_index INTEGER,
|
||||
name TEXT DEFAULT 'My Deck',
|
||||
cards TEXT DEFAULT '[]',
|
||||
updated_at TEXT DEFAULT (datetime('now')),
|
||||
PRIMARY KEY (steam_id, deck_index)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS equipment (
|
||||
steam_id TEXT PRIMARY KEY,
|
||||
equipment TEXT DEFAULT '{}',
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS arsenal_loadouts (
|
||||
steam_id TEXT,
|
||||
hero_name TEXT,
|
||||
loadout TEXT DEFAULT '{}',
|
||||
updated_at TEXT DEFAULT (datetime('now')),
|
||||
PRIMARY KEY (steam_id, hero_name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS arsenal_inventory (
|
||||
steam_id TEXT,
|
||||
instance_id TEXT,
|
||||
item_name TEXT,
|
||||
quality TEXT,
|
||||
upgrade_level INTEGER DEFAULT 0,
|
||||
serial INTEGER,
|
||||
global_serial INTEGER,
|
||||
owner_name TEXT,
|
||||
pinned INTEGER DEFAULT 0,
|
||||
favorite INTEGER DEFAULT 0,
|
||||
stats TEXT DEFAULT '[]',
|
||||
PRIMARY KEY (steam_id, instance_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS arsenal_market_listings (
|
||||
listing_id TEXT PRIMARY KEY,
|
||||
steam_id TEXT NOT NULL,
|
||||
instance_id TEXT,
|
||||
item_name TEXT,
|
||||
quality TEXT,
|
||||
upgrade_level INTEGER DEFAULT 0,
|
||||
serial INTEGER,
|
||||
global_serial INTEGER,
|
||||
price_free INTEGER DEFAULT 0,
|
||||
status TEXT DEFAULT 'active',
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS arsenal_market_sales (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
listing_id TEXT,
|
||||
seller_steam_id TEXT,
|
||||
buyer_steam_id TEXT,
|
||||
item_name TEXT,
|
||||
price_free INTEGER,
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS death_sentence_contracts (
|
||||
steam_id TEXT PRIMARY KEY,
|
||||
contracts TEXT DEFAULT '{}',
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
`);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { getDb } from './db';
|
||||
|
||||
export function seedDatabase() {
|
||||
const db = getDb();
|
||||
const count = db.prepare('SELECT COUNT(*) as c FROM promo_codes').get() as { c: number };
|
||||
if (count.c > 0) return;
|
||||
|
||||
const insert = db.prepare(`
|
||||
INSERT INTO promo_codes (code, free_currency, donate_currency, dust_currency, max_uses, expires_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
const codes = [
|
||||
['WELCOME100', 100, 0, 0, 100, null],
|
||||
['ZOMBIE500', 500, 50, 0, 50, null],
|
||||
['DONATE100', 0, 100, 0, 20, null],
|
||||
['DUST250', 0, 0, 250, 30, null],
|
||||
];
|
||||
|
||||
const tx = db.transaction(() => {
|
||||
for (const c of codes) {
|
||||
insert.run(...c);
|
||||
}
|
||||
});
|
||||
tx();
|
||||
|
||||
console.log('Database seeded with promo codes');
|
||||
}
|
||||
Reference in New Issue
Block a user