161 lines
7.4 KiB
SQL
161 lines
7.4 KiB
SQL
-- Clinician-only asynchronous prescription analysis; no automatic prescription writes.
|
|
-- Apply before enabling prescription_analysis.ENABLED. Existing report tables are unchanged.
|
|
CREATE TABLE IF NOT EXISTS `zyt_prescription_ai_subject` (
|
|
`prescription_id` bigint unsigned NOT NULL,
|
|
`revision` int unsigned NOT NULL DEFAULT 1,
|
|
`clinical_hash` char(64) NOT NULL,
|
|
`first_batch_id` bigint unsigned NOT NULL DEFAULT 0,
|
|
`latest_batch_id` bigint unsigned NOT NULL DEFAULT 0,
|
|
`updated_at` int unsigned NOT NULL,
|
|
PRIMARY KEY (`prescription_id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS `zyt_prescription_ai_batch` (
|
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
|
`event_key` char(64) NOT NULL,
|
|
`prescription_id` bigint unsigned NOT NULL,
|
|
`prescription_revision` int unsigned NOT NULL,
|
|
`clinical_hash` char(64) NOT NULL,
|
|
`patient_id` bigint unsigned NOT NULL DEFAULT 0,
|
|
`diagnosis_id` bigint unsigned NOT NULL DEFAULT 0,
|
|
`doctor_id` int unsigned NOT NULL DEFAULT 0,
|
|
`actor_id` int unsigned NOT NULL,
|
|
`trigger_type` varchar(40) NOT NULL,
|
|
`reason` varchar(500) NOT NULL DEFAULT '',
|
|
`ai_assisted` varchar(16) NOT NULL DEFAULT 'unknown',
|
|
`status` varchar(32) NOT NULL DEFAULT 'preparing',
|
|
`validity` varchar(32) NOT NULL DEFAULT 'current',
|
|
`comparison_type` varchar(40) NOT NULL DEFAULT 'latest_context',
|
|
`baseline_eligible` tinyint NOT NULL DEFAULT 0,
|
|
`baseline_exclusions_json` text NULL,
|
|
`prescription_cipher` longtext NOT NULL,
|
|
`context_cipher` longtext NULL,
|
|
`access_cipher` longtext NULL,
|
|
`source_hash` char(64) NOT NULL DEFAULT '',
|
|
`source_diagnosis_ids_json` text NULL,
|
|
`source_summary_json` text NULL,
|
|
`missing_json` text NULL,
|
|
`coverage_status` varchar(32) NOT NULL DEFAULT 'pending',
|
|
`cutoff_at` int unsigned NOT NULL DEFAULT 0,
|
|
`decision_at` int unsigned NOT NULL,
|
|
`wait_until` int unsigned NOT NULL,
|
|
`next_run_at` int unsigned NOT NULL,
|
|
`prepare_attempts` int unsigned NOT NULL DEFAULT 0,
|
|
`lock_token` varchar(64) NOT NULL DEFAULT '',
|
|
`lock_until` int unsigned NOT NULL DEFAULT 0,
|
|
`error_code` varchar(64) NOT NULL DEFAULT '',
|
|
`created_at` int unsigned NOT NULL,
|
|
`updated_at` int unsigned NOT NULL,
|
|
PRIMARY KEY (`id`), UNIQUE KEY `uk_event` (`event_key`),
|
|
KEY `idx_due` (`status`,`next_run_at`,`lock_until`),
|
|
KEY `idx_rx` (`prescription_id`,`id`),
|
|
KEY `idx_patient` (`patient_id`,`created_at`,`id`),
|
|
KEY `idx_diagnosis` (`diagnosis_id`,`id`),
|
|
KEY `idx_doctor` (`doctor_id`,`created_at`,`id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS `zyt_prescription_ai_task` (
|
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
|
`batch_id` bigint unsigned NOT NULL,
|
|
`model_key` varchar(16) NOT NULL,
|
|
`status` varchar(32) NOT NULL DEFAULT 'queued',
|
|
`attempts` int unsigned NOT NULL DEFAULT 0,
|
|
`total_attempts` int unsigned NOT NULL DEFAULT 0,
|
|
`manual_retries` int unsigned NOT NULL DEFAULT 0,
|
|
`next_run_at` int unsigned NOT NULL,
|
|
`lock_token` varchar(64) NOT NULL DEFAULT '',
|
|
`lock_until` int unsigned NOT NULL DEFAULT 0,
|
|
`progress_cipher` longtext NULL,
|
|
`error_code` varchar(64) NOT NULL DEFAULT '',
|
|
`result_id` bigint unsigned NOT NULL DEFAULT 0,
|
|
`started_at` int unsigned NOT NULL DEFAULT 0,
|
|
`finished_at` int unsigned NOT NULL DEFAULT 0,
|
|
`updated_at` int unsigned NOT NULL,
|
|
PRIMARY KEY (`id`), UNIQUE KEY `uk_batch_model` (`batch_id`,`model_key`),
|
|
KEY `idx_due` (`model_key`,`status`,`next_run_at`,`lock_until`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS `zyt_prescription_ai_result` (
|
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
|
`batch_id` bigint unsigned NOT NULL,
|
|
`model_key` varchar(16) NOT NULL,
|
|
`body_cipher` longtext NOT NULL,
|
|
`score` decimal(10,6) NULL,
|
|
`herb_score` decimal(10,6) NULL,
|
|
`comparison_status` varchar(32) NOT NULL,
|
|
`comparison_reason_code` varchar(64) NOT NULL DEFAULT '',
|
|
`coverage_status` varchar(32) NOT NULL,
|
|
`model_name` varchar(100) NOT NULL DEFAULT '',
|
|
`prompt_version` varchar(100) NOT NULL DEFAULT '',
|
|
`algorithm_version` varchar(100) NOT NULL DEFAULT '',
|
|
`dictionary_version` varchar(100) NOT NULL DEFAULT '',
|
|
`generated_at` int unsigned NOT NULL,
|
|
PRIMARY KEY (`id`), UNIQUE KEY `uk_result` (`batch_id`,`model_key`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS `zyt_prescription_ai_review` (
|
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
|
`result_id` bigint unsigned NOT NULL,
|
|
`admin_id` int unsigned NOT NULL,
|
|
`status` varchar(32) NOT NULL,
|
|
`comment_cipher` text NOT NULL,
|
|
`created_at` int unsigned NOT NULL,
|
|
PRIMARY KEY (`id`), KEY `idx_result` (`result_id`,`id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS `zyt_prescription_ai_attempt` (
|
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
|
`task_id` bigint unsigned NOT NULL,
|
|
`attempt_no` int unsigned NOT NULL,
|
|
`status` varchar(32) NOT NULL,
|
|
`error_code` varchar(64) NOT NULL DEFAULT '',
|
|
`started_at` int unsigned NOT NULL,
|
|
`finished_at` int unsigned NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (`id`), UNIQUE KEY `uk_attempt` (`task_id`,`attempt_no`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS `zyt_prescription_ai_limit` (
|
|
`limit_key` varchar(100) NOT NULL,
|
|
`used_count` int unsigned NOT NULL DEFAULT 0,
|
|
`updated_at` int unsigned NOT NULL,
|
|
PRIMARY KEY (`limit_key`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS `zyt_prescription_ai_request` (
|
|
`request_key` char(64) NOT NULL,
|
|
`actor_id` int unsigned NOT NULL,
|
|
`request_hash` char(64) NOT NULL,
|
|
`prescription_id` bigint unsigned NOT NULL DEFAULT 0,
|
|
`created_at` int unsigned NOT NULL,
|
|
PRIMARY KEY (`request_key`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
|
|
-- Exact permission checks also live in logic; missing menu rows never grant access.
|
|
SET @rx_ai_parent := (SELECT id FROM zyt_system_menu WHERE perms='tcm.prescription/lists' LIMIT 1);
|
|
INSERT INTO zyt_system_menu
|
|
(pid,type,name,icon,sort,perms,paths,component,selected,params,is_cache,is_show,is_disable,create_time,update_time)
|
|
SELECT COALESCE(@rx_ai_parent,0),'A',p.label,'',85,p.perm,'','','','',0,1,0,UNIX_TIMESTAMP(),UNIX_TIMESTAMP()
|
|
FROM (
|
|
SELECT '处方AI状态' label,'tcm.prescriptionAi/statuses' perm UNION ALL
|
|
SELECT '处方AI历史','tcm.prescriptionAi/reports' UNION ALL
|
|
SELECT '处方AI报告','tcm.prescriptionAi/detail' UNION ALL
|
|
SELECT '重新分析处方','tcm.prescriptionAi/regenerate' UNION ALL
|
|
SELECT '重试处方AI','tcm.prescriptionAi/retry' UNION ALL
|
|
SELECT '复核处方AI','tcm.prescriptionAi/review' UNION ALL
|
|
SELECT '处方AI医生统计','tcm.prescriptionAi/statistics'
|
|
) p WHERE NOT EXISTS (SELECT 1 FROM zyt_system_menu m WHERE m.perms=p.perm);
|
|
|
|
-- Preserve the existing distinction between AI reading and generation permissions.
|
|
INSERT IGNORE INTO zyt_system_role_menu (role_id,menu_id)
|
|
SELECT DISTINCT rm.role_id, target.id FROM zyt_system_role_menu rm
|
|
JOIN zyt_system_menu old ON old.id=rm.menu_id
|
|
JOIN zyt_system_menu target ON target.perms IN
|
|
('tcm.prescriptionAi/statuses','tcm.prescriptionAi/reports','tcm.prescriptionAi/detail','tcm.prescriptionAi/statistics')
|
|
WHERE old.perms='tcm.diagnosis/patientAiReports';
|
|
INSERT IGNORE INTO zyt_system_role_menu (role_id,menu_id)
|
|
SELECT DISTINCT rm.role_id, target.id FROM zyt_system_role_menu rm
|
|
JOIN zyt_system_menu old ON old.id=rm.menu_id
|
|
JOIN zyt_system_menu target ON target.perms IN
|
|
('tcm.prescriptionAi/regenerate','tcm.prescriptionAi/retry','tcm.prescriptionAi/review')
|
|
WHERE old.perms='tcm.diagnosis/generatePatientAiReport';
|