-- Data-quality rule evolution evidence. Additive and safe to run repeatedly on MySQL 8. -- This migration does not activate rules or change any asset lifecycle state. CREATE TABLE IF NOT EXISTS `aihr_processing_rule` ( `id` bigint NOT NULL AUTO_INCREMENT, `tenant_id` varchar(20) NOT NULL, `rule_code` varchar(64) NOT NULL, `version_no` int NOT NULL, `stage` varchar(30) NOT NULL, `risk_class` varchar(20) NOT NULL, `action` varchar(20) NOT NULL, `implementation_type` varchar(30) NOT NULL, `scope_json` json DEFAULT NULL, `config_json` json NOT NULL, `status` varchar(20) NOT NULL DEFAULT 'DRAFT', `owner_id` bigint NOT NULL, `supersedes_rule_id` bigint DEFAULT NULL, `shadow_started_time` datetime DEFAULT NULL, `retired_time` datetime DEFAULT NULL, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_aihr_processing_rule_version` (`tenant_id`, `rule_code`, `version_no`), KEY `idx_aihr_processing_rule_status` (`tenant_id`, `status`, `stage`, `update_time`), CONSTRAINT `ck_aihr_processing_rule_stage` CHECK (`stage` IN ('INGESTION','PARSING','NORMALIZATION','STRUCTURING','DEDUPLICATION','PRIVACY','DOMAIN','QUALITY','PUBLISHING','INDEXING')), CONSTRAINT `ck_aihr_processing_rule_risk` CHECK (`risk_class` IN ('LOW','MEDIUM','HIGH','CRITICAL')), CONSTRAINT `ck_aihr_processing_rule_action` CHECK (`action` IN ('FLAG','REVIEW','QUARANTINE')), CONSTRAINT `ck_aihr_processing_rule_implementation` CHECK (`implementation_type` IN ('DETERMINISTIC','STATISTICAL','LLM_ASSISTED')), CONSTRAINT `ck_aihr_processing_rule_status` CHECK (`status` IN ('DRAFT','SHADOW','CANARY','ACTIVE','PAUSED','RETIRED')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Versioned data-quality processing rules'; CREATE TABLE IF NOT EXISTS `aihr_processing_rule_transition` ( `id` bigint NOT NULL AUTO_INCREMENT, `tenant_id` varchar(20) NOT NULL, `rule_id` bigint NOT NULL, `from_status` varchar(20) NOT NULL, `to_status` varchar(20) NOT NULL, `reason` varchar(500) NOT NULL, `operator_id` bigint NOT NULL, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_aihr_rule_transition_rule` (`tenant_id`, `rule_id`, `create_time`), CONSTRAINT `ck_aihr_rule_transition_from` CHECK (`from_status` IN ('DRAFT','SHADOW','CANARY','ACTIVE','PAUSED','RETIRED')), CONSTRAINT `ck_aihr_rule_transition_to` CHECK (`to_status` IN ('DRAFT','SHADOW','CANARY','ACTIVE','PAUSED','RETIRED')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Audited processing-rule status transitions'; CREATE TABLE IF NOT EXISTS `aihr_rule_evaluation` ( `id` bigint NOT NULL AUTO_INCREMENT, `tenant_id` varchar(20) NOT NULL, `rule_id` bigint NOT NULL, `asset_id` bigint DEFAULT NULL, `version_id` bigint DEFAULT NULL, `sample_key` varchar(100) NOT NULL, `evaluation_mode` varchar(20) NOT NULL DEFAULT 'SHADOW', `expected_decision` varchar(20) NOT NULL, `actual_decision` varchar(20) NOT NULL, `confidence` decimal(6,5) DEFAULT NULL, `expected_source` varchar(20) NOT NULL, `matched_reason_codes_json` json DEFAULT NULL, `false_allow` tinyint(1) NOT NULL DEFAULT 0, `false_block` tinyint(1) NOT NULL DEFAULT 0, `run_id` varchar(64) NOT NULL, `evaluator_id` bigint NOT NULL, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_aihr_rule_evaluation_sample` (`tenant_id`, `rule_id`, `run_id`, `sample_key`), KEY `idx_aihr_rule_evaluation_metrics` (`tenant_id`, `rule_id`, `evaluation_mode`, `create_time`), KEY `idx_aihr_rule_evaluation_asset` (`tenant_id`, `asset_id`, `version_id`), CONSTRAINT `ck_aihr_rule_evaluation_mode` CHECK (`evaluation_mode` IN ('SHADOW','CANARY')), CONSTRAINT `ck_aihr_rule_expected_decision` CHECK (`expected_decision` IN ('PASS','REVIEW','BLOCK')), CONSTRAINT `ck_aihr_rule_actual_decision` CHECK (`actual_decision` IN ('PASS','REVIEW','BLOCK')), CONSTRAINT `ck_aihr_rule_expected_source` CHECK (`expected_source` IN ('HUMAN','GOLDEN')), CONSTRAINT `ck_aihr_rule_false_allow` CHECK (`false_allow` IN (0,1)), CONSTRAINT `ck_aihr_rule_false_block` CHECK (`false_block` IN (0,1)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Shadow and canary rule evaluations against human or golden labels'; CREATE TABLE IF NOT EXISTS `aihr_review_sample` ( `id` bigint NOT NULL AUTO_INCREMENT, `tenant_id` varchar(20) NOT NULL, `rule_id` bigint NOT NULL, `source_evaluation_id` bigint DEFAULT NULL, `asset_id` bigint DEFAULT NULL, `version_id` bigint DEFAULT NULL, `sample_key` varchar(100) NOT NULL, `sampling_strategy` varchar(30) NOT NULL, `status` varchar(20) NOT NULL DEFAULT 'PENDING', `review_result` varchar(30) DEFAULT NULL, `review_note` varchar(1000) DEFAULT NULL, `sampled_by` bigint NOT NULL, `sampled_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `reviewed_by` bigint DEFAULT NULL, `reviewed_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_aihr_review_sample` (`tenant_id`, `rule_id`, `sample_key`), KEY `idx_aihr_review_sample_queue` (`tenant_id`, `status`, `sampling_strategy`, `sampled_time`), CONSTRAINT `ck_aihr_review_sample_strategy` CHECK (`sampling_strategy` IN ('RANDOM','RISK_WEIGHTED','MISMATCH','MANUAL')), CONSTRAINT `ck_aihr_review_sample_status` CHECK (`status` IN ('PENDING','REVIEWED')), CONSTRAINT `ck_aihr_review_sample_result` CHECK (`review_result` IS NULL OR `review_result` IN ('CONFIRMED','FALSE_ALLOW','FALSE_BLOCK','NOT_APPLICABLE')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Risk-based human review samples for automated rule outcomes';