-- Know Foolery Database Initialization -- This script sets up the basic database structure for Phase 1A -- Create database (if not exists - handled by POSTGRES_DB env var) \c knowfoolery; -- Create tables CREATE TABLE IF NOT EXISTS questions ( id TEXT PRIMARY KEY, theme TEXT NOT NULL, text TEXT NOT NULL, answer TEXT NOT NULL, hint TEXT, difficulty TEXT DEFAULT 'medium' CHECK (difficulty IN ('easy', 'medium', 'hard')), is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS game_sessions ( id TEXT PRIMARY KEY, player_name TEXT NOT NULL, user_id TEXT, total_score INTEGER DEFAULT 0, questions_asked INTEGER DEFAULT 0, questions_correct INTEGER DEFAULT 0, hints_used INTEGER DEFAULT 0, start_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, end_time TIMESTAMP, status TEXT DEFAULT 'active' CHECK (status IN ('active', 'completed', 'timeout', 'abandoned')), current_question_id TEXT, current_attempts INTEGER DEFAULT 0, session_data TEXT ); CREATE TABLE IF NOT EXISTS question_attempts ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, question_id TEXT NOT NULL, attempt_number INTEGER NOT NULL, submitted_answer TEXT NOT NULL, is_correct BOOLEAN NOT NULL, used_hint BOOLEAN DEFAULT FALSE, points_awarded INTEGER DEFAULT 0, submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, time_taken_ms BIGINT DEFAULT 0, metadata TEXT ); -- Create indexes for performance CREATE INDEX IF NOT EXISTS idx_questions_theme ON questions(theme); CREATE INDEX IF NOT EXISTS idx_questions_difficulty ON questions(difficulty); CREATE INDEX IF NOT EXISTS idx_questions_active ON questions(is_active); CREATE INDEX IF NOT EXISTS idx_questions_theme_active ON questions(theme, is_active); CREATE INDEX IF NOT EXISTS idx_sessions_user ON game_sessions(user_id); CREATE INDEX IF NOT EXISTS idx_sessions_status ON game_sessions(status); CREATE INDEX IF NOT EXISTS idx_sessions_score ON game_sessions(total_score DESC); CREATE INDEX IF NOT EXISTS idx_sessions_start_time ON game_sessions(start_time); CREATE INDEX IF NOT EXISTS idx_attempts_session ON question_attempts(session_id); CREATE INDEX IF NOT EXISTS idx_attempts_question ON question_attempts(question_id); CREATE INDEX IF NOT EXISTS idx_attempts_session_question ON question_attempts(session_id, question_id); -- Insert sample data for testing INSERT INTO questions (id, theme, text, answer, hint, difficulty, is_active) VALUES ('q1', 'Geography', 'What is the capital of France?', 'Paris', 'It''s also known as the City of Light', 'easy', true), ('q2', 'Geography', 'Which country has the most time zones?', 'France', 'This country has territories across the globe', 'medium', true), ('q3', 'Science', 'What is the chemical symbol for gold?', 'Au', 'It comes from the Latin word aurum', 'medium', true), ('q4', 'History', 'In which year did World War II end?', '1945', 'It was in the mid-1940s', 'easy', true), ('q5', 'Geography', 'What is the smallest country in the world?', 'Vatican City', 'It''s located within Rome', 'hard', true), ('q6', 'Science', 'What is the speed of light in vacuum?', '299792458', 'About 300,000 km/s', 'hard', true), ('q7', 'Literature', 'Who wrote "Romeo and Juliet"?', 'Shakespeare', 'An English playwright from the 16th century', 'easy', true), ('q8', 'Mathematics', 'What is the value of Pi to 2 decimal places?', '3.14', 'The ratio of circumference to diameter', 'easy', true), ('q9', 'Sports', 'How many players are on a basketball team on court?', '5', 'Same as fingers on one hand', 'easy', true), ('q10', 'Technology', 'What does HTTP stand for?', 'HyperText Transfer Protocol', 'It''s about transferring hypertext', 'medium', true); -- Insert a sample game session for testing INSERT INTO game_sessions (id, player_name, user_id, total_score, questions_asked, questions_correct, hints_used, status) VALUES ('session-1', 'Test Player', 'player-1', 150, 3, 2, 1, 'active'); -- Insert sample attempts for testing INSERT INTO question_attempts (id, session_id, question_id, attempt_number, submitted_answer, is_correct, used_hint, points_awarded, time_taken_ms) VALUES ('attempt-1', 'session-1', 'q1', 1, 'Paris', true, false, 100, 5000), ('attempt-2', 'session-1', 'q2', 1, 'Russia', false, true, 0, 8000), ('attempt-3', 'session-1', 'q2', 2, 'France', true, true, 50, 3000); -- Create a function to update the updated_at timestamp CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ language 'plpgsql'; -- Create trigger to automatically update updated_at CREATE TRIGGER update_questions_updated_at BEFORE UPDATE ON questions FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- Grant permissions GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO knowfoolery; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO knowfoolery; -- Print success message \echo 'Database initialized successfully with sample data!' \echo 'Tables created: questions, game_sessions, question_attempts' \echo 'Sample questions inserted: 10' \echo 'Sample game session inserted: 1' \echo 'Sample attempts inserted: 3'