liuwenxin
|
fb398c3835
|
test(e2e): 绩效核算与月度结算端到端用例——台账重算与月结审批链路
覆盖台账页按回款 ID 重算、版本筛选三态、月结生成/提交审批/明细回显,
用随机远未来月份造数,重复运行互不碰撞。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 13:50:13 +08:00 |
|
liuwenxin
|
c5f219423b
|
docs: 2026-10-19 业务答复与需求留档——T+ 清单 v1.4、排序表、催办清单与 M4 计划
- T+ 对接数据需求清单 v1.4 与业务方答复回执
- 待确认事项排序表两版、待答复催办清单
- 剩余开发计划回填 3.3.1 答复落定状态
- 新增 M4 报表统计实施计划
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 13:49:42 +08:00 |
|
liuwenxin
|
a536608b53
|
docs(tests): 2026-10-19 业务答复落实批次记录与分摊尾差缺陷表更新
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 13:29:37 +08:00 |
|
liuwenxin
|
ccfd20651b
|
feat(calc): 二次分摊拆行与 #12 单笔侧开关——按方案比例拆给参与人、余额归负责人
- _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>
|
2026-10-19 13:15:59 +08:00 |
|
liuwenxin
|
48c0a86279
|
docs: 推送状态补正——feat/m3-increments 已推送至远端 e48cfb7
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 13:13:23 +08:00 |
|
liuwenxin
|
e48cfb752d
|
docs: 待确认事项汇总更新至 2026-10-19(答复落实/code-review/远端恢复)
- 立即待办:远端 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>
|
2026-10-19 13:01:50 +08:00 |
|
liuwenxin
|
028a94a6eb
|
refactor(m3): settlement_service 三段收尾——生成/聚合/调整单拆分
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>
|
2026-10-19 12:52:36 +08:00 |
|
liuwenxin
|
a89d540e3f
|
docs(tests): code-review 修复批次测试记录与缺陷表更新
- 运行记录: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>
|
2026-10-19 12:30:41 +08:00 |
|
liuwenxin
|
7a99994d17
|
refactor(m3): calc_receipt 五段拆分——218 行收敛为编排 + 私有函数
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>
|
2026-10-19 12:25:36 +08:00 |
|
liuwenxin
|
45c268b146
|
fix(m3): code-review P2——金额校验、参数解析与运维脚本容错
- 调整单金额恒正: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>
|
2026-10-19 12:10:29 +08:00 |
|
liuwenxin
|
828b57350a
|
test(settlement): #12 聚合基数开关用例——经理个人户计入可配置
默认 0 时聚合 6.84 不变;开关 1 时个人户行按 personnel_id 归经理本人
(不走 manager_id 上溯)、基数 139.11 → 聚合 24.34,两档金标准锁定
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 12:06:07 +08:00 |
|
liuwenxin
|
76ded6d5ec
|
fix(m3): code-review P1——锁定不变量、入结回填与双轨漂移
- 月结锁定拦截补全:原仅新增回款一处,现覆盖回款编辑(原月+新月,防跨月
搬数)/删除、发货新增(按发货日)/编辑(原月+新月)/删除、核算与重算
(已审定月份金额只走调整单);拦截先于「被引用/已核算」判定
- 台账 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>
|
2026-10-19 11:59:49 +08:00 |
|
liuwenxin
|
7a460cb682
|
feat(formula): 首日计提比例取整 10‰(#14 答复——图示口径覆盖公式)
- salesperson_rate 首日特判:第 1 天不递减直接取起始值(原公式 9.9889‰ 作废)
- 第 2 天起公式段不变、360 天=6‰ 锚点与 361 天=4‰ 分界不变;preview/核算共用一处
- 用例反转:首日断言改 Fraction(10,1000),补第 2 天公式段边界
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 11:40:07 +08:00 |
|
liuwenxin
|
cb4f38dfd9
|
fix(m3): code-review P0 六项——算错钱与不可用
- 经理聚合分成放大 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>
|
2026-10-19 11:25:21 +08:00 |
|
liuwenxin
|
35fe37fb0c
|
feat(ops): 增量备份——binlog 归档脚本与全量位点记录(#19 答复)
- backup_incremental.sh:归档已写完 binlog(tar 拷出+gzip),状态文件对齐序号,有更新才产出,保留 30 天
- backup_full.sh:补 .pos 位点文件(SHOW MASTER STATUS),增量重放的起点锚
- 手册新增增量章节:恢复顺序=全量→binlog 重放,含 mysqlbinlog 缺席镜像的说明
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 11:22:39 +08:00 |
|
liuwenxin
|
7008de0c69
|
feat(api): 计提参数查看放开登录用户、修改仅管理员(#17/#6 答复)
- deps 新增 LoginUser 依赖;params 只读七端点改登录即可,写(提交/撤回)保持 AdminUser
- 前端 params 路由 requiresAdmin → allowedRoles(admin/finance/leader);页面写按钮按角色显隐
- 权限用例分层:普通用户目录 200、提交/撤回 403、未登录拦截
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 11:19:16 +08:00 |
|
liuwenxin
|
2652397720
|
chore(migration): 收敛重复 V8 SQL——保留英文名版本(与并行会话对账,内容等价)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-19 11:13:28 +08:00 |
|
liuwenxin
|
0e8c5713fa
|
feat(migration): V8 业务答复口径落实——审批开关默认开启、撤试用期统一参数、经理基数开关、台账分摊唯一键
- #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>
|
2026-10-19 11:09:05 +08:00 |
|
liuwenxin
|
238a38c356
|
test(m3-core): 核算/月结用例收口,目录断言 19 项,测试记录更新
- 金标准金额断言锚定 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>
|
2026-10-17 01:08:31 +08:00 |
|
liuwenxin
|
a1217f4482
|
feat(frontend): 绩效台账与月度结算两页接入(新组绩效工资)
- 绩效台账页(order17):月/版本筛选 + 行展开计算快照 + 重算(原因
对话框,管理员/财务);核算入口在回款管理页(每笔回款行内触发)
- 月结页(order18):生成快照(月份输入)+ 状态筛选 + 提交审批 +
详情抽屉(按人明细三口径/试用期说明/审批单号关联)
- 均复用 usePagedList/AppPagination/--ys-* 惯例;金额 str 直出
- type-check 零错误;build 通过
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-17 00:54:51 +08:00 |
|
liuwenxin
|
e7e47d88bc
|
feat(settlement): 月度结算快照生成与审批锁定,调整单(补发/扣减)与审批联动
- 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>
|
2026-10-17 00:33:31 +08:00 |
|
liuwenxin
|
22a2872100
|
feat(calc): 重算授权留痕与批量核算
- 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>
|
2026-10-16 21:49:44 +08:00 |
|
liuwenxin
|
df1a3839a1
|
feat(calc): 单笔回款核算引擎与绩效台账
- 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>
|
2026-10-16 20:52:02 +08:00 |
|
liuwenxin
|
a5c86640e2
|
feat(migration): V7 核算台账/月结/调整单四表与核算纯函数
- 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>
|
2026-10-16 16:32:32 +08:00 |
|
liuwenxin
|
30a179fc4c
|
docs: 新增待确认事项汇总(立即待办/业务 24 项/IT 18 项/里程碑分层)
- 立即待办:推送被远端 Git 服务阻塞(服务器侧重启)、M2 分支合并 main
- 业务澄清 24 项按高/中/低分层(含建议默认),IT 18 项按优先级分层
- 里程碑待办(M3 剩余/M4/评审遗留 2 项)与文档待办
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-16 15:08:03 +08:00 |
|
liuwenxin
|
1c93ea0a4b
|
fix(m3): code-review 15 项修复(13 项落地,2 项依赖分摊语义记待办)
- 审批:删 _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>
|
2026-10-16 14:23:53 +08:00 |
|
liuwenxin
|
fc8a42bcd9
|
test(m3): 集成/e2e 增补三模块用例并更新测试记录
- 新增 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>
|
2026-10-16 12:01:52 +08:00 |
|
liuwenxin
|
b5e27810fd
|
feat(backup): mysqldump 定时备份/恢复演练/健康检查脚本与手册
- 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>
|
2026-10-16 09:44:50 +08:00 |
|
liuwenxin
|
927592b472
|
feat(frontend): 公司设置/二次分配/审批三页接入,参数页编码中文化
- 公司信息页(设置 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>
|
2026-10-16 09:38:05 +08:00 |
|
liuwenxin
|
74f1ef1cf9
|
feat(frontend): 审批与系统设置模块页面接入及业务列表调整
|
2026-10-16 09:32:12 +08:00 |
|
liuwenxin
|
8ef26e22fb
|
feat(approval): 审批单/节点状态机与二次分配接入(开关自动通过)
- 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>
|
2026-10-15 18:50:38 +08:00 |
|
liuwenxin
|
680661a80b
|
feat(allocation): 二次分配方案录入/替换/终态门槛(分摊计算待澄清另批)
- 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>
|
2026-10-15 18:31:27 +08:00 |
|
liuwenxin
|
efed29647c
|
feat(settings): 公司信息配置与 logo 管理(public 端点供登录页)
- 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>
|
2026-10-15 18:22:12 +08:00 |
|
liuwenxin
|
e95dc4b2de
|
style(backend): formatter 收口两处漏网文件(纯格式无行为变化)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-15 17:25:24 +08:00 |
|
liuwenxin
|
acf87fdfdc
|
feat(migration): V6 系统设置/二次分配/审批表与角色参数种子
- 新增 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>
|
2026-10-15 17:25:23 +08:00 |
|
liuwenxin
|
94c49138bf
|
refactor(e2e): 六个列表页 UI helper 收口 common.py
open_menu 时分组参数化、fill_filter :text-is 精确匹配、messagebox 带
:visible(base_data 实现为准)——两脚本此前各持一份且匹配精度漂移
(has_text 子串 vs :text-is),使用者误以为两者等价;登录/系统管理/
基础数据/业务数据四链路 e2e 复跑全过。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-15 11:01:31 +08:00 |
|
liuwenxin
|
f75a9d534e
|
refactor(test): 集成工厂上提共用,submit_change 拆校验段,审计重试断言对齐全局兜底
- 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>
|
2026-10-15 10:58:44 +08:00 |
|
liuwenxin
|
0ef3adec21
|
refactor(frontend): 金额正则/分页/抽屉状态/行编辑与下拉收口
- 金额形态正则收进 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>
|
2026-10-15 10:08:24 +08:00 |
|
liuwenxin
|
60f6af6494
|
refactor(repos): 归属留痕共享数据访问,人员在职校验收口单点
- 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>
|
2026-10-15 09:49:53 +08:00 |
|
liuwenxin
|
409e26614f
|
refactor(business): 编辑出参取校验返回值省重查,submit_change 批量预载
- 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>
|
2026-10-15 09:32:35 +08:00 |
|
liuwenxin
|
5ef48abf47
|
test(schema-sync): 迁移链按序重放 ALTER,比对基准由历史并集改为终态
早前实现把全部 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>
|
2026-10-15 09:24:34 +08:00 |
|
liuwenxin
|
7f8f88c148
|
fix(frontend): 错误提示单一化/成功提示后置/日志页首次成功拉取
- 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>
|
2026-10-15 09:22:12 +08:00 |
|
liuwenxin
|
c2b462df3b
|
fix(rating): 区间重叠判定改用锁定读取,防并发重叠双提交
先查后写无锁时,两管理员并发提交重叠区间互判不重叠而双双入库
(区间重叠无唯一键可拦,同一总分命中多等级且结果取决于插入顺序);
判重叠的 list_all 加 for_update 锁全表行串行化并发判定,只读直出
list_grades 不加锁。SQL 形态用例锁定两条口径。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-14 19:01:11 +08:00 |
|
liuwenxin
|
e6c2c71d1b
|
fix(business): 行金额乘积显式两位固化,计提比例对负天数钳制
- 明细行金额(数量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>
|
2026-10-14 18:58:30 +08:00 |
|
liuwenxin
|
91fc6f6293
|
fix(product): 删除引用保护/单价小数位校验,IntegrityError 全局兜底转 400
- 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>
|
2026-10-14 18:48:32 +08:00 |
|
liuwenxin
|
9a70264b51
|
style(backend): ruff format 统一此前批次的排版残留
纯排版无行为变化(ruff format 重排 7 个此前批次的文件),
涉及模块集成回归全绿(67 passed)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-14 18:46:43 +08:00 |
|
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
|
a0086554b1
|
refactor(core): 1062 唯一键冲突判定收口至 core/db_errors
六个 service 各自复制的 _is_duplicate_entry(口径已漂移:rating/product
用 _ERR_DUP_ENTRY 常量、其余四处写字面量 1062)收敛为共享函数;
is_duplicate_entry 语义与文案注释各处保留,非 1062 完整性错误仍原样
上抛由全局处理器收敛。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-10-14 15:17:00 +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 |
|