Initial commit of step-competition project

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-20 15:38:42 +02:00
commit 05e4a505b3
18 changed files with 5373 additions and 0 deletions

118
src/database.js Normal file
View File

@@ -0,0 +1,118 @@
const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const dbPath = path.join(__dirname, '..', 'step_competition.db');
const db = new sqlite3.Database(dbPath);
// Initialize database schema
function initializeDatabase() {
db.serialize(() => {
// Teams table
db.run(`
CREATE TABLE IF NOT EXISTS teams (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
// Participants table
db.run(`
CREATE TABLE IF NOT EXISTS participants (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
team_id INTEGER NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (team_id) REFERENCES teams(id)
)
`);
// Daily steps table
db.run(`
CREATE TABLE IF NOT EXISTS daily_steps (
id INTEGER PRIMARY KEY AUTOINCREMENT,
participant_id INTEGER NOT NULL,
date DATE NOT NULL,
steps INTEGER NOT NULL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (participant_id) REFERENCES participants(id),
UNIQUE(participant_id, date)
)
`);
// Daily monsters table
db.run(`
CREATE TABLE IF NOT EXISTS daily_monsters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date DATE NOT NULL UNIQUE,
monster_name TEXT NOT NULL,
monster_description TEXT,
step_goal INTEGER NOT NULL,
monster_icon TEXT DEFAULT '👹',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
// Monster catches table
db.run(`
CREATE TABLE IF NOT EXISTS monster_catches (
id INTEGER PRIMARY KEY AUTOINCREMENT,
team_id INTEGER NOT NULL,
monster_id INTEGER NOT NULL,
caught_at DATETIME DEFAULT CURRENT_TIMESTAMP,
final_steps INTEGER NOT NULL,
FOREIGN KEY (team_id) REFERENCES teams(id),
FOREIGN KEY (monster_id) REFERENCES daily_monsters(id),
UNIQUE(team_id, monster_id)
)
`);
// Create indexes for better query performance
db.run(`CREATE INDEX IF NOT EXISTS idx_daily_steps_date ON daily_steps(date)`);
db.run(`CREATE INDEX IF NOT EXISTS idx_daily_steps_participant ON daily_steps(participant_id)`);
db.run(`CREATE INDEX IF NOT EXISTS idx_participants_team ON participants(team_id)`);
db.run(`CREATE INDEX IF NOT EXISTS idx_daily_monsters_date ON daily_monsters(date)`);
db.run(`CREATE INDEX IF NOT EXISTS idx_monster_catches_team ON monster_catches(team_id)`);
db.run(`CREATE INDEX IF NOT EXISTS idx_monster_catches_monster ON monster_catches(monster_id)`);
console.log('Database initialized successfully');
});
}
// Helper function to run queries with promises
function runQuery(sql, params = []) {
return new Promise((resolve, reject) => {
db.run(sql, params, function(err) {
if (err) reject(err);
else resolve({ id: this.lastID, changes: this.changes });
});
});
}
function getQuery(sql, params = []) {
return new Promise((resolve, reject) => {
db.get(sql, params, (err, row) => {
if (err) reject(err);
else resolve(row);
});
});
}
function allQuery(sql, params = []) {
return new Promise((resolve, reject) => {
db.all(sql, params, (err, rows) => {
if (err) reject(err);
else resolve(rows);
});
});
}
module.exports = {
db,
initializeDatabase,
runQuery,
getQuery,
allQuery
};