420 lines
14 KiB
SQL
420 lines
14 KiB
SQL
-- Description: SQLite database schema for Lemontropia Suite
|
|
-- Implements the Data Principle: Every session is a Project
|
|
-- Schema version: 2.0.0 - Added comprehensive hunting session tracking
|
|
-- Created: 2026-02-08
|
|
-- Updated: 2026-02-09
|
|
|
|
-- 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);
|
|
|
|
-- ============================================================================
|
|
-- LOADOUTS (Complete gear configurations)
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS loadouts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL UNIQUE,
|
|
description TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
-- Weapon
|
|
weapon_name TEXT,
|
|
weapon_damage REAL DEFAULT 0.0,
|
|
weapon_decay_pec REAL DEFAULT 0.0,
|
|
weapon_ammo_pec REAL DEFAULT 0.0,
|
|
weapon_dpp REAL DEFAULT 0.0,
|
|
weapon_efficiency REAL DEFAULT 0.0,
|
|
|
|
-- Weapon attachments
|
|
amplifier_name TEXT,
|
|
amplifier_decay_pec REAL DEFAULT 0.0,
|
|
scope_name TEXT,
|
|
scope_decay_pec REAL DEFAULT 0.0,
|
|
absorber_name TEXT,
|
|
absorber_decay_pec REAL DEFAULT 0.0,
|
|
|
|
-- Armor
|
|
armor_name TEXT,
|
|
armor_decay_per_hp REAL DEFAULT 0.05,
|
|
|
|
-- Plates (JSON: {"head": "Plate Name", "torso": ...})
|
|
plates_json TEXT,
|
|
|
|
-- Healing
|
|
healing_tool_name TEXT,
|
|
healing_decay_pec REAL DEFAULT 0.0,
|
|
healing_amount REAL DEFAULT 0.0,
|
|
|
|
-- Mindforce
|
|
mindforce_implant_name TEXT,
|
|
mindforce_decay_pec REAL DEFAULT 0.0,
|
|
|
|
-- Accessories (JSON)
|
|
left_ring TEXT,
|
|
right_ring TEXT,
|
|
pet_name TEXT,
|
|
accessories_json TEXT,
|
|
|
|
-- Enhancers (JSON: {"1": {"name": "...", "decay": 0.01}, ...})
|
|
enhancers_json TEXT,
|
|
|
|
-- Per-action costs (pre-calculated)
|
|
cost_per_shot_ped REAL DEFAULT 0.0,
|
|
cost_per_hit_ped REAL DEFAULT 0.0,
|
|
cost_per_heal_ped REAL DEFAULT 0.0,
|
|
|
|
-- Metadata
|
|
is_active BOOLEAN DEFAULT 0,
|
|
metadata TEXT -- JSON for extensibility
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_loadouts_name ON loadouts(name);
|
|
CREATE INDEX IF NOT EXISTS idx_loadouts_active ON loadouts(is_active);
|
|
|
|
-- ============================================================================
|
|
-- HUNTING SESSIONS (Extended tracking for hunting activities)
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS hunting_sessions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
session_id INTEGER NOT NULL UNIQUE,
|
|
loadout_id INTEGER, -- Links to loadouts table
|
|
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
ended_at TIMESTAMP,
|
|
|
|
-- Loot breakdown
|
|
total_loot_ped REAL DEFAULT 0.0,
|
|
total_shrapnel_ped REAL DEFAULT 0.0,
|
|
total_universal_ammo_ped REAL DEFAULT 0.0,
|
|
total_other_loot_ped REAL DEFAULT 0.0, -- Marketable loot excluding shrapnel/UA
|
|
|
|
-- Cost breakdown (tracked from loadout + actual events)
|
|
weapon_cost_ped REAL DEFAULT 0.0,
|
|
armor_cost_ped REAL DEFAULT 0.0,
|
|
healing_cost_ped REAL DEFAULT 0.0,
|
|
plates_cost_ped REAL DEFAULT 0.0,
|
|
enhancer_cost_ped REAL DEFAULT 0.0,
|
|
mindforce_cost_ped REAL DEFAULT 0.0,
|
|
total_cost_ped REAL DEFAULT 0.0,
|
|
|
|
-- Combat statistics
|
|
damage_dealt REAL DEFAULT 0.0,
|
|
damage_taken REAL DEFAULT 0.0,
|
|
healing_done REAL DEFAULT 0.0,
|
|
shots_fired INTEGER DEFAULT 0,
|
|
shots_missed INTEGER DEFAULT 0,
|
|
evades INTEGER DEFAULT 0,
|
|
kills INTEGER DEFAULT 0,
|
|
hits_taken INTEGER DEFAULT 0, -- Number of times hit by mobs
|
|
heals_used INTEGER DEFAULT 0, -- Number of heals performed
|
|
|
|
-- Special events
|
|
globals_count INTEGER DEFAULT 0,
|
|
hofs_count INTEGER DEFAULT 0,
|
|
|
|
-- Equipment used (snapshot from loadout)
|
|
weapon_name TEXT,
|
|
weapon_dpp REAL DEFAULT 0.0,
|
|
armor_name TEXT,
|
|
fap_name TEXT,
|
|
|
|
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE,
|
|
FOREIGN KEY (loadout_id) REFERENCES loadouts(id) ON DELETE SET NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hunting_sessions_session ON hunting_sessions(session_id);
|
|
CREATE INDEX IF NOT EXISTS idx_hunting_sessions_loadout ON hunting_sessions(loadout_id);
|
|
CREATE INDEX IF NOT EXISTS idx_hunting_sessions_weapon ON hunting_sessions(weapon_name);
|
|
|
|
-- ============================================================================
|
|
-- HUNTING GLOBALS/HoFs (Record of notable loot events)
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS hunting_globals (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
hunting_session_id INTEGER NOT NULL,
|
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
creature_name TEXT,
|
|
value_ped REAL NOT NULL,
|
|
is_hof BOOLEAN DEFAULT 0,
|
|
screenshot_path TEXT,
|
|
FOREIGN KEY (hunting_session_id) REFERENCES hunting_sessions(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hunting_globals_session ON hunting_globals(hunting_session_id);
|
|
CREATE INDEX IF NOT EXISTS idx_hunting_globals_value ON hunting_globals(value_ped);
|
|
|
|
-- ============================================================================
|
|
-- 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,
|
|
is_shrapnel BOOLEAN DEFAULT 0,
|
|
is_universal_ammo BOOLEAN DEFAULT 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);
|
|
|
|
-- ============================================================================
|
|
-- COMBAT EVENTS (Detailed combat tracking)
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS combat_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 ('damage_dealt', 'damage_taken', 'heal', 'evade', 'kill', 'critical_hit')),
|
|
|
|
damage_amount REAL,
|
|
heal_amount REAL,
|
|
creature_name TEXT,
|
|
weapon_name TEXT,
|
|
|
|
raw_log_line TEXT,
|
|
|
|
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_combat_session ON combat_events(session_id);
|
|
CREATE INDEX IF NOT EXISTS idx_combat_type ON combat_events(event_type);
|
|
|
|
-- ============================================================================
|
|
-- 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,
|
|
decay_amount_pec 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/update version
|
|
INSERT OR REPLACE INTO schema_version (version, description)
|
|
VALUES (2, 'Added comprehensive hunting session tracking with loot/cost breakdown');
|
|
|
|
-- ============================================================================
|
|
-- 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;
|
|
|
|
-- Hunting session detailed view
|
|
CREATE VIEW IF NOT EXISTS v_hunting_session_summary AS
|
|
SELECT
|
|
hs.id,
|
|
hs.session_id,
|
|
s.project_id,
|
|
p.name as project_name,
|
|
hs.started_at,
|
|
hs.ended_at,
|
|
hs.total_loot_ped,
|
|
hs.total_other_loot_ped,
|
|
hs.total_cost_ped,
|
|
hs.damage_dealt,
|
|
hs.kills,
|
|
hs.globals_count,
|
|
hs.hofs_count,
|
|
hs.weapon_name,
|
|
hs.weapon_dpp,
|
|
CASE
|
|
WHEN hs.total_cost_ped > 0
|
|
THEN ROUND((hs.total_other_loot_ped / hs.total_cost_ped) * 100, 2)
|
|
ELSE 0
|
|
END as return_percent,
|
|
CASE
|
|
WHEN hs.kills > 0
|
|
THEN ROUND(hs.total_cost_ped / hs.kills, 4)
|
|
ELSE 0
|
|
END as cost_per_kill,
|
|
CASE
|
|
WHEN hs.total_cost_ped > 0
|
|
THEN ROUND(hs.damage_dealt / hs.total_cost_ped, 2)
|
|
ELSE 0
|
|
END as dpp
|
|
FROM hunting_sessions hs
|
|
JOIN sessions s ON hs.session_id = s.id
|
|
JOIN projects p ON s.project_id = p.id;
|
|
|
|
-- Weapon performance analysis
|
|
CREATE VIEW IF NOT EXISTS v_weapon_performance AS
|
|
SELECT
|
|
weapon_name,
|
|
COUNT(*) as sessions_count,
|
|
AVG(total_other_loot_ped) as avg_loot,
|
|
AVG(total_cost_ped) as avg_cost,
|
|
AVG(CASE WHEN total_cost_ped > 0 THEN (total_other_loot_ped / total_cost_ped) * 100 ELSE 0 END) as avg_return_percent,
|
|
AVG(dpp) as avg_dpp,
|
|
SUM(kills) as total_kills,
|
|
SUM(globals_count) as total_globals,
|
|
SUM(hofs_count) as total_hofs
|
|
FROM hunting_sessions
|
|
WHERE weapon_name IS NOT NULL AND weapon_name != ''
|
|
GROUP BY weapon_name;
|