[B1][S-P0-2] 五注册表单源收敛 + 启动自检 #210
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
批次:B1(#199 v0.7 §7.1)。依据:来源 S 报告 §4.1/§7.1;台账 S-P0-2;五注册表人工同步点 data_source_registry:77 / ingest_service:138 / _runner UPSERT_DISPATCH / metric_registry:381。
验收标准
不做项
实施前现状核查 + 收敛设计(待评审,未改码,2026-10-07)
按 S-P0-2「纯收敛、采集数字前后等价」要求,先用只读脚本实测了各注册表的键空间(不猜)。结论:这不是「同一键集合抄五份」,不能做朴素的全键全等校验,否则会立刻报出一堆「看似失配、实为有意」的项。
一、注册表实测清单(n=键数)
二、客观差集(脚本实测,ENV=test)
DATA_TYPE_REGISTRY(18) 与UPSERT_DISPATCH(18):双向差集都为空——当前完全同步(纯人工双写,暂无失配)。SEEDS.code与model.__tablename__:18/21 不一致(code=逻辑名单数refund/wallet/ticket,物理表名=refunds/wallet_withdrawals/service_tickets)。故 code ≠ table_name 是常态,跨表对照必须以 model.tablename 为桥,不能拿 code 直接 join。_MODEL_REGISTRY(13) 是 SEEDS 物理表名的严格子集(反向差集空);SEEDS 有、MODEL_REGISTRY 无的 8 张:bms_orders, device_flow_usage, device_tag_rel, device_tags, manual_refunds, return_trackings, scrm_operators, shanmao_refunds(疑似「不进分析视图」的有意子集,待裁定)。device_profile、merchant(能入库但数据查看树无注册——缺口 or 有意不展示,待裁定)。scrm_operator/scrm_session/scrm_session_transfer(走 scrm_sync 专用通道,非 ingest_table)。另有 2 个 internal(cash_flow_wide/refund_wide,系统物化)。三、根因(为什么会「五处」)
其实是 3 条入库通道 × 2 个消费子集:
各自的键空间本来就不该相等——缺的是一处「某 code 参与哪些通道/是否可分析/是否 internal」的能力位声明与启动交叉校验。
四、推荐方案(两阶段,降风险)
新增
app/services/registry_index.py(显式汇聚,符合验收「显式汇聚 + 单一事实定义」),以 SEEDS 为锚,为每个 code 声明:code, table_name(=model.__tablename__), ingest(data_type 或 None), channel, upsert(是否在 DISPATCH), analyzable(bool), internal(bool)。启动(create_app/lifespan)跑
validate_registry_integrity()fail-fast,校验:(a) DATA_TYPE_REGISTRY.keys == UPSERT_DISPATCH.keys(当前已等,防未来漂移);
(b) 每个声明
ingest=table的 code 必在 DISPATCH;(c) 每个
analyzable=True的表名必在 _MODEL_REGISTRY,反之 MODEL_REGISTRY 每个表名能在主表找到;(d) SEEDS 每项 code/table_name/model 可解析且 name_cn 唯一(复用既有命名规范约束)。
现状的 SCRM/internal/分析子集通过能力位显式登记为例外,使自检零误报。
五、需要人工/评审裁定的 5 点(实施前请拍板)
device_profile、merchant能入库但查看树无注册——补登记还是确认为有意不展示?scrm)与能力位 schema 是否照此登记?测试:validate 函数纯输入、构造「DISPATCH 缺映射 / MODEL_REGISTRY 多表 / name_cn 重复」三类用例断言抛错(验收可测);不改采集路径,全量 pytest + ruff 保证数字等价。
倾向:先做阶段 A(满足本单验收且零采集行为变更),待上述 5 点裁定后再开阶段 B。请评审。
关闭凭证核验 (2026-10-08)
backend/app/services/registry_index.py:build_registry_index()从 DATA_TYPE_REGISTRY(18)/UPSERT_DISPATCH(18)/DATA_SOURCE_SEEDS(21+1投影)/_MODEL_REGISTRY(13) 动态汇聚能力位主表(非第四份硬编码);例外语义唯一来源CAPABILITY_NOTES(14 条登记)。commit21f16ddmain.py create_app()顶部validate_registry_integrity()(纯内存校验,不依赖 DB);五类违例汇总抛RegistryIntegrityError:①REGISTRY↔DISPATCH 键集漂移 ②采集通道缺 dispatch ③_MODEL_REGISTRY 双向漂移 ④SEEDS model 不可解析/name_cn 重名 ⑤失配无登记/冗余登记tests/test_registry_index_210.py9 例:现状零误报 + monkeypatch 构造 DISPATCH 缺映射/多映射/_MODEL_REGISTRY 漂移/name_cn 重名/无登记失配/冗余登记六类 fail-fast,pytest tests/test_registry_index_210.py -q9 passedpytest tests/ -q2128 passed exit=0;ruff check app/ tests/全绿;仅新增校验层,四注册表本体与采集链路零改动(git show 21f16dd --stat= 3 files, +307/-0)不做项核实:未拆 today.py(S-P0-3 另批);未做多 worker。
范围说明:本单落地阶段 A(汇聚 + fail-fast 自检)。阶段 B(注册表派生去双写)与「指标体系是否纳入第五注册表」界定另开后续单挂 #199。裁定记录(2026-10-07 评论五点)已逐项落实:device_profile/merchant 登记「有意不上查看树」、_MODEL_REGISTRY 13 张为有意全集(8 张 analyzable=False 已登记)、SCRM 三表 channel='scrm' 已登记。