diff --git a/docs/feature-matrix.md b/docs/feature-matrix.md index 8e5a8d53..9c67194e 100644 --- a/docs/feature-matrix.md +++ b/docs/feature-matrix.md @@ -1,8 +1,8 @@ -# hyb-oa 实现状态矩阵(P5-P19+IM-1+ERP-3) +# hyb-oa 实现状态矩阵(P5-P19+IM-1+ERP-3+R10) **快照日期**:2026-03-09 -**范围**:`F1-F42`(含 `F19b/F19c/F19d`)+ `R1-S2` + `P9A1-P9D1` + `P10E1-P10G1` + `G0-G6` + `H1` + `M1-M4` + `P13-0-P13-8` + `P14-0-P14-8` + `P15A-0-P15A-5` + `P15B-0-P15B-6` + `P16A-0-P16A-6` + `P16B-0-P16B-6` + `P16C-0-P16C-6` + `R9-0-R9-3` + `G2-0-G2-6` + `P17A-0-P17A-6` + `P17B-0-P17B-6` + `P18A-0-P18A-6` + `P18B-0-P18B-6` + `P19-0-P19-6` + `P19IM1-0-P19IM1-6` + `P19ERP1-0-P19ERP1-6` + `P19ERP2-0-P19ERP2-6` + `P19ERP3-0-P19ERP3-6`,共 220 项。 -**事实源**:`issues/2026-02-09_13-39-02-p5-blueprint-v3.csv` + `issues/2026-02-09_23-30-00-p6-p8-remaining-work-master.csv` + `issues/2026-02-10_09-42-31-p9-maintenance-performance-matrix.csv` + `issues/2026-02-10_10-35-30-p10-production-hardening.csv` + `issues/2026-02-11-p11-p12-governance-mobile.csv` + `issues/2026-02-12_01-09-41-p13-l5-governance.csv` + `issues/2026-02-13_00-11-56-p14-l5-operationalization.csv` + `issues/2026-03-06_14-30-00-p15a-l5-permission-decouple.csv` + `issues/2026-03-06_14-30-00-p15b-l5-leave-v1.csv` + `issues/2026-03-07_13-47-05-p16a-l5-master-data-core.csv` + `issues/2026-03-07_16-22-07-p16b-l5-holiday-calendar.csv` + `issues/2026-03-07_17-14-39-p16c-l5-suppliers.csv` + `issues/2026-03-07_18-15-03-r9-g2-p19-roadmap-refresh.csv` + `issues/2026-03-07_18-16-00-g2-l5-cross-domain-bridge.csv` + `issues/2026-03-07_19-33-09-p17a-l5-procurement-core.csv` + `issues/2026-03-07_21-00-37-p17b-l5-procurement-budget-archive.csv` + `issues/2026-03-07_22-02-09-p18a-l5-asset-registry-core.csv` + `issues/2026-03-07_22-34-03-p18b-l5-asset-movements-inventory.csv` + `issues/2026-03-07_23-22-00-p19-l4-integration-readiness.csv` + `issues/2026-03-08_12-18-10-p19-im-1-l5-collaboration-adapter.csv` + `issues/2026-03-08_14-10-53-p19-erp-1-l5-masterdata-journal-bridge.csv` + `issues/2026-03-08_22-46-51-p19-erp-2-l5-procurement-commitment-archive.csv` + `issues/2026-03-09_00-10-00-p19-erp-3-l5-asset-ledger-summary.csv`(执行合同) +**范围**:`F1-F42`(含 `F19b/F19c/F19d`)+ `R1-S2` + `P9A1-P9D1` + `P10E1-P10G1` + `G0-G6` + `H1` + `M1-M4` + `P13-0-P13-8` + `P14-0-P14-8` + `P15A-0-P15A-5` + `P15B-0-P15B-6` + `P16A-0-P16A-6` + `P16B-0-P16B-6` + `P16C-0-P16C-6` + `R9-0-R9-3` + `G2-0-G2-6` + `P17A-0-P17A-6` + `P17B-0-P17B-6` + `P18A-0-P18A-6` + `P18B-0-P18B-6` + `P19-0-P19-6` + `P19IM1-0-P19IM1-6` + `P19ERP1-0-P19ERP1-6` + `P19ERP2-0-P19ERP2-6` + `P19ERP3-0-P19ERP3-6` + `R10-0-R10-4`,共 225 项。 +**事实源**:`issues/2026-02-09_13-39-02-p5-blueprint-v3.csv` + `issues/2026-02-09_23-30-00-p6-p8-remaining-work-master.csv` + `issues/2026-02-10_09-42-31-p9-maintenance-performance-matrix.csv` + `issues/2026-02-10_10-35-30-p10-production-hardening.csv` + `issues/2026-02-11-p11-p12-governance-mobile.csv` + `issues/2026-02-12_01-09-41-p13-l5-governance.csv` + `issues/2026-02-13_00-11-56-p14-l5-operationalization.csv` + `issues/2026-03-06_14-30-00-p15a-l5-permission-decouple.csv` + `issues/2026-03-06_14-30-00-p15b-l5-leave-v1.csv` + `issues/2026-03-07_13-47-05-p16a-l5-master-data-core.csv` + `issues/2026-03-07_16-22-07-p16b-l5-holiday-calendar.csv` + `issues/2026-03-07_17-14-39-p16c-l5-suppliers.csv` + `issues/2026-03-07_18-15-03-r9-g2-p19-roadmap-refresh.csv` + `issues/2026-03-07_18-16-00-g2-l5-cross-domain-bridge.csv` + `issues/2026-03-07_19-33-09-p17a-l5-procurement-core.csv` + `issues/2026-03-07_21-00-37-p17b-l5-procurement-budget-archive.csv` + `issues/2026-03-07_22-02-09-p18a-l5-asset-registry-core.csv` + `issues/2026-03-07_22-34-03-p18b-l5-asset-movements-inventory.csv` + `issues/2026-03-07_23-22-00-p19-l4-integration-readiness.csv` + `issues/2026-03-08_12-18-10-p19-im-1-l5-collaboration-adapter.csv` + `issues/2026-03-08_14-10-53-p19-erp-1-l5-masterdata-journal-bridge.csv` + `issues/2026-03-08_22-46-51-p19-erp-2-l5-procurement-commitment-archive.csv` + `issues/2026-03-09_00-10-00-p19-erp-3-l5-asset-ledger-summary.csv` + `issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv`(执行合同) **说明**: - 本矩阵用于全局读图(审计/交接/回归覆盖追踪),不替代 `issues/*.csv` 的执行合同职责。 @@ -255,3 +255,8 @@ | P19ERP3-5 | 文档事件与矩阵同步 | N/A | 2026-03-09_00-10-00-p19-erp-3-l5-asset-ledger-summary.csv | 2026-03-09_00-10-00-p19-erp-3-l5-asset-ledger-summary.csv | 2026-03-09 | DONE | validate-feature-matrix | 集成边界、领域事件、Feature Matrix 与校验器同步到 `P5-P19+IM-1+ERP-3` 并纳入 ERP-3 合同事实源 | | P19ERP3-6 | P19ERP3回归与验收收口 | N/A | 2026-03-09_00-10-00-p19-erp-3-l5-asset-ledger-summary.csv | 2026-03-09_00-10-00-p19-erp-3-l5-asset-ledger-summary.csv | 2026-03-09 | DONE | server:test + regression-integrations + regression-all + client:typecheck/build | 资产 ERP 摘要出站、详情挂件、脱敏权限、同一 outbox 覆盖同步与既有采购 / 报销 / IM 主流程回归全部通过 | +| R10-0 | R10执行合同建档 | N/A | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09 | DONE | CSV 校验 | 后 ERP-3 时代总控路线合同建档,冻结未来主线顺序与执行纪律 | +| R10-1 | 冻结R10到P21主线顺序 | N/A | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09 | DONE | CSV 校验 | 固定 `P19+MCP-1 -> P19+AI-1 -> P20+TRAVEL-1/2/3 -> P21+PWA-1/2`,并为后续阶段预生成执行合同 | +| R10-2 | 冻结后置backlog与进入条件 | N/A | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09 | DONE | manual | `IM-2/3/4`、车辆、资产财务深化明确降为后置 backlog,仅保留进入条件不抢主线 | +| R10-3 | 同步路线文档与矩阵事实源 | N/A | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09 | DONE | validate-feature-matrix | 集成边界与 Feature Matrix 纳入 R10 路线事实源,且不提前把未来 TODO phase 计入完成总数 | +| R10-4 | R10校验与收口 | N/A | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | 2026-03-09 | DONE | CSV 校验 + validate-feature-matrix | 新旧合同校验通过,主线 roadmap 可直接承接 P19+MCP-1 到 P21+PWA-2 | diff --git a/docs/integration-boundaries.md b/docs/integration-boundaries.md index ca976652..18bd77ac 100644 --- a/docs/integration-boundaries.md +++ b/docs/integration-boundaries.md @@ -1,8 +1,8 @@ -# 集成边界冻结(P19 / P19+IM-1 / P19+ERP-3) +# 集成边界冻结(P19 / P19+IM-1 / P19+ERP-3 / R10) **快照日期**:2026-03-09 **当前基线**:`P19+IM-1`、`P19+ERP-1`、`P19+ERP-2` 与 `P19+ERP-3` 已完成;当前运行时已落地企微群机器人 + 深链 + Outbox 异步派发的一期协同适配,以及 ERP 主数据 Pull、报销付款凭证切片、采购双阶段 journal / 归档摘要出站、资产台账摘要出站。 -**目标**:在保持核心域稳定的前提下,冻结 ERP / IM / AI / MCP 的长期边界,并记录 IM 一期与 ERP 两期的已实现范围、禁入规则和后续扩展位。 +**目标**:在保持核心域稳定的前提下,冻结 ERP / IM / AI / MCP 的长期边界,并记录 IM 一期与 ERP 三期的已实现范围、禁入规则以及 R10 之后的固定主线顺序。 ## 1. 总体原则 @@ -186,3 +186,30 @@ - 不接入飞书 / 钉钉真实生产推送 - 不新增 AI 写库动作 - 不引入绕过工作流与权限体系的外部回调路径 + +## 8. R10 后续路线冻结 + +### 8.1 固定主线顺序 +- `R10` 之后的固定主线顺序为:`P19+MCP-1 -> P19+AI-1 -> P20+TRAVEL-1 -> P20+TRAVEL-2 -> P20+TRAVEL-3 -> P21+PWA-1 -> P21+PWA-2`。 +- 后续阶段继续遵循“先治理,再工具,再建议,再业务,再移动”的总顺序,不并行开启两个重业务 phase。 +- 每个 phase 固定遵循:`执行合同 CSV -> 方案批准 -> 开发 -> 测试 -> 文档矩阵收口 -> 合并 main`。 + +### 8.2 MCP / AI 前置关系 +- `P19+MCP-1` 是首次真实启用 MCP 的唯一前置 phase;在其完成前,`docs/mcp-tools.md` 仍不得作为已存在事实源引用。 +- `P19+AI-1` 固定在 `P19+MCP-1` 之后启动,继续遵守“AI 只做建议,不直接写库”的硬边界。 +- AI 一期只覆盖采购、报销、资产详情的只读建议工作台,不开放自由聊天、自动审批或 agent 自治。 + +### 8.3 差旅统付主线 +- `P20+TRAVEL-1` 固定负责差旅申请、行程段与 `travel_orders` 入站整合,作为对公统付的前置主数据与流程基线。 +- `P20+TRAVEL-2` 固定采用企业卡 / 虚拟卡授权与交易导入路线,优先复用 `docs/adr/adr-enterprise-card-control.md` 的既有结论。 +- `P20+TRAVEL-3` 固定负责核销闭环与 ERP / AP 摘要桥接;个人垫资报销继续与对公统付并存,不互相替代。 + +### 8.4 PWA 兑现顺序 +- `P21+PWA-1` 固定先做移动资产扫码与盘点增强,优先兑现一线资产作业的生产价值。 +- `P21+PWA-2` 固定后做离线动作队列与企微深链增强,继续复用现有 `APP_ORIGIN + targetPath` 深链规范。 +- PWA 路线继续限定在浏览器 / PWA 栈内,不引入原生 App、小程序或双栈移动壳。 + +### 8.5 后置 backlog +- `P19+IM-2 / IM-3 / IM-4`、`P22+VEH-1`、`P22+ASSET-FIN-1` 明确列为后置 backlog,本轮不进入主线。 +- 这些方向只保留“触发条件 / 进入时机”的规划地位,不提前写入已完成矩阵或事实源校验器。 +- 若后续优先级发生变化,必须通过新的路线合同显式改序,不直接口头跳 phase。 diff --git a/issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv b/issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv new file mode 100644 index 00000000..0ac4bc80 --- /dev/null +++ b/issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv @@ -0,0 +1,6 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +R10-0,R10执行合同建档,创建并校验P19+ERP-3之后的新路线总控合同CSV,CSV通过校验且字段完整并成为后续阶段的总控快照,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv,manual,DONE,DONE,DONE,issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv,[],R10只冻结顺序与执行边界 不直接实现AI差旅PWA业务代码 +R10-1,冻结R10到P21主线顺序,将后续主线固定为P19+MCP-1到P21+PWA-2并为每个阶段预生成Issue合同,后续阶段顺序和合同文件可追溯且不再并行开启两个重业务phase,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv,manual,DONE,DONE,DONE,issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv | issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv | issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv | issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv | issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv | issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv | issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv,"[""R10-0""]",固定顺序为先MCP AI 再差旅统付 再PWA增强 +R10-2,冻结后置backlog与进入条件,明确IM-2到IM-4 车辆管理 资产财务深化为后置backlog并补充进入条件,主线优先级与后置backlog边界在集成边界文档中可追溯且不再混入本轮主线,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv,manual,DONE,DONE,DONE,docs/integration-boundaries.md | issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv,"[""R10-1""]",后置backlog只保留方向与触发条件 不提前进入Feature Matrix事实源 +R10-3,同步路线文档与矩阵事实源,将R10路线冻结写入集成边界并把R10纳入Feature Matrix和事实源校验器,R10成为新的已完成路线治理阶段且Feature Matrix计数与事实源一致,python3 scripts/validate-feature-matrix.py,manual,DONE,DONE,DONE,docs/integration-boundaries.md | docs/feature-matrix.md | scripts/validate-feature-matrix.py | issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv,"[""R10-2""]",仅把R10纳入已完成矩阵 不提前把未来TODO阶段计入总数 +R10-4,R10校验与收口,完成R10合同 路线文档和未来阶段CSV的整体验证并确保主干保持干净可继续开发,所有新CSV通过校验且Feature Matrix事实源校验通过,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv && python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv && python3 scripts/validate-feature-matrix.py,manual,DONE,DONE,DONE,issues/2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv | docs/feature-matrix.md | docs/integration-boundaries.md | scripts/validate-feature-matrix.py,"[""R10-3""]",R10只做治理收口 不新增运行时代码或数据库迁移 diff --git a/issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv b/issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv new file mode 100644 index 00000000..1a77ff2e --- /dev/null +++ b/issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv @@ -0,0 +1,6 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +P19MCP1-0,P19MCP1执行合同建档,创建并校验MCP只读工具基线执行合同CSV,CSV通过校验且字段完整并冻结只读MCP范围,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv,manual,TODO,TODO,TODO,issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv,[],P19MCP1只做只读MCP目录与使用边界 不引入运行时业务能力 +P19MCP1-1,MCP工具目录建档,新增docs/mcp-tools.md并用目录生成流程固化postgres与github的可用工具清单,docs/mcp-tools.md可稳定重建且仅包含postgres github两类只读MCP工具,manual: 使用mcp-tools-catalog生成docs/mcp-tools.md并人工核对内容,manual,TODO,TODO,TODO,docs/mcp-tools.md | issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv,"[""P19MCP1-0""]",若工具目录需脚本辅助 只能新增文档生成或校验脚本 +P19MCP1-2,MCP使用边界与回滚策略,补MCP的用途 权限 禁止事项 审计边界与失败退回策略,MCP边界文档与集成边界文档一致且明确禁止写库改状态绕过本地验证,python3 scripts/validate-feature-matrix.py,manual,TODO,TODO,TODO,docs/integration-boundaries.md | docs/mcp-tools.md | issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv,"[""P19MCP1-1""]",首次启用仍限定只读排障和PR协作 不接应用运行时 +P19MCP1-3,MCP文档校验与治理脚本,如有必要新增最小校验脚本以验证mcp工具目录存在且格式可复建,仓库内存在可复用的MCP目录校验流程且不改变业务接口,manual: 运行新增校验脚本或文档生成命令并确认无错误,manual,TODO,TODO,TODO,scripts | docs/mcp-tools.md | issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv,"[""P19MCP1-2""]",禁止为MCP引入新的服务端运行时依赖 +P19MCP1-4,P19MCP1文档矩阵与验收收口,完成MCP工具目录 集成边界 Feature Matrix与回归说明的统一收口,文档收口完成且无业务回归并可作为后续AI phase前置条件,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv && python3 scripts/validate-feature-matrix.py,manual,TODO,TODO,TODO,docs/mcp-tools.md | docs/integration-boundaries.md | docs/feature-matrix.md | scripts/validate-feature-matrix.py | issues/2026-03-09_10-25-00-p19-mcp-1-l4-readonly-tools-baseline.csv,"[""P19MCP1-3""]",P19MCP1完成后才允许按合同讨论真实MCP使用 diff --git a/issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv b/issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv new file mode 100644 index 00000000..af4f0602 --- /dev/null +++ b/issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv @@ -0,0 +1,7 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +P19AI1-0,P19AI1执行合同建档,创建并校验AI只读建议工作台执行合同CSV,CSV通过校验且字段完整并冻结AI只读建议边界,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv,manual,TODO,TODO,TODO,issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv,[],AI一期只做建议摘要异常提示与下一步建议 不做写库动作 +P19AI1-1,AI provider与治理开关,新增AI配置 环境变量 feature flag与ai.assist权限并固化provider契约,AI调用具备mock和http openai-compatible两类provider且默认关闭并受权限与flag双重控制,cd server && npm run test,manual,TODO,TODO,TODO,server/src/config.js | server/src/constants/permissions.js | server/src/constants/featureFlags.js | server/src/services/ai | server/tests | issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv,"[""P19AI1-0""]",首期不落AI持久化表 仅请求时生成与审计摘要 +P19AI1-2,AI建议服务与接口,实现采购 报销 资产三类只读suggestion接口并补敏感信息脱敏与审计,三个suggestion接口可返回summary riskHints nextActions sourceSnapshot providerMeta generatedAt且失败不影响原业务,cd server && npm run test,manual,TODO,TODO,TODO,server/src/routes/ai.js | server/src/services/ai/provider.js | server/src/services/ai/prompts.js | server/src/services/ai/sanitizer.js | server/src/services/ai/suggestions.js | server/tests,"[""P19AI1-1""]",审计只记录target provider model promptHash tokenUsage 不记录原始敏感prompt +P19AI1-3,详情页AI建议卡片,在报销 采购 资产详情页增加只读AI建议卡片并处理权限与失败展示,有权限用户可在详情页查看AI建议卡片 无权限或AI关闭时不暴露入口且页面主流程零回归,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/pages/ReimbursementDetailPage.tsx | client/src/pages/PurchaseRequestsPage.tsx | client/src/pages/AssetRegistryPage.tsx | client/src/api/ai.ts | client/src/components | issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv,"[""P19AI1-2""]",不新增独立AI后台 页面仅作详情侧建议挂件 +P19AI1-4,AI文档事件与矩阵同步,同步AI边界 API事实源 Feature Matrix与使用说明,AI文档与矩阵完成收口并明确AI只做建议不提升为自动执行能力,python3 scripts/validate-feature-matrix.py,manual,TODO,TODO,TODO,docs/integration-boundaries.md | docs/domain-events.md | docs/feature-matrix.md | scripts/validate-feature-matrix.py | issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv,"[""P19AI1-3""]",若新增AI状态接口需同步到API说明但不引入新的公共领域事件名 +P19AI1-5,P19AI1回归与验收收口,完成AI provider 权限门禁 详情卡片与降级容错验证后收口,AI mock和http失败语义均可回归且不影响报销采购资产详情与既有集成流程,cd server && npm run test && cd ../client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,issues/2026-03-09_10-35-00-p19-ai-1-l5-suggestion-workbench.csv | server/tests | client/src/pages/ReimbursementDetailPage.tsx | client/src/pages/PurchaseRequestsPage.tsx | client/src/pages/AssetRegistryPage.tsx,"[""P19AI1-4""]",重点核对AI关闭 无权限 4xx 5xx timeout与脱敏日志 diff --git a/issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv b/issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv new file mode 100644 index 00000000..3d5e6025 --- /dev/null +++ b/issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv @@ -0,0 +1,7 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +P20TRAVEL1-0,P20TRAVEL1执行合同建档,创建并校验差旅申请与行程入站整合执行合同CSV,CSV通过校验且字段完整并冻结差旅一期范围,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv,manual,TODO,TODO,TODO,issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv,[],差旅一期只做申请审批与行程入站 不做对公支付与ERP出站 +P20TRAVEL1-1,差旅模型与工作流接入,新增TravelRequest TravelRequestSegment并将差旅申请接入现有workflow与预算预占确认,差旅申请具备draft reviewing approved rejected withdrawn closed状态并与预算语义一致,cd server && npm run prisma:validate && npm run test,manual,TODO,TODO,TODO,server/prisma/schema.prisma | server/src/routes/workflow.js | server/src/routes/travelRequests.js | server/tests | issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv,"[""P20TRAVEL1-0""]",以travel_orders为入站事实表增量扩展 不推翻既有导入语义 +P20TRAVEL1-2,差旅申请接口与订单导入扩展,实现差旅申请CRUD submit withdraw接口并扩展travel orders import支持travelRequestId,差旅申请与travel_orders可关联且导入失败不阻断既有手工差旅申请主流程,cd server && npm run test,manual,TODO,TODO,TODO,server/src/routes/travelRequests.js | server/src/routes/travelOrders.js | server/src/services/integrations/travel.js | server/tests,"[""P20TRAVEL1-1""]",保留linked_reimbursement_id 继续支持个人垫资报销并存 +P20TRAVEL1-3,差旅申请前端入口与详情,新增差旅申请列表 详情 表单与基础审批交互并展示导入订单关联信息,前端可完成差旅申请创建提交撤回与查看导入行程信息且权限边界正确,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/api/travelRequests.ts | client/src/pages/TravelRequestsPage.tsx | client/src/router/index.tsx | client/src/components/navigation/NavLinks.tsx | issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv,"[""P20TRAVEL1-2""]",若采用采购式详情布局 需保持与现有页面风格一致 +P20TRAVEL1-4,差旅事件文档与矩阵同步,同步差旅一期状态机 事件名 API边界与Feature Matrix事实源,差旅一期文档完成收口并明确travel_order.imported仅作为内部集成事实候选,python3 scripts/validate-feature-matrix.py,manual,TODO,TODO,TODO,docs/domain-events.md | docs/feature-matrix.md | docs/integration-boundaries.md | scripts/validate-feature-matrix.py | issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv,"[""P20TRAVEL1-3""]",若travel_order.imported未冻结为公共事件则文档需明确其内部事实身份 +P20TRAVEL1-5,P20TRAVEL1回归与验收收口,完成差旅申请 workflow 预算语义 订单入站扩展与前端回归验证后收口,差旅申请与报销采购资产既有主流程零回归且差旅一期happy path通过,cd server && npm run prisma:validate && npm run test && cd ../client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,issues/2026-03-09_10-45-00-p20-travel-1-l5-request-intake.csv | server/tests | client/src/pages/TravelRequestsPage.tsx,"[""P20TRAVEL1-4""]",重点核对预算预占释放 导入关联与撤回语义 diff --git a/issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv b/issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv new file mode 100644 index 00000000..fab72dd3 --- /dev/null +++ b/issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv @@ -0,0 +1,7 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +P20TRAVEL2-0,P20TRAVEL2执行合同建档,创建并校验差旅对公统付授权与交易导入执行合同CSV,CSV通过校验且字段完整并冻结差旅统付二期范围,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv,manual,TODO,TODO,TODO,issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv,[],优先采用企业卡虚拟卡授权与交易导入路线 不自建清结算系统 +P20TRAVEL2-1,统付模型与预算台账语义,新增CardAuthorization CardTransaction并固化authorize settle reverse预算语义,对公统付模型可承载授权 交易 撤销退款且不回滚差旅申请审批,cd server && npm run prisma:validate && npm run test,manual,TODO,TODO,TODO,server/prisma/schema.prisma | server/src/routes/budgets.js | server/src/routes/travelRequests.js | server/tests | issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv,"[""P20TRAVEL2-0""]",以docs/adr/adr-enterprise-card-control.md为设计锚点 +P20TRAVEL2-2,统付导入接口与支付轨道,实现授权导入 交易导入 freeze suggestion与travel payment track接口,授权和交易导入具备幂等与异常提示且可关联TravelRequest travelOrder BudgetPool,cd server && npm run test,manual,TODO,TODO,TODO,server/src/routes/travelAuthorizations.js | server/src/routes/travelTransactions.js | server/src/routes/travelRequests.js | server/tests,"[""P20TRAVEL2-1""]",异常交易只影响统付轨道状态 不阻断差旅申请主流程 +P20TRAVEL2-3,统付前端轨道与异常提示,在差旅详情中增加统付轨道视图 授权交易列表与冻结建议交互,前端可查看授权交易轨道与异常建议且权限边界与后端一致,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/api/travelRequests.ts | client/src/api/travelPayments.ts | client/src/pages/TravelRequestsPage.tsx | issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv,"[""P20TRAVEL2-2""]",不实现真实拒付 仅做冻结建议与状态展示 +P20TRAVEL2-4,ADR文档事件与矩阵同步,同步差旅统付ADR 事件映射 集成边界与Feature Matrix事实源,差旅统付文档收口完成并明确不做真实退款回调和银行清结算,python3 scripts/validate-feature-matrix.py,manual,TODO,TODO,TODO,docs/adr/adr-enterprise-card-control.md | docs/domain-events.md | docs/integration-boundaries.md | docs/feature-matrix.md | scripts/validate-feature-matrix.py | issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv,"[""P20TRAVEL2-3""]",如需补ADR修订须保持PoC结论与正式范围一致 +P20TRAVEL2-5,P20TRAVEL2回归与验收收口,完成统付授权 交易导入 预算语义与前端轨道回归后收口,差旅统付happy path与异常重复撤销场景通过且既有主流程零回归,cd server && npm run prisma:validate && npm run test && cd ../client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,issues/2026-03-09_10-55-00-p20-travel-2-l5-corporate-payments.csv | server/tests | client/src/pages/TravelRequestsPage.tsx,"[""P20TRAVEL2-4""]",重点核对authorize settle reverse幂等与异常交易提示 diff --git a/issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv b/issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv new file mode 100644 index 00000000..9c928221 --- /dev/null +++ b/issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv @@ -0,0 +1,7 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +P20TRAVEL3-0,P20TRAVEL3执行合同建档,创建并校验差旅核销闭环与ERP应付摘要桥执行合同CSV,CSV通过校验且字段完整并冻结差旅ERP三期范围,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv,manual,TODO,TODO,TODO,issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv,[],差旅三期只做核销闭环与ERP摘要桥接 不做journal过账 +P20TRAVEL3-1,差旅ERP出站契约与provider扩展,新增erp.travel.export契约与binding类型并扩展ERP provider dispatcher outbox语义,差旅ERP摘要可通过现有IntegrationOutbox Dispatcher IntegrationBinding骨架处理且不污染核心表,cd server && npm run test,manual,TODO,TODO,TODO,server/src/services/integrations/erp.js | server/src/services/integrations/dispatcher.js | server/src/services/integrations/outbox.js | server/src/services/integrations/travelErp.js | server/tests | issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv,"[""P20TRAVEL3-0""]",新增binding entity_type为travel_payable_summary和travel_settlement_batch +P20TRAVEL3-2,核销服务与ERP轨道接口,实现差旅订单 企业卡交易 报销单的核销关系及track requeue接口,差旅对公支付可形成本地核销闭环并具备ERP track requeue dead_letter重入能力,cd server && npm run test,manual,TODO,TODO,TODO,server/src/routes/travelReconciliation.js | server/src/routes/integrations.js | server/src/services/integrations/travelErp.js | server/tests,"[""P20TRAVEL3-1""]",任何ERP失败都不回滚差旅申请与核销事实 +P20TRAVEL3-3,差旅核销与ERP前端挂件,在差旅详情页增加核销摘要 ERP轨道与手动补发交互,前端可查看对公差旅核销状态并在授权用户下执行ERP补发或重试,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/api/travelRequests.ts | client/src/api/integrationsTravel.ts | client/src/pages/TravelRequestsPage.tsx | issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv,"[""P20TRAVEL3-2""]",个人垫资报销仍走原ERP报销路径并与统付并存 +P20TRAVEL3-4,差旅ERP文档事件与矩阵同步,同步差旅核销闭环 ERP摘要桥 边界 事件映射与Feature Matrix事实源,差旅ERP文档收口完成并明确只做AP应付摘要桥接不做复杂票规和税分摊,python3 scripts/validate-feature-matrix.py,manual,TODO,TODO,TODO,docs/domain-events.md | docs/integration-boundaries.md | docs/feature-matrix.md | scripts/validate-feature-matrix.py | issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv,"[""P20TRAVEL3-3""]",不新增差旅折旧税分摊或复杂票规导出字段 +P20TRAVEL3-5,P20TRAVEL3回归与验收收口,完成差旅核销关系 ERP摘要出站与前端轨道回归验证后收口,差旅ERP happy path与重试容错通过且报销差旅采购资产IM主流程零回归,cd server && npm run test && cd ../client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,issues/2026-03-09_11-05-00-p20-travel-3-l5-reconciliation-erp-bridge.csv | server/tests | client/src/pages/TravelRequestsPage.tsx,"[""P20TRAVEL3-4""]",重点核对requeue dead_letter binding回写与个人报销并存 diff --git a/issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv b/issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv new file mode 100644 index 00000000..e8f65255 --- /dev/null +++ b/issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv @@ -0,0 +1,7 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +P21PWA1-0,P21PWA1执行合同建档,创建并校验移动资产扫码与盘点增强执行合同CSV,CSV通过校验且字段完整并冻结PWA一期移动生产力范围,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv,manual,TODO,TODO,TODO,issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv,[],PWA一期只做浏览器PWA下的扫码盘点增强 不引入原生App +P21PWA1-1,移动扫码能力与路由入口,基于现有PWA注册能力新增移动资产扫码页面并优先使用BarcodeDetector回退成熟扫码库,移动端可通过相机扫码或手工输入识别资产并进入后续盘点或详情流程,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/pwa.ts | client/src/pages/MobileAssetScanPage.tsx | client/src/router/index.tsx | client/src/components | issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv,"[""P21PWA1-0""]",不引入蓝牙 NFC 人脸或平台私有SDK +P21PWA1-2,盘点任务与资产详情移动挂件,为资产详情和盘点任务页增加扫码调起与批量录入能力并复用现有资产盘点API,移动盘点录入可直达资产详情或盘点任务且不新增移动专用后端协议,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/pages/AssetRegistryPage.tsx | client/src/pages/MobileInventoryTaskPage.tsx | client/src/api/assets.ts | client/src/api/inventory.ts | issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv,"[""P21PWA1-1""]",优先复用现有资产和盘点接口 不重写后端路由 +P21PWA1-3,PWA权限与回归清单增强,补移动扫码权限守卫 错误提示与PWA回归清单新场景,非授权用户不可访问移动扫码与盘点入口 且PWA回归清单覆盖扫码场景,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/router/index.tsx | docs/mobile/pwa-regression-checklist.md | client/src/pages/MobileAssetScanPage.tsx | issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv,"[""P21PWA1-2""]",保持现有PWA安装和离线壳场景不回退 +P21PWA1-4,PWA一期文档与矩阵同步,同步移动扫码盘点范围 集成边界与Feature Matrix事实源,PWA一期文档收口完成并明确不做离线后台持续同步与原生壳,python3 scripts/validate-feature-matrix.py,manual,TODO,TODO,TODO,docs/feature-matrix.md | docs/integration-boundaries.md | docs/mobile/pwa-regression-checklist.md | scripts/validate-feature-matrix.py | issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv,"[""P21PWA1-3""]",如需补充移动页面说明 保持PWA路线不切换到双栈App +P21PWA1-5,P21PWA1回归与验收收口,完成移动扫码 盘点录入 权限边界与PWA回归验证后收口,移动扫码happy path和权限拒绝场景通过且现有PWA能力零回归,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,issues/2026-03-09_11-15-00-p21-pwa-1-l5-asset-scan.csv | docs/mobile/pwa-regression-checklist.md | client/src/pages/MobileAssetScanPage.tsx,"[""P21PWA1-4""]",重点核对扫码回退输入 盘点录入与安装离线壳兼容 diff --git a/issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv b/issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv new file mode 100644 index 00000000..cdeb3e6d --- /dev/null +++ b/issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv @@ -0,0 +1,7 @@ +ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes +P21PWA2-0,P21PWA2执行合同建档,创建并校验离线队列与企微深链增强执行合同CSV,CSV通过校验且字段完整并冻结PWA二期增强范围,python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv,manual,TODO,TODO,TODO,issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv,[],PWA二期只做离线动作队列与企微深链增强 不新增移动专用通知通道 +P21PWA2-1,离线动作队列内核,新增统一offlineQueue模块以缓存待重放动作并定义queued syncing succeeded failed状态,移动拍照与移动盘点可复用统一离线队列且所有动作具备幂等键,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/offlineQueue | client/src/pwa.ts | client/src/query | issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv,"[""P21PWA2-0""]",离线队列只缓存待重放动作 不缓存敏感业务全量副本 +P21PWA2-2,IM深链与幂等支持,将现有APP_ORIGIN加targetPath深链扩展到移动页面并为必要接口补幂等请求支持,企微通知可直达移动页面且离线重放不会因重复提交破坏业务状态,cd server && npm run test && cd ../client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,server/src/routes | server/src/services/notifications | client/src/pages/NotificationsPage.tsx | client/src/router/index.tsx | issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv,"[""P21PWA2-1""]",深链复用现有targetPath机制 不重造第二套链接协议 +P21PWA2-3,离线队列状态UI与冲突提示,为移动拍照和移动盘点增加队列状态 可视化重放与冲突提示界面,用户可查看待同步动作状态并对失败重放进行人工感知和处理,cd client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,client/src/pages/MobileAssetScanPage.tsx | client/src/pages/MobileInventoryTaskPage.tsx | client/src/pages/MobileCapturePage.tsx | client/src/components | issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv,"[""P21PWA2-2""]",如现有移动拍照页面命名不同 则按真实文件落点调整合同锚点 +P21PWA2-4,PWA二期文档与矩阵同步,同步离线队列 深链增强 回归清单与Feature Matrix事实源,PWA二期文档收口完成并明确不做后台持续同步和移动专用通知通道,python3 scripts/validate-feature-matrix.py,manual,TODO,TODO,TODO,docs/mobile/pwa-regression-checklist.md | docs/feature-matrix.md | docs/integration-boundaries.md | scripts/validate-feature-matrix.py | issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv,"[""P21PWA2-3""]",如需新增离线说明 文档必须同步幂等键与冲突提示策略 +P21PWA2-5,P21PWA2回归与验收收口,完成离线队列 IM深链 幂等重放与移动UI回归后收口,离线入队 恢复网络重放 深链直达与PWA主流程通过且现有通知零回归,cd server && npm run test && cd ../client && npm run typecheck && npm run build,manual,TODO,TODO,TODO,issues/2026-03-09_11-25-00-p21-pwa-2-l5-offline-deeplink.csv | docs/mobile/pwa-regression-checklist.md | client/src/offlineQueue,"[""P21PWA2-4""]",重点核对幂等不重复 队列状态可视化与企微直达移动页面 diff --git a/scripts/validate-feature-matrix.py b/scripts/validate-feature-matrix.py index a743defe..b465fa49 100755 --- a/scripts/validate-feature-matrix.py +++ b/scripts/validate-feature-matrix.py @@ -42,6 +42,7 @@ CSV_FACT_SOURCES = [ ROOT / "issues" / "2026-03-08_14-10-53-p19-erp-1-l5-masterdata-journal-bridge.csv", ROOT / "issues" / "2026-03-08_22-46-51-p19-erp-2-l5-procurement-commitment-archive.csv", ROOT / "issues" / "2026-03-09_00-10-00-p19-erp-3-l5-asset-ledger-summary.csv", + ROOT / "issues" / "2026-03-09_10-15-00-r10-post-erp3-roadmap-refresh.csv", ] ID_PATTERN = re.compile(r"^[A-Z][0-9][0-9A-Za-z-]*$")