Files
group_fqcd_jr/alembic/versions/20260911_drop_review_separation.py
T
张胜宇 e239eb778b docs: 品牌全量口径统一为「南方基金」+ 作废文档清理
1) 客服 Agent 四份交付文档 + 构建脚手架:品牌由包装占位 XX科技 / 旧名 南方财富
   统一为南方基金(热线 400-889-8899 / 官网 nffund.com),系统名改为「智能服务系统」;
   同步追加 §0.4 修订记录行,工程记录行保留原占位字面以支撑硬编码扫描验收。
2) 开发文档:清理 28 份已作废/残留文档(14 份移出归档 + 14 份仓库副本),
   新增《文档规整方案与开发前待决事项-2026-09-17》。
3) 客服agent 四份交付文档首次纳入本分支。
2026-09-17 15:15:22 +08:00

65 lines
2.5 KiB
Python
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.
"""撤下配置发布的"审核人不得等于创建人"检查约束。
为什么撤下:单管理员部署下自审是唯一可行的发布路径。原约束
`chk_config_release_separation`(`reviewer_id IS NULL OR reviewer_id <> created_by`)
让"创建人自审"在数据库层被拒绝,表现为审核接口 500 而不是业务异常;同时自审若按
"留空 reviewer_id"规避约束,又会被 `admin_service` 的激活分支判为"版本未审核"
(该分支要求 `reviewer_id is not None`),自审版本因此无法激活。
服务层 `ConfigReleaseService.approve`、`AdminService` 均已按"允许自审、如实写入
reviewer_id"实现,本迁移补齐缺失的数据库侧变更。
对基线的影响:本迁移只删除 `config_release` 上的一个 CHECK 约束,不新增、不重命名、
不删除任何表或字段,不改变任何字段的类型、可空性与业务含义;`chk_config_release_status`
约束以及全部外键、唯一键、索引保持原样(可用 `tools/schema_fingerprint.py` 与
`tools/audit_constraints.py` 复核)。
回滚:`downgrade` 重建该约束。若库中已存在 `reviewer_id = created_by` 的行,重建会被
MySQL 拒绝——这是有意为之:回滚到"双人复核"语义前必须先处理这些自审记录。
"""
from sqlalchemy import text
from alembic import op
revision = "20260911_drop_review_separation"
down_revision = "20260911_field_correction"
branch_labels = None
depends_on = None
TABLE = "config_release"
CONSTRAINT = "chk_config_release_separation"
CLAUSE = "reviewer_id IS NULL OR reviewer_id <> created_by"
def _constraint_exists() -> bool:
connection = op.get_bind()
found = connection.scalar(
text(
"""
SELECT COUNT(*)
FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = database()
AND TABLE_NAME = :table
AND CONSTRAINT_NAME = :constraint
AND CONSTRAINT_TYPE = 'CHECK'
"""
),
{"table": TABLE, "constraint": CONSTRAINT},
)
return int(found or 0) > 0
def upgrade() -> None:
"""撤下检查约束;约束已不存在时跳过(兼容手工处理过的库)。"""
if not _constraint_exists():
return
op.execute(f"ALTER TABLE {TABLE} DROP CHECK {CONSTRAINT}")
def downgrade() -> None:
"""恢复双人复核约束;存在自审记录时 MySQL 会拒绝执行。"""
if _constraint_exists():
return
op.execute(f"ALTER TABLE {TABLE} ADD CONSTRAINT {CONSTRAINT} CHECK ({CLAUSE})")