feat/m3-increments
main
需求 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>
需求 2.5.1 用户账号管理,全部要求管理员权限(require_admin 依赖): - 接口:列表/详情/新增/编辑/删除/重置密码/启停/角色下拉, 角色下拉放 /users/meta/roles 以避开 /{user_id} 的路由匹配冲突 - 删除、禁用、改角色三处自我保护:不允许对当前登录账号执行, 避免管理员误操作后立刻失去全部管理权限且无法自行恢复 - 重置密码与禁用均提升 token_version,使已签发令牌立即失效, 不依赖 Redis 黑名单 - 密码按字节数校验(bcrypt 5.0 硬上限 72 字节,中文一字 3 字节) - 用户列表按 id 倒序:create_time 为秒级精度,同秒数据分页结果不确定 - 修复 replace_roles 未同步关系集合的缺陷:改用 user.user_roles 集合追加,此前 session.add(UserRole(...)) 会表现为保存成功但返回空角色 - update_user 的自我保护原先依赖返回 None 的占位函数,恒不生效, 改为显式传入 operator_id Co-Authored-By: Claude Code <noreply@anthropic.com>
- 操作日志审计机制: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>
- BasicLayout:侧边栏/顶栏/面包屑/移动端抽屉;菜单从路由表派生; 路由守卫新增 requiresAdmin 层(菜单隐藏 + 直连 URL 弹回) - 用户/角色/日志三个页面:分页请求序号防竞态、确认动作流抽 useConfirmAction、 时间范围配 default-time、日志详情按需懒加载并缓存 - 空 catch 统一改 handledError 显式声明;词表/选项常量集中(与后端对齐), 「停用」文案全站统一为「禁用」 - 品牌色提升为全局 token,Element Plus 主色指向赭金 - e2e:公共工具抽 common.py;系统管理 13 项(含详情懒加载脱敏断言), 管理员密码改 E2E_ADMIN_PASSWORD 环境变量;login_flow 8 项回归通过 Co-Authored-By: Claude Code <noreply@anthropic.com>
- .gitignore:logs/ 收窄为 /backend/logs/ —— 原规则(无前导斜杠)匹配任意 层级同名目录,曾把 frontend/src/views/system/logs 整个吞出版本库 - 同步根/frontend README(进度、e2e 运行方式与环境变量) - 收录业务确认问题清单(完整版) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 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>
- 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>
- 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>
- 四层实现:仓储(FOR UPDATE 锁行 + 引用计数钩子预留)/ schemas / service / api 共 7 个端点 - 保护规则:内置岗位禁删禁停、编码创建后不可改、模板须在注册表内(未注册 400) - 写操作全走审计上下文;冒烟验证 7 项(含成功/失败双路径落日志) - 端点:列表/新增/详情/编辑/删除/启停 + meta/templates 模板下拉 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 9 个端点:目录快照(asOf)/单参数历史/变更批次提交与撤回/批次分页与明细/两日期对比/Excel 导出/计算预览 - submit_change 全量前置校验(注册表/维度岗位/取值域/同批去重)→ 建批次 → 逐项留痕(旧值取提交时生效值) - 撤回:FOR UPDATE 锁行 + 已生效禁撤,删除后解析自然回退;同日多次变更取最新留痕 - 预览按岗位模板分派公式(经理聚合口径明确拒绝),出参含所用参数与生效时点;导出走 openpyxl - ECharts 决策记录:前端统计图使用 echarts(用户指定) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 主色改靛蓝 #2E4BA8(白字对比 7.5:1),EP 色阶按混合公式重算 - 中性灰白体系:雾灰底/纸白/半透明界线/三级墨色文字 - 旧 token 名保留映射(深水青→冷墨、金色→靛蓝),存量引用平滑过渡,迁移完成后移除 - 设计依据:docs/design/视觉方向预览.html(2026-10-12 确认) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 岗位角色页:列表/新增/编辑/启停/删除,内置岗位保护、模板受控下拉(含声明参数引导) - 计提参数页:分组目录(多维度生效值)→ 修改入「待提交」→ 批次提交(立即/指定日期 + 二次确认); 版本管理抽屉(记录分页/明细旧值→新值/两日期对比/撤回未生效/xlsx 导出);计算预览抽屉(按回款到账日取参数) - request.ts 对 responseType=blob 直通(导出文件流非统一信封) - 路由注册岗位角色/计提参数(系统管理组 order 5/6);日志模块词表补两处 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 登录页:雾灰点阵底 + 右上涟漪同心圆 + 顶部靛蓝天光;居中纸白卡片(品牌区/欢迎回来/表单);逻辑不变 - BasicLayout:侧栏深色面板改为中性灰微渐变 + 白底浮起当前项(左 2px 靛蓝条);logo 区水线;内容区雾灰点阵 - 首页:Bento Grid 仪表盘(参数 16 项/岗位 3 个为真实数据;绩效/回款/待办为业务上线前的精致空态) - AppMenu:激活项白底浮起样式,菜单变量随浅色侧栏调整 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 集成用例 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>
- 信息员预览基数改用本人销售额(原误用折算毛利润额,金额算错且口径自相矛盾) - 产品类别入参与维度值加存在性校验(拼错静默回退默认阈值 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>
Co-Authored-By: Claude Code <noreply@anthropic.com>
- TPlusSyncMixin 统一 T+ 同步预留四列(可空+普通索引,唯一键待 IT 定键后升级) - 留痕表实体 ID 无外键冗余固化,删除保护由服务层承担 - init-dev.sql 同步六表 DDL,alembic_version 标记更新 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 删除保护:被团队成员/客户归属引用禁删,引导改离职 - 子表全量替换采用 clear 后立即 flush 防御写法 - 工资标准字符串进出,超两位小数拒绝而非静默舍入 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 归属变更同事务更新主表+插留痕;归属调整唯一入口防旁路 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 覆盖:401/引用校验/删除保护/子表全量替换/类别与组合唯一/归属变更留痕/审计双记录 - 缺陷修复:personnel/product/customer 三 service 的前置校验移入审计上下文, 校验失败(400)同样留痕(成功与失败都记的既定原则) - conftest 兜底清理扩展到 M2 五表(留痕无外键,按 operator_name + 前缀双轨清理) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 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>
- 判定=按 sort_order 升序首个 min_score≤总分,边界相邻不算重叠 - 新增同样执行重叠判定(判定表语义下插出重叠即脏配置) - 等级配置无下游引用(评级为纯计算器,对照表 #25),允许清空 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 编号 YW{日期}-{序号}:MAX+FOR UPDATE 并发安全 + 1062 兜底重试(no_generator 三单据共用) - 明细全量替换重算五项汇总冗余;销售额服务层按数量×单价固化不信任前端 - 状态机终态拦截、终止必填原因、创建写首条留痕;归属变更同事务留痕防旁路 - 毛利润视图按行实时计算(不含运费 #2),阈值按 asOf 取 M1 快照,率输出 Fraction 分数字符串同 M1 预览口径;成本缺失行标注无法计算 - 入参契约统一为蛇形直出(撤回 customer/business 的驼峰 alias,与前端 businessRoles.ts 模式对齐) Co-Authored-By: Claude Code <noreply@anthropic.com>
- FOR UPDATE 锁业务行防发货/回款并发丢失更新;终态业务禁新发货 - 行金额服务层按数量×单价固化;明细行 remark 按设计定稿移除(冒烟修复) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 批次 HK 生成;shipment_id 同业务强校验(统一失败面防探测) - 已核算回款禁改禁删(M3 防重锚点);payment_days 派生(发货日首日=第 1 天) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 人员页:编辑抽屉内区域/计划子表编辑;产品页:类别阈值提示条; 客户页:归属变更二次确认含「不回溯历史」+变更记录抽屉 - 评级页:五项评分实时出等级(纯前端判定,不落库 #25)+ 等级映射维护抽屉 - 菜单两组:基础数据(8-10)/业务数据(14);金额字符串直出禁 float Co-Authored-By: Claude Code <noreply@anthropic.com>
- 业务页:明细行编辑器、详情抽屉五分区(含状态时间线与毛利润卡片) - 回款页:业务→发货批次级联指定(可清空)、已核算行禁改禁删 - 金额/比率字符串直出;毛利润卡片注明不含运费口径 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 覆盖:编号格式与序号递增/状态机终态拦截/三处汇总冗余一致性/跨业务批次 400/已核算禁改禁删/毛利润金标准与防除零/asOf 回溯/评级重叠/审计双记录 - 缺陷修复①:change_status 留痕 old_status 取到赋值后属性(时间线失真 3→3) - 缺陷修复②:freight_amount 漏金额校验(负数/三位小数可落库污染运费合计) - conftest 扩展业务六表清理(编号前缀 + FK 逆序收口)与评级种子基线恢复 - 全量回归 603 passed(单元 381 / 集成 222) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 客户删除保护:被业务引用 → 400(T4 占位注释在业务表就位后漏补,FK 500 暴露) - 人员删除保护:业务归属(负责/协助)引用纳入检查(同样漏检 500) - schema 单价类列(DECIMAL 14,4)小数位放行至 4 位:回显 '5000.0000' 原样提交被两位校验永久拒收(编辑任何带精度单价的历史行都失败) - 补 2 个集成用例锁定;文案同步「客户归属或业务归属引用」 Co-Authored-By: Claude Code <noreply@anthropic.com>
- wait_toast 超时返回最后见到的非空提示(错误 toast 一闪而过时诊断信息全丢) - 业务/发货明细行单价类字段放行 4 位小数(与后端 DECIMAL(14,4) 对齐) - 清理步骤适配删除保护(被终态业务/引用拦截时留档而非失败) Co-Authored-By: Claude Code <noreply@anthropic.com>
跨位宽(-9999→-10000)后纯字典序反转,MAX 恒取旧值导致当日建单 持续撞唯一键;同前缀下长度大即数值大,同级同长时字典序与数值一致。 新增跨位宽/同宽/空表三个集成用例。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 企业户与信息员预览分支把 ‰ 存储值当纯比例直接相乘,绩效金额放大 1000 倍;补两个岗位路径的精确数值用例(既有用例仅覆盖业务员路径) - 批次版本号改用 no_generator.next_no(MAX FOR UPDATE 锁当日区间), 移除无锁全拉重造的 _next_version_no(依赖前一笔的长度优先排序) - 岗位维度值经 ci 校对命中后以库里规范 role_code 落库,防快照字典 精确匹配静默不命中;变形大小写提交补回读断言 - 删正常路径冗余双 commit;支付权重 R 封底封顶口径注释声明 Co-Authored-By: Claude Code <noreply@anthropic.com>
三处 create(业务/发货/回款)的 return _retry_create 是吞异常后正常 退出:外层审计把已回滚的首次尝试记成 success(假成功),重入整个 create_* 违反 audit_service「不支持嵌套」约定,且 _NO_RETRY 死常量 导致持续冲突时无界递归至 RecursionError。改为 audit 内 for 循环 (上限 _NO_RETRY),rollback 后重新锁行与取号,成功/最终失败各恰好 一条审计。新增集成用例锁定两条路径的日志增量。 Co-Authored-By: Claude Code <noreply@anthropic.com>
六个 service 各自复制的 _is_duplicate_entry(口径已漂移:rating/product 用 _ERR_DUP_ENTRY 常量、其余四处写字面量 1062)收敛为共享函数; is_duplicate_entry 语义与文案注释各处保留,非 1062 完整性错误仍原样 上抛由全局处理器收敛。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 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>
纯排版无行为变化(ruff format 重排 7 个此前批次的文件), 涉及模块集成回归全绿(67 passed)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- delete_product 补 count_refs 引用检查(业务明细+发货明细 RESTRICT 外键)与并发窗口 IntegrityError→400 兜底(customer 先例同构), docstring 与两个 api 层过时注释同步更新 - 产品 schema 复用 schemas/business._check_amount:sale_price 走 (PRICE_MAX, scale=4)、stock_quantity 走 AMOUNT_MAX——此前私写 _parse_non_negative 不查小数位与容量,5 位小数被 Numeric(14,4) 静默截断(舍入即算错钱);新增 6 个秒级 schema 单测锁定口径 - 全局注册 IntegrityError handler:漏补引用保护的删除类操作收敛为 400 通用文案(e2e 撞见一个补一个的模式无法保证全覆盖),完整 异常记日志;rating/customer 的「非 1062 按 500」注释同步更正 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 明细行金额(数量2位×单价4位可产 6 位小数)直写 DECIMAL(14,2) 被 MySQL 静默舍入且回显漂移(创建响应读内存值、复查读库值不一致); 显式 quantize HALF_UP 固化,舍入方向与 MySQL 一致(业务/发货同改) - 先款后货回款(payment_days 为负)线性外插会算出高于起始值的计提 比例(多算绩效);钳制到 0 天按起始比例计提,payment_days 出参仍 照实输出负值(口径:2026-10-14 用户裁决) - 新增 formula 负天数钳制单测与 quantize 回显/库值一致性集成用例 Co-Authored-By: Claude Code <noreply@anthropic.com>
先查后写无锁时,两管理员并发提交重叠区间互判不重叠而双双入库 (区间重叠无唯一键可拦,同一总分命中多等级且结果取决于插入顺序); 判重叠的 list_all 加 for_update 锁全表行串行化并发判定,只读直出 list_grades 不加锁。SQL 形态用例锁定两条口径。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- request.ts blob 失败分支:先解析真实文案再统一提示——此前先弹兜底 「导出失败」再异步补弹真实 message(双提示),401 时跳转提示与 实际原因错位;401 语义文案在导出场景不再失真 - useConfirmAction:收尾(列表刷新)成功后才弹成功提示——此前先弹 「已删除」再刷新,after 失败被吞时成功/失败提示同屏矛盾 - 日志页登录 tab 首次成功加载后不再重复拉取(loginLoadedOk 由 fetcher 成功返回置位,失败切回可重拉,不复活「失败停空表」旧坑) - login_flow.py 密码改从 E2E_ADMIN_PASSWORD 读(与 system_management 同一约定),硬编码默认值在他机上会假绿为「凭据错误」 - e2e 冒烟:登录 8 项 + 系统管理 13 项全过(拦截器全局改动验证) Co-Authored-By: Claude Code <noreply@anthropic.com>
早前实现把全部 V*.sql 的 CREATE 列做并集:某表日后被 ALTER DROP COLUMN 时并集里旧列名永存,init-dev.sql 必须保留死列才能过测—— 守卫会主动背书一份与生产结构漂移的开发库 DDL。按文件序重放 ADD/DROP COLUMN 后比对基准为迁移链终态;列改名(CHANGE)出现时 重放报差异属人工核对时机(改名同时牵动 init-dev 与 ORM)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- update_receipt 取 _ensure_shipment_of_business 返回值组装出参 (shipment_id 已赋为 payload 新值,与 get_with_refs 重查同源), 省一次三表 join;update_shipment 同理取锁定行的 business_no - 删 business_repository.count_items(无任何调用的死代码,删除保护 实际走 has_docs) - submit_change 校验段定义与岗位各一条 IN 批量预载(逐条查询在批次 扩大时是写侧 N+1);岗位字典键 casefold 归一保持与单条版 ci 校对 等价的命中语义;旧值留痕保持逐条(窗口函数优化留待 M3 一并设计) Co-Authored-By: Claude Code <noreply@anthropic.com>
- ownership_log_repository:客户/业务两侧逐行同构的 list/count/add 收口(owner_type 与引用列参数化),双键倒序与被删人员兜底口径 单点维护;两侧 repository 变薄包装,service 层零改动 - PERSONNEL_STATUS_ACTIVE 单点导出于 models/personnel(对照 BUSINESS_STATUS_* 先例);业务/客户两侧的「存在且在职」校验收口 于 personnel_service.ensure_active——此前两份常量+校验仅靠注释 维持同步,在职判定调整时会两入口口径分叉;校验放 service 层遵守 「repositories 不抛业务异常」红线 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 金额形态正则收进 utils/validate.ts 单点导出(此前四页各写,精度 调整漏改一页即「A 页拦得住 B 页放行后端 400」或历史行无法编辑) - params 版本/历史两抽屉的手写分页五件套换 usePagedList(白得请求 序号防竞态——快速翻页旧响应覆盖新页的手写坑不再复现) - 业务抽屉三份 id 状态收为 drawerRowId computed(单一状态源,消除 「标题 A 业务、留痕表 B 业务」的失同步面) - useEditingRow(三页逐字相同的 computed)与 useDropdownOptions (取数失败不阻断列表的骨架)收口,映射函数由调用方给出 - e2e 冒烟:基础数据 13 步 + 业务全链路 16 步全过 Co-Authored-By: Claude Code <noreply@anthropic.com>
- tests/integration/factories.py:回款/发货两文件逐字重复的 _customer/_bitem/_bpayload/_create_business 上提(t_ 前缀与默认行 口径单点维护);test_audit_retry 的持续冲突断言由 500 更新为 400「数据完整性冲突」——全局 IntegrityError handler(批 6)收敛 行为属预期改进,非回归 - param_service.submit_change 拆出 _normalize_items(校验段独立, 主函数降至 50 行约定内);e2e 六个列表页 helper 收口 common.py (base_data 版为准:分组参数化、:text-is 精确匹配),两脚本变薄 - 全量回归 625 passed(基线 603 + 新增 22);e2e 四链路(登录 8/ 系统管理 13/基础数据 13/业务 16)全过 - 测试 README 补 2026-10-15 运行记录与 10 条评审缺陷(预览千分比/ 审计假成功/字典序 MAX/无锁编辑/删产品 500/schema 口径/quantize/ 负天数外插/评级并发/大小写不对称) Co-Authored-By: Claude Code <noreply@anthropic.com>
open_menu 时分组参数化、fill_filter :text-is 精确匹配、messagebox 带 :visible(base_data 实现为准)——两脚本此前各持一份且匹配精度漂移 (has_text 子串 vs :text-is),使用者误以为两者等价;登录/系统管理/ 基础数据/业务数据四链路 e2e 复跑全过。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 新增 system_settings(公司信息单行)/ business_secondary_allocations(二次 分配明细,比例不强制合计满额,分摊计算待澄清另批)/ approval_orders+ approval_steps(三级审批状态机,开关关闭自动通过留痕) - roles 种子新增营销后勤/财务/领导三职能角色;内置保护改 BUILTIN_ROLE_CODES 白名单(roles 表无 is_builtin 列,不加列) - PARAM_REGISTRY 首例 BOOL:两个审批开关(16→18 项,种子双写) - 双轨同步:V6 导出 SQL + init-dev.sql(表/索引/种子/版本号 79bcc5aa98d4) - 测试同步:EXPECTED_TABLES 四新表、角色种子断言 5 角色、目录断言 18 项 八分组、BOOL 校验边界;迁移 downgrade 修 1553(只保留 drop_table)并补 行级种子反向清理 Co-Authored-By: Claude Code <noreply@anthropic.com>
- system_settings 单行 CRUD:GET/PUT(AdminUser)+ GET /public(无鉴权, SettingPublicOut 白名单仅 company_name/logo_url 两字段,短缓存 300s) - logo 上传:后缀+magic bytes+2MB 三重校验,固定名覆盖落盘 uploads/logo/ (不使用上传方文件名,杜绝路径拼接);旧扩展名文件清理;文件流端点 no-cache,URL 带 update_time 版本参数破缓存 - logo 存目录不存库:图片入 DB 让每次读取与 mysqldump 放大传输且无法 独立替换;DB 只持一行相对路径 - 新增依赖 python-multipart(FastAPI UploadFile 必备传输层);.gitignore 增 backend/uploads/ 与 db/backups/ - 集成 11 例:单行语义/白名单字段/三重校验/越权 403/匿名 401/审计留痕 Co-Authored-By: Claude Code <noreply@anthropic.com>
- SecondaryAllocationIn/Out:比例走金额红线口径(str 入参、两位小数、 超 100 拒绝不静默舍入);参与人 schema 层去重(uk 前置友好提示) - create/update 同事务写入(replace_allocations,先删后 flush 再插—— uk 表防御写法);create 放编号重试循环内,rollback 后方案随业务重来 - 人员在职复用 ensure_active(label=分摊参与),personnel_name 冗余固化; FK RESTRICT:被方案引用人员禁删,方案回显不静默失联 - 合计不强制 100%(需求原文):详情 allocation_hint 只展示合计/余额, 余额归属待澄清 #2 不落库 - 单测 13 例(比例边界/去重)+ 集成 9 例(回显/替换清空/离职 400/ 终态禁改/RESTRICT 保护) Co-Authored-By: Claude Code <noreply@anthropic.com>
- approval_orders/approval_steps 服务层:submit_order(不 commit 不嵌套 audit,业务写路径统一收口)+ act 节点动作 + 分页/详情 - 开关关闭=提单即两级「自动通过」留痕(action=3,operator 记系统); 开启=财务→领导流转,一驳全驳,驳回必填意见 - 节点准入严格按角色(status=1 仅财务、status=2 仅领导),admin 不代办; 模块准入 require_roles 依赖工厂(admin/finance/leader,营销后勤待 澄清 #6 后放开) - 业务接入:创建/编辑带方案即提单(空方案不提单);再编辑自动撤回旧 在途单(node=0/action=4 留痕);AP 编号冲突 create 内可重取(外层 重试兜底)、update 直接抛出防静默丢失 - conftest 兜底清理增审批单(AP 前缀)与开关参数种子基线恢复 - 集成 11 例:自动通过/两节点流转/驳回留痕/缺意见 400/节点准入 403/ admin 不代办/重复操作 400/撤旧建新/模块准入 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 公司信息页(设置 order7):名称编辑 + logo 上传(png/jpg ≤2MB 前端先拦)+ 签名元素「登录页实景预览」(缩比登录卡,品牌名/logo 即时反映,所见即所得) - 审批管理页(order8):列表筛选(关键词/状态/类型)+ 签名元素 「竖排节点时间线」(财务复核→领导审核,人工/自动/驳回色区分)+ 在途单通过/驳回动作(驳回必填意见,经 useConfirmAction 确认流) - 路由扩展 allowedRoles 元数据:菜单按任一列入角色可见 + 守卫双 过滤(admin 须显式列入集合,不天然放行);审批页对 admin/ finance/leader 可见(营销后勤待权限清单 #6) - 业务表单二次分配区:参与人下拉(离职禁用)+比例输入+实时合计条 (合计≠100% 提示余额归属待业务确认,满额高亮);编辑全量替换、 空行自动忽略;校验(人员非重/比例两位小数)与后端 NUMERIC(5,2) 同口径 - 登录页接 /system/settings/public:品牌名与页脚动态,logo 展示, 失败静默回退默认(登录页必须可用) - 参数页中文化:维度角色名映射(营销员/营销经理/信息员)、枚举值 中文(当月全额/余额、含/扣/不计基本工资、开/关)、预览「所用参数」 由编码直出改中文名(编码括注) - 验证:pnpm type-check 零错误;pnpm build 通过 Co-Authored-By: Claude Code <noreply@anthropic.com>
- scripts/backup_full.sh:容器内 mysqldump --single-transaction,gzip 落盘 db/backups/,保留 30 天;凭据 source docker/.env 不硬编码;实测备份成功 - scripts/restore_drill.sh:恢复到临时库 payroll_drill_* 并逐表核对行数 (16 张关键表),默认不 DROP、--drop-exec 才删——绝不覆盖生产库; 实测 16 表全 ✓。规避嵌套 shell 吞反引号(mysqladmin create/drop、 双引号包裹表名) - scripts/health_check.sh:六项检查(容器健康×2/磁盘水位/备份新鲜度/ Redis 探活/24h 登录失败阈值),PASS/WARN/FAIL 报告,退出码供监控; Redis 密码经宿主机 .env 验证(容器内无该环境变量),实测六项全 PASS - docs/备份恢复手册.md:备份/演练/生产恢复七步/定时 schtasks 两则, db/backups/ 已入 .gitignore Co-Authored-By: Claude Code <noreply@anthropic.com>
- 新增 e2e:settings_flow(改名→登出→登录页即时生效→finally 还原防污染)、 secondary_allocation_flow(建客户/员→录两行 30%+40%→编辑回显与合计条 余额提示→删除清理;宽视口防弹窗遮挡、alloc-table 专属类防选择器错位) - 修复 e2e 首跑抓出的两处缺陷:① public 端点 300s 响应缓存让登录页拿旧 公司名(登录页改时间戳 fetch + cache:no-store,手动解包信封)② logo 同 扩展名覆盖时先写后删(清理移到写入前且仅异扩展名执行) - 分配表加 alloc-table 专属类(与产品明细 items-table 区分) - 全量回归 697 passed(基线 625 + 72);e2e 七脚本全过(既有五脚本回归 + 两个新增);pnpm type-check 零错误 - tests/README.md 增 M3 节(44 例明细)/运行记录/缺陷 3 行;frontend/ README.md 增 M3 e2e 节 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 审批:删 _flush_order 撞键内部重试(rollback 会回掉同事务业务行造成 静默丢数据,异常改由 create 外层重试整体重来/update 路径审计收敛); act() 出参固化前置到 commit 之前(commit 后查询失败会把已通过的审批 记成失败审计);驳回/撤回清空方案生效行(防被否决方案进 M3 快照); keyword 改 contains(autoescape=True) 对齐全库转义口径;撤单抽 withdraw_pending_orders 供编辑清空方案时显式调用 - 业务:删业务遇在途审批单禁删 400、终态审批单随 _hard_delete 清理; 编辑清空方案同步撤回在途单;历史离职参与人编辑放行(冗余姓名固化 语义,仅新增参与人做在职校验) - 迁移:business_secondary_allocations 补 uk(business_id, personnel_id) (模型/迁移 py/导出 SQL/init-dev 四方同步,开发库往返重放验证) - 设置:upload_logo 改同步 def(阻塞操作不卡事件循环)+ file.size 先拦; company_name schema 剥空白防全空白入库;logo 旧文件清理移到 commit 成功后(防库指旧路径而文件已删断链);uploadLogo 走 request() 解包 (原直发 service.post 不解包信封,logoUrl 会被置 undefined) - 备份:restore_drill --drop-exec 先清全部历史 drill 库再演练并即删本轮 (原语义永远删错对象,每轮净增一份整库拷贝) - 测试:conftest 清理补 system_settings 种子行与 uploads/logo 文件; 新增 5 例(驳回清方案/清空撤单/在途禁删终态随删/离职放行/BOOL 边界); 全量回归 701 passed - 遗留 2 项记 AI_CONTEXT(方案版本承载、审批单快照,依赖 ④ 分摊语义) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 立即待办:推送被远端 Git 服务阻塞(服务器侧重启)、M2 分支合并 main - 业务澄清 24 项按高/中/低分层(含建议默认),IT 18 项按优先级分层 - 里程碑待办(M3 剩余/M4/评审遗留 2 项)与文档待办 Co-Authored-By: Claude Code <noreply@anthropic.com>
- V7 四表:performance_ledgers(append-only 版本行,uk(receipt_id,calc_version) 库级防重兜底)/monthly_settlements(月份 uk,通过即锁定终态)/ settlement_items(按人固化可负工资,uk 三列)/adjustment_orders(TZ 单号) - registry +1:approval.adjustment.enabled(19 项,BOOL 首组扩至三开关) - formula 补核算纯函数:clamp_weight_r(从预览内联提取共用)/monthly_salary 三口径/probation_annual_note/manager_team_share(#12 暂口径:基数不含 经理个人户业绩,聚合集中一处答复后只改) - 迁移 downgrade 只保留 drop_table+alter 回滚+种子行反向 DELETE; performance_ledgers 表名复数(test_models 红线断言) - 断言同步:EXPECTED_TABLES 四新表/registry 19/BOOL 三开关/conftest 清理四新表与 ParamValue 边界 22 - schema_sync+全量单测 460 passed Co-Authored-By: Claude Code <noreply@anthropic.com>
- calc_service.calc_receipt:锁回款行→settlement_status=0 校验→发货批次/ 归属前置→resolve_snapshot(回款日)→按 calc_template 分派(与 _preview_rate 同构,‰÷1000 防线)→items 行级折算(行类别阈值,混合按行汇总)→ barter/起付/R→台账 v1→CAS 置已核算,单 audit 事务 - 策略点集中:_personal_rate(#12 经理个人户单笔落 0 待答复)、_row_profit (#20 不含税原样);核算粒度 #25 一期口径=业务级一次性计提(重复回款 repeated=True 仅登记进度) - 台账仓储:生效行查询/业务级判定/版本号;schemas LedgerOut/Query - api /api/v1/calc/*:台账分页/详情/核算触发(写限 admin+marketing_ops) - 测试 8 例:金标准双类别复算到分(DB 锚定 4000.00/39.11/39.11)、 一次性计提、已核算 400、未指定批次、成本缺失行保守 -3000、负绩效照算、 准入、列表筛选;行级明细折算两位固化 - conftest 清理顺序修正:V7 台账/月结清理移到回款/人员删除之前 (RESTRICT 外键不挡序) Co-Authored-By: Claude Code <noreply@anthropic.com>
- calc_receipt 双模式:recalc_reason 非 None=重算(audit action=重算/ reason 留痕、作废旧版本行、calc_version 自动递增、CAS 仅首算执行—— 重算状态本就是已核算,误跑 CAS 会误报并发撞车) - recalc_receipt 薄委托(reason 必填、未核算过 400);重算授权 require_roles(admin, finance),营销后勤不可重算 - batch_calc:逐笔独立事务不开外层 audit(嵌套禁令),逐笔成败清单 (同业务第二笔回款走 #25 重复分支 ok=True/repeated=True) - 测试 +5:重算版本对/原因缺失 400/未核算重算 400/越权 403/批量清单 - 修 next_version 空表 max NULL → int(None) TypeError Co-Authored-By: Claude Code <noreply@anthropic.com>
- settlement_service:generate(确认回款口径 #8 策略点=有效台账行按回款日 归月、经理聚合 #12 暂口径基数不含经理个人户、月结 uk 一行一月、草稿/ 驳回可重生成、已审定/待审 400)→ submit(审批开关分流,关=自动通过即 锁定、开=待财务复核)→ approval_service.act 扩 order_type=2/3 钩子 (通过=mark_locked/调整单生效;驳回=回草稿/作废,延迟导入防循环) - 锁定拦截:回款新增写路径校验回款月已审定 400(比需求「提示」取硬, 一期安全侧;M2 已核算禁改防线先于其生效) - 调整单:新建(TZ 单号,开关分流自动通过留痕/走审批)+ 列表 - schemas settlement:金额 Decimal 声明(str 声明遇 Decimal 入参拒绝) - 测试 6 例:生成回填/无记录 400/已审定重生成 400/关自动锁定/锁定后回款 禁改/开两节点流转至锁定(finance→leader) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 绩效台账页(order17):月/版本筛选 + 行展开计算快照 + 重算(原因 对话框,管理员/财务);核算入口在回款管理页(每笔回款行内触发) - 月结页(order18):生成快照(月份输入)+ 状态筛选 + 提交审批 + 详情抽屉(按人明细三口径/试用期说明/审批单号关联) - 均复用 usePagedList/AppPagination/--ys-* 惯例;金额 str 直出 - type-check 零错误;build 通过 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 金标准金额断言锚定 DB 事实源(NUMERIC(14,2) 读回恒两位);行级明细 折算两位固化;全量回归 756 passed(701+核算 13/月结 6/公式 12 等) - 目录断言 18→19(V7 调整单开关);tests/README 增 M3-core 节与运行记录; frontend/README 增核算与月结两页 Co-Authored-By: Claude Code <noreply@anthropic.com>
- #5/#7 答复默认开启:两审批开关 default 翻 1,插 10-19 生效行保时点历史 - #16 答复逐人维护:撤 probation.salary.basic(无业务消费点,月结已读 personnel.salary_standard) - #12 答复参数化:新增 manager.personal.included(默认 0=不计入聚合基数) - #1 答复分配绩效铺路:台账 uk 扩为 (receipt_id, calc_version, personnel_id) 支持分摊拆行 - schema_sync 解析器过滤 ADD CONSTRAINT 误捕获 Co-Authored-By: Claude Code <noreply@anthropic.com>
- deps 新增 LoginUser 依赖;params 只读七端点改登录即可,写(提交/撤回)保持 AdminUser - 前端 params 路由 requiresAdmin → allowedRoles(admin/finance/leader);页面写按钮按角色显隐 - 权限用例分层:普通用户目录 200、提交/撤回 403、未登录拦截 Co-Authored-By: Claude Code <noreply@anthropic.com>
- backup_incremental.sh:归档已写完 binlog(tar 拷出+gzip),状态文件对齐序号,有更新才产出,保留 30 天 - backup_full.sh:补 .pos 位点文件(SHOW MASTER STATUS),增量重放的起点锚 - 手册新增增量章节:恢复顺序=全量→binlog 重放,含 mysqlbinlog 缺席镜像的说明 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 经理聚合分成放大 100 倍:参数按百分数存储(12.5=12.5%),parse_fraction 后调用方又 ×100、函数内部再 ÷100,净效应「绩效×12.5」;去掉调用方 ×100,rate_text 改用实际参数原文(原硬编码 12.5%+5% 参数调整后失真) - 审批联动只认终审:财务节点通过(1→2)不再提前 mark_locked/调整单生效, 否则领导驳回后 locked_at/locked_by 残留、两级审批形同虚设;驳回在任何 节点即时联动;mark_rejected 补清锁定字段 - 调整单新建不可用:ENABLE_CODE_BY_TYPE 未登记 type=3 → is_enabled 恒 400; 补登记 approval.adjustment.enabled。另修复叠加缺陷——开关关闭分支手工 ApprovalStep(order_id=调整单id),而该外键指向 approval_orders,必然 errno 1452;统一改走 submit_order(自动通过留痕由它负责) - 重算双重计提:业务级一次性计提的「进度登记」回款无生效台账行,重算会 凭空落新行;无旧行一律 400 - 前端重算传错 id:台账行主键当 receipt_id 传给重算接口,会作废无关回款 的台账;改传 row.receipt_id(聚合行防御) - quantize 显式 ROUND_HALF_UP:9 处金额 quantize 缺省银行家舍入, x.xx5 与四舍五入口径差 1 分(docstring 却声称 HALF_UP) 测试:显式控制审批开关(V8 起种子默认开启,用例不再依赖默认值); 新增回归 4 例(经理聚合比例/调整单即生效/进度登记重算 400/财务节点不提前 锁定),test_calc+test_settlements 22 passed Co-Authored-By: Claude Code <noreply@anthropic.com>
- salesperson_rate 首日特判:第 1 天不递减直接取起始值(原公式 9.9889‰ 作废) - 第 2 天起公式段不变、360 天=6‰ 锚点与 361 天=4‰ 分界不变;preview/核算共用一处 - 用例反转:首日断言改 Fraction(10,1000),补第 2 天公式段边界 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 月结锁定拦截补全:原仅新增回款一处,现覆盖回款编辑(原月+新月,防跨月 搬数)/删除、发货新增(按发货日)/编辑(原月+新月)/删除、核算与重算 (已审定月份金额只走调整单);拦截先于「被引用/已核算」判定 - 台账 settlement_id 回填落地:generate 在 replace_items 后回填纳入行、 重生成前先解绑(clear_ledger_settlement_id)——不回填/不解绑会让 「未入结」判据失效:重生成漏算整月或把已固化行反复计入 - 经理聚合行落库:原只进内存参与 items 汇总,台账表永远无 calc_type=2 行、报表下钻落空;重生成先作废旧聚合行(deactivate_month_aggregates), _confirm_scope 限定计算类型避免聚合行混入单笔池 - 月结取参锚定所属月月末(_month_end):原用 date.today(),补生成历史 月份时分成/月工资口径随生成日漂移;聚合行 receipt_date 同步为月末 - generate/submit 出参固化前置到 commit 之前(commit 后 SELECT 失败会把 已生成的月结记成失败审计,与库中事实相反) - V9 迁移:business_secondary_allocations 唯一键条件式补齐(幂等裸 SQL, 临时库验证「无键→补」「有键→跳过」两分支),修复旧 V6 升级库拿不到 V6 就地加入的约束;V8 迁移 revision 声明补类型注解(原格式漂移使 schema 同步测试的 head 推断静默漏检 V8);init-dev 版本号推进至 V9 - V7 留存 SQL 约束/索引名单数改复数(与 alembic op.f 与 init-dev 对齐, 消除 SHOW CREATE TABLE 双轨漂移) - 测试:显式控制审批开关(不依赖 V8 翻转后的种子默认值);新增回归 8 例 (回填落库/聚合不重复/月末取参/月末纯函数 5 例/锁定拦截回款与发货与 核算);全量 773 passed Co-Authored-By: Claude Code <noreply@anthropic.com>
默认 0 时聚合 6.84 不变;开关 1 时个人户行按 personnel_id 归经理本人 (不走 manager_id 上溯)、基数 139.11 → 聚合 24.34,两档金标准锁定 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 调整单金额恒正:schema 正则拦格式(非负两位小数、≤12 位整数防 NUMERIC(14,2) 溢出)+ 服务层 Decimal>0 语义校验——负数会反转补发/ 扣减语义,'abc' 原样入库会以 500 暴露 - 分界天数参数解析:int(parse_fraction(...)) 替代 int(参数原文)—— '360.0' 是 INT 参数的合法入库值(Fraction 分母为 1),直接 int(str) 抛 ValueError 会让整月核算 500 - logo 旧文件清理容错:OSError 只记 warning——裸抛会把成功的 logo 更新 记成失败审计并 500(库中 logo_path 却已是新值,审计与事实相反) - health_check.sh:Redis 探活改容器内环境变量展开(密码不进宿主进程 命令行,模式同 backup_full.sh);compose redis 补 REDIS_PASSWORD - restore_drill.sh:行数核对扩到全部 32 张业务表(原 16 张漏 V7 四表、 二次分配等核心表,备份漏表演练全绿);查询失败回显 '?' 一律判 ✗ (原 '?'=='?' 判一致,表缺失时误报「备份可恢复」) - 并入 88 会话的 #12 实现:manager.personal.included 开关消费 (_build_manager_aggregates 参数化,测试见 828b573) - 测试:调整单金额恒正 5 稿、INT 参数小数原文核算 200 回归;单测 469 Co-Authored-By: Claude Code <noreply@anthropic.com>
code-review 约定合规项(CLAUDE.md「单一职责 ≤50 行」):原 218 行单函数 把锁行校验、模式预处理、输入装载、逐行折算、计提组成、落库全部内联, 待澄清答复回填时改动回归面大。按原执行顺序拆为四段私有函数 + 两个 冻结 dataclass(_Conversion/_Amounts),主函数只做编排;行为零变化 (M3 全部用例原样通过): - _load_and_guard:锁行 + 模式校验 + 月结锁定拦截 + 业务归属校验 - _prepare_mode:重算作废旧版本 / 首算判一次性计提(进度登记提前返回) - _load_shipment / _load_person / _load_items:输入装载三查 - _convert_items → _Conversion:逐行折算(行级阈值/缺成本标记/行级明细) - _compose_amounts → _Amounts:比例分派 → 绩效 → 抵顶 → 权重 → 应付 - _persist_ledger:落台账行 + 首算 CAS - 局部 q2 提为模块级 _q2(新增单测锁定 HALF_UP:2.345→2.35, 缺省银行家舍入会得 2.34) 验证:全量 780 passed;type-check 绿 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 运行记录:M3 定点 34 例与全量回归 780 passed(2026-10-19)两行 - 缺陷表:补 14 条(聚合 ×100/审批提前锁定/调整单双重缺陷/重算双重计提/ 前端传错 ID/quantize 银行家舍入/锁定拦截 1-4/回填死代码/聚合不落库/ 生成日取参/迁移三处漂移/演练误报与密码明文/金额与 INT 解析与 logo 清理) - 待补用例:绩效工资核算行更新为 M3-core 已完成(e2e calc_settlement_flow 与答复回填批次待补) Co-Authored-By: Claude Code <noreply@anthropic.com>
code-review 约定合规项续(calc_receipt 之后的剩余超长函数): - generate(~120 行)→ 编排 + 六段私有函数:_guard_regeneration(重生成 准入)、_release_previous_round(解绑回填+旧聚合作废)、_upsert_draft (草稿头表新建/重置)、_build_items(=_bucket_rows + _item_of 记账)与 _apply_totals(头表三合计) - _build_manager_aggregates(~110 行)→ _ShareParams 冻结 dataclass + _manager_share_params(月末取参/百分数口径/#12 开关同源)/ _collect_team_buckets (含 #12「个人户行归经理本人」分支)/ _add_team_performance / _aggregate_row; 全公司基数循环外算一次(口径逐行固定,行为等价) - create_adjustment(~90 行)→ _adjustment_amount(恒正)/ _wire_adjustment_approval (submit_order 分流与留痕,含「不得手工插 ApprovalStep」外键教训注释)/ _adjustment_out(出参前置到 commit 之前) 行为零变化;#12 参数化(include_manager_personal 过滤、个人户行按 personnel_id 直归经理、snapshot 的 manager_personal_included)语义原样保留。 验证:重构后月结集成 15 例 + 月结单测 5 例全绿(81s 内无并发干扰的一轮); 全量回归待 88 会话 calc_service 收口后复跑(其进行中的拆行改动与测试 并发互清导致临时 401,非本重构所致) Co-Authored-By: Claude Code <noreply@anthropic.com>
- 立即待办:远端 Git 服务已恢复(ls-remote 实测连通);标注远端已到 35fe37f、本地领先 8 提交 - 业务方澄清:#12 经理个人户基数 → 已落实为参数 manager.personal.included (默认 0=不计入);#5/#7 审批开关默认开启、#14 首日整 10‰(A 口径)、 #16 试用期参数撤销、#17 参数查看放开、#19 增量备份 → 均已落实(2026-10-19) - 里程碑:M3 剩余改为已完成主体 + 余项(二次分摊待 #1–#3、答复回填批次 收口);杂项收口标注 calc_receipt 与 settlement_service 拆分进度 - T+ 小节:清单已升 v1.4(2026-10-19),本节口径待收编 - 新增修复批次口径记录:月结聚合/月工资按月月末取参(单笔行按回款日) Co-Authored-By: Claude Code <noreply@anthropic.com>
e48cfb7
- _personal_rate 的 TPL_MANAGER_SHARE 分支读 manager.personal.included:1=按业务员递减公式计提,0=单笔落 0(现状) - _load_allocations 装载生效方案并防御拦截(合计超 100%、参与人含负责人) - _persist_ledger 拆行落库:参与人=份额×比例(q2)、负责人=q2 全额−已分累计(行合计守恒防分漂);快照带 alloc_plan/alloc_role/alloc_ratio - _prepare_mode 重算改 list_active_by_receipt 作废全部拆分行;uk 三列版支持同回款按人多行 - business_service 保存侧同口径校验(超 100% 400、负责人自分 400、hint 文案定稿) - 集成用例 +5(拆行守恒/叠加进度登记/重算全作废/双拦截)+保存侧 3 条 Co-Authored-By: Claude Code <noreply@anthropic.com>
- T+ 对接数据需求清单 v1.4 与业务方答复回执 - 待确认事项排序表两版、待答复催办清单 - 剩余开发计划回填 3.3.1 答复落定状态 - 新增 M4 报表统计实施计划 Co-Authored-By: Claude Code <noreply@anthropic.com>
覆盖台账页按回款 ID 重算、版本筛选三态、月结生成/提交审批/明细回显, 用随机远未来月份造数,重复运行互不碰撞。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- report_meta:回款天数区间桶(含可空/负值兜底桶)、客户类型标签、导出上限 - schemas/report:明细/汇总查询入参与分页响应,金额比例全程 Decimal - report_repository:报表专用只读聚合,显式排除台账聚合行、口径与月结区分 - constants:新增报表统计模块与导出动作常量 Co-Authored-By: Claude Code <noreply@anthropic.com>
- index.css 两处字体栈移除 Microsoft YaHei:品牌字与正文统一思源黑体(OFL) + HarmonyOS Sans 开源序列,Helvetica/Arial 仅作西文回退 - README 视觉章节对齐 v3 靛蓝体系:配色表/质感来源/落地方式/签名元素/构图 更新,旧「宋体品牌字」「两档金」表述修正并写明商用字体禁用约定 - 设计预览页字体栈与品牌字候选卡同步,echarts chartFont 去雅黑 Co-Authored-By: Claude Code <noreply@anthropic.com>
字符/干扰/噪点/底色改用 --ys-ink / --ys-ink-2 / --ys-ink-3 / --ys-paper 对应色值,与 2026-10-12 后的前端视觉方向一致;识别难度参数未变, tests/unit/test_captcha.py 12 项通过。 Co-Authored-By: Claude Code <noreply@anthropic.com>
calc_settlement_flow e2e 首跑即暴露三处真实缺陷(三页自 2026-10-17 交付 起一直「暂无数据」且翻页失效,此前无 e2e 覆盖): - api/{calc,settlements,approvals}.ts 误用默认导出 `request`(axios 实例, 返回 AxiosResponse 未解包),usePagedList 拿到的 data.list 恒 undefined → 三页永远「暂无数据」;改为具名导入 `{ request }`(统一信封解包版) - 三页均无 onMounted 初始加载 → 进页不取数;补 `onMounted(() => void load())` - 三页 AppPagination 用 `v-model:page-num` + `@change`(组件无该事件、 也未实现 update:*)→ 翻页失效;统一为 `:page-num/:page-size` + `@page-change/@size-change` - 并入并行会话的操作列 align="center" 样式与 M4 报表页 README 段落 验证:e2e calc_settlement_flow 8 步全过(API 预置→台账筛选→重算对话框 按回款 ID→版本三态筛选→月结生成→提交锁定→详情抽屉);type-check 绿 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 新增 table-actions.css:操作列 flex 居中、间距交给 gap、破坏性动作前 加分组竖线、链接按钮悬停加深并加下划线(默认浅靛蓝在表格底色上对比度 不足);包装 span 改 flex,消除行内盒基线导致的约 1.7px 垂直错位 - 11 个列表页操作列套用统一容器与分隔线,列宽按动作自然宽度调整并居中 - 确认框不再传 type:warning(Element Plus 的实心黄圆图标与正文并排成 两列,标题行反被留空),图标改由全局样式画在标题行左侧,正文与标题 文字左对齐;图标为 CSS 伪元素,不进无障碍树 验证:pnpm type-check 绿 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 四表接口 /api/v1/reports/*:个人明细(全筛选 summary)、部门汇总(团队基数与月结聚合同源、12.5%/5% 分列、零行经理、冻结对照)、业务统计(排除聚合行)、回款统计(8 档区间恒在、回款金额按 receipt_id 去重防分摊拆行翻倍) - Excel 导出:公司页眉/财务复核栏/领导签字栏/日期/版本、Decimal 原值 + number_format、文本防公式注入、2 万行超限 400、导出行为入操作日志 - manager_share 共享模块:月结聚合与报表部门汇总同源取参与分桶(薄委托保留测试入口) - 区间元数据落 core/report_meta(repository 需要类型,避免反向依赖 service 层) - 准入 require_roles(admin/finance/leader),支持自定义 403 文案 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 个人绩效明细/部门绩效汇总/业务统计/回款统计四页,路由组「报表统计」order19-22(allowedRoles admin/finance/leader) - 明细分页页脚全筛选合计;部门汇总成员内联与跨页下钻;业务统计展开回款/台账;回款统计 8 档区间(档位由后端下发)与桶下钻 - 打印视图独立顶层路由(不挂 BasicLayout):公司页眉走 public 端点、循环翻页取全量(2000 行截断提示)、@media print A4 横版每页表头、签字栏 - AppPagination 只派发 page-change/size-change,四页按事件绑定并补初始加载(@change/v-model 不生效的同类缺陷) - e2e report_flow.py:四页筛选与导出下载、打印视图 window.print 桩断言 Co-Authored-By: Claude Code <noreply@anthropic.com>
回填 2026-10-16 业务方 24 项澄清答复(12 确认默认 / 4 项与默认不同已落实 / 仍开放三态)、 AC-12 口径修正、二次分摊拆行与月末取参实现口径;FR 42 条 / AC 12 条结构校验通过, 作废口径仅出现在修订对照与作废声明语境。 Co-Authored-By: Claude Code <noreply@anthropic.com>
No dependencies set.
The note is not visible to the blocked user.
需求 2.5.1 用户账号管理,全部要求管理员权限(require_admin 依赖): - 接口:列表/详情/新增/编辑/删除/重置密码/启停/角色下拉, 角色下拉放 /users/meta/roles 以避开 /{user_id} 的路由匹配冲突 - 删除、禁用、改角色三处自我保护:不允许对当前登录账号执行, 避免管理员误操作后立刻失去全部管理权限且无法自行恢复 - 重置密码与禁用均提升 token_version,使已签发令牌立即失效, 不依赖 Redis 黑名单 - 密码按字节数校验(bcrypt 5.0 硬上限 72 字节,中文一字 3 字节) - 用户列表按 id 倒序:create_time 为秒级精度,同秒数据分页结果不确定 - 修复 replace_roles 未同步关系集合的缺陷:改用 user.user_roles 集合追加,此前 session.add(UserRole(...)) 会表现为保存成功但返回空角色 - update_user 的自我保护原先依赖返回 None 的占位函数,恒不生效, 改为显式传入 operator_id Co-Authored-By: Claude Code <noreply@anthropic.com>- 编号 YW{日期}-{序号}:MAX+FOR UPDATE 并发安全 + 1062 兜底重试(no_generator 三单据共用) - 明细全量替换重算五项汇总冗余;销售额服务层按数量×单价固化不信任前端 - 状态机终态拦截、终止必填原因、创建写首条留痕;归属变更同事务留痕防旁路 - 毛利润视图按行实时计算(不含运费 #2),阈值按 asOf 取 M1 快照,率输出 Fraction 分数字符串同 M1 预览口径;成本缺失行标注无法计算 - 入参契约统一为蛇形直出(撤回 customer/business 的驼峰 alias,与前端 businessRoles.ts 模式对齐) Co-Authored-By: Claude Code <noreply@anthropic.com>e48cfb748c0a86279calc_settlement_flow e2e 首跑即暴露三处真实缺陷(三页自 2026-10-17 交付 起一直「暂无数据」且翻页失效,此前无 e2e 覆盖): - api/{calc,settlements,approvals}.ts 误用默认导出 `request`(axios 实例, 返回 AxiosResponse 未解包),usePagedList 拿到的 data.list 恒 undefined → 三页永远「暂无数据」;改为具名导入 `{ request }`(统一信封解包版) - 三页均无 onMounted 初始加载 → 进页不取数;补 `onMounted(() => void load())` - 三页 AppPagination 用 `v-model:page-num` + `@change`(组件无该事件、 也未实现 update:*)→ 翻页失效;统一为 `:page-num/:page-size` + `@page-change/@size-change` - 并入并行会话的操作列 align="center" 样式与 M4 报表页 README 段落 验证:e2e calc_settlement_flow 8 步全过(API 预置→台账筛选→重算对话框 按回款 ID→版本三态筛选→月结生成→提交锁定→详情抽屉);type-check 绿 Co-Authored-By: Claude Code <noreply@anthropic.com>