|
|
484725f0b2
|
fix(deploy): [skip-issue] 共享文档登录脚本迁移至 app/services/ 修复清理清单导致镜像内缺失
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 3s
backend-test / backend-lint-test (push) Failing after 1h9m31s
backend-test / frontend-lint-test (push) Successful in 1m35s
根因: 两脚本在 scripts/archive/ 子目录, 但 upgrade.sh 白名单 find 只保留 scripts/ 根目录
同名文件, .dockerignore 放行规则 !scripts/kdocs_login.py 也匹配不到 archive/ 路径,
导致 docker compose build 时脚本被排除, 镜像内根本没有 → 共享文档同步反复报
"未找到金山登录态"
修复:
- kdocs_login.py / tencent_doc_login.py 迁入 app/services/shared_doc_{kdocs,tencent}_cli.py
- 去掉 sys.path 注入, 直接 from app.core.config import settings
- upgrade.sh: 整个 backend/scripts/ 清空(不再需要按文件名白名单保留)
- .dockerignore: 删掉两条 scripts/ 登录脚本放行规则
- package.sh: 删掉追加登录脚本到 tar 的 staging 逻辑
- 服务层/错误提示/测试断言同步更新路径引用
- 旧文件删除
|
2026-10-20 20:06:35 +08:00 |
|
|
|
6517f8501e
|
fix(bms): #336 refund_record_report 导出 GET query ISO 日期改写 — 根治 E 路静默空采 6 天
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 3s
backend-test / backend-lint-test (push) Failing after 35m44s
backend-test / frontend-lint-test (push) Successful in 1m4s
根因(生产抓包实证): BMS 前端 10-15 深夜发版后, wxRefundBill/downLoadExcel
GET query 携带 ISO-8601 UTC 日期(refundStartTime=2026-10-11T16:00:00.000Z),
BMS 静默返 137 字节纯表头空 CSV — 与 #335 return_tracking 同族(日期选择器
v-model 被 toISOString 序列化), 但走 GET+query 且无报错, 6 次同步全部
"成功 0 行"。对照: 页面默认查询用正常格式 → total=1948, 数据一直在。
修法: 白名单加 refund_record_report; route 改写扩展支持 GET query string
(parse_qsl 逐值改写 → urlencode 重组, 空格→+ 与 BMS 自身拼参一致)。
验证: ISO 改写 9 项全绿(新增 GET query 3 项), bms 回归 77 项全绿,
ruff 全绿, 全量 pytest 全绿。
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
|
2026-10-20 15:45:22 +08:00 |
|
|
|
e0612509ec
|
fix(bms): #335 bms_order 导入分批 commit — 根治 DB memcg OOM/recovery
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 6m18s
backend-test / frontend-lint-test (push) Successful in 55s
根因(2026-10-19 生产三次实证+内核日志): 10 万行单事务单语句 upsert 使
postgres backend 进程 RSS 膨胀至 ~1.9GiB, 撞破 db 容器 2GiB memcg 限额被
OOM kill → postmaster 全库 recovery → 导入 retry 仍撞 recovery → 「本轮未完成」。
修法: upsert_bms_orders 分批 2000 行/commit(回归 docstring 原始设计),
单批 ~3.8 万绑定参数(<65535), WAL/事务内存随 commit 释放; upsert 幂等,
中途失败重跑安全。
|
2026-10-19 16:46:04 +08:00 |
|
|
|
b4e1d56a28
|
fix(bms): #335 return_tracking route 模式补 download — 导出接口不含 export
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 5m14s
backend-test / frontend-lint-test (push) Successful in 1m6s
根因(生产实证 2026-10-19 12:57): return_tracking 导出接口 URL 为
.../customer-return-tracking/downLoadExcel, 不含子串 "export", 导致
page.route(r"export") 未命中 → ISO 日期未被改写 → BMS 仍返回 400。
导出响应监听器原本就用 "export|download|record" 三选一判据, route 模式
与之对齐为 export|download(return_tracking 命中 download)。
|
2026-10-19 12:58:45 +08:00 |
|
|
|
4cb7d7c2f2
|
fix(bms): #335 return_tracking 导出请求 ISO 日期 route 改写
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 3s
backend-test / frontend-lint-test (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
根因(生产实证 2026-10-19): BMS 后端 ~10-11 起收紧导出接口日期反序列化,
只收 yyyy-MM-dd HH:mm:ss; 而 return_tracking 页面导出把日期选择器
v-model(JS Date 对象)直接 JSON 序列化为 ISO-8601 UTC 串(实锤 payload:
2026-10-19T01:41:07.000Z = 北京 09:41:07 窗口终点) → BMS 400 JSON parse
error, 该源自 10-11 起每次失败。
修法: 导出前对白名单源(仅 return_tracking)注册 page.route 拦截, 把请求
体中完整匹配 ISO 形态的日期串改写为北京时 yyyy-MM-dd HH:mm:ss 后放行。
非 POST / 非 JSON / 无 ISO 日期一律原样放行; 改写异常不阻断导出。
- 改写逻辑 _rewrite_iso_dates_in_json 递归处理嵌套 dict/list, 只改完整
匹配 ISO 的字符串值(防误伤长文本内嵌日期子串), 返回改写处数
- _download_with_retry 拆出重试循环体 _download_retry_loop, 外层套
route 注册/卸载 try/finally; 公共签名不变, 两处调用点零改动
- 新增 6 用例单测锁定: Z/偏移/跨日换算、嵌套计数、非 ISO 形态不改写、
白名单契约
|
2026-10-19 12:34:12 +08:00 |
|
|
|
38f8042cf7
|
fix(bms): #335 低频采集两类失败 —— bms_order OOM 循环 + 导出异常请求诊断
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 3s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 14m3s
backend-test / frontend-lint-test (push) Failing after 36m8s
- _fetch.py 两处全量导出读取(openpyxl→calamine): bms_order 导出被 BMS
硬截断 10 万行, openpyxl DOM 全量加载峰值 RSS>4GiB 触发 memcg OOM
(dmesg 实证 anon-rss 4161640kB), gunicorn 被杀→重启→僵尸清理标 failed,
2026-10-13 起每小时循环; calamine 内存降一个量级(data_parser 同款先例)
- docker-compose.yml backend 内存 4G→8G 双保险(主机 23G 余量充足)
- _browser.py 导出 JSON 异常时记录请求 url/method/post_data(诊断):
定位 return_tracking 页面把日期序列化为 ISO-UTC(BMS 10-11 收紧只认
yyyy-MM-dd HH:mm:ss)的实际端点与 payload, 为下一步 route 改写供事实
- ruff 全绿; bms/fetch/browser 相关测试 EXIT=0
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
|
2026-10-19 10:01:27 +08:00 |
|
|
|
ad8ed8661c
|
feat(data): #333 数据查看树五路原始表采纳状态只读展示
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 3s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 4m59s
backend-test / frontend-lint-test (push) Has been cancelled
- refund_adoption 新增 ADOPT_REASON_CN 规则码中文释义(17码, 单一来源紧贴
规则码定义), ADOPT_REASON_ENUM/ADOPT_STATE_ENUM 经 fields API 下发前端
- data_source_registry: 经营五路 A~E 程序化补采纳四列 FIELD_OVERRIDES
(adopt_state 三态枚举+可筛选 / adopt_reason 释义枚举不可筛 /
adopt_rule_ver+adopted_at 仅展示); 启动 lifespan 自动注册生效
- Browser.vue 三层落地: ①设计说明补 #333 段(取舍: 不提供改采纳状态入口,
人工治理一律走 adoption_overrides 留痕); ②页面层 adopt_state 列头 ⓘ
三态口径说明(含"未判定=未跑作业"); ③行级 el-tag 三态徽标 + 规则码
中文 tooltip(支持 manual: 前缀人工覆盖展示) + 采纳状态下拉筛选(待定
治理跟进); 释义前端零硬编码, 规则升级只改后端
- 测试 test_adopt_state_display_333.py 5 用例: 注册四列齐全/三态元数据/
释义与规则码全集一致(防两处漂移)/版本与时间不可筛
- ruff 全绿; 前端 build 通过; 全量 pytest 零失败
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
|
2026-10-19 09:12:35 +08:00 |
|
|
|
b5b7b8aa75
|
refactor(refund): #334 退款域业务代码零读 ods —— 全状态场景迁 std_*_all 镜像视图
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 3s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 15m29s
backend-test / frontend-lint-test (push) Has been cancelled
- 新增 5 个全量镜像视图(std_refund_online_all/std_wallet_flow_all/
std_refund_shanmao_all/std_refund_manual_all/std_refund_record_all,
SELECT * 透传 ods 含采纳四列), 单一来源 STD_ALL_VIEWS 供迁移/conftest 共用
- 迁移范围(业务读取→视图, 写入一律不动仍落 ods):
analytics/refund.py 18 处(挽回专项/状态分布/工作量/导出明细/登记水位)
analytics/refund_chain.py 3 处(链路台账, ORM→table()/column()轻量句柄
避免对只读视图 autoflush) today/_staff.py 2 处(退款工作量)
device_profile 5 / audit_timeline 7 / reconcile_check 24 /
matcher 8 / reconcile 7(读; backfill_d_op_time 写路径保留)
- quality_disposition_service 保留 ods 读(质量治理本职, 铁律第三本职)
- ods 回归三本职: 采集写入 / 采纳作业读取 / 质量治理标记
- 口径文档+AGENTS.md 铁律15: 全状态语义一律读 std_*_all, 业务代码禁直读 ods
- ruff app/ tests/ 全绿; 全量 pytest 2513 全绿(首轮 5 个 flake 重跑收敛)
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
|
2026-10-19 08:30:32 +08:00 |
|
|
|
687a817f6e
|
docs(analytics): #332 铁律15例外声明补齐 —— 退款挽回专项全状态读点
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 3s
backend-test / backend-lint-test (push) Failing after 8m19s
backend-test / frontend-lint-test (push) Successful in 36s
- _refund_recovery_core / refund_recovery_analysis / person_devices /
device_analysis / device_detail docstring 声明: 读 ods 原始层 refunds
为全状态语义例外(挽回漏斗需追申请中/无需退款未完结工单, std 只含
已退款采纳行), 防后续按铁律15误"修"成读 std 导致漏斗数字失真
- 纯注释, 零行为变更; ruff 与挽回相关测试全绿
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
|
2026-10-19 06:16:19 +08:00 |
|
|
|
9e1e609425
|
docs(governance): #332 蓄水池口径拍板纯B一本账 —— A路转入提现工单仅作按单台账
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 3s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 4m58s
backend-test / frontend-lint-test (push) Successful in 52s
- 口径文档 §四: 进水/出水一律以 std_wallet_flow 为唯一准绳, 不引入 A 路
工单; 「转入提现账户」工单与「订单退费转入」是同一笔钱两本账, 前者仅
用于按单链路分析, 不参与蓄水池/水位核算, 严禁重复计入; §二说明同步
- refund_chain 注释改口: 链路分析=按单业务台账语义(非蓄水核算), 保留
A 路工单锚点 —— 生产实测 B 路进水 remark 无 RF 单号, 纯 B 无法按单还原
- 代码侧水位/勾稽本已是纯 B(std_wallet_flow), 零行为变更; 链路相关测试全绿
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
|
2026-10-19 01:38:49 +08:00 |
|
|
|
b76c3a49c5
|
docs(governance): #332 退款五路标准层 批次E(T9 口径文档定稿+铁律15挂链)
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 31m57s
backend-test / frontend-lint-test (push) Successful in 56s
- 口径文档去草案标注, 升版 v1.0(实施), 记录 T7 双跑确认与 T8 切换完成
- README §6.1 引用列 ⏳→✅ 铁律 15
- AGENTS.md 绝对禁止新增第 15 条: 统计一律读 std_*、禁止查询侧散落
复刻采纳条件、ods 只同步不治理(采纳四列 upsert 不可覆盖)、规则变更
必须升版 ADOPT_RULE_VER、企业商户统一走 dim_device_merchant
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
|
2026-10-19 00:46:48 +08:00 |
|
|
|
00d5845878
|
feat(analytics): #332 退款五路标准层 批次D(T8 analytics全入口切换std五表)
gitleaks / gitleaks (push) Failing after 12s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 19m30s
backend-test / frontend-lint-test (push) Successful in 3m54s
- 退款统计全入口 clean 视图取数切换 std 五表(refund/cash/refund_chain/
rr_views/today 系列/category/complaint/reception), 导出仅汇总切 std
- 删除查询侧散落排除 WHERE(失败/冻结关键词、质量状态过滤)——已在
采纳作业 r20261016_v1 表层固化; 全状态/全方式语义例外改读 ods 原始层
- 删 analytics 重导出的 9 个内部符号; 两处悬空注释改写(宽表/投诉侧)
- 测试适配: seed ods 后跑采纳作业固化 std(commit=False 同连接/
commit=True 隔离连接), quality_parity 语义升版为同源 std 断言
- 全量 pytest 2585 通过(exit=0), ruff app/ tests/ 全过; analytics 内
*_clean 取数 grep 零残留(TR-8.2)
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
|
2026-10-18 22:47:57 +08:00 |
|
|
|
23a041833d
|
feat(governance): #332 退款五路标准层 批次B(T4人工覆盖API+T5企业商户维表+T6调度接入与并发互斥)
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 3s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 29m42s
backend-test / frontend-lint-test (push) Successful in 56s
T4 人工覆盖 API: admin_refund_adoption(单路/全量提交覆盖 upsert + 审计留痕 +
作业联动重跑), 非法枚举/路由 422, 列表与撤销。
T5 E 路企业商户维表: dim_device_merchant_service 纯 SQL 全量重建(集团映射 +
LAG/LEAD SCD 分段 + overlap 冲突 + 假SN 过滤 + 档案仲裁), 迁移 a332b05d6e7f
新增 arbiter_pick 列; 提供消费侧 as-of JOIN 标准片段。
T6 调度接入: bms_scheduler 同步成功后顺序触发采纳作业→维表重建; jobs.py 以
事务级 pg_try_advisory_xact_lock(随作业 commit 自动释放)实现并发互斥,
admin 手动触发/维表重建返回摘要, 每次运行写 system_event 留痕。
测试: T4 8例 / T5 8例 / T6 5例; T2 用例补事务内清残留, 规避作业内部 commit
落在持久测试库导致的绝对计数假红。
全量 pytest 2519 例通过, ruff(app+tests) 通过。
|
2026-10-16 16:30:09 +08:00 |
|
|
|
8bc7e7bca7
|
feat(governance): #332 退款五路标准层 T2采纳作业+T3同步护栏与回归测试
- T2 新增 app/services/governance/refund_adoption.py: 15个机器规则码集中
定义(含普查来源注释)+ADOPT_RULE_VER=r20261016_v1; 五路集合化SQL
(text+绑定参数)keyset分批盖章(UPDATE_BATCH=5000)ods四列; TRUNCATE+
INSERT…SELECT 重建5张std表(B写flow_dir/D写source_grade/E全量);
人工覆盖LEFT JOIN(state以覆盖为准, reason永记机器码); 返回三态计数/
std行数/Decimal金额/耗时; 未知枚举→pending不进std。
- T3 同步护栏: _execute_upsert 双保险(rows入口剔除ADOPT_COLUMNS+update
列清单再排除); manual独立路径与E路 update_cols 同步排除; wallet
do_nothing 天然安全以测试固化。
- 测试: test_refund_adoption_rules.py 9例(全规则码命中/std派生列/pending
不进std/覆盖撤销往返/幂等校验和/小批次游标); test_sync_preserves_
adoption.py 6例(五路径更新不覆盖+插入为NULL+投毒rows护栏);
test_e_route_switch dup夹具加order_suffix兼容测试库唯一索引。
- 全量 pytest EXIT=0 无失败; ruff 全绿。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-10-16 14:45:39 +08:00 |
|
|
|
9700715be1
|
feat(models): #332 退款五路标准层 T1 迁移+ORM(治理四列/std五表/dim两表/override表)
- 迁移 f332a01b2c3d(单 head, down=c3d4e5f6a7b8): 五路 ods 加
adopt_state/adopt_reason/adopt_rule_ver/adopted_at + 10 个部分索引;
建 std_refund_online/std_wallet_flow(flow_dir)/std_refund_shanmao/
std_refund_manual(source_grade)/std_refund_record + dim_merchant_group(种子
云客猫系3行) + dim_device_merchant + adoption_overrides; downgrade 完整逆序。
- ORM: AdoptionColumnsMixin(含 ADOPT_COLUMNS 常量)混入五路 ods 模型;
新增 refund_standard.py / dim_merchant.py 并注册。
- conftest: 建表前 DROP 五路旧 ods 表(create_all 不 ALTER)+补迁移专属
uq_manual_refunds_dedup 部分唯一索引(同步路径测试依赖)。
- 探针库验证: 空库全链 upgrade/种子恰3行/downgrade 往返无损; ruff 绿。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-10-16 14:45:18 +08:00 |
|
|
|
96d6ef8859
|
docs(#332): 新增退款五路数据标准与采纳规则 META v1.0
- 定义原始同步(ods+三态采纳标识)→std_*标准物理表→analytics 的权威分层
- A/B/C/D/E 逐路采纳口径(2026-10-16 业务逐条确认+生产只读普查验证)
- B 路钱包蓄水池恒等式;E 路企业商户维表与云客猫集团归并
- README §6.1 META 索引登记(15 份);AGENTS 铁律 15 待文档批准后挂
|
2026-10-16 11:57:25 +08:00 |
|
|
|
7632342c39
|
docs: #328 #329 #330 #331 技术债批次处置交接记录(20261016 接续点)
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 19m32s
backend-test / frontend-lint-test (push) Successful in 2m3s
|
2026-10-15 23:08:31 +08:00 |
|
|
|
aa9bf2fd30
|
docs: #328 #329 #330 #331 台账新增 §十八 技术债分类处置(批次A/B + 实查纠偏)
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 3s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / frontend-lint-test (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
|
2026-10-15 22:56:29 +08:00 |
|
|
|
b2f781492e
|
fix(tests): #331 删 test_device_dim_filter 未使用 import(F401)
main 上 ruff 门禁红灯(F401), 删 from sqlalchemy import select; ruff check app/ tests/ 归零。
|
2026-10-15 22:56:29 +08:00 |
|
|
|
564b6e7912
|
docs(services): #329 manual_refund_sync 去重键 docstring 与实现对齐
原 docstring 写 (register_time, order_no, refund_amount), 与 _key_cols 不符;
改为真实键 (北京登记日期, order_no, COALESCE(device_sn,''), COALESCE(registrant,'')).
|
2026-10-15 22:56:28 +08:00 |
|
|
|
05e15e385d
|
fix(alembic): #328 迁移残留裸 print 改 logger(4 处/3 文件)
AGENTS 铁律 1 禁裸 print; 改 logging.getLogger("alembic.runtime.migration"),
保留原提示文案与语义。
|
2026-10-15 22:56:28 +08:00 |
|
|
|
f87998e9b8
|
chore(repo): #330 工具目录 .trae/.dsh/.workbuddy 去跟踪 + .gitignore
依据《仓库入库规范》C7(工具私有状态不入库):
- git rm -r --cached .trae .dsh .workbuddy (15 文件, 仅去跟踪, 磁盘保留)
- .gitignore 增补 .trae/ .dsh/
|
2026-10-15 22:56:27 +08:00 |
|
|
|
8c35a7ae95
|
docs(spec): #191/#299 收口任务清单勾选进度(T1-T5,T9-T11 完成)
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 1m43s
backend-test / frontend-lint-test (push) Successful in 1m9s
|
2026-10-15 17:20:34 +08:00 |
|
|
|
a8b68f6ba4
|
fix(scheduler): #191 低频档 per-source 小时窗口修复 + #299 覆盖率守卫
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 3s
backend-test / frontend-lint-test (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
#191: 调度器低频分支调用 should_run_low_freq 时漏传 deadline_hour, 取默认 7
→ now_hour>=7 恒 False, 使 per-source hour>=7 的低频档(E 路 15:00)**永不触发**
(生产实测近 20 天零 scheduled 记录, E 路数据仅靠人工手动触发维持, 已落后 5 天)。
修复: 显式 deadline_hour=now_cn.hour+1, 窗口 = [该源配置小时, 该源配置小时+1)。
补 4 个单测: 窗口语义 / 根因复现 / 源码漂移守卫 / 覆盖率告警。
#299 顺带项 5: source_freshness_service 新增 check_device_combo_coverage 只读巡检,
无套餐设备占比超 5%(当前 2.62%) → system_events 告警(日节流), 接入每小时巡检入口;
抓"成功但覆盖不完整"(0 行当成功 / 回补不全)。
|
2026-10-15 17:08:20 +08:00 |
|
|
|
0ea12267b8
|
Merge branch 'main' of http://10.147.17.41:3000/tanzk/csctalon
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 3s
backend-test / backend-lint-test (push) Failing after 1m41s
backend-test / frontend-lint-test (push) Successful in 58s
|
2026-10-15 16:11:01 +08:00 |
|
|
|
8fd561835c
|
feat(mcp): #327 MCP 只读数据出口(SSE + external_token 复用)
- 新增 app/mcp/: MCP over SSE 最小实现(initialize/tools/list/tools/call)
- 首批 2 工具: device_behavior(设备360) / recharge_traffic(充值流量)
- 认证/限流/审计复用 external_service 体系, scope 沿用 device/recharge
- 只读兜底: 每个 tools/call 前 SET TRANSACTION READ ONLY(PG 会话级硬约束)
- SSE 端点兼容 ?token= query(EventSource 无法带 Header)
- 测试: 11 项单测覆盖握手/鉴权/白名单/只读/正常调用
- 回归: 全量 pytest 2480 通过 0 失败 / ruff 通过 / C2 门禁 0 违规
|
2026-10-15 16:10:41 +08:00 |
|
|
|
d6006e9b8b
|
fix(frp): frpc 模板补登 talon-http 隧道条目 (talon.kimirock.top → 本地 4080)
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Failing after 2s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 1m45s
backend-test / frontend-lint-test (push) Successful in 36s
生产迁移 node-2080 (prod-csctalon-talon VM) 后 frpc.toml 只保留 web-http,
talon 隧道条目丢失 → VPS OpenResty (mTLS 通过) → frps 无此 customDomain → 404。
模板补登 talon-http, 重装/迁移时不再丢。
|
2026-10-15 04:38:28 +08:00 |
|
|
|
af0572b2f0
|
refactor(analytics): #326 cs_records 有效接待判据归一为单一谓词(零语义变更)
gitleaks / gitleaks (push) Failing after 10s
backend-test / commit-message-lint (push) Successful in 3s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 1h3m31s
backend-test / frontend-lint-test (push) Successful in 2m54s
- _core 新增三件套: _cs_time_cond(ORM 时间窗)/_cs_operator_cond(操作人
弱判据)/_cs_time_sql(裸SQL片段); NULL 三写法(IS NOT NULL+比较/裸比较/
BETWEEN)在 PG WHERE 中同为不通过, 行选择等价
- 替换 25 处等价出现点(today×18/reception×5/complaint×2/refund 裸SQL);
保留 8 处非「有效接待」语义的专用条件(±24h 邻近JOIN/c2工单±2天等)不强行归一
- f-string 仅嵌代码内常量片段, 值一律走绑定参数(参数化铁律不破)
- 回归: 全量 pytest 0 失败 / ruff 通过 / C2 门禁 0 违规
- 生产对账: 发布后同窗口(date=2026-09-15)三口径 KPI 与改前基线 diff=0
|
2026-10-14 23:34:17 +08:00 |
|
|
|
d1199b8686
|
fix(analytics): #325 清理5个存量红测试, 修复投诉根因热力图双bug
gitleaks / gitleaks (push) Failing after 11s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 2s
backend-test / backend-lint-test (push) Failing after 7m4s
backend-test / frontend-lint-test (push) Successful in 1m4s
- rr_views 投诉根因热力图(_view_complaint_root_heatmap) SA2.0 双bug:
① CompoundSelect(union) 直接取 .c → AttributeError, 线上调用即500;
② Row 字符串下标 r["投诉子类"] 已移除 → 改 _mapping。空库冒烟原即红,
属存量代码缺陷(冒烟从未跑通过该 preset)
- category_ops_overview 设备类型维测试: #293 起 key 源已从 DimDeviceType
改为 devices.device_type(中文名), 测试对齐
- ai_data_supply 行为画像测试: 补 package_name(#293 质检排除会把 NULL
行过滤掉) + 时间锚定(写死 2026-09-01 已滑出 30 天窗口)
- llm_tiers 测试: expert 首选对齐 #300 值班切换后的 gpt-oss-120b
全量5红→0, smoke 套件全过, ruff 通过
|
2026-10-14 18:50:29 +08:00 |
|
|
|
6b80c7b94c
|
fix(deploy): #148 修复 package.sh 因登录脚本移入archive而静默失败
gitleaks / gitleaks (push) Failing after 14s
backend-test / commit-message-lint (push) Successful in 2s
backend-test / analytics-ods-isolation (push) Failing after 3s
backend-test / backend-lint-test (push) Failing after 1m55s
backend-test / frontend-lint-test (push) Successful in 48s
tencent_doc_login.py/kdocs_login.py 移入 backend/scripts/archive/ 后,
原 tar rf ... 2>/dev/null 在 set -e 下静默中止 → 不产出 .tar.gz/latest.tar.gz,
方式B(tar包)发布链路不可用且无报错。改为 canonical 缺失回退 archive/,
经暂存目录以标准路径追加; 均缺失则告警跳过, 绝不静默。
|
2026-10-14 18:14:36 +08:00 |
|
|
|
354d84dd61
|
fix(scripts): #293 设备档案SN补全CLI容错未知参数(parse_known_args)
手动长跑入口(最长15-19h)对手动误传的额外参数不再硬崩;
本脚本无程序化调用方(调度器走服务层), 仅影响手动CLI体验。
|
2026-10-14 18:14:29 +08:00 |
|
|
|
89d1057b1b
|
#322 P2 方案A 全线: 10 张 public 干净视图 + analytics 全改读, C2 基线清零
backend-test / commit-message-lint (push) Has been cancelled
backend-test / analytics-ods-isolation (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
- 新增迁移 c3d4e5f6a7b8: 批量建 bms_order_clean/device_combo_clean/card_complaint_clean/
external_complaint_clean/cs_record_clean/wallet_withdrawal_clean/device_flow_usage_clean/
manual_refund_clean/refund_record_report_clean/shanmao_refund_clean 共 10 张薄视图,
逐列取自 ods 源表(口径逐字不变, 不做任何加工), 仅排除内部溯源列 synced_at/raw_extra/updated_by_raw
- 新增 app/models/ods_clean.py: CLEAN_VIEWS 作为单一列清单来源 + 11 个只读模型
(RefundClean 从 refund.py 迁入); 迁移与 conftest 视图重建共用同一来源, 消除双份定义漂移
- analytics 14 文件: ORM 模型类与裸 SQL 表名全部由 ods 改读 *_clean 视图
- 手动退款质检写路径移出 analytics → app/services/quality/manual_refund_review.py
(读走 ManualRefundClean; 确认/修正写走 ods 基表 ManualRefund, 视图不可写);
analytics 门面继续导出原 4 个函数, 路由零改动
- tests/conftest.py: refund_clean 专用拆表重建 → 按 CLEAN_VIEWS 通用循环
- C2 棘轮基线 64 → 0(scripts/analytics_ods_isolation_baseline.txt 仅剩表头)
|
2026-10-14 17:30:50 +08:00 |
|
|
|
cc37a68c37
|
#322 方案A: refund 域 analytics 改读 public.refund_clean 精简视图
gitleaks / gitleaks (push) Failing after 3h11m7s
backend-test / analytics-ods-isolation (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
- 新增迁移 a9b0c1d2e3f4: CREATE VIEW public.refund_clean AS SELECT 21 列
FROM ods.refunds, 口径逐字不变(不暴露 package_price/raw_extra/synced_at/
updated_by_raw/quality_note 5 个内部列)
- 新增只读模型 RefundClean(不继承 Quality/Timestamp mixin); Refund 写入
模型不动, upsert 入库与 actual_refund_time 回填仍直写 ods.refunds
- services/analytics 14 个文件全部由 Refund/ods.refunds 切换到
RefundClean/refund_clean; refund.py GROUP BY 补 refund_amount
(视图无主键致 PG 丢失函数依赖推断, refund_no 唯一故语义不变)
- conftest: 测试库不跑迁移, create_all 后按同口径重建 refund_clean 视图
- C2 棘轮基线 80 -> 64(收敛 16 条)
|
2026-10-14 12:52:40 +08:00 |
|
|
|
0cae935765
|
#321 current_combo_name 投影: dim 当前切片只补空回写(+可选覆盖)
backend-test / commit-message-lint (push) Has been cancelled
backend-test / analytics-ods-isolation (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
- dim_device_combo_service.refresh_current_combo_from_dim(db, *, overwrite=False):
默认**只补空**(保留 BMS 现值, 零回归); overwrite=True 则以 dim 覆盖(仅改差异行)
- 生产实测 dim 当前切片仅覆盖 86% 有 current 的设备(缺 44.5 万台) → 故不默认覆盖
- scripts/backfill_current_combo_from_dim.py: 回填脚本(--allow-real-db / --overwrite)
- bms_scheduler: 回补重建 dim 后"只补空"投影(current_combo_name 不再由三写入方各写各的)
- CSV 导入仍覆盖 current 的冲突: 经确认**后续仲裁**, 本次不动
|
2026-10-14 11:39:46 +08:00 |
|
|
|
95e9ff622c
|
#322 C2 门禁落地: analytics↔ods 隔离棘轮检查器 + CI job
backend-test / commit-message-lint (push) Has been cancelled
backend-test / analytics-ods-isolation (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
- scripts/check_analytics_ods_isolation.py: 检 ods_prefix/sql_table/orm_model 三类违规,
与基线棘轮比对(新增违规阻断 CI, 减少则提示收敛)
- scripts/analytics_ods_isolation_baseline.txt: 80 条存量基线(orm_model 64 + sql_table 16)
- .gitea/workflows/test.yml: 新增 analytics-ods-isolation job(纯 python3, 不依赖 docker)
|
2026-10-14 11:06:10 +08:00 |
|
|
|
11dffa14c7
|
#320 C4登记: dim_device_combo 唯一键+口径说明入数据库表结构说明 §四
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
|
2026-10-14 10:23:54 +08:00 |
|
|
|
52938da587
|
#320 前端ⓘ: 补口径拍板说明(钱包退款归SN套餐/赠送包不过滤/#321问题保留)
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
- 退款侧: A路钱包退款归设备时点套餐(钱包=中间态,特征跟SN走); 赠送包命名无规律不过滤
- 投诉侧: 空时回落 current 基准; current 与订单源 37% 不一致问题保留, 排查见 #321
|
2026-10-14 10:17:57 +08:00 |
|
|
|
8a3d12ed18
|
#320 fix: 过滤 evt_time NULL 行(create_date/created_at_raw)
gitleaks / gitleaks (push) Failing after 3h5m28s
backend-test / commit-message-lint (push) Failing after 3h5m28s
backend-test / backend-lint-test (push) Failing after 3h5m28s
backend-test / frontend-lint-test (push) Has been cancelled
|
2026-10-14 00:58:31 +08:00 |
|
|
|
f12f5dc510
|
#320 fix: 去重 (device_sn, evt_time) 撞唯一键(bms_order 优先于 device_combo)
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
|
2026-10-14 00:52:23 +08:00 |
|
|
|
9d37acba72
|
#320 P1 套餐维度样板: dim_device_combo SCD2 干净维度 + 退款/投诉两侧同读
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
- 新表 dim_device_combo(SCD Type 2): bms_orders + device_combos 两路事件合并去工厂质检,
切出每台设备套餐变化区间, valid_to=NULL/is_current=true 标记当前生效
- 构建服务 rebuild_dim_device_combo 纯 SQL(TRUNCATE + INSERT...SELECT 窗口函数),
回填脚本 backfill_dim_device_combo; 调度器在 device_combo 夜间回补完成后自动刷新
- 退款 by_combo / 投诉 by_package 改读 dim_device_combo 时点真身
(事件时点 ∈ [valid_from, valid_to)), 回落退款记录 package_name → 当前套餐;
新增 lookup_point_in_time_combo 共享助手
- 对账脚本 diff_dim_combo 抽样比对新旧口径差异
- 前端 ⓘ 设计说明同步更新套餐真身位置
|
2026-10-14 00:45:08 +08:00 |
|
|
|
b3a35e94be
|
#319 数据分层: 21 张信源表移入 ods schema(M1 建 schema/M2 移表/M3 autogen 适配)
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
背景: 86 张表混居 public, 其中 21 张为 BMS/SCRM/企微等信源浅层拷贝, 与系统
业务表(强逻辑/强约束)边界不清。按数据中台思路分层: public=系统业务库,
ods=信源直连层, 为数据治理与业务分析划清边界。
改动:
1. M1(d6e7f8a9b0c1) CREATE SCHEMA ods; M2(e7f8a9b0c1d2) ALTER TABLE ×21
SET SCHEMA ods(目录级元数据操作, 不搬数据, 索引/约束/序列随表迁移)。
2. 21 个模型 __table_args__ 加 {"schema": "ods"}; 3 处跨 schema FK 显式加
ods. 前缀(scrm_session_transfers/complaint_same_source_members/reconcile_matches)。
3. 裸 SQL 兼容方案调整(替代工单正文的"逐处补 ods. 前缀"): 实查裸 SQL 300+
处(refund.py 单文件 60+), 逐处改写风险高噪音大, 改为连接级
SET search_path TO public,ods(database.py connect 事件, 必须 commit——
连接池 reset_on_return=rollback 会撤销未提交的 SET); public 在前,
系统表解析行为不变, ods 兜底, 42P01 风险从根上消除。
4. information_schema 查询 11 处 table_schema='public' 改 IN ('public','ods')
(采集 _runner ×2 / governance_detector ×7 / governance_execute ×2)。
5. alembic env.py 两处 configure 加 include_schemas=True, 防 autogen 把
ods 表误判为待新建。
6. 补登记 ShanmaoRefund/LlmCloudPolicy 到 models/__init__(存量缺失,
autogen 一直将这两表当孤儿要 drop)。
7. tests/conftest: 独立 engine 同步 search_path(带 commit); create_all 前
CREATE SCHEMA + 清理 public 残留旧表及 2 张带跨 schema FK 的依赖表。
验证(dev 库 csctalon_dev):
- upgrade/downgrade 往返零报错; 21 表迁移前后 count(*)+金额列 sum 零差异
(对账脚本 workdata/issue319_snapshot.py, 一次性现场不入库)。
- autogen 检查: 无因本次移动引入的新 op(剩余 alter_column/索引抖动为
存量基线漂移, public 表同等存在, 与 ods 无关)。
- pytest 全量: 2464 通过 / 5 失败, 5 个均为存量问题(3 个 #293 口径漂移
+ 2 个 llm 模型名配置漂移), 与本改动无关; ruff 本次改动文件全净。
|
2026-10-13 23:13:01 +08:00 |
|
|
|
204b9d6399
|
#318 修正 extended-dims 套餐口径 stale docstring(方案0)
gitleaks / gitleaks (push) Failing after 3h13m19s
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
调研实证: by_package(complaint_extended_dims) 与 category_by_package 并非
「同一投诉页面两维度」——category_by_package 在 Category.vue(退款分类页),
by_package 经 /complaints/extended-dims 暴露但前端无任何消费
(ComplaintAnalysis.vue 明确「取舍=不重复展示 extended-dims」)。
两者测不同域(退款金额 vs 投诉单数)不同页, 用户侧无桶名冲突,
故不动统计口径(避免方案A对退款分类页的回归风险), 仅修文档漂移:
- analytics/complaint.py complaint_extended_dims docstring:
套餐口径仍写「combo_name_alias 归一」, 但 #313 已改 _device_dim_attrs
三源回落 + 工厂质检过滤 → 同步为现行口径
- complaints/_extended_dims.py 头部设计说明口径段同步
v0.9.0
|
2026-10-13 18:20:40 +08:00 |
|
|
|
b8f7487b35
|
#316 修复 refund_group_comparison 金额计算 float+Decimal 报错
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
预热实测发现: refund:gc (refund_group_comparison) 函数内部
refund_op_amount 初始化 0.0 (float) 与 sd["refund_op_amount"] (Decimal,
line 395 round 对 Decimal 返回 Decimal) 相加报错
「unsupported operand type(s) for +=: 'float' and 'decimal.Decimal'」,
违反铁律 4「金额字段一律使用定点数 Decimal」。
修复:
- refund_op_amount 初始化 0.0 → Decimal("0")
- est_amt (估算挽回金额) 初始化 0.0 → Decimal("0")
- 出参 round(d["refund_op_amount"], 2) / round(est_amt, 2) 保持
(round 对 Decimal 返回 Decimal, FastAPI jsonable_encoder 自动转 float)
此 bug 不只影响预热, 也影响路由层 /api/v1/analytics/refund/group-comparison
接口本身(用户访问会 500)。
|
2026-10-13 17:47:11 +08:00 |
|
|
|
0d2edef5c0
|
#316 缓存预热扩展: 接待/退款深度看板纳入 warm_idle 节流预热
gitleaks / gitleaks (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
- 新增 _warm_reception: 预热接待看板 4 接口(overview/catsum/percapita/group)
默认近 90 天, group-detail 用近 7 天(与前端 ReceptionDashboard.vue:710 约定对齐)
- 新增 _warm_refund_deep: 预热退款深度分析 8 接口(do/gc/pa/prm/ptd/tt/da/pt)
覆盖 RefundDashboard 月报场景默认入口(近 30 天)
- warm_idle 调用上述两个新函数, 节流模式 TTL≤60 才重算
- key 与 analytics.py 路由层逐字符对齐(缓存规范 §5.2 铁律)
- 时间语义已确认无 8h 偏移: service 内部统一走 _date_range(_core.py:191),
naive 入参按北京时间解释转 UTC aware, 不存在 SCRM naive 当 UTC 风险
|
2026-10-13 17:30:12 +08:00 |
|
|
|
6fa3afcfca
|
#317 combo_backfill end_date 由前天改为昨天, 兜底 06:00 低频档失败缺口
gitleaks / gitleaks (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
原 end_date = n.date() - 2 (前天), 昨天整天归 06:00 低频档; 若低频档失败/熔断
昨天缺口无人兜底. 改为 n.date() - 1 (昨天), 与 06:00 低频档重叠但 upsert 主键
recharge_order_no 幂等不冲突, 不影响 01:00-04:45 夜间窗口硬停止.
|
2026-10-13 17:23:43 +08:00 |
|
|
|
499e0252c6
|
#314 手动上传入口补齐缓存失效 + 缓存规范文档对齐
gitleaks / gitleaks (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
- uploads.confirm_import: inserted+updated>0 时按 data_type 查 _CACHE_PATTERNS_BY_TYPE
推断受影响前缀(退款→refund+today; 投诉→complaint+today; 设备→两侧+today; 其他→today),
调 cache_invalidate_recent_days(pat) 与 sync_task_manager finally 同口径; 失败静默
- 缓存规范 §6.1 finally pattern: 补 reception:* (3→4, 与代码逐字符对齐)
- §九 G2 标记已修复; G3 标记部分修复(已失效, 未预热→#316); 覆盖矩阵/缺口表/关联文件同步
|
2026-10-13 17:22:38 +08:00 |
|
|
|
e644ccf4f4
|
#315 docs file:// 路径前缀批量修正: /Users/tanzk/dev/csctalon → /Users/tanzk/dev-tmp/csctalon
gitleaks / gitleaks (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
docs/ 下 14 个文档(缓存规范/规划设计/arch 架构决策/安全处置/审计报告)内
file:// 链接路径前缀漂移, 导致导航断链. 纯文档改动, 不影响容器镜像, 无需重建.
|
2026-10-13 17:16:32 +08:00 |
|
|
|
2e5ae8d11a
|
#313 投诉侧 by_package 套餐口径统一到退款侧 _device_dim_attrs 三源回落
gitleaks / gitleaks (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
投诉侧 by_package 原走 devices.current_combo_name 单源 + combo_name_alias 归一,
与退款侧 by_combo 的 _device_dim_attrs 三源回落(最新非质检订单→devices→
device_combos, 工厂质检过滤)不一致。统一方向: 投诉侧向退款侧看齐。
改动:
- complaint_extended_dims 的 by_package 改为调用 _device_dim_attrs 获取 combo
(三源回落 + 工厂质检过滤, 与退款侧 a["combo"] 同源)
- 去掉 combo_name_alias → combo_dict 归一(与退款侧对齐)
- category_by_package / package_alias_coverage 不受影响(独立用 _package_canonical_sq)
- 测试 test_dims_package_three_source_and_qc_filter 覆盖三源回落 + 质检过滤 + 无归一
退款侧 #312 已发布, 不改动。
|
2026-10-13 16:14:55 +08:00 |
|
|
|
a1e70e4386
|
#312 by_combo 口径扩展: 最新非质检订单 + device_combos 回落链
gitleaks / gitleaks (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
修复1: combo 改取 bms_orders 最新非质检订单(跳过质检单)——
设备退款/提现后回厂质检, 质检单 create_date 最新会把历史正常套餐掩埋,
90天实测 480 SN 因此白归 (未填); type_name 仍取最新订单不变。
修复2: 回落链接 device_combos.package_name(created_at_raw DESC 最新非质检)——
bms_orders 无订单但充值流水有套餐的设备, 90天实测 256 SN 白归 (未填)。
回落链: 最新非质检订单 → devices.current_combo_name → device_combos 最新,
三源统一过滤工厂质检。退款/投诉两侧共用 _device_dim_attrs, 单点修复双受益。
|
2026-10-13 15:52:29 +08:00 |
|
|
|
aab1d9ba7e
|
#311 回填脚本防撞去重键: 撞 uq_manual_refunds_dedup 行分流 dup_residual
gitleaks / gitleaks (push) Has been cancelled
backend-test / commit-message-lint (push) Has been cancelled
backend-test / backend-lint-test (push) Has been cancelled
backend-test / frontend-lint-test (push) Has been cancelled
生产首跑发现: 同订单存在"带SN重复登记行", 空SN行回填后与既有行完全重复,
触发 uq_manual_refunds_dedup 唯一约束(事务已回滚, 库无损)。
修复: 命中后先预检撞键, 撞键行打标 dup_residual(STATS_EXCLUDED, 不进统计);
UPDATE 带 NOT EXISTS 双保险防批次内互撞。
生产实测: 安全回填 769 / dup_residual 1 / sn_unresolvable 103, 自检零遗留。
|
2026-10-13 15:20:51 +08:00 |
|