CREATE TABLE IF NOT EXISTS miningcheck_projects ( project_key VARCHAR(64) NOT NULL PRIMARY KEY, project_name VARCHAR(160) NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS miningcheck_settings ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, project_key VARCHAR(64) NOT NULL, baseline_measured_at DATETIME NOT NULL, baseline_coins_total DECIMAL(20,6) NOT NULL, daily_cost_amount DECIMAL(20,10) NOT NULL, daily_cost_currency VARCHAR(10) NOT NULL, report_currency VARCHAR(10) NULL, crypto_currency VARCHAR(10) NULL, display_timezone VARCHAR(64) NULL, fx_max_age_hours DECIMAL(10,2) NULL, module_theme_mode VARCHAR(16) NULL, module_theme_accent VARCHAR(16) NULL, preferred_currencies JSON NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT fk_mining_settings_project FOREIGN KEY (project_key) REFERENCES miningcheck_projects(project_key) ON DELETE CASCADE, CONSTRAINT uq_mining_settings_project UNIQUE (project_key) ); CREATE TABLE IF NOT EXISTS miningcheck_cost_plans ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, project_key VARCHAR(64) NOT NULL, label VARCHAR(120) NOT NULL, starts_at DATETIME NOT NULL, runtime_months INT NOT NULL, auto_renew TINYINT(1) NOT NULL DEFAULT 0, base_price_amount DECIMAL(20,8) NULL, payment_type VARCHAR(10) NOT NULL DEFAULT 'fiat', total_cost_amount DECIMAL(20,8) NOT NULL, currency VARCHAR(10) NOT NULL, note TEXT NULL, is_active TINYINT(1) NOT NULL DEFAULT 1, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT fk_mining_cost_plans_project FOREIGN KEY (project_key) REFERENCES miningcheck_projects(project_key) ON DELETE CASCADE ); CREATE INDEX idx_miningcheck_cost_plans_project_start ON miningcheck_cost_plans(project_key, starts_at); CREATE TABLE IF NOT EXISTS miningcheck_measurements ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, project_key VARCHAR(64) NOT NULL, measured_at DATETIME NOT NULL, coins_total DECIMAL(20,6) NOT NULL, price_per_coin DECIMAL(20,8) NULL, price_currency VARCHAR(10) NULL, note TEXT NULL, source ENUM('manual', 'image_ocr', 'seed_import') NOT NULL, image_path VARCHAR(255) NULL, ocr_raw_text MEDIUMTEXT NULL, ocr_confidence DECIMAL(6,4) NULL, ocr_flags JSON NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT fk_mining_measurements_project FOREIGN KEY (project_key) REFERENCES miningcheck_projects(project_key) ON DELETE CASCADE, CONSTRAINT uq_mining_measurements_unique UNIQUE (project_key, measured_at, coins_total) ); CREATE INDEX idx_miningcheck_measurements_project_measured_at ON miningcheck_measurements(project_key, measured_at); CREATE TABLE IF NOT EXISTS miningcheck_targets ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, project_key VARCHAR(64) NOT NULL, label VARCHAR(120) NOT NULL, target_amount_fiat DECIMAL(20,2) NOT NULL, currency VARCHAR(10) NOT NULL, miner_offer_id BIGINT UNSIGNED NULL, is_active TINYINT(1) NOT NULL DEFAULT 1, sort_order INT NOT NULL DEFAULT 0, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT fk_mining_targets_project FOREIGN KEY (project_key) REFERENCES miningcheck_projects(project_key) ON DELETE CASCADE, CONSTRAINT fk_mining_targets_offer FOREIGN KEY (miner_offer_id) REFERENCES miningcheck_miner_offers(id) ON DELETE SET NULL, CONSTRAINT uq_mining_targets_project_label UNIQUE (project_key, label) ); CREATE TABLE IF NOT EXISTS miningcheck_dashboard_definitions ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, project_key VARCHAR(64) NOT NULL, name VARCHAR(160) NOT NULL, chart_type ENUM('line', 'bar', 'area', 'table') NOT NULL, x_field VARCHAR(64) NOT NULL, y_field VARCHAR(64) NOT NULL, aggregation VARCHAR(32) NOT NULL DEFAULT 'none', filters_json JSON NULL, is_active TINYINT(1) NOT NULL DEFAULT 1, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT fk_mining_dashboards_project FOREIGN KEY (project_key) REFERENCES miningcheck_projects(project_key) ON DELETE CASCADE, CONSTRAINT uq_mining_dashboards_project_name UNIQUE (project_key, name) );