Commit Graph

21 Commits

Author SHA1 Message Date
liuwenxin
6d612daf30 fix(business): 编辑/流转/归属加锁与终态编辑门槛,has_docs 单点收口
- get_with_names 加 for_update 参数:update/change_status/change_ownership
  以锁定读取行,与发货/回款写路径同一锁口径——「有发货禁换客户」的
  快照读校验不再被并发新增发货旁路(此前 delete 有锁、唯独编辑无锁)
- update_business 补终态门槛(明细/汇总是 M3 核算基线,与发货/回款
  服务禁写终态同口径);前端编辑按钮按终态禁用并加 tooltip
- 新增 business_repository.has_docs(单条 OR exists):替换 update
  换客户与 delete 两处内联双查询,M3 新增挂靠单据类型时只改一处
- 出参组装复用首查 row:change_ownership 的姓名侧按「变更项取校验
  函数返回的新人名、未变项沿用首查名」处理(首查名是变更前快照)
- 新增终态编辑 400 且明细未动的集成用例

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 17:30:21 +08:00
liuwenxin
5a3778a424 fix(business): 唯一键冲突重试改为审计上下文内循环,单条审计无递归
三处 create(业务/发货/回款)的 return _retry_create 是吞异常后正常
退出:外层审计把已回滚的首次尝试记成 success(假成功),重入整个
create_* 违反 audit_service「不支持嵌套」约定,且 _NO_RETRY 死常量
导致持续冲突时无界递归至 RecursionError。改为 audit 内 for 循环
(上限 _NO_RETRY),rollback 后重新锁行与取号,成功/最终失败各恰好
一条审计。新增集成用例锁定两条路径的日志增量。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 15:09:05 +08:00
liuwenxin
cb977979da fix(param): 预览千分比换算/版本号复用 next_no/维度规范值落库/冗余提交清理
- 企业户与信息员预览分支把 ‰ 存储值当纯比例直接相乘,绩效金额放大
  1000 倍;补两个岗位路径的精确数值用例(既有用例仅覆盖业务员路径)
- 批次版本号改用 no_generator.next_no(MAX FOR UPDATE 锁当日区间),
  移除无锁全拉重造的 _next_version_no(依赖前一笔的长度优先排序)
- 岗位维度值经 ci 校对命中后以库里规范 role_code 落库,防快照字典
  精确匹配静默不命中;变形大小写提交补回读断言
- 删正常路径冗余双 commit;支付权重 R 封底封顶口径注释声明

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 14:20:05 +08:00
liuwenxin
64c57e9141 fix(no_generator): 编号 MAX 检索改长度优先排序,破解位宽进位后字典序失效
跨位宽(-9999→-10000)后纯字典序反转,MAX 恒取旧值导致当日建单
持续撞唯一键;同前缀下长度大即数值大,同级同长时字典序与数值一致。
新增跨位宽/同宽/空表三个集成用例。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 14:09:30 +08:00
liuwenxin
d77728265b docs(business): M2 收尾——e2e 记录、缺陷表、AI_CONTEXT 摘要更新
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 17:13:21 +08:00
liuwenxin
fba8cfc215 fix(business): 删除保护补齐与单价小数位口径修复(e2e 发现)
- 客户删除保护:被业务引用 → 400(T4 占位注释在业务表就位后漏补,FK 500 暴露)
- 人员删除保护:业务归属(负责/协助)引用纳入检查(同样漏检 500)
- schema 单价类列(DECIMAL 14,4)小数位放行至 4 位:回显 '5000.0000'
  原样提交被两位校验永久拒收(编辑任何带精度单价的历史行都失败)
- 补 2 个集成用例锁定;文案同步「客户归属或业务归属引用」

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 17:06:46 +08:00
liuwenxin
ca4cc72eea test(business): 业务数据管理模块集成用例(70 例)与两处缺陷修复
- 覆盖:编号格式与序号递增/状态机终态拦截/三处汇总冗余一致性/跨业务批次
  400/已核算禁改禁删/毛利润金标准与防除零/asOf 回溯/评级重叠/审计双记录
- 缺陷修复①:change_status 留痕 old_status 取到赋值后属性(时间线失真 3→3)
- 缺陷修复②:freight_amount 漏金额校验(负数/三位小数可落库污染运费合计)
- conftest 扩展业务六表清理(编号前缀 + FK 逆序收口)与评级种子基线恢复
- 全量回归 603 passed(单元 381 / 集成 222)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 13:39:09 +08:00
liuwenxin
899bf3afa5 docs(test): 基础数据模块测试记录(48 例/审计盲区缺陷/待补用例更新)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 11:24:29 +08:00
liuwenxin
20fcf06f51 feat(business): 新增业务数据七表及 V5 迁移(业务/明细/状态留痕/发货/回款/评级配置)
- businesses 五项汇总冗余列服务层事务内维护;毛利润不落库(派生值,M3 台账固化)
- 行级 product_category 折算锚点(#14);回款 settlement_status 预置为 M3 防重锚点
- 评级等级种子四条(迁移+init-dev 双写);编号前缀常量 YW/SH/HK
- 双轨 SQL 同步(V4/V5 重导,schema_sync+test_models 164 例全绿)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 11:22:34 +08:00
liuwenxin
ca88ee7a0b test(base): 基础数据管理模块集成用例(48 例)与审计盲区修复
- 覆盖:401/引用校验/删除保护/子表全量替换/类别与组合唯一/归属变更留痕/审计双记录
- 缺陷修复:personnel/product/customer 三 service 的前置校验移入审计上下文,
  校验失败(400)同样留痕(成功与失败都记的既定原则)
- conftest 兜底清理扩展到 M2 五表(留痕无外键,按 operator_name + 前缀双轨清理)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 11:22:34 +08:00
liuwenxin
f22d14e439 feat(base): 新增基础数据六表及 V4 迁移(人员/辐射区域/拓展计划/产品/客户/归属留痕)
- TPlusSyncMixin 统一 T+ 同步预留四列(可空+普通索引,唯一键待 IT 定键后升级)
- 留痕表实体 ID 无外键冗余固化,删除保护由服务层承担
- init-dev.sql 同步六表 DDL,alembic_version 标记更新

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 09:49:05 +08:00
liuwenxin
8668e58c30 test(system): 补交岗位角色与参数管理集成用例(M1 遗漏入库)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 09:26:08 +08:00
liuwenxin
fbf044f240 fix(system): code-review 15 项修复(预览基数/维度校验/脱敏穿透/并发版本号等)
- 信息员预览基数改用本人销售额(原误用折算毛利润额,金额算错且口径自相矛盾)
- 产品类别入参与维度值加存在性校验(拼错静默回退默认阈值 30% 会算错轨交工资)
- submit 校验顺序前置查库(未注册 param_code 由 500 修正为 400)
- 金额拒绝 NaN/Infinity(比较抛 InvalidOperation、计算抛溢出均穿透为 500)
- version_no 并发冲突翻译为 400(对齐 user/role service 的 IntegrityError 处理)
- 旧值留痕改取条目生效日时点的值(多未来批次下留痕链不再错位)
- 脱敏红线:phone/mobile/id_card 键名整值抹除 + 手机号正则兼容分隔符写法
- 前端:撤回按钮与导出文件名改本地日期(UTC/本地混算)、维度行内精确「改」入口、
  detailOf 补 catch、抽屉分页 size 生效、blob 错误读出真实 message
- e2e 密码移除硬编码 fallback(缺失即报错退出);按钮文案同步「改」
- 全量回归:后端 406 + 集成 104 + 前端 type-check/build + e2e 7 步 全绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 02:28:20 +08:00
liuwenxin
6219698a39 test(system): M1 参数体系集成用例、e2e 脚本与文档更新
- 集成用例 26 项:岗位角色(CRUD/内置保护/权限)+ 参数管理(目录回溯/变更生命周期/值校验/预览金标准)
- 361 天分界断言按 Fraction 数值比较(4/1000 自动约分为 1/250,值相等)
- e2e param_management.py:7 步全通过(含预览金标准 27 天/9.7‰/145.5 元)
- 结果卡补「计提比例」精确分数行(对账透明)
- 三份 README 更新:接口职责/AI 摘要/M1 用例清单与运行记录/e2e 记录

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 01:05:07 +08:00
liuwenxin
8ad3650dd3 feat(system): 计提参数版本管理、变更留痕与计算预览接口
- 9 个端点:目录快照(asOf)/单参数历史/变更批次提交与撤回/批次分页与明细/两日期对比/Excel 导出/计算预览
- submit_change 全量前置校验(注册表/维度岗位/取值域/同批去重)→ 建批次 → 逐项留痕(旧值取提交时生效值)
- 撤回:FOR UPDATE 锁行 + 已生效禁撤,删除后解析自然回退;同日多次变更取最新留痕
- 预览按岗位模板分派公式(经理聚合口径明确拒绝),出参含所用参数与生效时点;导出走 openpyxl
- ECharts 决策记录:前端统计图使用 echarts(用户指定)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-12 20:24:17 +08:00
liuwenxin
1b3509b20f feat(system): 计提参数按业务日期时点化取值服务
- param_repository.resolve_values:窗口函数一条 SQL 取全量快照(同日多次变更取 effective_date DESC, id DESC 首条)
- param_service.ParamSnapshot:冻结快照 + 覆盖链(角色 > 产品类别 > 默认行)+ 注册表默认值兜底;fraction/integer/boolean/text 类型化取值
- 12 项单元用例:覆盖链优先级、兜底、同日取最新、冻结不可变

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-12 16:27:56 +08:00
liuwenxin
5ed5665a54 feat(system): 计提公式模板注册表与精确分数计算函数
- formula.py 八个纯函数:回款天数(首日计1)、业务员分段递减(360=6‰/361=4‰)、折算毛利润额化简式(防除零)、乘法方向绩效、以物抵顶/R×R/起付
- param_registry.py:16 项参数元数据(与迁移种子同源)+ Fraction 精确解析(4/360 禁截断)+ 类型/取值域/枚举校验
- calc_templates.py:5 个公式模板注册表(岗位绑定的受控集合)
- 新增 43 项单元用例:精确分数断言(899/90000、27 天、9/25),畸形值拒绝

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-12 16:22:32 +08:00
liuwenxin
bc019cadf5 feat(system): 新增岗位角色与计提参数四表及 V3 迁移
- business_roles/param_definitions/param_change_batches/param_values 四表 + 种子(3 内置岗位/16 参数定义/19 版本条目/初始批次 P20260101-00)
- 双轨迁移:Alembic bfbda9c3191d + db/migration/V3 导出 + init-dev.sql 同步(schema_sync 校验通过)
- 参数值以 Fraction 可解析字符串存储(4/360 禁 0.011111);企业户 2‰→3‰ 双种子支持按到账日回溯

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-12 16:13:13 +08:00
liuwenxin
c83287819a feat(system): 完成后端系统管理(审计/角色/操作日志/日志查询)
- 操作日志审计机制:audit 上下文(成功与失败都记、独立提交、操作人标量
  固化、commit 后查询前置约定),用户/角色全部写操作接入;request_data
  按键名的结构化脱敏 + UTF-8 字节边界截断
- 角色管理:CRUD 与启停;admin 禁删禁停、有绑定禁删(FOR UPDATE 锁行)、
  编码创建后不可改、停用角色不可再分配
- 日志查询:操作/登录两端点,列表与详情两段式(详情含已脱敏请求参数);
  时间参数统一转本地 naive(修混用时区 500 与偏移丢弃)
- 用户管理:补齐 reset_password 操作人、编辑空串归一 NULL、并发唯一键兜底 400
- 测试 301 例全绿(单元 223 / 集成 78)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-10 16:28:04 +08:00
liuwenxin
ad5fe4a411 feat(system): 新增操作日志表与 V2 迁移
需求 2.5.1 要求记录用户管理操作,先落表结构:

- operation_logs 表:冗余 username 保证账号删除后仍可追溯,
  user_id 外键 ON DELETE SET NULL,success 默认 '0' 与 login_logs 口径一致
- 截断常量(USERNAME/ERROR_MESSAGE/REQUEST_DATA)集中定义,供写入方引用
- 修复既有 V1 迁移与迁移模板的 downgrade:索引是外键唯一支撑索引,
  先 drop_index 会报 errno 1553,改为只 drop_table
- 同步 db/migration/V2 与 init-dev.sql,迁移版本号更新为 a45a8087831b

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-10 10:44:05 +08:00
liuwenxin
273ebf4657 chore: 初始化项目结构与登录鉴权模块
后端 FastAPI 六层结构(api/services/repositories/models/schemas/core),
统一响应信封、全局异常、日志脱敏;6 张表经 Alembic 迁移建库,SQL 留存
db/migration;登录鉴权含图形验证码(Redis GETDEL 防重放)、JWT、登录限流、
登出黑名单(TTL=令牌剩余有效期)、登录日志。

前端 Vue3 + TS + Element Plus 骨架,含登录页、路由守卫、请求封装与 Vite 代理。

工程配置:uv 锁定 Python 3.12、ruff 检查与格式化、editorconfig、gitattributes。

测试 184 项(单元 155 / 集成 29)全绿,浏览器端到端 8 项通过。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-09 18:46:36 +08:00