-- Deploymentcenter Unified Database Schema -- UTF-8 (utf8mb4) & InnoDB SET FOREIGN_KEY_CHECKS = 0; -- Core Platform Tables DROP TABLE IF EXISTS dc_users; DROP TABLE IF EXISTS dc_settings; -- LicenseLabrador Module Tables DROP TABLE IF EXISTS license_api_rate_limit; DROP TABLE IF EXISTS license_audit_log; DROP TABLE IF EXISTS license_activations; DROP TABLE IF EXISTS license_licenses; DROP TABLE IF EXISTS license_products; -- Watchdog Module Tables DROP TABLE IF EXISTS watchdog_proxmox_targets; DROP TABLE IF EXISTS watchdog_agent_tokens; DROP TABLE IF EXISTS watchdog_cron_jobs; DROP TABLE IF EXISTS watchdog_event_log; DROP TABLE IF EXISTS watchdog_monitors; -- UpdateService Module Tables DROP TABLE IF EXISTS updateservice_releases; SET FOREIGN_KEY_CHECKS = 1; -- 1. Core Platform Tables CREATE TABLE dc_users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(64) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, totp_secret VARCHAR(64) NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE dc_settings ( skey VARCHAR(64) PRIMARY KEY, svalue TEXT NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 2. LicenseLabrador Module Tables CREATE TABLE license_products ( id INT AUTO_INCREMENT PRIMARY KEY, slug VARCHAR(64) NOT NULL UNIQUE, name VARCHAR(190) NOT NULL, notes TEXT NULL, default_cache_ttl_hours INT NOT NULL DEFAULT 168, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE license_licenses ( id INT AUTO_INCREMENT PRIMARY KEY, product_id INT NOT NULL, license_key CHAR(29) NOT NULL UNIQUE, customer_name VARCHAR(190) NULL, customer_email VARCHAR(190) NULL, status ENUM('active','revoked','suspended') NOT NULL DEFAULT 'active', expires_at DATETIME NULL, max_activations INT NOT NULL DEFAULT 2, notes TEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (product_id) REFERENCES license_products(id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE license_activations ( id INT AUTO_INCREMENT PRIMARY KEY, license_id INT NOT NULL, hardware_id VARCHAR(128) NOT NULL, hostname VARCHAR(190) NULL, app_version VARCHAR(64) NULL, first_seen DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, last_seen DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, is_blocked TINYINT(1) NOT NULL DEFAULT 0, UNIQUE KEY uq_lic_hw (license_id, hardware_id), FOREIGN KEY (license_id) REFERENCES license_licenses(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE license_audit_log ( id BIGINT AUTO_INCREMENT PRIMARY KEY, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, actor VARCHAR(64) NOT NULL, action VARCHAR(64) NOT NULL, details TEXT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE license_api_rate_limit ( ip VARBINARY(16) NOT NULL, window_start DATETIME NOT NULL, request_count INT NOT NULL DEFAULT 0, PRIMARY KEY (ip, window_start) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 3. Watchdog Module Tables CREATE TABLE watchdog_monitors ( id BIGINT AUTO_INCREMENT PRIMARY KEY, source VARCHAR(100) NOT NULL, instance VARCHAR(100) NOT NULL DEFAULT 'default', type ENUM('heartbeat','host','hypervisor_node','guest') NOT NULL DEFAULT 'heartbeat', state ENUM('up','warning','down','error','stopped','maintenance') NOT NULL DEFAULT 'up', expected_interval_sec INT NOT NULL DEFAULT 60, last_seen_utc DATETIME NULL, last_status ENUM('ok','warning','error') NULL, last_message TEXT NULL, metrics_json JSON NULL, metric_state_reason VARCHAR(255) NULL, group_key VARCHAR(150) NULL, parent_source VARCHAR(100) NULL, notes TEXT NULL, url VARCHAR(255) NULL, icon VARCHAR(255) NULL, is_muted TINYINT(1) NOT NULL DEFAULT 0, expect_running TINYINT(1) NOT NULL DEFAULT 1, os VARCHAR(50) NULL, first_contact_deadline_utc DATETIME NULL, ack_until_utc DATETIME NULL, acknowledged_by VARCHAR(100) NULL, warning_notified_utc DATETIME NULL, suppress_until_utc DATETIME NULL, last_started_utc DATETIME NULL, last_stopped_utc DATETIME NULL, last_crash_utc DATETIME NULL, created_utc DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_utc DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uq_monitor (source, instance) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE watchdog_event_log ( id BIGINT AUTO_INCREMENT PRIMARY KEY, source VARCHAR(100) NOT NULL, instance VARCHAR(100) NOT NULL DEFAULT 'default', kind ENUM('started','stopped_graceful','crash_suspected','hard_error', 'recovered','warning_raised','warning_cleared', 'maintenance_start','maintenance_end','watchdog_started') NOT NULL, from_state VARCHAR(20) NULL, to_state VARCHAR(20) NULL, severity ENUM('info','warning','alarm') NOT NULL DEFAULT 'info', at_utc DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, message TEXT NULL, meta_json JSON NULL, notified TINYINT(1) NOT NULL DEFAULT 0, notified_at_utc DATETIME NULL, channel VARCHAR(40) NULL, KEY ix_evt (source, instance, at_utc), KEY ix_evt_time (at_utc) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE watchdog_cron_jobs ( name VARCHAR(50) PRIMARY KEY, interval_sec INT NOT NULL, last_run_utc DATETIME NULL, running TINYINT(1) NOT NULL DEFAULT 0, lock_until_utc DATETIME NULL, last_status VARCHAR(20) NULL, last_duration_ms INT NULL, enabled TINYINT(1) NOT NULL DEFAULT 1 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE watchdog_agent_tokens ( token_id VARCHAR(64) PRIMARY KEY, token_hash VARCHAR(128) NOT NULL, name VARCHAR(100) NOT NULL, monitor_source VARCHAR(100) NULL, monitor_instance VARCHAR(100) NULL, created_at_utc DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, last_used_at_utc DATETIME NULL, revoked TINYINT(1) NOT NULL DEFAULT 0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE watchdog_proxmox_targets ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, url VARCHAR(255) NOT NULL, token_id VARCHAR(150) NOT NULL, token_secret TEXT NOT NULL, cert_fingerprint VARCHAR(100) NULL, enabled TINYINT(1) NOT NULL DEFAULT 1, last_poll_utc DATETIME NULL, last_status VARCHAR(50) NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- 4. UpdateService Module Tables CREATE TABLE updateservice_releases ( id INT AUTO_INCREMENT PRIMARY KEY, product_slug VARCHAR(64) NOT NULL, version VARCHAR(32) NOT NULL, release_notes TEXT NULL, download_url VARCHAR(255) NOT NULL, sha256_hash VARCHAR(64) NULL, is_critical TINYINT(1) NOT NULL DEFAULT 0, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uq_prod_ver (product_slug, version) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Seed default cron jobs for Watchdog INSERT INTO watchdog_cron_jobs (name, interval_sec, enabled) VALUES ('evaluator', 60, 1), ('proxmox_poll', 60, 1), ('proxmox_smart', 600, 1), ('warning_digest', 43200, 1), ('self_ping', 60, 1), ('eventlog_cleanup', 86400, 1) ON DUPLICATE KEY UPDATE interval_sec = VALUES(interval_sec);