"""add offsite fund operation tables""" from alembic import op revision = "20260910_offsite_fund" down_revision = "20260909_api_receipt" branch_labels = None depends_on = None TABLES = [ """CREATE TABLE offsite_fund_mail ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, mail_id VARCHAR(16) NOT NULL, imap_uid VARCHAR(64) NOT NULL, message_id VARCHAR(255) NOT NULL, received_date DATE NOT NULL, sender VARCHAR(255) NOT NULL, return_path VARCHAR(255) NULL, auth_result JSON NOT NULL, original_eml_path VARCHAR(500) NOT NULL, status VARCHAR(32) NOT NULL DEFAULT 'received', created_at DATETIME(6) NOT NULL, updated_at DATETIME(6) NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_offsite_mail_id (mail_id), UNIQUE KEY uk_offsite_mail_source (imap_uid, message_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci""", """CREATE TABLE offsite_fund_attachment ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, attachment_id VARCHAR(24) NOT NULL, mail_id VARCHAR(16) NOT NULL, filename VARCHAR(255) NOT NULL, file_hash VARCHAR(128) NOT NULL, media_type VARCHAR(128) NOT NULL, size_bytes BIGINT UNSIGNED NOT NULL DEFAULT 0, document_type VARCHAR(24) NOT NULL, original_file_path VARCHAR(500) NOT NULL, ocr_text MEDIUMTEXT NOT NULL, extracted_fields JSON NOT NULL, field_confidence JSON NOT NULL, page_evidence JSON NOT NULL, status VARCHAR(32) NOT NULL DEFAULT 'recognized', created_at DATETIME(6) NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_offsite_attachment_id (attachment_id), UNIQUE KEY uk_offsite_attachment_hash (file_hash, mail_id), KEY idx_offsite_attachment_mail (mail_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci""", """CREATE TABLE offsite_fund_document ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, task_id VARCHAR(24) NOT NULL, mail_id VARCHAR(16) NOT NULL, attachment_id VARCHAR(24) NOT NULL, document_type VARCHAR(24) NOT NULL, fund_code VARCHAR(32) NULL, fund_name VARCHAR(255) NULL, account_identifier VARCHAR(128) NULL, investor_name VARCHAR(128) NULL, application_no VARCHAR(128) NULL, application_date DATE NULL, raw_application_date VARCHAR(64) NULL, agency VARCHAR(128) NULL, subscription_amount_yuan DECIMAL(20,4) NULL, redemption_shares DECIMAL(20,4) NULL, operator_decision VARCHAR(16) NOT NULL DEFAULT '未处理', status VARCHAR(32) NOT NULL DEFAULT 'planned', created_at DATETIME(6) NOT NULL, updated_at DATETIME(6) NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_offsite_document_task (task_id), KEY idx_offsite_document_summary (fund_code, application_date) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci""", """CREATE TABLE offsite_execution_plan_task ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, task_id VARCHAR(24) NOT NULL, stage VARCHAR(16) NOT NULL, rule_code VARCHAR(64) NOT NULL, title VARCHAR(128) NOT NULL, depends_on JSON NOT NULL, input_json JSON NOT NULL, output_json JSON NULL, status VARCHAR(16) NOT NULL DEFAULT '待执行', error_message VARCHAR(500) NULL, created_at DATETIME(6) NOT NULL, updated_at DATETIME(6) NOT NULL, PRIMARY KEY (id), KEY idx_offsite_plan_task (task_id, stage, rule_code) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci""", """CREATE TABLE offsite_rule_result ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, task_id VARCHAR(24) NOT NULL, rule_code VARCHAR(64) NOT NULL, rule_name VARCHAR(128) NOT NULL, result VARCHAR(16) NOT NULL, document_value JSON NOT NULL, database_value JSON NOT NULL, calculation JSON NOT NULL, created_at DATETIME(6) NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_offsite_rule_task (task_id, rule_code) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci""", """CREATE TABLE offsite_query_record ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, task_id VARCHAR(24) NOT NULL, rule_code VARCHAR(64) NOT NULL, natural_language_request MEDIUMTEXT NOT NULL, script_path VARCHAR(500) NOT NULL, result_summary JSON NOT NULL, status VARCHAR(24) NOT NULL, error_message VARCHAR(500) NULL, created_at DATETIME(6) NOT NULL, PRIMARY KEY (id), KEY idx_offsite_query_task (task_id, rule_code) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci""", """CREATE TABLE offsite_notification ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, notification_type VARCHAR(32) NOT NULL, business_key VARCHAR(64) NOT NULL, receiver_id VARCHAR(64) NOT NULL, operator_id VARCHAR(64) NOT NULL, agent_draft MEDIUMTEXT NOT NULL, final_content MEDIUMTEXT NOT NULL, payload JSON NOT NULL, status VARCHAR(16) NOT NULL DEFAULT '待发送', retry_count INT UNSIGNED NOT NULL DEFAULT 0, provider_message_id VARCHAR(128) NULL, failure_reason VARCHAR(500) NULL, created_at DATETIME(6) NOT NULL, sent_at DATETIME(6) NULL, PRIMARY KEY (id), KEY idx_offsite_notice_business (business_key, notification_type) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci""", ] def upgrade() -> None: for statement in TABLES: op.execute(statement) def downgrade() -> None: raise RuntimeError("场外运营业务数据禁止自动删除,请使用前向兼容迁移")