Files
AIclinicalresearch/backend/prisma/migrations/manual_fulltext_screening.sql
HaHafeng 88cc049fb3 feat(asl): Complete Day 5 - Fulltext Screening Backend API Development
- Implement 5 core API endpoints (create task, get progress, get results, update decision, export Excel)
- Add FulltextScreeningController with Zod validation (652 lines)
- Implement ExcelExporter service with 4-sheet report generation (352 lines)
- Register routes under /api/v1/asl/fulltext-screening
- Create 31 REST Client test cases
- Add automated integration test script
- Fix PDF extraction fallback mechanism in LLM12FieldsService
- Update API design documentation to v3.0
- Update development plan to v1.2
- Create Day 5 development record
- Clean up temporary test files
2025-11-23 10:52:07 +08:00

142 lines
5.4 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =====================================================
-- 全文复筛数据库迁移脚本(手动执行)
-- Schema: asl_schema
-- 日期: 2025-11-23
-- 说明: 只操作asl_schema不影响其他schema
-- =====================================================
-- 1. 修改 literatures 表,添加全文复筛相关字段
ALTER TABLE asl_schema.literatures
ADD COLUMN IF NOT EXISTS stage TEXT DEFAULT 'imported',
ADD COLUMN IF NOT EXISTS has_pdf BOOLEAN DEFAULT false,
ADD COLUMN IF NOT EXISTS pdf_storage_type TEXT,
ADD COLUMN IF NOT EXISTS pdf_storage_ref TEXT,
ADD COLUMN IF NOT EXISTS pdf_status TEXT DEFAULT 'pending',
ADD COLUMN IF NOT EXISTS pdf_uploaded_at TIMESTAMP(3),
ADD COLUMN IF NOT EXISTS full_text_storage_type TEXT,
ADD COLUMN IF NOT EXISTS full_text_storage_ref TEXT,
ADD COLUMN IF NOT EXISTS full_text_url TEXT,
ADD COLUMN IF NOT EXISTS full_text_format TEXT,
ADD COLUMN IF NOT EXISTS full_text_source TEXT,
ADD COLUMN IF NOT EXISTS full_text_token_count INTEGER,
ADD COLUMN IF NOT EXISTS full_text_extracted_at TIMESTAMP(3);
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_literatures_stage ON asl_schema.literatures(stage);
CREATE INDEX IF NOT EXISTS idx_literatures_has_pdf ON asl_schema.literatures(has_pdf);
CREATE INDEX IF NOT EXISTS idx_literatures_pdf_status ON asl_schema.literatures(pdf_status);
-- 2. 创建 fulltext_screening_tasks 表
CREATE TABLE IF NOT EXISTS asl_schema.fulltext_screening_tasks (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL,
model_a TEXT NOT NULL,
model_b TEXT NOT NULL,
prompt_version TEXT,
status TEXT NOT NULL DEFAULT 'pending',
total_count INTEGER NOT NULL DEFAULT 0,
processed_count INTEGER NOT NULL DEFAULT 0,
success_count INTEGER NOT NULL DEFAULT 0,
failed_count INTEGER NOT NULL DEFAULT 0,
degraded_count INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER DEFAULT 0,
total_cost DOUBLE PRECISION DEFAULT 0,
started_at TIMESTAMP(3),
completed_at TIMESTAMP(3),
estimated_end_at TIMESTAMP(3),
error_message TEXT,
error_stack TEXT,
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_fulltext_task_project FOREIGN KEY (project_id)
REFERENCES asl_schema.screening_projects(id) ON DELETE CASCADE
);
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_fulltext_tasks_project_id ON asl_schema.fulltext_screening_tasks(project_id);
CREATE INDEX IF NOT EXISTS idx_fulltext_tasks_status ON asl_schema.fulltext_screening_tasks(status);
CREATE INDEX IF NOT EXISTS idx_fulltext_tasks_created_at ON asl_schema.fulltext_screening_tasks(created_at);
-- 3. 创建 fulltext_screening_results 表
CREATE TABLE IF NOT EXISTS asl_schema.fulltext_screening_results (
id TEXT PRIMARY KEY,
task_id TEXT NOT NULL,
project_id TEXT NOT NULL,
literature_id TEXT NOT NULL,
-- Model A (DeepSeek-V3) 结果
model_a_name TEXT,
model_a_status TEXT,
model_a_fields JSONB,
model_a_overall JSONB,
model_a_processing_log JSONB,
model_a_verification JSONB,
model_a_tokens INTEGER,
model_a_cost DOUBLE PRECISION,
model_a_error TEXT,
-- Model B (Qwen-Max) 结果
model_b_name TEXT,
model_b_status TEXT,
model_b_fields JSONB,
model_b_overall JSONB,
model_b_processing_log JSONB,
model_b_verification JSONB,
model_b_tokens INTEGER,
model_b_cost DOUBLE PRECISION,
model_b_error TEXT,
-- 验证结果
medical_logic_issues JSONB,
evidence_chain_issues JSONB,
-- 冲突检测
is_conflict BOOLEAN DEFAULT false,
conflict_severity TEXT,
conflict_fields TEXT[],
conflict_details JSONB,
review_priority INTEGER DEFAULT 50,
review_deadline TIMESTAMP(3),
-- 人工复核
final_decision TEXT,
final_decision_by TEXT,
final_decision_at TIMESTAMP(3),
exclusion_reason TEXT,
review_notes TEXT,
-- 处理状态
processing_status TEXT DEFAULT 'pending',
is_degraded BOOLEAN DEFAULT false,
degraded_model TEXT,
-- 元数据
processed_at TIMESTAMP(3),
prompt_version TEXT,
raw_output_a JSONB,
raw_output_b JSONB,
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_fulltext_result_task FOREIGN KEY (task_id)
REFERENCES asl_schema.fulltext_screening_tasks(id) ON DELETE CASCADE,
CONSTRAINT fk_fulltext_result_project FOREIGN KEY (project_id)
REFERENCES asl_schema.screening_projects(id) ON DELETE CASCADE,
CONSTRAINT fk_fulltext_result_literature FOREIGN KEY (literature_id)
REFERENCES asl_schema.literatures(id) ON DELETE CASCADE,
CONSTRAINT unique_project_literature_fulltext UNIQUE (project_id, literature_id)
);
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_fulltext_results_task_id ON asl_schema.fulltext_screening_results(task_id);
CREATE INDEX IF NOT EXISTS idx_fulltext_results_project_id ON asl_schema.fulltext_screening_results(project_id);
CREATE INDEX IF NOT EXISTS idx_fulltext_results_literature_id ON asl_schema.fulltext_screening_results(literature_id);
CREATE INDEX IF NOT EXISTS idx_fulltext_results_is_conflict ON asl_schema.fulltext_screening_results(is_conflict);
CREATE INDEX IF NOT EXISTS idx_fulltext_results_final_decision ON asl_schema.fulltext_screening_results(final_decision);
CREATE INDEX IF NOT EXISTS idx_fulltext_results_review_priority ON asl_schema.fulltext_screening_results(review_priority);
-- 完成
SELECT 'Migration completed successfully!' AS status;