-- Durable alert center. Apply before switching API/evaluator binaries. CREATE TABLE IF NOT EXISTS vehicle_alert_rule ( id VARCHAR(64) NOT NULL PRIMARY KEY, name VARCHAR(80) NOT NULL, description VARCHAR(500) NOT NULL DEFAULT '', severity ENUM('critical','major','minor') NOT NULL, value_type ENUM('numeric','boolean') NOT NULL, metric VARCHAR(64) NOT NULL, operator VARCHAR(8) NOT NULL, threshold_value DOUBLE NOT NULL DEFAULT 0, boolean_threshold TINYINT NULL, duration_sec INT NOT NULL DEFAULT 0, recovery_operator VARCHAR(8) NOT NULL DEFAULT '', recovery_threshold DOUBLE NOT NULL DEFAULT 0, repeat_interval_sec INT NOT NULL DEFAULT 0, scope_protocols_json TEXT NOT NULL, scope_vins_json LONGTEXT NOT NULL, notification_channels_json TEXT NOT NULL, enabled TINYINT(1) NOT NULL DEFAULT 1, version INT NOT NULL DEFAULT 1, created_by VARCHAR(128) NOT NULL, updated_by VARCHAR(128) NOT NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), KEY idx_alert_rule_enabled (enabled, severity), KEY idx_alert_rule_metric (metric) ); CREATE TABLE IF NOT EXISTS vehicle_alert_rule_audit ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, rule_id VARCHAR(64) NOT NULL, rule_version INT NOT NULL, actor VARCHAR(128) NOT NULL, action VARCHAR(32) NOT NULL, snapshot_json LONGTEXT NOT NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), KEY idx_alert_rule_audit_rule (rule_id, rule_version), KEY idx_alert_rule_audit_created (created_at) ); CREATE TABLE IF NOT EXISTS vehicle_alert_candidate ( rule_id VARCHAR(64) NOT NULL, vin VARCHAR(64) NOT NULL, protocol VARCHAR(32) NOT NULL, first_matched_at DATETIME(3) NOT NULL, last_matched_at DATETIME(3) NOT NULL, latest_value DOUBLE NOT NULL, source_event_id VARCHAR(128) NOT NULL DEFAULT '', PRIMARY KEY (rule_id, vin, protocol), KEY idx_alert_candidate_duration (first_matched_at, last_matched_at) ); CREATE TABLE IF NOT EXISTS vehicle_alert_event ( id VARCHAR(64) NOT NULL PRIMARY KEY, fingerprint VARCHAR(255) NOT NULL, rule_id VARCHAR(64) NOT NULL, rule_name VARCHAR(80) NOT NULL, rule_version INT NOT NULL, severity ENUM('critical','major','minor') NOT NULL, status ENUM('unprocessed','processing','recovered','closed','ignored') NOT NULL, vin VARCHAR(64) NOT NULL, plate VARCHAR(64) NOT NULL DEFAULT '', protocol VARCHAR(32) NOT NULL DEFAULT '', metric VARCHAR(64) NOT NULL, operator VARCHAR(8) NOT NULL, trigger_value DOUBLE NOT NULL, threshold_value DOUBLE NOT NULL, unit VARCHAR(24) NOT NULL DEFAULT '', duration_sec INT NOT NULL DEFAULT 0, location_text VARCHAR(255) NOT NULL DEFAULT '', longitude DOUBLE NULL, latitude DOUBLE NULL, source_event_id VARCHAR(128) NOT NULL DEFAULT '', event_at DATETIME(3) NULL, received_at DATETIME(3) NULL, triggered_at DATETIME(3) NOT NULL, recovered_at DATETIME(3) NULL, handler VARCHAR(128) NOT NULL DEFAULT '', version INT NOT NULL DEFAULT 1, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), KEY idx_alert_event_list (triggered_at, id), KEY idx_alert_event_status (status, severity, triggered_at), KEY idx_alert_event_vehicle (vin, triggered_at), KEY idx_alert_event_rule (rule_id, triggered_at), KEY idx_alert_event_fingerprint (fingerprint, status) ); CREATE TABLE IF NOT EXISTS vehicle_alert_event_action ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, event_id VARCHAR(64) NOT NULL, action VARCHAR(32) NOT NULL, from_status VARCHAR(32) NOT NULL DEFAULT '', to_status VARCHAR(32) NOT NULL, actor VARCHAR(128) NOT NULL, note VARCHAR(200) NOT NULL DEFAULT '', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), KEY idx_alert_action_event (event_id, created_at), KEY idx_alert_action_actor (actor, created_at) ); CREATE TABLE IF NOT EXISTS vehicle_alert_notification ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, event_id VARCHAR(64) NOT NULL, title VARCHAR(120) NOT NULL, content VARCHAR(500) NOT NULL, severity ENUM('critical','major','minor') NOT NULL, channel ENUM('in_app','sms','email','wecom') NOT NULL DEFAULT 'in_app', delivery_status ENUM('created','reserved','sent','failed') NOT NULL DEFAULT 'created', is_read TINYINT(1) NOT NULL DEFAULT 0, read_by VARCHAR(128) NOT NULL DEFAULT '', read_at DATETIME(3) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), KEY idx_alert_notification_unread (channel, is_read, created_at), KEY idx_alert_notification_event (event_id) );