Lemontropia-Suite/core/schema.sql

202 lines
7.2 KiB
SQL

-- Description: SQLite database schema for Lemontropia Suite
-- Implements the Data Principle: Every session is a Project
-- Schema version: 1.0.0
-- Created: 2026-02-08
-- Enable foreign key support
PRAGMA foreign_keys = ON;
-- ============================================================================
-- PROJECT MANAGEMENT (Data Principle Core)
-- ============================================================================
CREATE TABLE IF NOT EXISTS projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL CHECK (type IN ('hunt', 'mine', 'craft', 'inventory')),
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'paused', 'completed', 'archived')),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
archived_at TIMESTAMP,
metadata TEXT -- JSON blob for extensible project data
);
CREATE INDEX IF NOT EXISTS idx_projects_type ON projects(type);
CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);
CREATE INDEX IF NOT EXISTS idx_projects_created ON projects(created_at);
-- ============================================================================
-- SESSIONS (Active gameplay instances)
-- ============================================================================
CREATE TABLE IF NOT EXISTS sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL,
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ended_at TIMESTAMP,
duration_seconds INTEGER DEFAULT 0,
total_spent_ped REAL DEFAULT 0.0, -- Decimal stored as REAL, handled in code
total_return_ped REAL DEFAULT 0.0,
net_profit_ped REAL DEFAULT 0.0,
notes TEXT,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id);
CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at);
-- ============================================================================
-- LOOT EVENTS (Core data capture)
-- ============================================================================
CREATE TABLE IF NOT EXISTS loot_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id INTEGER NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
event_type TEXT NOT NULL CHECK (event_type IN ('global', 'hof', 'regular', 'skill')),
-- Loot data
item_name TEXT,
quantity INTEGER DEFAULT 1,
value_ped REAL DEFAULT 0.0,
-- Context
creature_name TEXT, -- For hunter module
zone_name TEXT,
-- Raw log line for debugging/audit
raw_log_line TEXT,
-- Screenshot reference (if triggered)
screenshot_path TEXT,
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_loot_session ON loot_events(session_id);
CREATE INDEX IF NOT EXISTS idx_loot_timestamp ON loot_events(timestamp);
CREATE INDEX IF NOT EXISTS idx_loot_type ON loot_events(event_type);
CREATE INDEX IF NOT EXISTS idx_loot_value ON loot_events(value_ped);
-- ============================================================================
-- SKILL GAINS (Character progression tracking)
-- ============================================================================
CREATE TABLE IF NOT EXISTS skill_gains (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id INTEGER NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
skill_name TEXT NOT NULL,
gained_amount REAL DEFAULT 0.0,
new_total REAL,
raw_log_line TEXT,
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_skill_session ON skill_gains(session_id);
CREATE INDEX IF NOT EXISTS idx_skill_name ON skill_gains(skill_name);
-- ============================================================================
-- DECAY TRACKING (Weapon/tool durability)
-- ============================================================================
CREATE TABLE IF NOT EXISTS decay_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id INTEGER NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
item_name TEXT NOT NULL,
decay_amount_ped REAL DEFAULT 0.0,
shots_fired INTEGER DEFAULT 0,
raw_log_line TEXT,
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_decay_session ON decay_events(session_id);
-- ============================================================================
-- SCREENSHOTS (Auto-capture on high-value events)
-- ============================================================================
CREATE TABLE IF NOT EXISTS screenshots (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id INTEGER NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
file_path TEXT NOT NULL,
trigger_event TEXT, -- What triggered the screenshot
trigger_value_ped REAL,
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_screenshots_session ON screenshots(session_id);
-- ============================================================================
-- APPLICATION STATE (Singleton table for app settings)
-- ============================================================================
CREATE TABLE IF NOT EXISTS app_state (
key TEXT PRIMARY KEY,
value TEXT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- ============================================================================
-- DATABASE VERSION TRACKING
-- ============================================================================
CREATE TABLE IF NOT EXISTS schema_version (
version INTEGER PRIMARY KEY,
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
description TEXT
);
-- Insert initial version
INSERT OR IGNORE INTO schema_version (version, description)
VALUES (1, 'Initial schema with Data Principle support');
-- ============================================================================
-- VIEWS FOR COMMON QUERIES (Performance optimization)
-- ============================================================================
-- Active project summary
CREATE VIEW IF NOT EXISTS v_project_summary AS
SELECT
p.id,
p.name,
p.type,
p.status,
p.created_at,
COUNT(DISTINCT s.id) as session_count,
SUM(s.total_spent_ped) as total_spent,
SUM(s.total_return_ped) as total_return,
SUM(s.net_profit_ped) as net_profit,
SUM(CASE WHEN l.event_type = 'global' THEN 1 ELSE 0 END) as global_count,
SUM(CASE WHEN l.event_type = 'hof' THEN 1 ELSE 0 END) as hof_count
FROM projects p
LEFT JOIN sessions s ON p.id = s.project_id
LEFT JOIN loot_events l ON s.id = l.session_id
GROUP BY p.id;
-- Session performance metrics
CREATE VIEW IF NOT EXISTS v_session_metrics AS
SELECT
s.id,
s.project_id,
p.name as project_name,
s.started_at,
s.ended_at,
s.duration_seconds,
s.total_spent_ped,
s.total_return_ped,
s.net_profit_ped,
CASE
WHEN s.total_spent_ped > 0
THEN ROUND((s.net_profit_ped / s.total_spent_ped) * 100, 2)
ELSE 0
END as roi_percent,
COUNT(l.id) as loot_events,
SUM(CASE WHEN l.event_type IN ('global', 'hof') THEN 1 ELSE 0 END) as notable_events
FROM sessions s
JOIN projects p ON s.project_id = p.id
LEFT JOIN loot_events l ON s.id = l.session_id
GROUP BY s.id;