diff --git a/AGENTS.md b/AGENTS.md index 6e1e581..d9cc7dd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,16 +9,24 @@ hotsrm 是基于 [ObjectStack](https://github.com/objectstack-ai/objectstack) 管理(SRM)应用,由三层组成: - **通用核心**:设计在 `docs/design/`,源码在 `src/core/`(`type: app`); -- **行业扩展包**:设计在 `docs/packs/`,源码在 `src/bulk/`、`src/hazmat/`、`src/soe/` - (`type: module`),构建时与核心合成一个应用([ADR-0002](./docs/adr/0002-packs-composed-into-one-app.md)); -- **客户配置**:参数取值、组织、物资目录、样式等,放在客户的私有仓库,**不进本仓库**。 +- **行业扩展包**:设计在 `docs/packs/`,源码将放在 `src/bulk/`、`src/hazmat/`、`src/soe/` + (`type: module`),构建时与核心合成一个应用([ADR-0002](./docs/adr/0002-packs-composed-into-one-app.md))。 + **现阶段只做核心包**,三个扩展包保留为设计、未排期([ADR-0009](./docs/adr/0009-core-first-pack-criteria-and-customer-layer.md)); +- **客户配置**:参数取值、组织、物资目录、样式、Studio 覆盖层、客户私有包,放在客户的 + 私有仓库和客户环境,**不进本仓库**(ADR-0009)。 + +核心做什么、不做什么:供应商生命周期、合同、质量、绩效、风险、门户、寻源在核心; +采购订单、收货、对账、发票、付款留在 ERP,SRM 只记结论、不记过程 +([ADR-0008](./docs/adr/0008-order-to-pay-stays-in-erp.md))。路线:内部核心 → 门户 → 寻源, +见 [docs/design/07](./docs/design/07-delivery-plan.md)。 文档地图见 [docs/README.md](./docs/README.md),关键决定见 [docs/adr/](./docs/adr/README.md)。 ## 2. 红线(违反即退回) 1. **只用元数据**([ADR-0001](./docs/adr/0001-declarative-only.md)):业务规则不得依赖生命周期 - 钩子、插件或服务端函数。托管云不执行应用包代码,依赖它们的规则会静默失效。 + 钩子、插件或服务端函数。平台本身有沙箱钩子,但本仓库不用:托管云可以关闭应用包 + 代码,依赖它们的规则会静默失效。例外只能按包写新的 ADR。 2. **供应商之间零可见**([ADR-0003](./docs/adr/0003-portal-isolation-by-supplier-position.md)): - 新增面向供应商的顶层对象,必须同时有 `portal_position` 字段、前缀校验规则、门户 RLS 和隔离测试; @@ -26,19 +34,26 @@ hotsrm 是基于 [ObjectStack](https://github.com/objectstack-ai/objectstack) - 不得删除或跳过隔离测试。 3. **封标**([ADR-0004](./docs/adr/0004-sealed-bid.md)):任何能读到报价的权限集、报表、视图 都必须受 `bid_opened == true` 约束;不得给任何角色报价对象的全量读取权限。 -4. **扩展包不改核心**:扩展包只能用 `objectExtensions`、`picklistExtensions`、导航贡献三种 - 方式接入核心,不修改 `src/core/` 下的文件;扩展包之间不互相引用,联动放 - `src/bridges/-/`。 +4. **扩展包不改核心**([ADR-0009](./docs/adr/0009-core-first-pack-criteria-and-customer-layer.md)): + 扩展包只能用 `objectExtensions`、`picklistExtensions`、导航贡献三种方式接入核心,不修改 + `src/core/` 下的文件;包主要新增自己的对象并用 `lookup` 关联核心,对核心对象的 + `objectExtensions` 每包不超过 2–3 个字段;扩展包之间不互相引用,桥接模块现阶段不做。 + 新包必须满足准入标准(受法规约束 / 三家以上复用 / 保护测试资产)之一才立项。 5. **不写客户信息**:本仓库是公开仓库。不写客户名称,也不写能认出客户的组合(某客户的 物料清单、组织形态、合同条款);参数只用标明「示例」的行业常见值。 6. **不提交密钥**:连接串、令牌、密码、证书私钥一律不进仓库、提交信息、PR 和文档。 +7. **核心 API 名冻结**(ADR-0009):对象名、字段名、字段类型一旦合入主干不再改;改必须附 + ADR,门槛 2(v0.7 结束)之后还要附迁移说明。客户个性化放客户层,核心字段只能隐藏, + 不能删除。 ## 3. 元数据约定 - `@objectstack/spec` 是唯一契约。元数据跑不通时改元数据,不去放宽运行时;不确定某个 写法是否合法时,查框架源码中的规范定义,不要猜。 - 命名:核心对象 `srm_*`;扩展包对象 `srm_bulk_*`、`srm_hz_*`、`srm_soe_*`;字段名和选项值 - 用 snake_case,不以数字开头。 + 用 snake_case,不以数字开头;字段名不含 `role`(平台保留词,联系人角色叫 `contact_function`)。 +- 字段谓词(`requiredWhen`、`readonlyWhen`、`visibleWhen`)只能读本记录;关联记录只在 + `script` 校验规则里经一跳读取。其余建模规则见 [docs/engineering/](./docs/engineering/README.md)。 - 建模原则见[核心 02 §1](./docs/design/02-domain-model.md#1-建模原则),要点: - 状态是主对象上的 `select` 字段,作为 `stageField`,每个选项带 `kind`; `state_machine` 校验同时声明 `transitions` 和 `initialStates`; @@ -56,7 +71,10 @@ hotsrm 是基于 [ObjectStack](https://github.com/objectstack-ai/objectstack) - 正文用简体中文,机器名用英文。 - 先改设计再改元数据:行为变化先更新 `docs/design/` 或 `docs/packs/` 的对应章节,再改源码。 -- 新的关键决定写 ADR;改变已有决定时写新的 ADR 取代旧的,不改写旧记录的「决定」部分。 +- 新的关键决定写 ADR;改变已有决定时写新的 ADR 取代旧的,不改写旧记录的「决定」部分; + 「待验证」有结论后在该条下追加「结果(日期)」。 +- 版本出口时同步 `docs/design/07` 的路线表和根 README 的对象数;模板里不写死会进系统的 + 数字,一律引用 `params/`。 - `docs/reference/` 由脚本从元数据生成,禁止手改。 - 体系文件条款与系统控制点同步修改:改了一边,检查另一边([ADR-0005](./docs/adr/0005-governance-and-system-share-parameters.md))。 - 体系文件模板只写通用表述,不写【待确认】和任何客户信息;客户的取值、标注和专属段落放 diff --git a/README.md b/README.md index e9986c9..d888ffb 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,20 @@ 基于 [ObjectStack](https://github.com/objectstack-ai/objectstack) 的通用供应商关系管理(SRM)应用。 -hotsrm 管企业**与供应商协同**的那一半:供应商全生命周期、寻源定价、合同、订单与送货协同、 -质量整改、绩效、对账开票、风险,以及面向供应商的门户。物料、库存、应付凭证和付款仍由 -ERP 记账,hotsrm 不做第二套账。 +hotsrm 管企业**与供应商协同**的那一半:供应商全生命周期、合同、质量整改、绩效、风险、 +寻源定价,以及面向供应商的门户。采购订单、收货、对账、发票、付款留在 ERP,hotsrm 只记 +结论、不做第二套账([ADR-0008](./docs/adr/0008-order-to-pay-stays-in-erp.md))。 ## 三层结构 | 层 | 内容 | 设计 | 源码 | |---|---|---|---| | 通用核心 | 所有企业都需要的功能与管理制度 | [`docs/design/`](./docs/design/README.md) | `src/core/`(`type: app`) | -| 行业扩展包 | 同类企业共有的做法,按需组合:[大宗物料包](./docs/packs/bulk-materials.md)、[危化品包](./docs/packs/hazmat.md)、[国企采购合规包](./docs/packs/soe-procurement.md) | [`docs/packs/`](./docs/packs/README.md) | `src/bulk/`、`src/hazmat/`、`src/soe/`(`type: module`) | -| 客户配置 | 某个客户的参数取值、组织结构、物资目录、审批权限、文件样式 | — | 客户的私有仓库,不在本仓库 | +| 行业扩展包 | 同类企业共有的做法,按需组合:[大宗物料包](./docs/packs/bulk-materials.md)、[危化品包](./docs/packs/hazmat.md)、[国企采购合规包](./docs/packs/soe-procurement.md)。**设计保留,未排期**([ADR-0009](./docs/adr/0009-core-first-pack-criteria-and-customer-layer.md)) | [`docs/packs/`](./docs/packs/README.md) | 将来放 `src/bulk/`、`src/hazmat/`、`src/soe/`(`type: module`) | +| 客户配置 | 某个客户的参数取值、组织结构、物资目录、审批权限、文件样式、Studio 覆盖层、客户私有包 | — | 客户的私有仓库与客户环境,不在本仓库 | -客户需求按「通用核心 → 扩展包 → 参数 → 定制」的顺序归位,定制尽量少(见 -[扩展包总览](./docs/packs/README.md#1-三层结构))。 +客户需求按「通用核心 → 扩展包 → 参数 → 定制」的顺序归位;现阶段只做核心包,客户个性化 +放客户层,核心 API 名冻结(见 [扩展包总览](./docs/packs/README.md#1-三层结构) 与 ADR-0009)。 ## 扩展包怎么组合与安装 @@ -27,8 +27,8 @@ ObjectStack 中客户能安装的只有应用(`type: app`)。扩展包是模 | 标准版 | 核心 | 本仓库 | 公开应用市场 | | 客户版 | 核心 + 客户选定的扩展包 + 客户初始化数据 | 客户的私有仓库 | 只发布到该客户的组织 | -扩展包只通过对象扩展、选项列表扩展和导航贡献接入核心,不修改核心;两个扩展包之间的 -联动放在桥接模块里。客户后来要加扩展包,发布同一个应用的新版本并升级即可(见 +扩展包只通过对象扩展、选项列表扩展和导航贡献接入核心,不修改核心;桥接模块等第二个 +包出现再做。客户后来要加扩展包,发布同一个应用的新版本并升级即可(见 [扩展包总览 §3](./docs/packs/README.md#3-扩展包怎么组合与安装))。 ## 管理制度与系统同源 @@ -42,6 +42,8 @@ hotsrm 附带一套供应商管理体系文件模板(程序文件、管理办 - **只用元数据实现**:对象、校验规则、行级权限、flow、审批全部用平台元数据表达,在托管云 上无需应用代码即可运行([ADR-0001](./docs/adr/0001-declarative-only.md))。 +- **记结论、不记过程**:订单到付款留在 ERP,SRM 用导入的交付记录算绩效,预留集成点 + ([ADR-0008](./docs/adr/0008-order-to-pay-stays-in-erp.md))。 - **供应商之间零可见**:门户按供应商隔离,取不到隔离依据时一行也不放行 ([ADR-0003](./docs/adr/0003-portal-isolation-by-supplier-position.md))。 - **封标**:开标前,内部任何角色(包括 AI 助手)都读不到报价 @@ -57,17 +59,17 @@ hotsrm/ ├── CLAUDE.md 指向 AGENTS.md ├── docs/ 文档,地图见 docs/README.md │ ├── design/ 核心设计 -│ ├── packs/ 扩展包设计 +│ ├── packs/ 扩展包设计(设计保留,未排期) +│ ├── engineering/ 建模规范、CI 门禁、测试与版本策略 │ └── adr/ 决策记录 ├── governance/ 体系文件模板与生成脚本 ├── params/ 参数定义与示例默认值(制度与系统共用) ├── src/ -│ ├── core/ 核心(type: app) -│ ├── bulk/ hazmat/ soe/ 三个扩展包(type: module) 〔待建〕 -│ └── bridges/ 扩展包之间的联动(type: module) 〔待建〕 -├── test/ 启动测试;门户隔离、封标、组合构建、flow 测试随功能补齐 -├── objectstack.composition.ts 按开关选出要组合的模块 -├── objectstack.config.ts 合成一个发布制品 +│ └── core/ 核心(type: app);v0.1 已合入(PR #5) +│ (扩展包 bulk/ hazmat/ soe/ 与桥接模块等有客户要求时再建,ADR-0009) +├── test/ 启动测试与 flow 测试;门户隔离(v0.6 起)、封标(v0.7 起) +├── objectstack.composition.ts 按开关选出要组合的模块(现只有核心) +├── objectstack.config.ts 发布制品 └── objectstack.manifest.json 标准版的应用标识(市场展示信息) ``` @@ -86,7 +88,20 @@ pnpm validate # 每次改元数据后跑;其余检查见 AGENTS.md §6 ## 当前状态 -v0.1 开发中:工程骨架、CI 和核心应用外壳(`srm_workbench` 工作台、采购品类)已就位。 -建议的 v0.1 范围是内部工作台上的供应商主数据、准入审批和资质到期预警,门户、寻源和 ERP 集成 -放在后续版本。设计文档目录见 [docs/README.md](./docs/README.md);参与开发前先读 -[AGENTS.md](./AGENTS.md)。 +2026-10-23:范围与路线重定(ADR-0008、ADR-0009)。核心收到 **27 个对象**,按版本交付: + +| 版本 | 内容 | 累计对象 | +|---|---|---| +| v0.1(已合入,PR #5) | 内部工作台:主数据、两级准入审批、资质到期扫描 | 7 | +| v0.2 | 物料只读副本、银行账户、存量导入、信息变更单 | 10 | +| v0.3 | 合同与协议、供应商处置 | 13 | +| v0.4 | 交付记录导入、质量问题 / SCAR、供应商审核 | 16 | +| v0.5 | 绩效、风险事件、管理报表 = 内部版 MVP,试运行 | 20 | +| v0.6 | 供应商门户(依赖 objectstack#25233) | 21 | +| v0.7 | 寻源与封标、价格库;核心对象冻结 | 27 | + +已完成:核心设计、三个扩展包设计(保留)、ADR-0001~0009、参数文件首版、体系文件生成脚本 +和 12 份模板、v0.1 内部工作台(PR #5)。文档目录见 [docs/README.md](./docs/README.md); +参与开发前先读 [AGENTS.md](./AGENTS.md)。 + +下一步:v0.2 主数据补齐——物料只读副本、银行账户、存量导入、信息变更单([07 §1](./docs/design/07-delivery-plan.md#1-分期路线图))。 diff --git a/docs/README.md b/docs/README.md index eae277d..0a00999 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,8 +4,9 @@ | 目录 / 文件 | 内容 | 读者 | |---|---|---| -| [design/](./design/README.md) | 核心设计:需求、领域模型、流程与自动化、权限与门户、界面与分析、集成与 AI、交付计划 | 产品、开发、实施 | -| [packs/](./packs/README.md) | 行业扩展包:大宗物料包、危化品包、国企采购合规包,以及扩展包的组合与接入方式 | 产品、开发、实施 | +| [design/](./design/README.md) | 核心设计:需求、领域模型、流程与自动化、权限与门户、界面与分析、预留集成点与 AI、交付计划 | 产品、开发、实施 | +| [packs/](./packs/README.md) | 行业扩展包(设计保留,未排期):大宗物料包、危化品包、国企采购合规包,以及扩展包的组合与接入方式 | 产品、开发、实施 | +| [engineering/](./engineering/README.md) | 建模规范、分支与 PR、CI 门禁、测试策略、版本与升级 | 开发者、AI agent | | [adr/](./adr/README.md) | 决策记录 | 全体 | | [../governance/](../governance/README.md) | 体系文件(管理制度)模板的结构、参数与生成方式 | 实施顾问、客户体系工程师 | | [../AGENTS.md](../AGENTS.md) | 开发规则与红线 | 开发者、AI agent | @@ -15,9 +16,8 @@ | 目录 | 内容 | 时机 | |---|---|---| | `requirements/` | 需求记录 `NNNN-*.md`:客户需求提炼成通用表述后登记,写明落在核心、扩展包还是参数 | 收到第一个新需求时 | -| `engineering/` | 元数据建模规范、测试策略、版本与升级策略 | 开始写代码前 | -| `integration/` | ERP 等外部系统的接口规格,每个数据流一份(I1–I15) | 第一期开发前(先写 I1–I6) | -| `implementation/` | 实施手册、数据导入模板、上线检查清单 | 第一个客户项目启动时 | +| `integration/` | ERP 等外部系统的接口规格,每个数据流一份(I1–I15) | ERP 集成立项时([ADR-0008](./adr/0008-order-to-pay-stays-in-erp.md)) | +| `implementation/` | 实施手册(含客户层四种定制方式的边界)、数据导入模板、上线检查清单 | v0.5 试运行前 | | `reference/` | 由元数据自动生成的对象、字段、选项、权限清单(禁止手改) | 有代码之后 | | `../content/docs/` | 对外的产品文档、用户手册、供应商操作指南 | 临近上线 | diff --git a/docs/adr/0001-declarative-only.md b/docs/adr/0001-declarative-only.md index 7aad215..598c877 100644 --- a/docs/adr/0001-declarative-only.md +++ b/docs/adr/0001-declarative-only.md @@ -38,3 +38,16 @@ hotsrm 的所有业务规则都用元数据表达,不依赖任何应用代码 - 一些规则要换一种写法:冗余判断依据到本记录再校验、用 screen flow 做受控写入口、 用追赶式扫描代替精确定时(见[核心 03 §2](../design/03-processes-and-automation.md#2-平台机制与本设计的用法))。 - 代码评审时,任何新增的钩子、插件或函数都要说明它为什么不是业务规则的唯一保障。 + +## 补充说明(2026-10-23) + +- 平台本身支持应用代码:钩子在 QuickJS 沙箱里运行,默认 CPU 预算 250 毫秒(动作 5 秒), + 嵌套的跨对象写入加入同一事务(objectstack ADR-0034、0102、0119);记录变更型 flow + 则不能否决触发它的写入(ADR-0077)。所以「纯元数据」是本仓库自己的选择,不是平台 + 的限制:理由仍是托管云与自托管行为一致、规则不会静默失效。 +- 「托管云不执行应用包代码」对应运行时开关 `OS_DISABLE_AUTHORED_HOOKS` / + `OS_DISABLE_AUTHORED_ACTIONS`;「安装时提示」来自实测而非平台文档,上生产前在目标 + 环境再验证一次(07 §6 V7)。 +- 核心 27 个对象([ADR-0008](./0008-order-to-pay-stays-in-erp.md))没有一个需要钩子。 + 将来某个扩展包出现「一起成功或一起失败」的跨对象动作时,按包写新的 ADR 给本记录 + 加例外,不在本记录里放宽。 diff --git a/docs/adr/0002-packs-composed-into-one-app.md b/docs/adr/0002-packs-composed-into-one-app.md index ab250e8..cbe1040 100644 --- a/docs/adr/0002-packs-composed-into-one-app.md +++ b/docs/adr/0002-packs-composed-into-one-app.md @@ -55,3 +55,13 @@ ObjectStack 的规定后发现这条路走不通: - 同一个应用升级到新版本时新增一批对象(加入一个扩展包),在托管云上的升级是否顺畅。 - 客户版用托管安装(定义锁定,可升级)还是模板安装(复制一份,完全可改,但以后不能升级)。 倾向托管安装,保住升级能力。 + - 结果(2026-10-23):objectstack ADR-0131 D6 已裁定托管安装 = 定义封存,客户按 + ADR-0126 的三种方式(参数、Studio 覆盖层、私有包)定制;模板安装在共库多租户上 + 被拒绝。托管云只能托管安装,结论定下。 + +## 补充说明(2026-10-23) + +[ADR-0009](./0009-core-first-pack-criteria-and-customer-layer.md) 收窄了本记录的扩展包 +接入规则:现阶段只做核心包,三个扩展包保留为设计;包主要新增自己的对象,对核心的 +`objectExtensions` 每包不超过 2–3 个字段;桥接模块和组合测试矩阵推迟到第二个包出现。 +构建时组合、「只加不减」和三种接入方式不变。 diff --git a/docs/adr/0003-portal-isolation-by-supplier-position.md b/docs/adr/0003-portal-isolation-by-supplier-position.md index 8648561..f1e4fa6 100644 --- a/docs/adr/0003-portal-isolation-by-supplier-position.md +++ b/docs/adr/0003-portal-isolation-by-supplier-position.md @@ -49,4 +49,12 @@ ## 待验证 - flow 能否以系统身份写岗位任命;不能时由管理员手工任命。 + - 结果(2026-10-23):岗位本身是元数据定义,flow 不能创建,由管理员新建(objectstack + ADR-0090 修订);用户 ↔ 岗位任命 `sys_user_position` 是数据行,但受委托管理范围 + 约束,系统身份的 flow 写入是否放行平台源码没有明确答案(objectstack#25251)。已向 + 平台提交「按外部方在运行时建岗位并任命」的需求(objectstack#25443)。门户在 v0.6 + 开工前按 07 §6 的 V2、V3 实测;不放行时「开通门户」screen flow 只做回填,任命由 + 管理员在成员页完成。 +- 门户用户能否列出全组织用户:实测可以(objectstack#25233,P1),与本记录的 + 「用户目录可见范围不在控制范围内」一致;平台修复前不开门户。 - 平台以后若支持在元数据里声明成员集合,可以改用成员集合的写法,取消逐家建岗位。 diff --git a/docs/adr/0006-single-org-with-business-units.md b/docs/adr/0006-single-org-with-business-units.md index 6926bb3..bc200ae 100644 --- a/docs/adr/0006-single-org-with-business-units.md +++ b/docs/adr/0006-single-org-with-business-units.md @@ -34,3 +34,9 @@ - 遇到需要开墙的法人时,先回答三个问题:它需要独立的管理员班子吗?有监管或合资方的 隔离要求吗?未来可能被出售或分立吗?三问都是「否」就不开墙;有一个「是」就开墙,并 另行设计供应商主数据在墙内外的共享方式(见[核心 04 §5](../design/04-security-and-portal.md#5-多法人与多工厂))。 + +## 补充说明(2026-10-23) + +- 订单、对账、发票不再进核心([ADR-0008](./0008-order-to-pay-stays-in-erp.md)),法人 + 维度现阶段只出现在合同的 `legal_entity` 和工厂的 `plant` 上;对象设计保留这两个字段, + 多组织、多币种作为客户驱动的主题(出海中国企业、外企在华)在 v0.7 之后立项。 diff --git a/docs/adr/0007-china-first-with-overseas-seams.md b/docs/adr/0007-china-first-with-overseas-seams.md index 134588e..4c1a3eb 100644 --- a/docs/adr/0007-china-first-with-overseas-seams.md +++ b/docs/adr/0007-china-first-with-overseas-seams.md @@ -72,3 +72,13 @@ - **空值与唯一约束**:`credit_code` 字段唯一,以及 `country` + `registration_no` 组合唯一时, 多条空值在各数据库上的表现不同(PostgreSQL 允许多个空值,SQL Server 的唯一约束只允许 一个空值)。实现前以平台实测为准,必要时改为只对非空值生效的约束。 + - 结果(2026-10-23):平台提供空值安全的租户内唯一索引(objectstack ADR-0120, + `nullSafeColumns`);v0.1 实现分支(PR #5)两条境外供应商 `credit_code` 均为空且 + 测试通过(内存库)。PostgreSQL / SQL Server 上的表现在 v0.1 上生产前实测(07 §6 V8)。 + +## 补充说明(2026-10-23) + +- 中国特有字段在对象里单独分组(供应商的「工商与税务」:统一社会信用代码、纳税人 + 类型等),证书类型里的中国资质(生产许可、3C)保留在共享选项列表。出现第一家全球 + 客户时,可按边界评估 §8 的清单拆成中国本地化包([ADR-0009](./0009-core-first-pack-criteria-and-customer-layer.md) 第 6 条)。 +- 核心的源语言(中文源英文译,还是英文源中文译)在 v0.3 前单独决定(计划 D4)。 diff --git a/docs/adr/0008-order-to-pay-stays-in-erp.md b/docs/adr/0008-order-to-pay-stays-in-erp.md new file mode 100644 index 0000000..9c682fa --- /dev/null +++ b/docs/adr/0008-order-to-pay-stays-in-erp.md @@ -0,0 +1,69 @@ +# ADR-0008:订单到付款不进核心,ERP 集成延后 + +- 状态:已采纳 +- 日期:2026-10-23 + +## 背景 + +- 目标客户是已经有 ERP 的大中型企业,更换 ERP 的可能性很低;没有 ERP 采购模块的 + 只有小企业,不是目标客户(2026-10-23 确认)。 +- 原设计把采购订单、送货单、收货、来料检验、对账单、发票、付款回写都放在核心 + ([02 §2](../design/02-domain-model.md#2-对象总览) 原 35 个对象,[06](../design/06-integration-and-ai.md) + I1–I15 数据流)。这些数据的记账系统都是 ERP:订单改变承诺与预算,收货改变库存 + 资产,发票和付款生成凭证。SRM 再做一遍就是第二套账,而且在 ERP 集成落地之前 + 手工维护的订单状态和付款状态会和 ERP 不一致,引来供应商投诉。 +- 完整的功能边界评估按「记录系统、财务过账、平台匹配、法规与外部接口、使用者」 + 五条标准逐项打分(外部文档「hotsrm 采购与 ERP 功能边界评估」,2026-10-23), + 结论:34 项功能中核心 14 项、扩展包 1 项(国企合规)、门户镜像 4 项、剥离 15 项。 +- 曾考虑把订单、收货、对账、发票、付款做成一个可选的「采购执行」扩展包,因为它只对 + 没有 ERP 采购模块的小企业有用而放弃。 +- 平台本身支持事务型钩子(嵌套写入加入同一事务),所以这不是「做不了」的问题,而是 + 「不该由 SRM 负责」的问题。 + +## 决定 + +**SRM 记「结论」,不记「过程」;订单到付款的过程留在 ERP。** + +1. **不进核心的对象**:采购订单与订单行、送货单与送货明细、收货记录、来料检验、 + 对账单与对账明细、发票、采购申请、货源清单与配额。它们从核心对象清单中移除, + 对应的流程(P5、P6、P8)、业务规则(BR-12、BR-14、BR-16、BR-17)和集成数据流 + (I7–I15)标为「ERP 集成后」或「不做」。 +2. **用交付记录替代收货和检验**:核心增加 `srm_delivery_record`(交付记录),字段只 + 取算绩效需要的:供应商、物料、订单号(文本)、应到日、实到日、订单数量、实收 + 数量、检验结论、不合格数。每月从 ERP 导出表格导入,没有质量系统的客户由质检员 + 直接录入。它只为算分,不做业务;不合格的交付记录可以开整改单。 +3. **物料只保留只读副本**:`srm_material` 由表格按编码导入,SRM 内只维护与品类的 + 关联,其他字段只读。 +4. **预留集成点,现阶段不实现**:供应商、银行账户、价格记录、合同上保留 + `erp_*` 外部单号字段,空着;[06](../design/06-integration-and-ai.md) 改为「预留 + 集成点」清单。ERP 连接器(用友、金蝶、SAP)在客户明确型号时立项。 +5. **门户镜像只在 ERP 集成落地后建**:订单确认与交期回复、送货通知、付款进度、 + VMI 这四项的记录系统是 ERP,但使用者是供应商。它们的对象定义将来放在核心,字段 + 对内部岗位只读、只有集成账号能写,供应商的动作写在镜像自己的字段里。没有集成 + 时门户不显示这些入口。 +6. **剥离项只留一个字段或一个集成点**:电子签章留签章单号与已签文件;付款留付款 + 状态、付款日、凭证号三个字段(随门户镜像一起建);工商与信用数据留风险事件; + 依法必须招标的项目留寻源单类型「外部招标」和中标结果。 + +核心对象因此从 35 个收到 27 个,清单见 [02 §2](../design/02-domain-model.md#2-对象总览)。 + +## 考虑过的方案 + +| 方案 | 为什么没选 | +|---|---| +| 维持原设计:订单到付款全部进核心,靠 ERP 集成同步 | 每个客户上线都先要 ERP 接口改造,交付周期和风险都被 ERP 排期绑住;集成之前手工维护的订单和付款状态不可信 | +| 做成可选的「采购执行」扩展包 | 只对没有 ERP 采购模块的小企业有用,不是目标客户;核心仍要为它预留对象和选项,白白增加复杂度 | +| 只做轻量的「订单登记」给供应商确认 | 订单数据的主人是 ERP,SRM 手工登记一份就是第二套账,交期回复也回不到 ERP | + +## 后果 + +- 开发路线改为「内部核心(生命周期、合同、质量、绩效、风险)→ 门户 → 寻源」, + 见 [07 §1](../design/07-delivery-plan.md#1-分期路线图);ERP 集成和门户镜像是 + v0.7 之后由客户驱动的主题。 +- 交付准时率、批次合格率、PPM 从交付记录计算,口径不变([05 §4](../design/05-experience-and-analytics.md#4-仪表盘与指标口径)); + 订单响应及时率、对账周期两个指标在 ERP 集成前没有数据。 +- 需求 01 的目标 G6、G9,功能 M5、M8,门户待办中的订单与对账,都标为「ERP 集成后」。 +- 大宗物料包和危化品包依赖订单与收货,排在 ERP 集成之后;国企采购合规包只依赖 + 寻源与合同,可以最先做([ADR-0009](./0009-core-first-pack-criteria-and-customer-layer.md))。 +- `srm_integration` 权限集、I1–I15 数据流、与主流 ERP 的字段对照保留在文档里作为 + 预留,立项时直接沿用。 diff --git a/docs/adr/0009-core-first-pack-criteria-and-customer-layer.md b/docs/adr/0009-core-first-pack-criteria-and-customer-layer.md new file mode 100644 index 0000000..c580ade --- /dev/null +++ b/docs/adr/0009-core-first-pack-criteria-and-customer-layer.md @@ -0,0 +1,67 @@ +# ADR-0009:先做核心包;扩展包的准入标准与接入规则;客户个性化放客户层 + +- 状态:已采纳;收窄 [ADR-0002](./0002-packs-composed-into-one-app.md) 的扩展包接入规则 +- 日期:2026-10-23 + +## 背景 + +- 三个行业扩展包(大宗物料、危化品、国企采购合规)已有设计,但还没有任何一个客户 + 要求它们。按包开发意味着从第一天起维护「只有核心」「核心 + 单包」「核心 + 全部」 + 的组合构建和测试,而这些组合没有客户验证。 +- 平台是元数据驱动的,AI 能完整读懂整个应用,把一组对象从核心拆成一个包、或把客户 + 需求生成为私有包,都是几天的工作。「先按包设计、再按包维护」在 AI 时代不再是省 + 力的做法;真正要守住的是核心的稳定性。 +- 真实客户落地时会要求改字段:标签、必填、选项、新增字段、隐藏字段。平台的 + 租户 Studio 覆盖层能表达这些(objectstack ADR-0029 D9、ADR-0126「标准软件包 + + Studio 定制」),扩展能加字段、索引、校验,但不能删除核心字段;覆盖层与包的 + 删除冲突平台目前不检测(objectstack ADR-0005)。 +- `objectExtensions` 给核心对象加字段后,Studio 里该对象的设计会分成「核心 + + 扩展」两层,字段不能自由重排;扩展字段过多时客户在 Studio 里难以设计。 +- 2026-10-23 与田騏讨论后确认:现阶段只做基础的核心包。 + +## 决定 + +1. **先做核心包,v0.7 前不做任何扩展包**。三个扩展包的设计文档保留,状态标为 + 「设计保留,未排期」,等客户出现时再决定做包还是进核心。 +2. **扩展包的准入标准**(满足任一才立项为包): + - 受法规约束,有明确的合规要求(如国企采购合规); + - 三家以上客户复用同一套做法; + - 需要保护专门的测试资产(如封标测试、安全事件流程)。 + 只是一家客户的做法,不做包,放客户层。 +3. **扩展包的接入规则**(在 ADR-0002 三种方式的基础上收窄): + - 包主要新增**自己的对象**(`srm_<前缀>_*`),用 `lookup` 关联核心对象; + - 对核心对象的 `objectExtensions` 每个包不超过 2–3 个字段,只放关联键和开关, + 业务字段放包自己的对象; + - **暂不做桥接模块**:两个包之间的联动等两个包都有客户时再设计; + - 组合构建测试在第二个包出现时才加入 CI,在此之前按单个应用开发。 +4. **客户个性化放客户层**,不改核心和包的源码。客户层包括:参数取值 + (`params`)、体系文件实例、Studio 覆盖层(标签、必填、选项、新增字段、隐藏 + 字段、视图、流程)、AI 生成的客户私有包(客户自己的对象和流程)。规则: + - 核心字段只能隐藏,不能删除; + - 不改核心对象和字段的 API 名、字段类型; + - 客户要求暴露核心设计错误时,改核心并对所有客户升级,不在客户层打补丁; + - 核心升级前跑一次「核心 + 客户层」组合构建,补平台尚未检测的覆盖层冲突。 +5. **核心 API 名冻结**:对象名、字段名、字段类型一旦合入主干就不再改;改必须附 + ADR。v0.7 结束时核心 27 个对象整体冻结(门槛 2),此后改动还要附迁移说明。 +6. **中国特有的做法仍直接进核心**(维持 [ADR-0007](./0007-china-first-with-overseas-seams.md)), + 但在对象里单独分组(如供应商的「工商与税务」分组:统一社会信用代码、纳税人 + 类型等),将来出现第一家全球客户时可以按边界评估 §8 的清单拆成中国本地化包。 + +## 考虑过的方案 + +| 方案 | 为什么没选 | +|---|---| +| 维持原计划:核心与三个包并行开发,每种组合都进 CI | 没有客户验证的组合,测试和文档成本先付出;核心会为包预留大量选项列表和分组 | +| 只做基础模板,每个客户完全个性化,不做任何包 | 受法规约束、多家复用的做法(国企合规)会在每个客户那里各写一遍,无法升级 | +| 大量使用 `objectExtensions` 把包的字段挂到核心对象上 | 核心对象在 Studio 里变成多层,客户难以设计;扩展字段也不能被客户删除 | + +## 后果 + +- [ADR-0002](./0002-packs-composed-into-one-app.md) 的构建时组合机制、「只加不减」 + 和三种接入方式仍然有效;桥接模块、组合测试矩阵推迟到第二个包出现。 +- [AGENTS.md](../../AGENTS.md) 红线 4 按本记录收窄,并增加「核心 API 名冻结」。 +- [docs/packs/](../packs/README.md) 标注「设计保留,未排期」,并写明包之间的依赖 + 顺序(大宗、危化依赖 ERP 集成;国企包可以最先做)。 +- 实施手册(`docs/implementation/`,待建)要写明客户层的四种定制方式和边界。 +- 源语言(中文源英文译,还是英文源中文译)在 v0.3 前单独决定(计划 D4),不影响 + 本记录。 diff --git a/docs/adr/README.md b/docs/adr/README.md index 62dce83..3bfa6ad 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -7,12 +7,14 @@ | 编号 | 决定 | 状态 | |---|---|---| | [0001](./0001-declarative-only.md) | 只用元数据实现,不依赖应用代码 | 已采纳 | -| [0002](./0002-packs-composed-into-one-app.md) | 扩展包在构建时与核心合成一个应用 | 已采纳 | +| [0002](./0002-packs-composed-into-one-app.md) | 扩展包在构建时与核心合成一个应用 | 已采纳(接入规则由 0009 收窄) | | [0003](./0003-portal-isolation-by-supplier-position.md) | 门户按「每家供应商一个岗位」隔离 | 已采纳 | | [0004](./0004-sealed-bid.md) | 封标:开标前内部读不到报价,截止后供应商改不了报价 | 已采纳 | | [0005](./0005-governance-and-system-share-parameters.md) | 体系文件与系统共用一份参数,源文件用 Markdown | 已采纳 | | [0006](./0006-single-org-with-business-units.md) | 多法人默认用单组织加业务单元树,不开墙 | 已采纳 | | [0007](./0007-china-first-with-overseas-seams.md) | 中国优先,为出海留三个口子(币种、中英双语、供应商标识按国家区分) | 已采纳 | +| [0008](./0008-order-to-pay-stays-in-erp.md) | 订单到付款不进核心,ERP 集成延后;核心收到 27 个对象 | 已采纳 | +| [0009](./0009-core-first-pack-criteria-and-customer-layer.md) | 先做核心包;扩展包的准入标准与接入规则;客户个性化放客户层;核心 API 名冻结 | 已采纳,收窄 0002 | ## 写法 @@ -23,4 +25,6 @@ - **决定**:一句话说清楚,再展开要点; - **考虑过的方案**:每个方案的代价,为什么没选; - **后果**:这个决定让哪些事变容易、哪些事变难,以及需要遵守的规则; -- **待验证**(如有):做决定时还没验证、实现前必须确认的事。 +- **待验证**(如有):做决定时还没验证、实现前必须确认的事。有了结论后在该条下追加 + 「结果(日期)」一行,不改写「决定」部分。 +- **补充说明**(如有):决定之后新了解到的事实或口径澄清,不改变决定本身。 diff --git a/docs/design/01-requirements.md b/docs/design/01-requirements.md index 53674ad..912e54a 100644 --- a/docs/design/01-requirements.md +++ b/docs/design/01-requirements.md @@ -21,7 +21,7 @@ ## 2. 建设目标与度量指标 每个目标都对应一个可以从系统数据直接算出来的指标,上线后按月复盘。基线值在 -第 0 期调研时实测填写。 +v0.2 存量数据导入时实测填写。 | 目标 | 指标(口径) | 一年目标值 | 对应痛点 | |---|---|---|---| @@ -30,10 +30,10 @@ | G3 准入提速 | 准入申请从提交到批准的中位用时 | ≤ 10 个工作日 | T3 | | G4 寻源线上化 | 线上询价定标金额 ÷ 新增定价总金额 | ≥ 90% | T4 | | G5 寻源降本 | 寻源节约额 =(预算价或上次价格 − 定标价)× 数量 | 按年度目标 | T4 | -| G6 订单协同 | PO 下发后 24 小时内被供应商确认的比例 | ≥ 95% | T5 | -| G7 交付可见 | 交付准时率(OTD)按月自动出数 | 100% 覆盖 | T5、T8 | +| G6 订单协同 | PO 下发后 24 小时内被供应商确认的比例(ERP 集成后,[ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md)) | ≥ 95% | T5 | +| G7 交付可见 | 交付准时率(OTD)按月出数(由导入的交付记录计算) | 100% 覆盖 | T5、T8 | | G8 质量闭环 | SCAR 按期关闭率 | ≥ 90% | T6 | -| G9 结算提速 | 对账单从生成到双方确认的中位用时 | 缩短 50% | T7 | +| G9 结算提速 | 对账单从生成到双方确认的中位用时(ERP 集成后) | 缩短 50% | T7 | | G10 绩效客观 | 季度绩效中由系统数据自动计算的分值占比 | ≥ 60% | T8 | ## 3. 干系人与角色 @@ -46,9 +46,9 @@ | 品类经理 / 寻源工程师 | 负责某几个品类的寻源、供应商开发与准入 | 发起准入和询价,评标,提出定标建议 | | 采购员 / 计划员 | 订单跟进、交期催办、日常沟通 | 跟进 PO 确认,处理交期异常,发起对账 | | SQE(供应商质量工程师) | 准入审核、质量整改、质量绩效 | 资质审核、现场审核、SCAR 跟进与验证 | -| IQC 检验员 | 来料检验 | 录入或同步检验结果,判定不合格 | -| 仓库收货员 | 收货 | 按 ASN 收货(一般在 ERP / WMS 中完成,结果同步到 SRM) | -| 应付会计 | 对账、发票校验、付款跟踪 | 确认对账单,校验发票,复核银行账户变更 | +| IQC 检验员 | 来料检验(在 ERP / QMS 中执行) | 按月导入检验结论到交付记录,或逐条录入 | +| 仓库收货员 | 收货(在 ERP / WMS 中执行) | 不使用 SRM;收货结果随交付记录导入 | +| 应付会计 | 银行账户复核;对账与付款在 ERP | 复核银行账户变更(对账单确认、发票校验待 ERP 集成) | | 需求部门申请人 | 提出非生产性采购需求 | 提交采购申请,参与技术评分 | | 内控 / 审计 | 合规检查 | 只读查看审批历史、价格和寻源记录 | | 系统管理员 | 配置和用户管理 | 维护品类、编码规则、权限,邀请供应商账号 | @@ -92,20 +92,22 @@ flowchart LR ### 4.2 范围内(按模块) -| 模块 | 编号 | 内容 | 期次 | +版本号见 [07 §1](./07-delivery-plan.md#1-分期路线图);「ERP 集成后」的模块现阶段不做([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md))。 + +| 模块 | 编号 | 内容 | 版本 | |---|---|---|---| -| 供应商主数据 | M1 | 基本信息、联系人、银行账户、资质证书、供货范围(品类) | 一期 | -| 供应商生命周期 | M2 | 注册、准入(资料 / 现场审核 / 样品)、合格名录、信息变更、冻结 / 淘汰 / 黑名单 | 一期(变更与处置在二期) | -| 寻源管理 | M3 | 询价单、邀请、报价、封标开标、比价评标、定标审批、价格库 | 一期(竞价、招标、配额在五期) | -| 合同与协议 | M4 | 框架协议、价格协议、质量协议、廉洁协议;审批、签署、到期提醒 | 二期 | -| 订单协同 | M5 | PO 下发、供应商确认 / 交期答复、变更重确认、送货单、收货回传 | 二期 | -| 质量协同 | M6 | 检验结果、不合格品、SCAR / 8D 整改、索赔 | 三期 | -| 绩效管理 | M7 | 指标库、季度考评、自动算分 + 人工评分、分级、结果应用 | 三期 | -| 对账结算 | M8 | 对账单生成与确认、发票登记与匹配、付款状态 | 四期 | -| 风险与合规 | M9 | 资质到期、工商风险监控、风险事件、黑名单 | 一期(资质),四期(外部风险) | -| 供应商门户 | M10 | 以上各模块的供应商侧功能 | 随各模块同期上线 | -| 分析与看板 | M11 | 支出、寻源节约、OTD、质量、绩效、风险看板 | 随各模块同期上线 | -| 集成与管理 | M12 | ERP 集成、通知模板、编码规则、审计 | 一期起 | +| 供应商主数据 | M1 | 基本信息、联系人、资质证书、供货范围(品类);银行账户、物料只读副本、存量导入 | v0.1(银行账户、物料、导入在 v0.2) | +| 供应商生命周期 | M2 | 内部登记与准入(资料 / 现场审核 / 样品)、合格名录、信息变更、冻结 / 淘汰 / 黑名单 | v0.1(变更 v0.2,处置 v0.3) | +| 寻源管理 | M3 | 询价单、邀请、报价、封标开标、比价评标、定标审批、价格库 | v0.7(竞价、招标增强、配额为客户驱动主题) | +| 合同与协议 | M4 | 框架协议、价格协议、质量协议、廉洁协议;审批、签署、到期提醒 | v0.3 | +| 订单协同 | M5 | PO 下发、供应商确认 / 交期答复、变更重确认、送货单、收货回传 | ERP 集成后(门户镜像) | +| 质量协同 | M6 | 交付记录导入(含检验结论)、SCAR / 8D 整改、索赔金额登记、供应商审核 | v0.4 | +| 绩效管理 | M7 | 指标库、按物资类别周期考评、自动算分 + 人工评分、分级、结果应用 | v0.5 | +| 对账结算 | M8 | 对账单生成与确认、发票登记与匹配、付款状态 | 不做,留在 ERP;付款进度在 ERP 集成后作为门户镜像 | +| 风险与合规 | M9 | 资质到期、风险事件(手工登记)、黑名单;工商数据接口 | v0.1(资质)、v0.5(风险事件);外部数据为客户驱动主题 | +| 供应商门户 | M10 | 以上各模块的供应商侧功能 | v0.6(依赖 objectstack#25233) | +| 分析与看板 | M11 | 寻源节约、OTD、质量、绩效、风险看板 | 随各模块同版本 | +| 集成与管理 | M12 | 通知模板、编码规则、审计;ERP 集成 | v0.1 起;ERP 集成为客户驱动主题 | ### 4.3 范围外(明确不做) @@ -116,7 +118,9 @@ flowchart LR | 依法必须招标项目的电子招投标 | 需要符合《电子招标投标办法》的专业平台,必要时只做集成 | | 电子签章本身 | 集成第三方电子签服务,SRM 只发起签署并保存结果 | | 发票真伪查验本身 | 集成税务查验服务商,SRM 只保存查验结果 | -| 采购计划与 MRP 运算 | ERP / APS 负责;SRM 接收它们产生的 PO 与需求 | +| 采购计划与 MRP 运算 | ERP / APS 负责 | +| 采购订单、收货入库、对账、发票、付款(ADR-0008) | ERP 是记账系统;SRM 只记结论:交付记录(导入)、SCAR 上的索赔金额;订单确认、送货通知、付款进度在 ERP 集成后作为门户镜像 | +| 采购申请、货源清单与配额 | 生产性需求在 ERP / MRP;非生产性申请多在 OA,客户明确要求时再评估 | ## 5. 功能需求 @@ -139,16 +143,17 @@ flowchart LR | 编号 | 用户故事 | 验收标准 | 优先级 | |---|---|---|---| -| FR-201 | 作为潜在供应商,我要不登录就能在线提交注册申请 | 公开注册表单可匿名提交;提交后生成「已提交」的准入申请,申请人收到受理通知 | P0 | -| FR-202 | 作为品类经理,我要邀请指定供应商注册 | 填写公司名和联系人邮箱即可发出邀请;该申请来源记为「邀请」 | P1 | +| FR-200 | 作为品类经理,我要在门户上线前自己登记潜在供应商并发起准入 | 内部新建准入申请,来源记为「内部登记」;跳过门户补资料,初审人默认为创建人所在品类的品类经理 | P0(v0.1) | +| FR-201 | 作为潜在供应商,我要不登录就能在线提交注册申请 | 公开注册表单可匿名提交;提交后生成「已提交」的准入申请,申请人收到受理通知。多组织托管云上公开表单落入部署默认组织(objectstack ADR-0138 D4),待 07 §6 V1 实测与 objectstack#25447 后启用 | P2(待平台) | +| FR-202 | 作为品类经理,我要邀请指定供应商注册 | 填写公司名和联系人邮箱即可发出邀请;供应商以受邀成员身份进门户后填申请,来源记为「邀请」。v0.6 的默认注册方式 | P0(v0.6) | | FR-203 | 作为采购初审人,我要在受理时自动看到重复和黑名单检查结果 | 身份标识命中已有供应商或黑名单时,申请页醒目提示并禁止进入下一步 | P0 | | FR-204 | 作为 SQE,我要按品类风险等级决定是否需要现场审核和样品验证 | 高风险品类的申请必须有通过(或有条件通过)的现场审核记录才能提交准入评审 | P0 | | FR-205 | 作为准入评审人,我要在一个审批里看到资料、审核报告和样品结论 | 审批页展示申请摘要、证书清单、审核得分;批准后供应商状态变为「合格」,对应品类资格变为「合格」或「试供」 | P0 | | FR-206 | 作为采购员,我要查到某品类的合格供应商名录 | 名录视图按品类筛选,只列资格为「合格」且供应商状态为「合格」的记录 | P0 | -| FR-207 | 作为供应商,我要提交关键信息变更(名称、地址、银行账户) | 变更单记录变更前后值,审批通过后自动写回供应商档案;银行账户变更需采购与财务双人审批 | P1(二期) | -| FR-208 | 作为品类经理,我要冻结、解冻、淘汰供应商或拉入黑名单 | 处置单需写明原因并经审批;冻结后不能被邀请询价;淘汰后不能直接恢复,只能重新走准入;黑名单不能重新准入,解除黑名单需单独审批 | P1(二期) | +| FR-207 | 作为供应商,我要提交关键信息变更(名称、地址、银行账户) | 变更单记录变更前后值,审批通过后自动写回供应商档案;银行账户变更需采购与财务双人审批。门户上线前由采购员代供应商发起 | P1(v0.2) | +| FR-208 | 作为品类经理,我要冻结、解冻、淘汰供应商或拉入黑名单 | 处置单需写明原因并经审批;冻结后不能被邀请询价;淘汰后不能直接恢复,只能重新走准入(受理时命中淘汰供应商不视为重复,见 03 §3);黑名单不能重新准入,解除黑名单需单独审批 | P1(v0.3) | -### 5.3 M3 寻源管理 +### 5.3 M3 寻源管理(v0.7) | 编号 | 用户故事 | 验收标准 | 优先级 | |---|---|---|---| @@ -162,19 +167,21 @@ flowchart LR | FR-308 | 作为采购总监,我要按金额分级审批定标结果 | 审批人按金额档自动确定;有效报价少于 3 家时必须填写原因,并升级一级审批 | P0 | | FR-309 | 作为系统,我要在定标后自动生成价格记录并通知结果 | 每个中标明细生成一条价格记录(生效日、失效日、来源询价单);中标与未中标的供应商分别收到通知 | P0 | | FR-310 | 作为采购员,我要查询某物料当前有效的协议价格 | 价格库按物料、供应商、有效期查询;同一供应商 × 物料 × 工厂的有效期不重叠 | P0 | -| FR-311 | 作为寻源工程师,我要用反向竞价拿到更低的价格 | 竞价期内供应商只看到自己的排名(不看到他人价格);每次出价必须低于自己上一次出价 | P2(五期) | +| FR-311 | 作为寻源工程师,我要用反向竞价拿到更低的价格 | 竞价期内供应商只看到自己的排名(不看到他人价格);每次出价必须低于自己上一次出价 | P2(客户驱动) | -### 5.4 M4 合同与协议 +### 5.4 M4 合同与协议(v0.3) | 编号 | 用户故事 | 验收标准 | 优先级 | |---|---|---|---| | FR-401 | 作为品类经理,我要从定标结果生成合同草稿 | 合同自动带出供应商、金额、来源询价单 | P1 | | FR-402 | 作为法务和采购总监,我要审批合同 | 金额与合同类型决定审批路径;审批中合同只读 | P0 | -| FR-403 | 作为采购员,我要上传双方签署的合同或发起电子签 | 签署完成后状态为「生效」并保存签署文件 | P0 | +| FR-403 | 作为采购员,我要上传双方签署的合同或发起电子签 | 上传盖章扫描件后状态为「生效」并保存签署文件;电子签只预留签章单号字段,接入为客户驱动主题 | P0 | | FR-404 | 作为品类经理,我要在合同到期前收到提醒 | 到期前 60 / 30 / 7 天各提醒一次;到期后自动变为「已到期」 | P0 | | FR-405 | 作为 SQE,我要确认每家合格供应商都签了质量协议和廉洁协议 | 供应商详情显示协议签署状态;缺失时在名录中标记 | P1 | -### 5.5 M5 订单协同 +### 5.5 M5 订单协同(ERP 集成后的门户镜像,现阶段不做) + +以下需求的记录系统是 ERP,只在 ERP 集成落地后作为门户镜像实现([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md) 第 5 条);保留在此作为集成立项时的需求基线。 | 编号 | 用户故事 | 验收标准 | 优先级 | |---|---|---|---| @@ -186,29 +193,33 @@ flowchart LR | FR-506 | 作为供应商,我要按未交数量创建送货单并打印送货标签 | 送货数量不超过订单行的未交数量;送货单带二维码 | P1 | | FR-507 | 作为采购员,我要看到收货结果并据此计算准时交付 | ERP / WMS 收货结果同步后,订单行自动累计已收数量并判定是否准时 | P0 | -### 5.6 M6 质量协同 +### 5.6 M6 质量协同(v0.4) | 编号 | 用户故事 | 验收标准 | 优先级 | |---|---|---|---| -| FR-601 | 作为系统,我要接收来料检验结果 | 检验结果从 QMS / ERP 同步或由 IQC 手工录入;记录批量、抽样数、不良数、判定 | P0 | -| FR-602 | 作为 SQE,我要在检验不合格后自动得到一张整改单 | 判定为不合格且严重度为「严重」或「主要」时自动生成 SCAR,指派给该品类 SQE | P0 | +| FR-601 | 作为 SQE,我要把每月的交付与检验结果落到供应商头上 | 交付记录按月从 ERP 导出表格导入(按订单号 + 行号幂等),没有质量系统时由质检员逐条录入;记录应到 / 实到日期、订单 / 实收数量、检验结论、不合格数 | P0 | +| FR-602 | 作为 SQE,我要在交付记录判定不合格后得到一张整改单 | 检验结论为不合格且严重度为「严重」或「主要」时自动生成 SCAR,指派给该品类 SQE;门户上线前由 SQE 代供应商填写回复 | P0 | | FR-603 | 作为供应商质量,我要在门户里按 8D 节奏回复整改 | 72 小时内提交临时围堵措施(D3);30 天内提交根因与永久措施(D4–D7);可上传证据 | P0 | | FR-604 | 作为 SQE,我要审核供应商的回复,必要时退回 | 审核可通过或退回;退回时必须填写意见,单据回到供应商待办 | P0 | | FR-605 | 作为 SQE,我要在整改逾期时自动升级 | 超期未回复时提醒供应商并抄送 SQE 主管;整改单标记「逾期」 | P1 | -| FR-606 | 作为 SQE,我要登记质量索赔并让供应商确认 | 索赔金额经供应商确认后进入当期对账单的扣款行 | P1 | +| FR-606 | 作为 SQE,我要登记质量索赔并让供应商确认 | 索赔金额与结论记录在整改单上,供财务在 ERP 扣款时参考;SRM 不生成扣款 | P1 | +| FR-607 | 作为 SQE,我要安排和记录供应商现场审核 | 审核记录有计划、检查表、问题项与结论;问题项可转为整改单 | P0 | -### 5.7 M7 绩效管理 +### 5.7 M7 绩效管理(v0.5) | 编号 | 用户故事 | 验收标准 | 优先级 | |---|---|---|---| | FR-701 | 作为采购总监,我要维护绩效指标库和权重 | 指标属于 QCDS 某一维度,标明自动或人工;同一考评方案内权重合计 100% | P0 | -| FR-702 | 作为系统,我要每季度自动为活跃供应商生成考评单并计算自动指标 | 季度首日生成上季度考评单;OTD、批次合格率、PPM、订单响应及时率自动计算 | P0 | +| FR-702 | 作为系统,我要按物资类别的周期自动为活跃供应商生成考评单并计算自动指标 | 周期按供应商所供最高物资类别取参数 `perf_cycle`(示例 A 类每月、B 类每季、C 类每年);期初生成上期考评单;OTD、批次合格率、PPM 由交付记录计算(订单响应及时率待 ERP 集成) | P0 | | FR-703 | 作为 SQE 和采购员,我要为人工指标打分 | 评分人只看到分配给自己的评分项;评分截止后未评项按规则处理(默认取 60 分并标记「未评」,可配置) | P0 | | FR-704 | 作为采购总监,我要审定考评结果并发布 | 总分与等级自动算出;发布后供应商可在门户查看本公司结果与扣分项 | P0 | | FR-705 | 作为品类经理,我要让绩效结果驱动后续动作 | C 级自动生成改善要求;连续两期 D 级自动发起淘汰评审 | P1 | | FR-706 | 作为供应商,我要对考评结果提出申诉 | 发布后 7 天内可申诉一次;申诉由采购总监处理,结果留痕 | P2 | -### 5.8 M8 对账结算 +### 5.8 M8 对账结算(不做,留在 ERP) + +对账、发票、付款的记录系统是 ERP([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md))。以下需求不实现; +供应商侧的付款进度查询在 ERP 集成后作为门户镜像另行设计。保留在此作为剥离项的记录。 | 编号 | 用户故事 | 验收标准 | 优先级 | |---|---|---|---| @@ -224,7 +235,7 @@ flowchart LR |---|---|---|---| | FR-901 | 作为 SQE,我要在资质到期前收到提醒 | 到期前 30 / 15 / 7 天提醒 SQE 和供应商;到期当天证书变为「已过期」 | P0 | | FR-902 | 作为系统,我要阻止关键资质过期的供应商参与新业务 | 必备资质过期时供应商被标记「资质异常」,不能被邀请询价,现有订单不受影响 | P0 | -| FR-903 | 作为风控,我要定期获取供应商的工商与司法风险 | 每周调用外部企业信息服务;新出现的经营异常、失信、重大诉讼生成风险事件 | P2(四期) | +| FR-903 | 作为风控,我要登记并处理供应商的工商与司法风险 | 风险事件可手工登记(类型、来源、处理结论),高风险生成处置单草稿;外部企业信息服务的自动拉取为客户驱动主题 | P1(v0.5) | | FR-904 | 作为内控,我要求供应商申报与我司员工的关联关系 | 注册与年审时填写关联申报;存在关联的供应商在寻源时提示评标人回避 | P1 | ### 5.10 M10 供应商门户(汇总) @@ -233,12 +244,11 @@ flowchart LR | 待办 | 来源 | |---|---| -| 待响应的询价、即将截止的报价 | M3 | -| 待确认的订单、变更待确认的订单 | M5 | -| 待回复 / 被退回的整改单 | M6 | -| 待确认的对账单、待上传的发票 | M8 | -| 即将到期的资质证书 | M9 | -| 最新一期绩效结果 | M7 | +| 待回复 / 被退回的整改单 | M6(v0.6) | +| 即将到期的资质证书、准入申请进度 | M9、M2(v0.6) | +| 最新一期绩效结果 | M7(v0.6) | +| 待响应的询价、即将截止的报价 | M3(v0.7) | +| 待确认的订单、变更待确认的订单;付款进度 | M5(ERP 集成后的门户镜像) | 门户的通用要求:手机浏览器可用;中英文界面;所有列表只含本公司数据(见 [04 §3](./04-security-and-portal.md#3-供应商门户的数据隔离))。 @@ -246,7 +256,7 @@ flowchart LR ### 5.11 M11 分析与 M12 集成 指标定义与看板见 [05 §4](./05-experience-and-analytics.md#4-仪表盘与指标口径),集成需求见 -[06 §1](./06-integration-and-ai.md#1-erp-集成)。 +[06 §1](./06-integration-and-ai.md#1-预留的-erp-集成点)。 ## 6. 关键业务规则 @@ -266,12 +276,12 @@ flowchart LR | BR-09 | 寻源发起人不得审批自己发起的定标(职责分离) | 发起岗与审批岗分离 + 审批 flow 在审批人等于发起人时改走上一级(见 [04 §6](./04-security-and-portal.md#6-职责分离sod)) | | BR-10 | 同一供应商 × 物料 × 工厂的价格有效期不得重叠 | 定标 flow 写新价格前把旧价格的失效日截断到新价格生效日前一天 | | BR-11 | 银行账户变更须采购与财务两人分别审批,生效前不推送 ERP | 变更单的两级审批,审批人不得为同一人 | -| BR-12 | PO 下发 24 小时未确认提醒供应商,48 小时升级采购主管 | 每小时的追赶式扫描 + 外部心跳(相对日期触发器按天计,精度不够) | +| BR-12 | PO 下发 24 小时未确认提醒供应商,48 小时升级采购主管(ERP 集成后) | 每小时的追赶式扫描 + 外部心跳(相对日期触发器按天计,精度不够) | | BR-13 | 答复交期晚于需求日期的订单行标记交期风险 | 订单行写入后的记录触发 flow | -| BR-14 | 送货数量不得超过订单行「未交数量 − 已发未收数量」 | 「创建送货单」screen flow 内校验(门户无直接创建送货明细的权限) | -| BR-15 | 严重 / 主要不合格自动生成 SCAR | 检验结果的记录触发 flow | -| BR-16 | 对账单经供应商确认后锁定,只能通过差异流程修改 | 状态机校验 + 确认后的写权限收回 | -| BR-17 | 发票金额与对账单差异超过容差不得提交 | 「提交发票」screen flow 内校验 | +| BR-14 | 送货数量不得超过订单行「未交数量 − 已发未收数量」(ERP 集成后) | 「创建送货单」screen flow 内校验(门户无直接创建送货明细的权限) | +| BR-15 | 严重 / 主要不合格自动生成 SCAR | 交付记录写入后的记录触发 flow | +| BR-16 | 对账单经供应商确认后锁定,只能通过差异流程修改(不做,留在 ERP) | — | +| BR-17 | 发票金额与对账单差异超过容差不得提交(不做,留在 ERP) | — | | BR-18 | 连续两期 D 级自动发起淘汰评审 | 考评发布后的记录触发 flow | | BR-19 | 供应商只能看到本公司数据 | 每家供应商一个门户岗位 + 门户 RLS | | BR-20 | 银行账号等敏感字段仅对应付会计和采购管理员可见 | 字段级权限(FLS) | @@ -287,8 +297,9 @@ flowchart LR | 性能 | 常用列表(≤ 10 万行)首屏 ≤ 2 秒;比价视图(≤ 20 家 × 200 行)≤ 3 秒 | 压测脚本 | | 并发 | 报价截止前 30 分钟高峰,门户 200 并发用户 | 压测脚本 | | 可用性 | 门户月可用率 ≥ 99.5%;截标、开标定时任务失败可重跑且结果幂等 | 监控 + 演练 | -| 集成可靠性 | ERP 推送失败自动重试,失败记录可见可重发;重复消息不产生重复单据 | 外部编号幂等测试 | +| 导入幂等 | 物料、交付记录、存量供应商的表格导入可重复执行,结果一致;按外部编号匹配 | 样例表格在 CI 跑两遍 | +| 集成可靠性(ERP 集成后) | ERP 推送失败自动重试,失败记录可见可重发;重复消息不产生重复单据 | 外部编号幂等测试 | | 易用性 | 供应商无需培训即可完成「确认订单」「提交报价」;手机浏览器可完成 | 可用性测试(5 家供应商) | | 国际化 | 全部界面中英文([ADR-0007](../adr/0007-china-first-with-overseas-seams.md));金额支持多币种与汇率换算;境外供应商按「国家 / 地区 + 注册号」建档 | `os i18n check --strict` 无缺失词条;境外供应商注册与查重用例 | -| 可配置性 | 新增字段、调整审批阈值、增加证书类型无需改代码发版 | 由管理员在配置界面完成 | +| 可配置性 | 新增字段、调整审批阈值、增加证书类型无需改核心发版 | 参数、Studio 覆盖层或客户私有包完成([ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md));核心字段只隐藏不删除 | | 数据迁移 | 存量供应商、联系人、证书、有效价格可批量导入 | 迁移演练两轮,抽检准确率 ≥ 99% | diff --git a/docs/design/02-domain-model.md b/docs/design/02-domain-model.md index 263253e..c53ad05 100644 --- a/docs/design/02-domain-model.md +++ b/docs/design/02-domain-model.md @@ -28,84 +28,94 @@ 计算后写入 `number` / `percent` 字段,而不是做成公式字段。 7. **复选框不设必填**:`boolean` 字段一律给 `defaultValue: false`,「必须勾选」 用校验规则表达。 -8. **ERP 来源数据带外部编号**:每个从 ERP 同步的对象有唯一的 `erp_*_id` 字段, - 集成按它幂等 upsert。反过来,SRM 要推给 ERP 的对象(供应商、银行账户、处置单、价格记录、 - 采购订单〔确认交期回写〕、送货单、对账单、发票)带 `erp_sync_status` / - `erp_sync_error` / `erp_synced_at` 三个同步字段,推送失败可见,由重推扫描补发(见 - [06 §1.1](./06-integration-and-ai.md#11-原则))。 +8. **外部单号字段预留、空着**:从 ERP 导入的对象(物料、交付记录)有唯一的外部编号 + 字段(`erp_material_no`、`erp_order_no` + 行号),表格导入按它幂等匹配。SRM 将来要推给 + ERP 的对象(供应商、银行账户、价格记录、合同)保留 `erp_*` 编号字段,现阶段不写; + 同步状态三字段(`erp_sync_status` / `erp_sync_error` / `erp_synced_at`)在 ERP 集成立项时 + 再加([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md),[06 §1](./06-integration-and-ai.md#1-预留的-erp-集成点))。 9. **每个对象显式声明 OWD**(`sharingModel`),这是平台 lint 的强制项;门户相关 对象的 OWD 和 RLS 设计见 [04](./04-security-and-portal.md)。 10. **金额用 `currency`,比例用 `percent`,附件用 `file`,地址用 `address`**。 11. **面向供应商的单据冗余门户岗位**:每张供应商要看的**顶层**单据都带一个 `portal_position`(text,只读)字段,在创建时由 flow 从供应商档案复制过来, 门户 RLS 只认它(见 [04 §3](./04-security-and-portal.md#3-供应商门户的数据隔离))。 - 带这个字段的对象:准入申请、变更单、寻源邀请、报价单、价格记录、合同、采购 - 订单、送货单、收货记录、来料检验、整改单、考评单、对账单、发票。它们的 - `master_detail` 子对象(报价明细、订单行、送货明细、评分明细、对账明细)用 - `controlled_by_parent` 跟随父记录,不重复冗余。注意 `controlled_by_parent` 的 + 带这个字段的对象:准入申请、变更单、寻源邀请、报价单、价格记录、合同、整改单、 + 考评单(订单、送货单、付款进度等 ERP 集成后的门户镜像同理)。它们的 + `master_detail` 子对象(报价明细、合同明细、评分明细)用 + `controlled_by_parent` 跟随父记录,不重复冗余。字段本身在 v0.6 门户上线时再加, + 不提前。注意 `controlled_by_parent` 的 **写**同样跟随父记录:改子记录要求对父记录有编辑权。所以凡是门户要改子记录的 地方(订单行答复、证书维护),门户对父记录授予编辑权,再用字段级权限把父记录 的字段全部设为只读(见 [04 §3.2](./04-security-and-portal.md#32-各对象的门户策略))。 -12. **校验规则最多读一跳**:`script` / `cross_field` 校验规则能读本记录,也能经一个 - 引用字段读关联记录(如邀请上的 `record.supplier.status`),该读取以系统身份进行、 - 读不到时拒绝写入。两跳以上或需要汇总的判断依据,要么在创建时由 flow 冗余到本 - 记录并设为只读(如把寻源单的截止时间复制到报价单,报价明细再经一跳读取), - 要么改走以系统身份运行的 screen flow。 +12. **只有 `script` 校验规则能读一跳关联记录**:`validations[]` 的 `script` 规则能读本记录, + 也能经一个引用字段读关联记录(如邀请上的 `record.supplier.status`),该读取以系统 + 身份进行、读不到时拒绝写入。**字段谓词**(`requiredWhen`、`readonlyWhen`、选项的 + `visibleWhen`)以及 `previous.*`、`parent.*` 只能读本记录,经引用字段读关联记录会在 + `objectstack validate` 阶段被拒绝(objectstack ADR-0137 D2)。两跳以上或需要汇总的 + 判断依据,要么在创建时由 flow 冗余到本记录并设为只读(如把寻源单的截止时间复制到 + 报价单,报价明细再经一跳读取),要么改走以系统身份运行的 screen flow。 13. **为扩展包预留接口**:扩展包不修改核心,只能给核心对象加字段与校验 (`objectExtensions`)、给共享选项列表追加选项(`picklistExtensions`)、往核心 应用的导航分组里挂菜单(见[扩展包 §3.2](../packs/README.md#32-扩展包怎么接入核心))。 所以可能被扩展包追加选项的枚举,在核心里做成**共享选项列表**(picklist),不直接写在 字段上:`srm_sourcing_event.sourcing_type`、`srm_contract.contract_type`、`srm_supplier_certificate.cert_type`、 `srm_quality_issue.source`、`srm_kpi.dimension`、`srm_risk_event.risk_type`、 - `srm_statement_line.line_type`、`srm_receipt.settlement_mode`。状态字段(stageField) - 不做成可扩展的,状态机只由核心定义。 + `srm_category.material_class`、`srm_supplier.country`。状态字段(stageField) + 不做成可扩展的,状态机只由核心定义(每个选项带 `kind`,平台不允许 stageField 用共享 + 选项列表)。现阶段只做核心包([ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md)), + 预留的方式只有这一条,不为未来的包多留分组或字段。 +14. **中国特有字段单独分组**:统一社会信用代码、纳税人类型等放在供应商的「工商与税务」 + 分组;外部单号字段放「外部系统」分组。便于将来拆中国本地化包和接 ERP(ADR-0009)。 ## 2. 对象总览 -「来源」列:**SRM** 表示在 SRM 内产生;**ERP** 表示从 ERP 同步、SRM 内只读; -**门户** 表示主要由供应商在门户里填写。 +核心共 **27 个对象**([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md)),按版本交付([07 §1](./07-delivery-plan.md#1-分期路线图))。 +「来源」列:**SRM** 表示在 SRM 内产生;**导入** 表示从 ERP 导出表格按外部编号幂等导入、SRM 内只读; +**门户** 表示门户上线(v0.6)后主要由供应商在门户里填写,在此之前由内部代录。 -| # | 对象 | 中文名 | 领域 | 父对象(master_detail) | 来源 | 期次 | +| # | 对象 | 中文名 | 领域 | 父对象(master_detail) | 来源 | 版本 | |---|---|---|---|---|---|---| -| 1 | `srm_category` | 采购品类 | 基础数据 | — | SRM | 一期 | -| 2 | `srm_material` | 物料 | 基础数据 | — | ERP | 一期 | -| 3 | `srm_plant` | 工厂 / 收货地点 | 基础数据 | — | ERP | 一期 | -| 4 | `srm_supplier` | 供应商 | 供应商主数据 | — | SRM | 一期 | -| 5 | `srm_supplier_contact` | 供应商联系人 | 供应商主数据 | 供应商 | SRM / 门户 | 一期 | -| 6 | `srm_supplier_bank_account` | 银行账户 | 供应商主数据 | 供应商 | 门户 | 一期 | -| 7 | `srm_supplier_certificate` | 资质证书 | 供应商主数据 | 供应商 | 门户 | 一期 | -| 8 | `srm_supplier_category` | 供货品类资格 | 供应商主数据 | 供应商 | SRM | 一期 | -| 9 | `srm_supplier_application` | 准入申请 | 生命周期 | — | 门户(公开表单) | 一期 | -| 10 | `srm_supplier_audit` | 供应商审核 | 生命周期 | — | SRM | 一期 | -| 11 | `srm_supplier_change_request` | 信息变更单 | 生命周期 | — | 门户 | 二期 | -| 12 | `srm_supplier_disposition` | 供应商处置单(冻结 / 解冻 / 淘汰 / 黑名单) | 生命周期 | — | SRM | 二期 | -| 13 | `srm_sourcing_event` | 寻源单(询价 / 招标 / 竞价) | 寻源 | — | SRM | 一期 | -| 14 | `srm_sourcing_item` | 寻源明细 | 寻源 | 寻源单 | SRM | 一期 | -| 15 | `srm_sourcing_invitation` | 寻源邀请 | 寻源 | —(lookup 寻源单) | SRM | 一期 | -| 16 | `srm_quotation` | 报价单 | 寻源 | — | 门户 | 一期 | -| 17 | `srm_quotation_line` | 报价明细 | 寻源 | 报价单 | 门户 | 一期 | -| 18 | `srm_price_record` | 价格记录(价格库) | 寻源 | — | SRM | 一期 | -| 19 | `srm_purchase_request` | 采购申请 | 寻源 | — | SRM / ERP | 二期 | -| 20 | `srm_source_list` | 货源清单与配额 | 寻源 | — | SRM | 五期 | -| 21 | `srm_contract` | 合同 / 协议 | 合同 | — | SRM | 二期 | -| 22 | `srm_purchase_order` | 采购订单 | 订单协同 | — | ERP | 二期 | -| 23 | `srm_po_line` | 订单行 | 订单协同 | 采购订单 | ERP / 门户 | 二期 | -| 24 | `srm_asn` | 送货单 | 订单协同 | — | 门户 | 二期 | -| 25 | `srm_asn_line` | 送货明细 | 订单协同 | 送货单 | 门户 | 二期 | -| 26 | `srm_receipt` | 收货记录(行级) | 订单协同 | — | ERP | 二期 | -| 27 | `srm_inspection` | 来料检验 | 质量 | — | ERP / QMS | 三期 | -| 28 | `srm_quality_issue` | 质量整改单(SCAR) | 质量 | — | SRM / 门户 | 三期 | -| 29 | `srm_kpi` | 绩效指标 | 绩效 | — | SRM | 三期 | -| 30 | `srm_performance_review` | 绩效考评单 | 绩效 | — | SRM | 三期 | -| 31 | `srm_performance_score` | 评分明细 | 绩效 | 考评单 | SRM | 三期 | -| 32 | `srm_statement` | 对账单 | 结算 | — | SRM | 四期 | -| 33 | `srm_statement_line` | 对账明细 | 结算 | 对账单 | SRM | 四期 | -| 34 | `srm_invoice` | 发票 | 结算 | — | 门户 | 四期 | -| 35 | `srm_risk_event` | 风险事件 | 风险 | — | SRM / 外部服务 | 四期 | +| 1 | `srm_category` | 采购品类 | 基础数据 | — | SRM | v0.1 | +| 2 | `srm_plant` | 工厂 / 收货地点 | 基础数据 | — | SRM(手工维护或导入) | v0.1 | +| 3 | `srm_supplier` | 供应商 | 供应商主数据 | — | SRM | v0.1 | +| 4 | `srm_supplier_contact` | 供应商联系人 | 供应商主数据 | 供应商 | SRM / 门户 | v0.1 | +| 5 | `srm_supplier_certificate` | 资质证书 | 供应商主数据 | 供应商 | SRM / 门户 | v0.1 | +| 6 | `srm_supplier_category` | 供货品类资格 | 供应商主数据 | 供应商 | SRM | v0.1 | +| 7 | `srm_supplier_application` | 准入申请 | 生命周期 | — | SRM(内部登记)/ 门户(邀请注册) | v0.1 | +| 8 | `srm_material` | 物料(只读副本) | 基础数据 | — | 导入 | v0.2 | +| 9 | `srm_supplier_bank_account` | 银行账户 | 供应商主数据 | 供应商 | SRM / 门户 | v0.2 | +| 10 | `srm_supplier_change_request` | 信息变更单 | 生命周期 | — | SRM / 门户 | v0.2 | +| 11 | `srm_contract` | 合同 / 协议 | 合同 | — | SRM | v0.3 | +| 12 | `srm_contract_line` | 合同明细 | 合同 | 合同 | SRM | v0.3 | +| 13 | `srm_supplier_disposition` | 供应商处置单(冻结 / 解冻 / 淘汰 / 黑名单) | 生命周期 | — | SRM | v0.3 | +| 14 | `srm_delivery_record` | 交付记录(含检验结论) | 质量 | — | 导入 / 质检员录入 | v0.4 | +| 15 | `srm_quality_issue` | 质量整改单(SCAR / 8D) | 质量 | — | SRM / 门户 | v0.4 | +| 16 | `srm_supplier_audit` | 供应商审核 | 质量 | — | SRM | v0.4 | +| 17 | `srm_kpi` | 绩效指标 | 绩效 | — | SRM | v0.5 | +| 18 | `srm_performance_review` | 绩效考评单 | 绩效 | — | SRM | v0.5 | +| 19 | `srm_performance_score` | 评分明细 | 绩效 | 考评单 | SRM | v0.5 | +| 20 | `srm_risk_event` | 风险事件 | 风险 | — | SRM(手工登记) | v0.5 | +| 21 | `srm_supplier_invitation` | 门户邀请 | 门户 | — | SRM | v0.6 | +| 22 | `srm_sourcing_event` | 寻源单(询价 / 招标 / 竞价) | 寻源 | — | SRM | v0.7 | +| 23 | `srm_sourcing_item` | 寻源明细 | 寻源 | 寻源单 | SRM | v0.7 | +| 24 | `srm_sourcing_invitation` | 寻源邀请 | 寻源 | —(lookup 寻源单) | SRM | v0.7 | +| 25 | `srm_quotation` | 报价单 | 寻源 | — | 门户 | v0.7 | +| 26 | `srm_quotation_line` | 报价明细 | 寻源 | 报价单 | 门户 | v0.7 | +| 27 | `srm_price_record` | 价格记录(价格库) | 寻源 | — | SRM | v0.7 | + +**从原设计移出核心的对象**(原 35 个中的 11 个,[ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md)): + +| 对象 | 去向 | +|---|---| +| `srm_purchase_order`、`srm_po_line`、`srm_asn`、`srm_asn_line` | ERP 集成后的**门户镜像**:对象定义保留在 §4.5,现阶段不建 | +| `srm_receipt`、`srm_inspection` | 由 `srm_delivery_record` 的导入字段替代(实收数量、实到日、检验结论、不合格数) | +| `srm_statement`、`srm_statement_line`、`srm_invoice` | 留在 ERP,不做;付款进度在 ERP 集成后作为门户镜像 | +| `srm_purchase_request` | 留在 ERP / OA,客户明确要求时再评估 | +| `srm_source_list` | 客户驱动主题(寻源上线后) | **刻意没有建的对象**:审批记录、审批步骤、流程节点(平台 flow 提供);评标结果表 (定标结果直接写在报价明细的中标字段上);通知记录(平台通知提供);操作日志 -(平台字段历史与审计提供)。 +(平台字段历史与审计提供);集成日志(ERP 集成立项时再定)。 ## 3. 关系图 @@ -118,8 +128,25 @@ erDiagram srm_category ||--o{ srm_supplier_category : "" srm_category ||--o{ srm_category : "上级品类" srm_category ||--o{ srm_material : "" - srm_supplier_application }o--o| srm_supplier : "批准后关联" + srm_supplier_application }o--o| srm_supplier : "资料审核通过时关联" + srm_supplier ||--o{ srm_supplier_change_request : "变更" + srm_supplier ||--o{ srm_supplier_disposition : "处置" + srm_supplier ||--o{ srm_supplier_invitation : "门户邀请" + + srm_supplier ||--o{ srm_contract : "" + srm_contract ||--o{ srm_contract_line : "明细" + srm_material ||--o{ srm_contract_line : "" + + srm_supplier ||--o{ srm_delivery_record : "交付" + srm_material ||--o{ srm_delivery_record : "" + srm_delivery_record ||--o| srm_quality_issue : "不合格生成" srm_supplier ||--o{ srm_supplier_audit : "审核" + srm_supplier_audit ||--o{ srm_quality_issue : "问题项转整改" + + srm_supplier ||--o{ srm_performance_review : "" + srm_performance_review ||--o{ srm_performance_score : "评分" + srm_kpi ||--o{ srm_performance_score : "" + srm_supplier ||--o{ srm_risk_event : "" srm_sourcing_event ||--o{ srm_sourcing_item : "明细" srm_sourcing_event ||--o{ srm_sourcing_invitation : "邀请" @@ -130,25 +157,6 @@ erDiagram srm_sourcing_item ||--o{ srm_quotation_line : "" srm_quotation_line ||--o| srm_price_record : "中标生成" srm_material ||--o{ srm_price_record : "" - srm_supplier ||--o{ srm_contract : "" - - srm_supplier ||--o{ srm_purchase_order : "" - srm_purchase_order ||--o{ srm_po_line : "订单行" - srm_asn ||--o{ srm_asn_line : "送货明细" - srm_po_line ||--o{ srm_asn_line : "" - srm_po_line ||--o{ srm_receipt : "收货" - srm_receipt ||--o{ srm_inspection : "检验" - srm_inspection ||--o| srm_quality_issue : "不合格生成" - - srm_supplier ||--o{ srm_statement : "" - srm_statement ||--o{ srm_statement_line : "对账明细" - srm_receipt ||--o| srm_statement_line : "" - srm_statement ||--o{ srm_invoice : "发票" - - srm_supplier ||--o{ srm_performance_review : "" - srm_performance_review ||--o{ srm_performance_score : "评分" - srm_kpi ||--o{ srm_performance_score : "" - srm_supplier ||--o{ srm_risk_event : "" ``` **master_detail 与 lookup 的取舍**:子记录离开父记录没有意义、权限应跟随父记录时 @@ -168,7 +176,7 @@ erDiagram ### 4.1 供应商主数据 -**`srm_supplier` 供应商**(OWD `public_read`;开启字段历史) +**`srm_supplier` 供应商**(OWD `public_read`;开启字段历史;表单分组:基本信息、工商与税务〔`credit_code`、`registration_no`、`taxpayer_type`、`registered_capital`、`legal_representative`〕、外部系统〔`erp_vendor_code`〕) | 字段 | 类型 | 说明 / 约束 | |---|---|---| @@ -192,8 +200,9 @@ erDiagram | `website` | url | | | `is_related_party` | boolean | 默认 false;存在关联关系申报时为 true(FR-904) | | `quality_agreement_signed` / `integrity_agreement_signed` | boolean | 默认 false;协议生效时由合同 flow 置为 true | -| `erp_vendor_code` | text | ERP 供应商编码,唯一;准入批准并推送 ERP 后回写 | -| `portal_position` | text | 门户岗位标识,如 `srm_vendor_sup0000128`;开通门户时写入,只读。校验规则:非空时必须以 `srm_vendor_` 开头(没开通门户的供应商为空) | +| `erp_vendor_code` | text | ERP 供应商编码,唯一;预留,ERP 集成前空着或由采购员手工填写 | +| `portal_position` | text | 门户岗位标识,如 `srm_vendor_sup0000128`;开通门户时写入,只读。校验规则:非空时必须以 `srm_vendor_` 开头(没开通门户的供应商为空)。v0.6 加 | +| `legacy_imported` | boolean | 默认 false;存量导入的供应商为 true 并进入「存量导入、待复核」视图(v0.2) | | `contact_count` | summary | `count` 联系人 | | `expired_certificate_count` | summary | `count` 资质证书,条件 `status == 'expired'` | @@ -202,13 +211,13 @@ erDiagram | 字段 | 类型 | 说明 | |---|---|---| | `name` | text | 必填 | -| `contact_function` | multiselect | `admin` 主账号 / `sales` 商务 / `logistics` 物流 / `quality` 质量 / `finance` 财务 | +| `contact_function` | multiselect | `admin` 主账号 / `sales` 商务 / `logistics` 物流 / `quality` 质量 / `finance` 财务(字段名不用 `role`,平台保留词) | | `mobile` / `email` | phone / email | email 必填(门户邀请与通知用) | | `portal_user` | user | 已开通门户账号时关联的平台用户;该用户同时被任命到供应商的门户岗位(见 [04 §3](./04-security-and-portal.md#3-供应商门户的数据隔离)) | -| `is_primary` | boolean | 默认 false;每家供应商至多一位主联系人(校验规则) | +| `is_primary` | boolean | 默认 false;每家供应商至多一位主联系人:跨记录规则,由「设为主联系人」screen flow 以系统身份清掉其他联系人的 `is_primary`,不写成校验规则 | | `active` | boolean | 默认 true | -**`srm_supplier_bank_account` 银行账户**(master_detail → 供应商) +**`srm_supplier_bank_account` 银行账户**(master_detail → 供应商;v0.2) | 字段 | 类型 | 说明 | |---|---|---| @@ -220,13 +229,14 @@ erDiagram | `status` | select | `pending_verify` 待核验 / `active` 有效 / `inactive` 停用 | | `verified_by` | user | 核验人(应付会计) | | `is_default` | boolean | 默认 false | +| `erp_bank_id` | text | 预留,ERP 集成前空着 | **`srm_supplier_certificate` 资质证书**(master_detail → 供应商) | 字段 | 类型 | 说明 | |---|---|---| | `cert_type` | select | `business_license` 营业执照 / `iso9001` / `iatf16949` / `iso14001` / `iso45001` / `production_license` 生产许可 / `ccc` 3C 认证 / `other` | -| `is_mandatory` | boolean | 默认 false;由 flow 按供货品类的必备资质清单写入,门户只读 | +| `is_mandatory` | boolean | 默认 false;由 `srm_supplier_qualification_recalc` 在证书或品类资格写入时按该供应商全部品类的 `mandatory_cert_types` 重算,门户只读 | | `cert_no` / `issuer` | text | | | `valid_from` / `valid_to` | date | `valid_to >= valid_from`(跨字段校验) | | `attachment` | file | 扫描件,必填 | @@ -235,28 +245,32 @@ erDiagram **`srm_category` 采购品类**(OWD `public_read`):`code`、`name`、`parent`(`tree`, 上级品类)、`category_manager`(user)、`sqe`(user)、`is_direct`(boolean,直接 -物料)、`risk_class`(`high` / `medium` / `low`,决定准入是否需要现场审核与样品)、 +物料)、`material_class`(共享选项列表 `srm_material_class`:`a` 战略类 / `b` 重要类 / +`c` 一般类,与体系文件的物资 A / B / C 分类同源,决定准入审批是否会签质量经理、 +审核频次和绩效周期)、`risk_class`(`high` / `medium` / `low`,决定准入是否需要现场 +审核与样品;A 类默认 `high`,B 类中涉及危化品、特种设备的也设 `high`)、 `mandatory_cert_types`(multiselect,必备资质类型)。 **`srm_supplier_category` 供货品类资格**(master_detail → 供应商):`category` (lookup)、`status`(`trial` 试供 / `qualified` 合格 / `suspended` 暂停)、 `approved_date`、`source_application`(lookup 准入申请)。同一供应商同一品类唯一。 -**`srm_material` 物料**(ERP 镜像,OWD `public_read`,内部只读):`erp_material_id` -(唯一)、`material_code`、`name`、`specification`、`uom`、`category`(lookup)、 -`active`。 +**`srm_material` 物料**(只读副本,OWD `public_read`;v0.2):`erp_material_no` +(唯一,导入匹配键)、`material_code`、`name`、`specification`、`uom`、`category`(lookup)、 +`active`。用平台导入按 `erp_material_no` 从 ERP 导出表格导入,可重复执行;采购员只 +维护 `category` 关联,其他字段对内部只读(FLS)。ERP 集成后改为 upsert 写入,结构不变。 -**`srm_plant` 工厂 / 收货地点**(ERP 镜像):`erp_plant_id`、`code`、`name`、 +**`srm_plant` 工厂 / 收货地点**(手工维护或导入):`erp_plant_id`(预留)、`code`、`name`、 `legal_entity`(法人名称或组织节点)、`address`。 ### 4.2 生命周期 -**`srm_supplier_application` 准入申请**(OWD `private`;公开表单匿名提交) +**`srm_supplier_application` 准入申请**(OWD `private`;v0.1 由内部登记,v0.6 起由受邀供应商在门户填写;公开表单匿名提交待平台,见 01 FR-201) | 字段 | 类型 | 说明 | |---|---|---| | `application_no` | autonumber | `APP{YYYY}{00000}`,按年重置 | -| `source` | select | `self_registered` 自助注册 / `invited` 邀请 | +| `source` | select | `internal` 内部登记(v0.1 默认)/ `invited` 邀请(v0.6)/ `self_registered` 自助注册(待平台) | | `company_name` | text | 必填 | | `country` | select | 必填,默认 `cn`,选项同供应商的 `srm_country` | | `credit_code` / `registration_no` | text | 规则同供应商:中国供应商填统一社会信用代码,境外供应商填当地注册号或税号 | @@ -267,46 +281,58 @@ erDiagram | `privacy_consent` | boolean | 默认 false;「必须勾选」由校验规则保证 | | `related_party_declaration` | textarea | 关联关系申报 | | `status` | select(stageField) | 见 §5.2 | -| `duplicate_check` | select | `pass` / `duplicate` / `blacklisted`,受理 flow 写入 | +| `duplicate_check` | select | `pass` / `duplicate` / `blacklisted` / `reapply`(命中已淘汰的供应商:不建新档,申请指向旧档,允许继续),受理 flow 写入 | | `risk_class` | select | 受理时从申请品类复制的最高风险等级,只读;决定是否需要现场审核 | -| `audit_passed` | boolean | 默认 false;现场审核结果为通过或有条件通过时由 flow 置为 true | +| `material_class` | select | 受理时从申请品类复制的最高物资类别(`srm_material_class`),只读;决定准入审批是否会签质量经理(03 §12) | +| `audit_passed` | boolean | 默认 false;现场审核结果为通过或有条件通过时由 flow 置为 true。v0.4 之前没有审核对象,由 SQE 直接勾选并上传 `audit_report` | +| `audit_report` | file | 审核报告(v0.4 前的过渡字段,之后由 `srm_supplier_audit.report` 替代) | | `reviewer` | user | 初审人(品类经理) | | `sqe` | user | 负责审核的 SQE | -| `supplier` | lookup → 供应商 | 批准时关联或新建的供应商 | +| `supplier` | lookup → 供应商 | 品类经理把申请推进到「资料审核」时新建(或 `reapply` 时关联旧档)的供应商;`submitted` 阶段只有申请记录,不建主数据 | | `reject_reason` | textarea | | | `cycle_days` | number | 从提交到批准的天数,批准时由 flow 写入(准入周期指标) | -> v0.1(内部代录,见 [07 §1.1](./07-delivery-plan.md#11-第一期的拆分))先实现一个子集:申请由内部人员为已登记的 +> v0.1(内部代录,见 [07 §1](./07-delivery-plan.md#1-分期路线图))先实现一个子集:申请由内部人员为已登记的 > 潜在或淘汰供应商发起,直接关联 `supplier`;申请品类用多值 lookup `applied_categories`(不经匿名表单, > 可以读品类对象);不含现场审核分支和公司资料等表单字段;`approval_status` 记录审批节点的结论。 -> 公开表单与门户随 v0.2 加入时再补齐本表其余字段。 +> 本表其余字段随 v0.4(供应商审核)和 v0.6(门户、邀请注册)补齐。 -**`srm_supplier_audit` 供应商审核**(OWD `private`):`audit_no`、`supplier` +**`srm_supplier_audit` 供应商审核**(OWD `private`;v0.4):`audit_no`、`supplier` (lookup)、`application`(lookup,可空)、`audit_type`(`admission` 准入 / `annual` -年度 / `special` 专项)、`audit_date`、`auditors`(user,多选)、`checklist_score` -(number)、`result`(`pass` / `conditional` 有条件通过 / `fail`)、`findings` -(richtext)、`report`(file)、`sample_result`(`not_required` / `pass` / `fail`)。 - -**`srm_supplier_change_request` 信息变更单**(二期):`supplier`、`change_type` +年度 / `special` 专项)、`planned_date` / `audit_date`、`auditors`(user,多选)、 +`checklist`(repeater:检查项、评分、备注)、`checklist_score`(number)、`result` +(`pass` / `conditional` 有条件通过 / `fail`)、`findings`(repeater:问题项、严重度、 +整改要求、关联整改单)、`report`(file)、`sample_result`(`not_required` / `pass` / `fail`)、 +`status`(`planned` / `done` / `cancelled`)。问题项可经「转整改单」screen flow 生成 +`srm_quality_issue`(`source = audit`)。 + +**`srm_supplier_change_request` 信息变更单**(v0.2):`supplier`、`change_type` (`basic` 基本信息 / `bank_account` 银行账户 / `address` 地址 / `contact` 联系人)、 `before_value` / `after_value`(json,变更前后快照)、`reason`、`status`、 `purchase_approver` / `finance_approver`(user)、`applied_at`(审批通过后写回档案 -的时间)。 +的时间)。门户上线前由采购员代供应商发起。 -**`srm_supplier_disposition` 供应商处置单**(二期):`supplier`、`action` +**`srm_supplier_disposition` 供应商处置单**(v0.3):`supplier`、`action` (`freeze` / `unfreeze` / `eliminate` / `blacklist` / `remove_blacklist`)、 `scope`(`all` 全部品类 / `category` 指定品类)、`categories`、`reason`(必填)、 `effective_date`、`status`。 -### 4.3 寻源 +**`srm_supplier_invitation` 门户邀请**(OWD `private`;v0.6):`supplier`(lookup, +可空:存量供应商批量邀请时填)、`company_name`、`contact_name`、`contact_email`、 +`token`(text,只读,flow 生成)、`expires_at`、`status`(`sent` / `accepted` / `expired` / +`revoked`)、`application`(lookup,供应商接受邀请并提交申请后回填)、`invited_by`(user)。 +邀请注册是 v0.6 的默认注册方式(01 FR-202);实现方式按 07 §6 V5 的结论。 -**`srm_sourcing_event` 寻源单**(OWD `private`,按品类共享给品类团队,见 04) +### 4.3 寻源(v0.7) + +**`srm_sourcing_event` 寻源单**(OWD `public_read`,预算、目标价、上次价格靠 FLS 保护, +不另做按品类的共享规则,见 [04 §4.2](./04-security-and-portal.md#42-字段级权限fls)) | 字段 | 类型 | 说明 | |---|---|---| | `event_no` | autonumber | `RFQ{YYYY}{00000}` | | `title` | text | 必填 | -| `sourcing_type` | select | `rfq` 询价 / `tender` 邀请招标 / `reverse_auction` 反向竞价(五期)/ `single_source` 单一来源 | +| `sourcing_type` | select(共享选项列表 `srm_sourcing_type`) | `rfq` 询价 / `tender` 邀请招标 / `single_source` 单一来源 / `external_tender` 外部招标(依法必须招标的项目在专业平台进行,这里只登记结果);`reverse_auction` 反向竞价为客户驱动主题 | | `category` | lookup → 品类 | 必填,决定可邀请的合格名录与审批路径 | | `plant` | lookup → 工厂 | 交货地点 | | `currency` | select | 报价币种 | @@ -319,7 +345,7 @@ erDiagram | `status` | select(stageField) | 见 §5.3;用户不可直接改(FLS 只读),只经发布、开标、下一轮、提交定标、取消等 screen flow 推进 | | `round` | number | 当前报价轮次,默认 1 | | `invited_count` | summary | `count` 邀请 | -| `submitted_quote_count` | summary | `count` 报价单,条件 `status == 'submitted'`;进入下一轮时上一轮报价变为 `superseded`,所以只计当前轮(封标期间内部也能看到「已报价 N 家」) | +| `submitted_quote_count` | summary | `count` 报价单,条件 `status == 'submitted'`;进入下一轮时上一轮报价变为 `superseded`,所以只计当前轮(封标期间内部也能看到「已报价 N 家」)。BR-07「有效报价少于 3 家」按当前轮次的这个计数判断,新一轮发布到首家提交之间为 0 属正常 | | `awarded_amount` | currency | 定标总金额,定标 flow 计算后写入 | | `savings_amount` | currency | 节约额 =(预算或上次价格 − 定标价)× 数量,定标 flow 写入 | | `low_competition_reason` | textarea | 有效报价少于 3 家时必填(BR-07) | @@ -377,16 +403,28 @@ erDiagram (lookup)、`source_contract`(lookup)、`status`(`active` / `expired` / `superseded` 被替代)、`erp_info_record_id`(推送 ERP 后回写)。 -### 4.4 合同 +### 4.4 合同(v0.3) **`srm_contract` 合同 / 协议**:`contract_no`(`CT{YYYY}{00000}`)、`title`、 -`contract_type`(`framework` 框架协议 / `price_agreement` 价格协议 / `purchase` -采购合同 / `quality_agreement` 质量协议 / `integrity` 廉洁协议 / `nda` 保密协议)、 -`supplier`、`legal_entity`、`amount`、`start_date` / `end_date`、`auto_renew` -(boolean)、`source_event`、`status`(见 §5.5)、`signed_file`(file)、 -`esign_request_id`(电子签流水号)、`legal_reviewer`(user)。 - -### 4.5 订单协同 +`contract_type`(共享选项列表 `srm_contract_type`:`framework` 框架协议 / `price_agreement` +价格协议 / `purchase` 采购合同 / `quality_agreement` 质量协议 / `integrity` 廉洁协议 / +`nda` 保密协议)、`supplier`、`legal_entity`、`amount`、`currency`、`start_date` / `end_date`、 +`auto_renew`(boolean)、`source_event`(lookup 寻源单,v0.7 起有值)、`status`(见 §5.5)、 +`signed_file`(file)、`signed_date`、`esign_request_id`(电子签流水号,预留;电子签接入为 +客户驱动主题)、`legal_reviewer`(user)、`erp_contract_no`(预留)。 + +**`srm_contract_line` 合同明细**(master_detail → 合同):`line_no`、`material`(lookup, +可空)、`description`、`quantity`、`uom`、`unit_price`、`tax_rate`、`amount`、`valid_from` / +`valid_to`。价格协议的明细在合同生效时可经 flow 生成价格记录(v0.7 起)。 + +### 4.5 订单协同(预留:ERP 集成后的门户镜像,现阶段不建) + +本节的四个对象(采购订单、订单行、送货单、送货明细)的记录系统是 ERP。按 +[ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md) 第 5 条,它们只在 ERP 集成落地后作为 +**门户镜像**建立:对象定义在核心,ERP 来的字段对内部岗位只读、只有集成账号能写,供应商 +在门户的动作(确认、答复交期、送货)写在镜像自己的字段里。没有集成时门户不显示这些入口。 +字段设计保留如下,集成立项时直接沿用;收货记录和来料检验不再单独建对象,由 §4.6 的 +交付记录替代。 **`srm_purchase_order` 采购订单**(ERP 来源;OWD `private`,内部按工厂共享) @@ -422,22 +460,33 @@ false,BR-13)、`received_quantity`(summary:`sum` 收货记录 `accepted_ `ship_quantity`(≤ 订单行 `open_quantity − in_transit_quantity`,BR-14)、`batch_no`、 `production_date`、`line_status`(`shipped` / `received` / `cancelled`,收货 flow 维护)。 -**`srm_receipt` 收货记录**(ERP / WMS 来源,行级):`erp_receipt_id`(唯一)、 -`po_line`、`asn_line`(可空)、`supplier`、`material`、`plant`、`receipt_date`、 -`received_quantity`、`accepted_quantity`、`rejected_quantity`、`movement_type` -(`receipt` 收货 / `return` 退货)、`amount`(currency,数量 × 订单行单价,flow 写入, -采购支出口径)、`on_time`(boolean,收货 flow 按 -`receipt_date <= promised_date` 判定)、`reconciled`(boolean,是否已进对账单)、 -`settlement_mode`(共享选项列表,核心只有 `standard` 一项,默认 `standard`;扩展包可以追加 -自己的结算方式,例如大宗物料包的 `bulk`,核心的月度对账只处理 `standard` 的收货)。 +订单行上原设计的 `received_quantity`、`returned_quantity`、`in_transit_quantity` 汇总依赖收货 +记录与送货明细,集成立项时按当时的集成范围重定。 + +### 4.6 质量(v0.4) -### 4.6 质量 +**`srm_delivery_record` 交付记录**(OWD `public_read`,内部只读;导入或质检员录入) -**`srm_inspection` 来料检验**(ERP / QMS 来源或 IQC 录入):`erp_inspection_id` -(唯一)、`inspection_no`、`receipt`(lookup)、`supplier`、`material`、`lot_quantity`、 -`sample_quantity`、`defect_quantity`、`result`(`pass` 合格 / `fail` 不合格 / -`concession` 让步接收)、`severity`(`critical` 严重 / `major` 主要 / `minor` 次要)、 -`defect_description`、`inspector`(user)、`inspection_date`、`photos`(image)。 +只为算绩效和开整改单,不做业务:不改库存、不对账。每月从 ERP 导出表格导入,按 +`erp_order_no` + `erp_line_no` 幂等匹配;没有质量系统的客户由质检员逐条录入。ERP 集成后 +改为 upsert 写入,结构不变。 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `erp_order_no` / `erp_line_no` | text | ERP 订单号与行号,组合唯一(导入匹配键) | +| `supplier` / `material` / `plant` | lookup | 必填(工厂可空) | +| `required_date` / `promised_date` | date | 需求日期 / 供应商承诺日期(可空) | +| `receipt_date` | date | 实到日 | +| `ordered_quantity` / `received_quantity` / `accepted_quantity` | number | 订单数量 / 实收数量 / 合格数量 | +| `uom` | text | | +| `on_time` | boolean | 默认 false;写入时由 flow 按 `receipt_date <= promised_date`(无承诺日期时按 `required_date`)判定 | +| `inspection_result` | select | `pass` 合格 / `fail` 不合格 / `concession` 让步接收 / `not_inspected` 未检 | +| `severity` | select | `critical` 严重 / `major` 主要 / `minor` 次要(不合格时填写) | +| `defect_quantity` | number | 不良数(PPM 口径) | +| `defect_description` | textarea | | +| `amount` | currency | 实收数量 × 单价(表格里带单价时写入,用于供应商维度的支出分析) | +| `period` | text | 所属期间,如 `2026-10`,导入时写入,供考评 flow 按期汇总 | +| `portal_position` | text | v0.6 加;供应商在门户只能看本公司的交付记录 | **`srm_quality_issue` 质量整改单 SCAR** @@ -445,70 +494,61 @@ false,BR-13)、`received_quantity`(summary:`sum` 收货记录 `accepted_ |---|---|---| | `issue_no` | autonumber | `SCAR{YYYY}{00000}` | | `supplier` / `material` | lookup | | -| `inspection` | lookup | 来源检验(可空) | -| `source` | select | `iqc` 来料 / `production` 制程 / `customer` 客户投诉 / `audit` 审核发现 | +| `delivery_record` | lookup | 来源交付记录(可空) | +| `audit` | lookup | 来源审核(可空) | +| `source` | select(共享选项列表 `srm_quality_issue_source`) | `iqc` 来料 / `production` 制程 / `customer` 客户投诉 / `audit` 审核发现 / `performance` 绩效改善 | | `severity` | select | 同检验 | | `problem_description` | richtext | D2 问题描述,必填 | | `status` | select(stageField) | 见 §5.6 | | `sqe` | user | 负责 SQE | | `containment_due` / `final_due` | datetime / date | 创建时按严重度计算:临时措施 72 小时,最终回复 30 天 | -| `containment_action` | richtext | D3,供应商填写 | +| `containment_action` | richtext | D3,供应商填写(v0.6 前由 SQE 代填) | | `root_cause` | richtext | D4 | | `corrective_action` / `preventive_action` | richtext | D5–D7 | | `evidence` | file | 整改证据 | | `sqe_comment` | textarea | 审核意见,退回时必填 | | `is_overdue` | boolean | 默认 false,逾期 flow 维护 | | `claim_amount` | currency | 索赔金额 | -| `claim_status` | select | `none` / `proposed` / `supplier_accepted` / `disputed` / `settled`(已计入对账单扣款,由对账生成 flow 写入,防止重复扣款) | +| `claim_status` | select | `none` / `proposed` / `supplier_accepted` / `disputed` / `settled`(财务已在 ERP 扣款,由应付会计手工标记;SRM 不生成扣款) | +| `steps` | repeater | 8D 各步骤的完成日期、责任人、附件(D1–D8),供看板显示进度 | -### 4.7 绩效 +### 4.7 绩效(v0.5) **`srm_kpi` 绩效指标**:`code`、`name`、`dimension`(`quality` / `cost` / `delivery` / `service`)、`method`(`auto` 自动 / `manual` 人工)、`weight`(percent)、 `scoring_rule`(textarea,评分规则说明,例如「OTD ≥ 98% 得满分,每低 1% 扣 5 分」)、 `active`。 -**`srm_performance_review` 绩效考评单**:`review_no`、`supplier`、`period`(text, -如 `2026Q3`)、`period_start` / `period_end`(date)、`quality_score` / +**`srm_performance_review` 绩效考评单**:`review_no`、`supplier`、`cycle`(`monthly` / +`quarterly` / `yearly`,按供应商所供最高物资类别取参数 `perf_cycle`)、`period`(text, +如 `2026Q3`、`2026-10`)、`period_start` / `period_end`(date)、`quality_score` / `cost_score` / `delivery_score` / `service_score` / `total_score`(number,存储字段, 由算分 flow 写入,供看板使用)、`grade`(`a` / `b` / `c` / `d`)、`status`(见 §5.7)、 -`otd_rate` / `lot_pass_rate`(percent)、`ppm`(number)、`ack_on_time_rate`(percent)、 -`reviewer`(user)、`appeal_reason`、`appeal_result`。 +`otd_rate` / `lot_pass_rate`(percent)、`ppm`(number)、`ack_on_time_rate`(percent, +ERP 集成前为空)、`reviewer`(user)、`appeal_reason`、`appeal_result`。自动指标由 +交付记录按 `period` 汇总。 **`srm_performance_score` 评分明细**(master_detail → 考评单):`kpi`(lookup)、 `raw_value`(number,自动指标的原始值)、`score`(number,0–100)、`weight` (percent,快照)、`scorer`(user,人工指标的评分人)、`comment`、`scored` (boolean,默认 false)。 -### 4.8 结算 - -**`srm_statement` 对账单**:`statement_no`(`ST{YYYY}{MM}{0000}`,按月流水)、 -`supplier`、`legal_entity`、`period_start` / `period_end`、`currency`、 -`receipt_amount` / `return_amount` / `deduction_amount`(summary,按明细类型带条件 -求和)、`net_amount`(currency,不含税,由 flow 计算为收货 − 退货 − 扣款后存储)、 -`tax_amount`(currency,flow 按明细税率计算)、`invoiced_amount`(summary:`sum` 发票 -`amount_excl_tax`,条件 `verify_status != 'mismatch'`)、`status`(见 §5.8)、 -`supplier_confirmed_at`、`dispute_reason`、`erp_doc_no`。 +### 4.8 结算(不做,留在 ERP) -**`srm_statement_line` 对账明细**(master_detail → 对账单):`line_type`(`receipt` / -`return` / `deduction` 质量索赔或其他扣款)、`receipt`(lookup,可空)、 -`quality_issue`(lookup,扣款来源,可空)、`po_no`、`material`、`quantity`、 -`unit_price`、`tax_rate`、`amount`、`disputed`(boolean,默认 false)、`dispute_note`。 +对账单、对账明细、发票三个对象从核心移除([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md)): +对账与开票的记录系统是 ERP,发票查验要接税务接口。SRM 保留的只有:整改单上的索赔金额与 +结论(供财务扣款参考);ERP 集成后在门户镜像上提供付款进度(付款状态、付款日、凭证号 +三个字段)。原字段设计见本文件 2026-10-23 之前的版本(git 历史)。 -**`srm_invoice` 发票**:`invoice_type`(`vat_special` 专票 / `vat_normal` 普票 / -`e_invoice` 数电票 / `overseas` 境外发票)、`invoice_code` / `invoice_no`、`supplier`、 -`statement`(lookup)、`invoice_date`、`amount_excl_tax` / `tax_amount` / `total_amount` -(currency)、`file`、`verify_status`(`pending` / `verified` / `mismatch`)、 -`erp_ap_doc_no`、`payment_status`(`unpaid` / `partially_paid` / `paid`)、`paid_amount`、 -`paid_date`(后两项由 ERP 回写)。发票代码 + 号码唯一。 +### 4.9 风险(v0.5) -### 4.9 风险 - -**`srm_risk_event` 风险事件**:`supplier`、`risk_type`(`qualification` 资质 / -`legal` 司法诉讼 / `operation` 经营异常 / `financial` 财务 / `delivery` 交付 / -`quality` 质量 / `esg` 环境社会治理 / `sanction` 制裁名单)、`severity`、`source` -(`system` / `external_api` / `manual`)、`external_ref`(外部服务的事件编号,去重用)、 -`description`、`status`(`open` / `mitigating` / `closed`)、`mitigation_plan`、`owner_note`。 +**`srm_risk_event` 风险事件**:`supplier`、`risk_type`(共享选项列表 `srm_risk_type`: +`qualification` 资质 / `legal` 司法诉讼 / `operation` 经营异常 / `financial` 财务 / +`delivery` 交付 / `quality` 质量 / `esg` 环境社会治理 / `sanction` 制裁名单)、`severity`、 +`source`(`system` / `external_api` / `manual`;现阶段只有 `system` 与 `manual`,外部企业 +信息服务的自动拉取为客户驱动主题)、`external_ref`(外部服务的事件编号,去重用)、 +`description`、`status`(`open` / `mitigating` / `closed`)、`mitigation_plan`、`owner_note`、 +`disposition`(lookup,`high` 级事件生成的处置单草稿)。 ## 5. 状态机 @@ -556,7 +596,7 @@ false,BR-13)、`received_quantity`(summary:`sum` 收货记录 `accepted_ | `awarded` | 已定标 | won | — | | `cancelled` | 已取消 / 流标 | lost | — | -### 5.4 采购订单 `srm_purchase_order.status` +### 5.4 采购订单 `srm_purchase_order.status`(预留,ERP 集成后) | 值 | 标签 | kind | 允许跳转到 | |---|---|---|---| @@ -570,7 +610,7 @@ false,BR-13)、`received_quantity`(summary:`sum` 收货记录 `accepted_ | `rejected_by_supplier` | 供应商拒绝 | lost | `change_pending`、`cancelled` | | `cancelled` | 已取消 | lost | — | -### 5.5 合同 `srm_contract.status` +### 5.5 合同 `srm_contract.status`(v0.3) `draft` ★(open)→ `in_review` 审批中(open)→ `signing` 签署中(open)→ `active` 生效(won)→ `expired` 已到期(lost)/ `terminated` 已终止(lost);`in_review` 可退回 @@ -593,17 +633,9 @@ false,BR-13)、`received_quantity`(summary:`sum` 收货记录 `accepted_ (open)→ `published` 已发布(won)→ `appealed` 申诉中(open)→ `published`; 作废为 `void`(lost)。 -### 5.8 对账单 `srm_statement.status` +### 5.8 对账单 -| 值 | 标签 | kind | 允许跳转到 | -|---|---|---|---| -| `draft` ★ | 草稿 | open | `sent` | -| `sent` | 待供应商确认 | open | `supplier_confirmed`、`disputed` | -| `disputed` | 有差异 | open | `sent`(处理后重发) | -| `supplier_confirmed` | 供应商已确认 | open | `finance_confirmed`、`disputed` | -| `finance_confirmed` | 双方已确认 | open | `invoiced` | -| `invoiced` | 已开票 | open | `paid` | -| `paid` | 已付款 | won | — | +不做(§4.8)。 ## 6. 编码规则 @@ -617,11 +649,12 @@ false,BR-13)、`received_quantity`(summary:`sum` 收货记录 `accepted_ | 寻源单 | `RFQ{YYYY}{00000}` | RFQ202600317 | 按年 | | 报价单 | `QT{YYYY}{000000}` | QT2026001024 | 按年 | | 合同 | `CT{YYYY}{00000}` | CT202600088 | 按年 | -| 送货单 | `ASN{YYYYMMDD}{0000}` | ASN202610220015 | 按日 | | 整改单 | `SCAR{YYYY}{00000}` | SCAR202600007 | 按年 | -| 对账单 | `ST{YYYY}{MM}{0000}` | ST2026100031 | 按月 | +| 供应商审核 | `AUD{YYYY}{0000}` | AUD20260012 | 按年 | +| 考评单 | `PR{YYYY}{00000}` | PR202600210 | 按年 | +| 送货单(预留) | `ASN{YYYYMMDD}{0000}` | ASN202610220015 | 按日 | -采购订单、收货、检验、物料、工厂沿用 ERP 编号,不在 SRM 内另行编号。 +物料、交付记录、工厂沿用 ERP 编号,不在 SRM 内另行编号。 ## 7. 元数据示例 diff --git a/docs/design/03-processes-and-automation.md b/docs/design/03-processes-and-automation.md index 576936d..7ed2bab 100644 --- a/docs/design/03-processes-and-automation.md +++ b/docs/design/03-processes-and-automation.md @@ -4,18 +4,21 @@ ## 1. 流程总览 -| 编号 | 流程 | 起点 → 终点 | 涉及对象 | 期次 | +版本号见 [07 §1](./07-delivery-plan.md#1-分期路线图)。P5、P6、P8 的记录系统是 ERP,按 +[ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md) 不在核心实现;P5、P6 在 ERP 集成后作为门户镜像,P8 不做。 + +| 编号 | 流程 | 起点 → 终点 | 涉及对象 | 版本 | |---|---|---|---|---| -| P1 | 供应商注册与准入 | 公开表单提交 → 合格供应商 | 准入申请、审核、供应商、品类资格 | 一期 | -| P2 | 信息变更与供应商处置 | 变更 / 处置申请 → 档案更新 | 变更单、处置单、供应商、银行账户 | 二期 | -| P3 | 寻源:询价 → 比价 → 定标 | 寻源单草稿 → 价格记录 | 寻源单、邀请、报价、价格记录 | 一期 | -| P4 | 合同审批、签署与到期 | 合同草稿 → 生效 → 到期 | 合同 | 二期 | -| P5 | 订单协同 | ERP 下发 PO → 供应商确认 | 订单、订单行 | 二期 | -| P6 | 送货与收货 | 送货单 → 收货回传 | 送货单、收货记录、订单行 | 二期 | -| P7 | 来料检验与质量整改 | 检验不合格 → SCAR 关闭 | 检验、整改单 | 三期 | -| P8 | 对账与结算 | 月度对账单 → 付款回写 | 对账单、发票、收货记录 | 四期 | -| P9 | 季度绩效评估 | 自动生成考评 → 发布与应用 | 考评单、评分明细、供应商 | 三期 | -| P10 | 资质与风险监控 | 到期 / 外部风险 → 预警与处置 | 证书、风险事件、供应商 | 一期 / 四期 | +| P1 | 供应商登记与准入 | 内部登记 / 邀请注册 → 合格供应商 | 准入申请、审核、供应商、品类资格 | v0.1(门户侧 v0.6,审核对象 v0.4) | +| P2 | 信息变更与供应商处置 | 变更 / 处置申请 → 档案更新 | 变更单、处置单、供应商、银行账户 | v0.2(变更)、v0.3(处置) | +| P3 | 寻源:询价 → 比价 → 定标 | 寻源单草稿 → 价格记录 | 寻源单、邀请、报价、价格记录 | v0.7 | +| P4 | 合同审批、签署与到期 | 合同草稿 → 生效 → 到期 | 合同、合同明细 | v0.3 | +| P5 | 订单协同 | ERP 下发 PO → 供应商确认 | 订单、订单行 | ERP 集成后(门户镜像) | +| P6 | 送货与收货 | 送货单 → 收货回传 | 送货单、交付记录 | ERP 集成后(门户镜像) | +| P7 | 交付记录导入与质量整改 | 交付记录不合格 → SCAR 关闭 | 交付记录、整改单、审核 | v0.4 | +| P8 | 对账与结算 | 月度对账单 → 付款回写 | — | 不做,留在 ERP | +| P9 | 绩效评估 | 自动生成考评 → 发布与应用 | 考评单、评分明细、供应商 | v0.5 | +| P10 | 资质与风险监控 | 到期 / 风险事件 → 预警与处置 | 证书、风险事件、供应商 | v0.1(资质)、v0.5(风险事件) | ## 2. 平台机制与本设计的用法 @@ -32,16 +35,16 @@ | 通知 | `notify` 节点(站内 / 邮件等通道) | 邀请、待办、提醒、升级 | | 外部系统 | `http` 节点、webhook | 推送 ERP、电子签、企业信息查询 | | 状态约束 | `state_machine` 校验规则(`transitions` + `initialStates`) | 所有单据的状态跳转 | -| 记录校验 | `script` / `cross_field` 校验规则(CEL,可用 `now()` / `today()`,可经一个引用字段读关联记录) | 截止后锁价、开标时限、邀请供应商的状态兜底、条件必填 | +| 记录校验 | `script` / `cross_field` 校验规则(CEL,可用 `now()` / `today()`,`script` 规则可经一个引用字段读关联记录);字段谓词(`requiredWhen` 等)只能读本记录 | 截止后锁价、开标时限、邀请供应商的状态兜底、条件必填 | | 受控写入口 | `screen` 类型的 flow,以系统身份运行,用户对目标对象**没有**直接创建权限 | 邀请供应商、建送货单、提交发票等需要跨对象判断的写操作 | 三条贯穿全文的取舍: -- **全部用元数据表达,托管云今天就能运行**。在托管云上安装应用包时,平台只合并包里 - 的元数据,包里的代码函数(钩子、任务处理函数、插件)不会执行。因此本设计不依赖 +- **全部用元数据表达,托管云今天就能运行**。平台本身有沙箱钩子,但托管云可以关闭 + 应用包代码([ADR-0001](../adr/0001-declarative-only.md) 补充说明)。因此本设计不依赖 任何应用代码;需要代码的增强只在自托管部署中启用,并单独标注。 -- **校验规则能读本记录和一跳关联记录**(如 `record.supplier.status`),更远或需要 - 汇总的判断用两种声明式办法强制: +- **只有 `script` 校验规则能读一跳关联记录**(如 `record.supplier.status`);字段谓词、 + `previous`、`parent` 只读本记录(02 §1 第 12 条)。更远或需要汇总的判断用两种声明式办法强制: 1. **冗余 + 校验**:把判断所需的值在创建时冗余到本记录(例如把寻源单的截止时间 复制到报价单,报价明细再经一跳读取),再用校验规则判断; 2. **受控写入口**:敏感的创建动作只开放为 `screen` flow(以系统身份运行,flow 里 @@ -78,7 +81,12 @@ | R2 扫描任务是追赶式且幂等的 | 每次扫描处理「所有已到期而尚未处理」的记录,而不是「今天到期」的记录;处理后打标记,重复运行不重复处理。漏掉一次,下一次自动补上 | | R3 关键扫描有外部心跳 | 截标、PO 催办、SCAR 逾期这三个时效敏感的扫描,同时暴露为 `api` 触发的 flow,由外部调度器(ERP 中间件或运维定时任务)每 10 分钟调用一次,保证准时 | -## 3. P1 供应商注册与准入 +## 3. P1 供应商登记与准入 + +v0.1 只有内部登记:品类经理在工作台新建准入申请(`source = internal`),下图中的公开 +表单、开通门户、门户补资料三步跳过,`reviewer` 默认取创建人所在品类的品类经理。v0.6 起 +受邀供应商在门户填申请(`source = invited`);公开表单(`self_registered`)待平台 +(01 FR-201)。现场审核对象在 v0.4 才有,之前由 SQE 在申请上勾选 `audit_passed` 并上传报告。 ```mermaid sequenceDiagram @@ -115,16 +123,16 @@ sequenceDiagram | 步骤 | 触发 | 自动化 / 人工动作 | |---|---|---| -| 1 受理 | 公开表单提交(匿名 `POST /forms/:slug/submit`) | flow `srm_application_intake`(record_change,after-create):按身份标识查供应商(`country == 'cn'` 用 `credit_code`,其他国家 / 地区用 `country` + `registration_no`,BR-01);命中 `blacklisted` → 申请置 `rejected`、`duplicate_check = blacklisted`,通知申请人;命中其他状态 → `duplicate`,通知品类经理人工判断;未命中 → `pass` | -| 2 建档 | 受理通过 | 同一 flow:新建 `potential` 供应商与主联系人,`supplier` 回填到申请;按申请品类找到品类经理和 SQE,写入 `reviewer` / `sqe`,并把这些品类中最高的风险等级写入 `risk_class`;申请→`doc_review`,供应商 `potential → qualifying`;通知品类经理 | -| 3 开通门户 | 品类经理 / 管理员 | 邀请主联系人加入组织并开通门户(见 [04 §3.3](./04-security-and-portal.md#33-门户账号的开通与回收)) | +| 1 受理 | 申请创建(v0.1 内部登记;v0.6 受邀供应商在门户提交) | flow `srm_application_intake`(record_change,after-create):按身份标识查供应商(`country == 'cn'` 用 `credit_code`,其他国家 / 地区用 `country` + `registration_no`,BR-01);命中 `blacklisted` → 申请置 `rejected`、`duplicate_check = blacklisted`,通知申请人;命中 `eliminated` → `reapply`,申请的 `supplier` 指向旧档并允许继续(淘汰后重新准入的唯一路径,FR-208);命中 `qualified` / `qualifying` / `frozen` / `potential` → `duplicate`,通知品类经理人工判断;未命中 → `pass`。同一 flow 按申请品类找到品类经理和 SQE,写入 `reviewer` / `sqe`,把这些品类中最高的 `risk_class` 和 `material_class` 复制到申请 | +| 2 建档 | 品类经理把申请推进到 `doc_review`(人工确认后,防止灌水污染主数据) | flow `srm_application_accept`:`duplicate_check == 'pass'` 时新建 `potential` 供应商与主联系人并回填 `supplier`;`reapply` 时沿用旧档;供应商 `potential / eliminated → qualifying`;`submitted` 阶段只有申请记录,不建主数据 | +| 3 开通门户 | 品类经理 / 管理员(v0.6) | 邀请主联系人加入组织并开通门户(见 [04 §3.3](./04-security-and-portal.md#33-门户账号的开通与回收));v0.1–v0.5 跳过 | | 4 补充资料 | 供应商 | 门户内补齐公司资料(门户可改的字段见 [04 §4.2](./04-security-and-portal.md#42-字段级权限fls))、银行账户、证书;品类经理可「退回补充」(申请→`returned`,通知联系人)。应付会计经「核验银行账户」、SQE 经「核验证书」两个 screen flow 完成核验 | -| 5 现场审核 | `risk_class == 'high'` | SQE 建供应商审核记录;结果为通过或有条件通过时,flow 把申请的 `audit_passed` 置为 true。条件校验:`risk_class == 'high' && audit_passed == false` 时申请不得进入 `admission_review`(FR-204) | -| 6 准入评审 | 申请→`admission_review` | flow `srm_admission_approval`:第 1 级 `field` 审批人 = `reviewer`;第 2 级 `position` = `srm_procurement_director`;高风险品类第 2 级并行加 `srm_quality_manager`(`unanimous`)。驳回 → 申请回 `doc_review` 并通知 | -| 7 批准后 | 审批通过 | 申请→`approved`,写入 `cycle_days`;供应商 `qualifying → qualified`;按申请品类建 `srm_supplier_category`(审核结论为有条件通过时为 `trial`,否则 `qualified`);`http` 节点调 ERP 建供应商,回写 `erp_vendor_code`;通知供应商 | -| 8 未通过 | 终止 | 申请→`rejected`;供应商 `qualifying → potential`;回收门户账号 | +| 5 现场审核 | `risk_class == 'high'` | v0.4 起:SQE 建供应商审核记录(`audit_type = admission`),结果为通过或有条件通过时,flow 把申请的 `audit_passed` 置为 true;v0.4 前由 SQE 直接勾选并上传 `audit_report`。条件校验:`risk_class == 'high' && audit_passed == false` 时申请不得进入 `admission_review`(FR-204) | +| 6 准入评审 | 申请→`admission_review` | flow `srm_admission_approval`:第 1 级 `field` 审批人 = `reviewer`(品类经理);第 2 级 `position` = `srm_procurement_director`;`material_class == 'a'` 或 `risk_class == 'high'` 时第 2 级并行加 `srm_quality_manager`(`unanimous`)。校验规则拦截提交人 = 审批人(平台没有「不可自审」选项,objectstack#25446)。驳回 → 申请回 `doc_review` 并通知 | +| 7 批准后 | 审批通过 | 申请→`approved`,写入 `cycle_days`;供应商 `qualifying → qualified`;按申请品类建 `srm_supplier_category`(审核结论为有条件通过时为 `trial`,否则 `qualified`);通知供应商。ERP 建档与 `erp_vendor_code` 回写为预留集成点(06 §1) | +| 8 未通过 | 终止 | 申请→`rejected`;供应商 `qualifying → potential`(`reapply` 的旧档回 `eliminated`);v0.6 起回收门户账号 | -## 4. P3 寻源:询价 → 比价 → 定标 +## 4. P3 寻源:询价 → 比价 → 定标(v0.7) ```mermaid flowchart TD @@ -149,7 +157,7 @@ flowchart TD | 步骤 | 触发 | 自动化 / 人工动作 | |---|---|---| | 1 建单 | 寻源工程师 | 建寻源单与明细(草稿)。邀请供应商只能通过「邀请供应商」screen flow:选择器带 `lookupFilters`(`status == 'qualified'`、`qualification_alert == false`),flow 再查一次供应商状态与该品类资格,不满足则拒绝并说明原因(BR-03、BR-04);邀请对象上另有一跳读取供应商状态的校验规则兜底;内部角色对邀请对象没有直接创建权限 | -| 2 发布 | 「发布」screen flow | 寻源单的 `status` 对用户只读,只经 screen flow 推进。普通询价直接→`published`;单一来源→`approval_pending`,由 `srm_single_source_approval` 审批(品类经理 → 采购总监,必须填写单一来源理由),通过后→`published`,驳回回到 `draft` | +| 2 发布 | 「发布」screen flow | 寻源单的 `status` 对用户只读,只经 screen flow 推进。发布前校验:邀请家数 ≥ `min_bidders`(单一来源除外)、综合评分法的技术权重 ≤ `tech_weight_max` 且两权重之和为 100%(参数见 `params/core.yaml`,FR-306)。普通询价直接→`published`;单一来源→`approval_pending`,由 `srm_single_source_approval` 审批(品类经理 → 采购总监,预算金额达到 `award_approval_tiers.high` 档时加总经理,必须填写单一来源理由),通过后→`published`,驳回回到 `draft` | | 3 发布后 | 状态→`published` | flow `srm_event_publish`:把 `quote_deadline` 复制为 `locked_deadline`;为本轮应报价的供应商(第 1 轮为全部受邀者,之后只取 `shortlisted == true` 的)各建一张 `draft` 报价单,冗余截止时间与门户岗位,再按明细建报价明细并快照物料信息(单价留空);通知这些供应商 | | 4 报价 | 供应商门户 | 供应商只填自己报价单上的单价、交期、税率、附件,提交后 `status → submitted`、记录 `submitted_at`;截止前可撤回重改 | | 5 截标 | 截止时间到 | **强制**(R1):报价单的校验规则 `now() > record.quote_deadline && record.bid_opened == false && record.status != 'expired'` 为真时拒绝写入;报价明细经一跳读报价单做同样判断。截止到开标之间报价被冻结;开标后门户写策略也不再放行([04 §3.4](./04-security-and-portal.md#34-rls-示例))。**扫描**:`srm_bid_close_sweep`(每 10 分钟,追赶式)把已过截止时间的 `published` 寻源单置为 `bid_closed`,其未提交的报价单置为 `expired` | @@ -158,7 +166,7 @@ flowchart TD | 8 多轮议价 | 「下一轮」screen flow | 先在邀请上勾选入围供应商(`shortlisted`);flow 把本轮报价单置为 `superseded`(只读保留,不再计入 `submitted_quote_count`),`round + 1`,同时写入本轮新的 `quote_deadline` 与 `locked_deadline`,寻源单→`published`,回到步骤 3 | | 9 提交定标 | 「提交定标」screen flow | 在 flow 里勾选中标明细并填写份额,flow 以系统身份写入报价明细的 `is_awarded` / `award_quantity` / `award_ratio`(内部角色对报价明细没有编辑权),汇总 `awarded_amount`、`savings_amount`;`submitted_quote_count < 3` 时要求填写 `low_competition_reason`(BR-07);寻源单→`award_review` | | 10 定标审批 | 状态→`award_review` | 见 §12 审批矩阵:按 `awarded_amount` 分档;有效报价少于 3 家时额外升一级 | -| 11 定标后 | 审批通过 | flow `srm_award_apply`:`loop` 中标明细 → 查同供应商 × 物料 × 工厂的有效价格,把它的 `valid_to` 截断到新价生效日前一天并置为 `superseded`(BR-10)→ 新建 `active` 价格记录 → `http` 推送 ERP 价格信息记录 → 通知中标与未中标供应商;二期起可选:生成合同草稿 | +| 11 定标后 | 审批通过 | flow `srm_award_apply`:`loop` 中标明细 → 查同供应商 × 物料 × 工厂的有效价格,把它的 `valid_to` 截断到新价生效日前一天并置为 `superseded`(BR-10)→ 新建 `active` 价格记录 → 通知中标与未中标供应商;可选:生成合同草稿。价格记录推送 ERP 为预留集成点,现阶段由采购员按价格库在 ERP 维护价格 | **封标的完整机制**(BR-05 / BR-06 / FR-304) @@ -176,32 +184,35 @@ flowchart TD ## 5. P2 信息变更与供应商处置 -**信息变更**(二期,FR-207):供应商在门户经「提交变更申请」screen flow 提交变更单 → +**信息变更**(v0.2,FR-207):供应商在门户经「提交变更申请」screen flow 提交变更单(v0.6 前由采购员代供应商发起)→ `before_value` 自动快照当前档案 → 审批 flow `srm_change_approval`:第 1 级 `position = srm_buyer_lead`(采购确认);`change_type == 'bank_account'` 时增加第 2 级 `position = srm_ap_accountant`(财务复核), 两级审批人由不同岗位担任(BR-11)→ 通过后 flow 把 `after_value` 写回供应商或银行 -账户,新银行账户为 `active`,旧账户为 `inactive`;ERP 推送成功前,银行账户变更在 -ERP 侧不生效。驳回时通知供应商并写明原因。 +账户,新银行账户为 `active`,旧账户为 `inactive`。驳回时通知供应商并写明原因。ERP 侧的 +银行账户由财务按 SRM 的审批记录维护(ERP 集成为预留集成点)。 -**供应商处置**(二期,FR-208):品类经理发起处置单 → 审批:冻结 / 解冻为品类经理 → +**供应商处置**(v0.3,FR-208):品类经理发起处置单 → 审批:冻结 / 解冻为品类经理 → 采购总监;淘汰与黑名单再加 `position = srm_general_manager`;解除黑名单单独走同一条 最高级别审批 → 通过后 flow 更新供应商 `status`(或指定品类资格为 `suspended`), -通知供应商,推送 ERP 冻结 / 解冻标志。冻结**不影响**在途订单,只阻止新的寻源邀请 -和新订单(ERP 侧的冻结标志拦截新订单)。 +通知供应商。冻结**不影响**在途订单,只阻止新的寻源邀请;ERP 侧的冻结标志由采购员 +手工同步(ERP 集成后自动推送)。 -## 6. P4 合同审批、签署与到期 +## 6. P4 合同审批、签署与到期(v0.3) | 步骤 | 触发 | 动作 | |---|---|---| | 1 起草 | 品类经理手工新建,或定标后由 flow 生成草稿 | 带出供应商、金额、来源寻源单 | | 2 审批 | 状态→`in_review` | 法务(`field = legal_reviewer`)→ 按金额分档的采购审批(同 §12);审批中合同只读(平台审批锁记录) | -| 3 签署 | 状态→`signing` | 方式一:上传双方盖章扫描件;方式二:`http` 节点调电子签服务发起签署,回调 `api` flow 写回签署文件和 `esign_request_id` | +| 3 签署 | 状态→`signing` | 上传双方盖章扫描件,填写 `signed_date`;电子签(`http` 发起 + `api` 回调写回 `esign_request_id`)为客户驱动主题,字段已预留 | | 4 生效 | 签署完成 | 状态→`active`;质量协议 / 廉洁协议生效时把供应商对应的布尔字段置为 true | | 5 到期提醒 | `time_relative`:`end_date`,提前 60 / 30 / 7 天 | 通知合同所有者和品类经理 | | 6 到期 | 追赶式扫描:`end_date < today` 且仍为 `active` | 状态→`expired`;`auto_renew == true` 的合同生成续签草稿 | -## 7. P5 订单协同与 P6 送货收货 +## 7. P5 订单协同与 P6 送货收货(预留:ERP 集成后的门户镜像,现阶段不做) + +本节保留原设计,作为 ERP 集成立项时的流程基线([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md) 第 5 条)。 +集成前交付结果按 §8 的交付记录导入。 ```mermaid sequenceDiagram @@ -235,11 +246,15 @@ sequenceDiagram | 6 送货 | 供应商通过「创建送货单」screen flow | flow 列出本公司「未交数量 − 在途数量 > 0」的订单行,校验送货数量 ≤ `open_quantity − in_transit_quantity`(BR-14,扣除已发未收的其他送货单)后以系统身份建送货单与明细(明细 `line_status = shipped`),生成二维码标签;门户对送货明细没有直接创建权限 | | 7 收货 | ERP / WMS upsert 收货记录 | flow `srm_receipt_apply`:按订单行的 `promised_date`(无答复时取 `required_date`)判定 `on_time`;按订单行单价写 `amount`;重算订单行 `open_quantity` 与 `line_status`;对应送货明细→`received`;更新送货单与订单头状态(未确认的订单也允许直接进入交货中 / 已收齐,见 02 §5.4) | -## 8. P7 来料检验与质量整改(SCAR / 8D) +## 8. P7 交付记录导入与质量整改(SCAR / 8D)(v0.4) + +**交付记录导入**:每月从 ERP 导出上月的收货与检验结果表格,用平台导入按 `erp_order_no` + +`erp_line_no` 匹配写入 `srm_delivery_record`(可重复执行);没有质量系统的客户由质检员 +逐条录入。写入后 flow `srm_delivery_apply` 判定 `on_time`,并按下表生成整改单。 ```mermaid stateDiagram-v2 - [*] --> open: 检验不合格(严重/主要)自动生成 + [*] --> open: 交付记录不合格(严重/主要)自动生成 open --> containment_submitted: 供应商提交 D3 临时措施 containment_submitted --> open: SQE 退回 containment_submitted --> action_submitted: 供应商提交 D4–D7 @@ -253,14 +268,17 @@ stateDiagram-v2 | 步骤 | 触发 | 动作 | |---|---|---| -| 1 生成 | 检验记录 upsert,`result == 'fail'` 且 `severity in ['critical','major']` | flow `srm_scar_create`:新建整改单,`sqe` 取物料品类的 SQE,`containment_due = 检验时间 + 72 小时`、`final_due = 检验日期 + 30 天`(可按严重度配置);通知供应商 `quality` 联系人与 SQE(BR-15)。`minor` 不合格只计入绩效,不自动开单 | +| 1 生成 | 交付记录写入,`inspection_result == 'fail'` 且 `severity in ['critical','major']`;或审核问题项经「转整改单」screen flow | flow `srm_scar_create`:新建整改单,`sqe` 取物料品类的 SQE,`containment_due = 创建时间 + scar_containment_hours`、`final_due = 创建日期 + scar_final_days`(参数见 `params/core.yaml`);通知供应商 `quality` 联系人与 SQE(BR-15)。`minor` 不合格只计入绩效,不自动开单。v0.6 前供应商的回复由 SQE 代填 | | 2 临时措施 | 供应商提交 D3 | 状态→`containment_submitted`;通知 SQE | | 3 根因与措施 | 供应商提交 D4–D7 | 状态→`action_submitted`;flow 发起 `approval` 节点:`field` 审批人 = `sqe`,驳回走「退回修改」回到供应商,退回意见写入 `sqe_comment`(FR-604) | | 4 效果验证 | SQE 审核通过 | 状态→`verifying`;SQE 跟踪后续批次,确认有效后关闭 | | 5 逾期升级 | 追赶式扫描 `srm_scar_overdue_sweep`(每小时 + 外部心跳) | 超过 `containment_due` 仍为 `open`、或超过 `final_due` 仍未到 `verifying`:`is_overdue = true`,提醒供应商并通知 SQE 主管(FR-605) | -| 6 索赔 | SQE 填写 `claim_amount`,`claim_status → proposed` | 供应商在门户接受或提出异议;接受后(`supplier_accepted`)由月度对账生成扣款行 | +| 6 索赔 | SQE 填写 `claim_amount`,`claim_status → proposed` | 供应商在门户接受或提出异议(v0.6 前线下确认后由 SQE 记录);接受后(`supplier_accepted`)由财务在 ERP 扣款,应付会计回来标记 `settled`。SRM 不生成扣款 | -## 9. P8 对账与结算 +## 9. P8 对账与结算(不做,留在 ERP) + +对账、开票、付款回写的记录系统是 ERP,本流程不在 SRM 实现([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md))。 +下表保留为剥离项的记录;付款进度查询在 ERP 集成后作为门户镜像另行设计。 | 步骤 | 触发 | 动作 | |---|---|---| @@ -277,116 +295,128 @@ stateDiagram-v2 > 更大时有两条路:按法人或品类拆成多个错峰的 `schedule` flow;或在自托管部署中把 > 「分组建单」实现为服务端函数,由 flow 调用(托管云上应用包函数不执行)。 -## 10. P9 季度绩效评估 +## 10. P9 绩效评估(v0.5) | 步骤 | 触发 | 动作 | |---|---|---| -| 1 生成 | `schedule`:每季度首日 03:00 | 为上季度有交易或在供的合格供应商各建一张考评单(`calculating`),按指标库建评分明细(FR-702) | -| 2 自动算分 | 同一次运行 | 按 [05 §4](./05-experience-and-analytics.md#4-仪表盘与指标口径) 的口径计算 OTD、批次合格率、PPM、订单响应及时率、价格指数,写入原始值与得分。计数类口径依赖收货、检验上的标志字段(`on_time`、`result`),由 flow 的查询节点按供应商和期间汇总 | +| 1 生成 | `schedule`:每月 1 日 03:00(追赶式) | 按供应商所供最高物资类别取周期参数 `perf_cycle`(示例 A 类每月、B 类每季、C 类每年);本次运行到期的供应商各建一张上期考评单(`calculating`,`cycle` / `period` 写明),按指标库建评分明细(FR-702);已有同期考评单的跳过 | +| 2 自动算分 | 同一次运行 | 按 [05 §4](./05-experience-and-analytics.md#4-仪表盘与指标口径) 的口径从交付记录计算 OTD、批次合格率、PPM,写入原始值与得分;订单响应及时率在 ERP 集成前为空、权重按参数重分配。由 flow 的查询节点按供应商和 `period` 汇总交付记录上的 `on_time`、`inspection_result`、`defect_quantity` | | 3 人工评分 | 状态→`scoring` | 按评分明细的 `scorer`(品类经理、SQE、需求部门评分人)通知,评分人经「提交评分」screen flow 只看到并填写分配给自己的评分项;截止 10 天,扫描任务提醒未评项;截止后未评项按「取 60 分并标记未评」处理(可配置) | -| 4 汇总分级 | 全部评分完成或截止 | `total_score = Σ(score × weight)`;等级默认 A ≥ 90、B 80–89、C 70–79、D < 70;状态→`reviewing` | +| 4 汇总分级 | 全部评分完成或截止 | `total_score = Σ(score × weight)`;等级线取参数 `perf_grade_min`(示例 A ≥ 90、B ≥ 80、C ≥ 70,其余 D);状态→`reviewing` | | 5 审定发布 | 审批:采购总监(`position = srm_procurement_director`) | 通过后→`published`;回写供应商 `grade`、`latest_score`;供应商可在门户查看结果与扣分项(FR-704) | -| 6 结果应用 | 发布后的记录触发 | C 级:生成改善要求(整改单,`source = audit`);连续两期 D 级:生成淘汰处置单草稿交品类经理评审(BR-18);A 级:在名录中标记优选,供寻源邀请参考 | +| 6 结果应用 | 发布后的记录触发 | C 级:生成改善要求(整改单,`source = performance`);D 级:生成处置单草稿(冻结);连续 `perf_d_exit_periods` 期 D 级:生成淘汰处置单草稿交品类经理评审(BR-18);A 级:在名录中标记优选,供寻源邀请参考 | | 7 申诉 | 供应商发布后 7 天内 | 状态→`appealed`,采购总监处理后回到 `published`,结果留痕(FR-706) | -## 11. P10 资质与风险监控 +## 11. P10 资质与风险监控(资质 v0.1,风险事件 v0.5) | 场景 | 触发 | 动作 | |---|---|---| | 到期提醒 | `time_relative`:证书 `valid_to`,提前 30 / 15 / 7 天 | 证书 `status → expiring`;通知 SQE 与供应商联系人(FR-901) | -| 到期生效 | 追赶式扫描:`valid_to < today` 且不是 `expired` | 证书→`expired`;`is_mandatory` 的证书过期时供应商 `qualification_alert = true`(FR-902);四期起同时新建 `qualification` 类风险事件 | +| 到期生效 | 追赶式扫描:`valid_to < today` 且不是 `expired`(定时 flow 在云上默认关闭,部署时打开,objectstack#25442) | 证书→`expired`;`is_mandatory` 的证书过期时供应商 `qualification_alert = true`(FR-902);v0.5 起同时新建 `qualification` 类风险事件 | | 供应商修改证书 | 证书的编号、有效期或附件被门户修改 | flow 把 `verified` 重置为 false,通知 SQE 重新核验 | -| 资质恢复 | 证书写入后的记录触发 | 重新计算:每一种必备资质类型都有 `status == 'valid'` 且 `verified == true` 的证书时,`qualification_alert = false`(四期起关闭对应风险事件)。只上传新证书而未经 SQE 核验,不会解除异常 | -| 外部风险 | `schedule`:每周一 04:00(四期) | flow 按批 `loop` 合格供应商,`http` 节点调用企业信息服务;新出现的经营异常、失信、重大诉讼、股权变更按 `external_ref` 去重后建风险事件,`high` 级通知品类经理(FR-903) | +| 资质恢复 | 证书或品类资格写入后的记录触发(`srm_supplier_qualification_recalc`) | 先按该供应商全部品类的 `mandatory_cert_types` 重算每张证书的 `is_mandatory`;再重新计算:每一种必备资质类型都有 `status == 'valid'` 且 `verified == true` 的证书时,`qualification_alert = false`(v0.5 起关闭对应风险事件)。只上传新证书而未经 SQE 核验,不会解除异常 | +| 风险事件处理 | 手工登记或系统生成(v0.5) | `high` 级事件通知品类经理并生成处置单草稿(冻结);关闭时填写处理结论 | +| 外部风险 | `schedule`:每周一 04:00(客户驱动主题) | flow 按批 `loop` 合格供应商,`http` 节点调用企业信息服务;新出现的经营异常、失信、重大诉讼、股权变更按 `external_ref` 去重后建风险事件(FR-903)。有客户要求时立项 | > v0.1 先实现其中的一部分:`srm_certificate_expire_sweep` 每日一次,把证书状态对齐到已过期 / 即将到期(30 天内)/ > 有效(有效期被延长时恢复);`srm_supplier_qualification_recalc` 在证书状态或「必备」标志变化后重算 -> `qualification_alert`。到期提醒通知、`is_mandatory` 按品类必备资质自动写入、「经 SQE 核验才解除」随门户版本 -> (v0.2)加入;v0.1 由内部人员维护证书与「必备」标志。 +> `qualification_alert`。到期提醒通知随 v0.1 收尾加入;`is_mandatory` 按品类必备资质自动写入随 v0.2;「经 SQE 核验才解除」 +> 随 v0.4 供应商审核加入;在此之前由内部人员维护证书与「必备」标志。 ## 12. 审批矩阵 -审批人一律按**岗位**或**记录上的人员字段**解析,不写死具体的人;换人只改岗位任命, -不改流程。金额阈值放在应用包的常量配置里,实施时按企业授权手册调整。 +本表是审批权限的**唯一来源**(2026-10-23 决定,P-D1):体系文件的 ZC-02、QP-01 附录 C、 +GL-02 附录 A 按本表编写,制度里的岗位称谓经 `governance/org.yaml` 的 `position.*` 映射到 +下列岗位。审批人一律按**岗位**或**记录上的人员字段**解析,不写死具体的人;换人只改岗位 +任命,不改流程。金额档、有效报价家数等阈值取 `params/core.yaml`(`award_approval_tiers`、 +`min_valid_quotes`),实施时按企业授权手册在客户参数里替换。 | 单据 | 条件 | 第 1 级 | 第 2 级 | 第 3 级 | 方式 | |---|---|---|---|---|---| | 准入申请 | 全部 | 品类经理(`field: reviewer`) | 采购总监 | — | 串行 | -| 准入申请 | 高风险品类 | 品类经理 | 采购总监 + 质量经理 | — | 第 2 级并行 `unanimous` | -| 单一来源寻源 | 全部 | 品类经理 | 采购总监 | — | 串行 | -| 定标 | `awarded_amount < 10 万` | 品类经理 | — | — | — | -| 定标 | `10 万 ≤ 金额 < 100 万` | 品类经理 | 采购总监 | — | 串行 | -| 定标 | `金额 ≥ 100 万` | 品类经理 | 采购总监 | 总经理 | 串行 | -| 定标 | 有效报价 < 3 家 | 在上表基础上增加一级 | | | | -| 合同 | 全部 | 法务(`field: legal_reviewer`) | 按定标同档金额审批 | | 串行 | -| 银行账户变更 | 全部 | 采购主管 | 应付会计 | — | 串行,两级不同岗位 | +| 准入申请 | A 类物资(`material_class == 'a'`)或高风险品类(`risk_class == 'high'`) | 品类经理 | 采购总监 + 质量经理 | — | 第 2 级并行 `unanimous` | +| 单一来源寻源 | 预算 < `high` 档 | 品类经理 | 采购总监 | — | 串行 | +| 单一来源寻源 | 预算 ≥ `high` 档 | 品类经理 | 采购总监 | 总经理 | 串行 | +| 定标 | `awarded_amount < mid` 档(示例 10 万) | 品类经理 | — | — | — | +| 定标 | `mid ≤ 金额 < high` 档(示例 10–100 万) | 品类经理 | 采购总监 | — | 串行 | +| 定标 | `金额 ≥ high` 档(示例 100 万) | 品类经理 | 采购总监 | 总经理 | 串行 | +| 定标 | 有效报价 < `min_valid_quotes`(按当前轮次) | 在上表基础上增加一级 | | | | +| 合同 | 全部 | 法务(`field: legal_reviewer`) | 按定标同档金额审批(框架协议按年度预计金额) | | 串行 | +| 银行账户新增 / 变更 | 全部 | 采购主管 | 应付会计 | — | 串行,两级不同岗位 | | 其他信息变更 | 全部 | 采购主管 | — | — | — | | 冻结 / 解冻 | 全部 | 品类经理 | 采购总监 | — | 串行 | -| 淘汰 / 黑名单 / 解除黑名单 | 全部 | 品类经理 | 采购总监 | 总经理 | 串行 | +| 淘汰 / 黑名单 / 解除黑名单 | 全部 | 品类经理 | 采购总监 | 总经理 | 串行;黑名单由内控会签 | | 绩效发布 | 全部 | 采购总监 | — | — | — | | SCAR 措施审核 | 全部 | SQE(`field: sqe`) | — | — | 可退回修改 | +物资 A / B / C 分类(`srm_category.material_class`,P-D2)在系统里决定三件事:准入是否会签 +质量经理、现场审核频次(制度)、绩效周期(`perf_cycle`)。制度原来按类别区分的准入层级和 +冻结层级统一为上表,减少一个判断维度。 + 职责分离:同一张单据的发起人不应出现在审批人中。平台审批服务目前**没有**内置 -「提交人不得审批本人单据」的开关,本设计用两层保证:岗位设置上,发起岗与审批岗不 -由同一人兼任;在 flow 中,审批人等于发起人时改用上一级岗位(`expression` 审批人)。 -详见 [04 §6](./04-security-and-portal.md#6-职责分离sod)。 +「提交人不得审批本人单据」的开关(已提需求 objectstack#25446),本设计用两层保证:岗位 +设置上,发起岗与审批岗不由同一人兼任;在 flow 中,审批人等于发起人时改用上一级岗位 +(`expression` 审批人),并用校验规则拦截提交人 = 审批人。详见 [04 §6](./04-security-and-portal.md#6-职责分离sod)。 ## 13. 自动化清单 -| flow | 触发 | 对象 | 期次 | +定时类 flow 在托管云上默认关闭(objectstack#25442),部署时打开开关。标「预留」的 +flow 属于 ERP 集成后的门户镜像,现阶段不建。 + +| flow | 触发 | 对象 | 版本 | |---|---|---|---| -| `srm_application_intake` | record_change:新建 | 准入申请 | 一期 | -| `srm_admission_approval` | record_change:状态→`admission_review` | 准入申请 | 一期 | -| `srm_certificate_expiry_notice` | time_relative:`valid_to` −30 / −15 / −7 天 | 资质证书 | 一期 | -| `srm_certificate_expire_sweep` | schedule:每日 01:00(追赶式) | 资质证书 | 一期 | -| `srm_supplier_qualification_recalc` | record_change:证书写入 | 资质证书 → 供应商 | 一期 | -| `srm_single_source_approval` | record_change:状态→`approval_pending` | 寻源单 | 一期 | -| `srm_event_publish` | record_change:状态→`published` | 寻源单 | 一期 | -| `srm_bid_close_sweep` | schedule:每 10 分钟 + api 心跳 | 寻源单、报价单 | 一期 | -| `srm_bid_open` | screen:「开标」 | 寻源单、报价单 | 一期 | -| `srm_bid_scoring` | record_change:技术评分写入 | 报价单 | 一期 | -| `srm_award_approval` | record_change:状态→`award_review` | 寻源单 | 一期 | -| `srm_award_apply` | record_change:状态→`awarded` | 寻源单 → 价格记录 | 一期 | -| `srm_change_approval` / `srm_change_apply` | record_change | 变更单 | 二期 | -| `srm_disposition_approval` / `srm_disposition_apply` | record_change | 处置单 | 二期 | -| `srm_contract_approval` | record_change:状态→`in_review` | 合同 | 二期 | -| `srm_contract_expiry_notice` / `srm_contract_expire_sweep` | time_relative / schedule | 合同 | 二期 | -| `srm_esign_callback` | api | 合同 | 二期 | -| `srm_po_release_notice` | record_change:新建 | 订单 | 二期 | -| `srm_po_line_ack` | record_change:答复交期写入 | 订单行 → 订单 | 二期 | -| `srm_po_ack_sweep` | schedule:每小时 + api 心跳 | 订单 | 二期 | -| `srm_receipt_apply` | record_change:新建 / 更新 | 收货记录 → 订单行、送货单 | 二期 | -| `srm_scar_create` | record_change:检验写入 | 检验 → 整改单 | 三期 | -| `srm_scar_review` | record_change:状态→`action_submitted` | 整改单 | 三期 | -| `srm_scar_overdue_sweep` | schedule:每小时 + api 心跳 | 整改单 | 三期 | -| `srm_performance_generate` | schedule:每季度首日 | 考评单 | 三期 | -| `srm_performance_publish` | record_change:状态→`reviewing` | 考评单 → 供应商 | 三期 | -| `srm_statement_generate` | schedule:每月 1 日 | 对账单 | 四期 | -| `srm_invoice_post` | record_change:发票校验通过 | 发票 → ERP | 四期 | -| `srm_payment_callback` | api | 发票、对账单 | 四期 | -| `srm_external_risk_scan` | schedule:每周一 | 风险事件 | 四期 | -| `srm_erp_push_retry` | schedule:每 15 分钟(追赶式) | 所有带同步字段的对象 | 一期 | +| `srm_application_intake` | record_change:新建 | 准入申请 | v0.1 | +| `srm_application_accept` | record_change:状态→`doc_review` | 准入申请 → 供应商、联系人 | v0.1 | +| `srm_admission_approval` | record_change:状态→`admission_review` | 准入申请 | v0.1 | +| `srm_certificate_expiry_notice` | time_relative:`valid_to` −30 / −15 / −7 天 | 资质证书 | v0.1 | +| `srm_certificate_expire_sweep` | schedule:每日 01:00(追赶式) | 资质证书 | v0.1 | +| `srm_supplier_qualification_recalc` | record_change:证书、品类资格写入 | 资质证书 → 供应商 | v0.1 | +| `srm_change_approval` / `srm_change_apply` | record_change | 变更单、银行账户 | v0.2 | +| `srm_contract_approval` | record_change:状态→`in_review` | 合同 | v0.3 | +| `srm_contract_expiry_notice` / `srm_contract_expire_sweep` | time_relative / schedule | 合同 | v0.3 | +| `srm_disposition_approval` / `srm_disposition_apply` | record_change | 处置单 | v0.3 | +| `srm_delivery_apply` | record_change:交付记录写入 | 交付记录 | v0.4 | +| `srm_scar_create` | record_change:交付记录不合格 | 交付记录 → 整改单 | v0.4 | +| `srm_scar_review` | record_change:状态→`action_submitted` | 整改单 | v0.4 | +| `srm_scar_overdue_sweep` | schedule:每小时 + api 心跳 | 整改单 | v0.4 | +| `srm_performance_generate` | schedule:每月 1 日(按类别周期) | 考评单 | v0.5 | +| `srm_performance_publish` | record_change:状态→`reviewing` | 考评单 → 供应商 | v0.5 | +| `srm_performance_apply` | record_change:状态→`published` | 考评单 → 整改单、处置单 | v0.5 | +| `srm_risk_event_apply` | record_change:风险事件新建 | 风险事件 → 处置单 | v0.5 | +| `srm_invitation_send` / `srm_invitation_expire_sweep` | record_change / schedule | 门户邀请 | v0.6 | +| `srm_portal_position_backfill` | record_change:供应商 `portal_position` 写入 | 供应商 → 带 `portal_position` 的单据 | v0.6 | +| `srm_single_source_approval` | record_change:状态→`approval_pending` | 寻源单 | v0.7 | +| `srm_event_publish` | record_change:状态→`published` | 寻源单 | v0.7 | +| `srm_bid_close_sweep` | schedule:每 10 分钟 + api 心跳 | 寻源单、报价单 | v0.7 | +| `srm_bid_scoring` | record_change:技术评分写入 | 报价单 | v0.7 | +| `srm_award_approval` | record_change:状态→`award_review` | 寻源单 | v0.7 | +| `srm_award_apply` | record_change:状态→`awarded` | 寻源单 → 价格记录 | v0.7 | +| `srm_po_release_notice`、`srm_po_line_ack`、`srm_po_ack_sweep`、`srm_receipt_apply` | — | 订单、送货单 | 预留(ERP 集成后) | +| `srm_esign_callback`、`srm_erp_push_retry`、`srm_external_risk_scan` | api / schedule | 合同、同步字段、风险事件 | 客户驱动主题 | +| `srm_statement_generate`、`srm_invoice_post`、`srm_payment_callback` | — | — | 不做(ERP) | 用户操作入口的 screen flow(均以系统身份运行,flow 内做校验后再写入): -| screen flow | 入口 | 使用者 | 期次 | +| screen flow | 入口 | 使用者 | 版本 | |---|---|---|---| -| `srm_invite_supplier` 邀请供应商 | 寻源单 | 寻源工程师 | 一期 | -| `srm_event_submit` 发布 | 寻源单 | 寻源工程师 | 一期 | -| `srm_deadline_extend` 延期截止 | 寻源单 | 寻源工程师 | 一期 | -| `srm_bid_open` 开标 | 寻源单 | 所有者、采购总监 | 一期 | -| `srm_technical_score` 技术评分 | 报价单 | 评标小组 | 一期 | -| `srm_next_round` 下一轮 | 寻源单 | 寻源工程师 | 一期 | -| `srm_award_submit` 提交定标 | 寻源单 | 寻源工程师 | 一期 | -| `srm_event_cancel` 取消 / 流标 | 寻源单 | 寻源工程师 | 一期 | -| `srm_certificate_verify` 核验证书 | 资质证书 | SQE | 一期 | -| `srm_bank_verify` 核验银行账户 | 银行账户 | 应付会计 | 一期 | -| `srm_portal_enable` 开通门户 | 供应商联系人 | `srm_supplier_admin` | 一期 | -| `srm_change_submit` 提交变更申请 | 门户:公司资料 | 门户管理员 | 二期 | -| `srm_asn_create` 创建送货单 | 门户:订单 | 门户用户 | 二期 | -| `srm_score_submit` 提交评分 | 考评单 | 评分人 | 三期 | -| `srm_appeal_submit` 申诉 | 门户:绩效 | 门户管理员 | 三期 | -| `srm_invoice_submit` 提交发票 | 门户:对账单 | 门户用户 | 四期 | +| `srm_certificate_verify` 核验证书 | 资质证书 | SQE | v0.1 | +| `srm_primary_contact_set` 设为主联系人 | 供应商联系人 | `srm_supplier_admin` | v0.1 | +| `srm_bank_verify` 核验银行账户 | 银行账户 | 应付会计 | v0.2 | +| `srm_change_submit` 提交变更申请 | 供应商档案(v0.6 起门户:公司资料) | 采购员;v0.6 起门户管理员 | v0.2 | +| `srm_audit_finding_to_scar` 转整改单 | 供应商审核 | SQE | v0.4 | +| `srm_score_submit` 提交评分 | 考评单 | 评分人 | v0.5 | +| `srm_appeal_submit` 申诉 | 门户:绩效 | 门户管理员 | v0.6 | +| `srm_portal_enable` 开通门户 | 供应商联系人 | `srm_supplier_admin` | v0.6 | +| `srm_invite_supplier` 邀请供应商 | 寻源单 | 寻源工程师 | v0.7 | +| `srm_event_submit` 发布 | 寻源单 | 寻源工程师 | v0.7 | +| `srm_deadline_extend` 延期截止 | 寻源单 | 寻源工程师 | v0.7 | +| `srm_bid_open` 开标 | 寻源单 | 所有者、采购总监 | v0.7 | +| `srm_technical_score` 技术评分 | 报价单 | 评标小组 | v0.7 | +| `srm_next_round` 下一轮 | 寻源单 | 寻源工程师 | v0.7 | +| `srm_award_submit` 提交定标 | 寻源单 | 寻源工程师 | v0.7 | +| `srm_event_cancel` 取消 / 流标 | 寻源单 | 寻源工程师 | v0.7 | +| `srm_asn_create` 创建送货单 | 门户:订单 | 门户用户 | 预留(ERP 集成后) | +| `srm_invoice_submit` 提交发票 | — | — | 不做(ERP) | 所有写其他用户不可见数据的 flow(例如开标时更新封标中的报价单、受理时创建供应商) 声明以系统身份运行;只改当前用户自己可见数据的 flow 以用户身份运行。 diff --git a/docs/design/04-security-and-portal.md b/docs/design/04-security-and-portal.md index c89060b..0a48efb 100644 --- a/docs/design/04-security-and-portal.md +++ b/docs/design/04-security-and-portal.md @@ -2,6 +2,10 @@ > 所属:[SRM 设计总览](./README.md) · 上一篇:[03 流程与自动化](./03-processes-and-automation.md) · 下一篇:[05 界面与分析](./05-experience-and-analytics.md) +> 版本:内部岗位与权限集随 v0.1–v0.5 逐步建立;供应商门户在 v0.6,前提是门槛 1 通过、 +> objectstack#25233(门户用户可列出全组织用户)修复,并完成 [07 §6](./07-delivery-plan.md#6-平台依赖与验证结果) 的 V1–V5 实测; +> 封标在 v0.7。订单、送货、对账、发票相关的权限为 ERP 集成后的预留([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md))。 + ## 1. 安全目标与主要威胁 SRM 同时服务内部员工和互相竞争的供应商,权限设计的首要目标是**供应商之间零可见**, @@ -14,9 +18,9 @@ SRM 同时服务内部员工和互相竞争的供应商,权限设计的首要 | S3 | AI 助手被用来绕过封标或越权查询 | 同 S1、S2 | AI 以提问者身份调用,受同一套 RLS / FLS 约束 | §4、[06 §3](./06-integration-and-ai.md#3-ai-助手) | | S4 | 伪造银行账户变更,把货款转到骗子账户 | 直接资金损失 | 变更双人审批、新账户待核验、ERP 推送前不生效 | [03 §5](./03-processes-and-automation.md#5-p2-信息变更与供应商处置) | | S5 | 寻源发起人自己审批自己的定标 | 职责分离失效 | 岗位分离 + 审批人等于发起人时改走上一级 | §6 | -| S6 | 公开注册表单被灌水或注入伪造字段 | 垃圾数据,越权写入 | 平台剥离服务端字段 + 初始状态约束 + 前置限流 | §8 | +| S6 | 公开注册表单被灌水或注入伪造字段 | 垃圾数据,越权写入 | v0.6 默认邀请注册,不开公开表单;开放时:平台剥离服务端字段 + 初始状态约束 + 前置限流 + 人工确认后才建主数据 | §8 | | S7 | 离职员工或终止合作的供应商账号仍可登录 | 数据外泄 | 账号回收流程,岗位任命随供应商状态撤销 | §3.3 | -| S8 | 门户用户通过用户目录看到其他供应商的账号或员工名单 | 暴露竞争对手、泄露员工联系方式 | 第 0 期实测用户目录可见范围,不满足时在平台层面解决或书面接受 | §3.6 | +| S8 | 门户用户通过用户目录看到其他供应商的账号或员工名单 | 暴露竞争对手、泄露员工联系方式 | 已实测存在(objectstack#25233,P1);平台修复前不开门户 | §3.6 | ## 2. 角色、岗位与权限集 @@ -50,17 +54,17 @@ SRM 同时服务内部员工和互相竞争的供应商,权限设计的首要 | `srm_internal_base` | 内部员工的基础:读品类、物料、工厂、供应商主数据(不含银行账号)、价格库;**不是** `isDefault` | | `srm_sourcing` | 寻源单、寻源明细的增改(状态只经 screen flow 推进);邀请、技术评分、定标只经 screen flow;读报价(受封标 RLS 约束);新建合同 | | `srm_supplier_admin` | 供应商档案、联系人、证书、准入申请、审核、供货品类资格、处置单、合同的增改;开通门户 | -| `srm_buyer` | 订单、订单行、送货单、收货记录读;订单行的内部字段可改;对账单增改 | -| `srm_quality` | 审核、检验、整改单的增改;证书只读,核验经 screen flow | -| `srm_iqc` | 检验的增改 | -| `srm_finance` | 银行账号可读,核验经 screen flow;对账单确认;发票读改 | +| `srm_buyer` | 供应商档案、合同、交付记录读;代供应商发起变更单(v0.6 前);ERP 集成后加订单、送货单的内部字段 | +| `srm_quality` | 审核、交付记录(录入)、整改单的增改;证书只读,核验经 screen flow | +| `srm_iqc` | 交付记录的录入(没有质量系统的客户) | +| `srm_finance` | 银行账号可读,核验经 screen flow;银行账户变更的第 2 级审批;整改单索赔结论标记 | | `srm_legal` | 合同读改(审批由 flow 授予) | | `srm_executive` | 全部 SRM 对象只读 + 仪表盘;审批由 flow 授予,不需要额外写权限 | | `srm_auditor` | 全部 SRM 对象只读(报价同样受封标约束),可读审批历史与字段历史,不可导出银行账号 | | `srm_admin` | 品类、指标库、编码、通知模板的配置;不授予报价读权限 | | `srm_portal_supplier` | 供应商门户用户:见 §3.2 | | `srm_portal_supplier_admin` | 在 `srm_portal_supplier` 之上:维护本公司联系人、银行账户,提交变更申请与绩效申诉;直接授予具体用户 | -| `srm_integration` | ERP 集成服务账号:物料、工厂、订单、收货、检验、付款结果的写入,供应商、价格、对账、发票的读取;**不**授予报价单与银行账号 | +| `srm_integration` | 预留(ERP 集成后):集成服务账号,物料、交付记录、订单镜像的写入;供应商仅可写 `erp_vendor_code`,价格记录只读;**不**授予报价单与银行账号 | **为什么 SRM 不用 `isDefault` 权限集**:`isDefault` 的权限集绑定到组织的每一个成员。 在托管云上,供应商的门户用户也是组织成员,一个 `isDefault` 的内部权限集会直接把 @@ -85,23 +89,22 @@ R 读 · C 建 · E 改 · D 删 · F 仅经 flow / screen flow 写入 · — | 寻源邀请 | R | RF | R | — | — | — | RE(本公司:接受 / 拒绝) | | 报价单 / 明细 | — | R(开标后)+ F(评分、定标) | — | — | — | — | RE(本公司,截止前且未开标) | | 价格记录 | R | RF | R | R | — | R | R(本公司) | -| 合同 | — | RC | RCE | RE(上传签署件) | — | R | R(本公司,签署中及以后) | -| 采购订单 / 行 | R | — | — | RE | R | R | RE(本公司:订单头字段全部只读,订单行只能改答复字段) | -| 送货单 / 明细 | R | — | — | RE | R | — | R + F(创建) | -| 收货 / 检验 | R | — | — | R | RCE | R | R(本公司) | -| 整改单 | R | — | — | R | RCE | — | RE(本公司:回复) | +| 合同 / 合同明细 | — | RC | RCE | RE(上传签署件) | — | R | R(本公司,签署中及以后) | +| 交付记录 | R | — | — | R | RCE(录入) | R | R(本公司) | +| 供应商审核 | R | — | R | — | RCE | — | — | +| 整改单 | R | — | — | R | RCE | R(索赔结论) | RE(本公司:回复) | | 考评单 / 评分明细 | R | — | — | R | R | — | R(本公司,已发布)+ F(申诉) | -| 对账单 / 明细 | — | — | — | RCE | — | RE | RE(本公司:确认 / 差异) | -| 发票 | — | — | — | R | — | RE | R + F(提交) | | 风险事件 | R | R | RCE | R | RCE | R | — | +| 门户邀请 | — | — | RCE | RC | — | — | — | +| 采购订单 / 行、送货单 / 明细 | 预留(ERP 集成后的门户镜像):内部 R,采购员改内部字段,门户只改答复字段 / 经 F 建送货单 | | | | | | | +| 对账单、发票 | 不做(ERP) | | | | | | | 表中未列的权限集:`srm_executive`、`srm_auditor` 对全部对象只读(报价同样受封标约束); `srm_legal` 对合同读改;`srm_iqc` 对检验增改;绩效评分只经「提交评分」screen flow。 -**`controlled_by_parent` 的写入规则**:子记录(联系人、证书、银行账户、订单行、报价 -明细、对账明细)的修改要求对父记录有编辑权。所以门户对供应商、订单、对账单都授予 -编辑权,再用字段级权限把父记录上门户不该改的字段设为只读——表中「RE」带括号说明的 -就是这种情况。 +**`controlled_by_parent` 的写入规则**:子记录(联系人、证书、银行账户、合同明细、报价 +明细)的修改要求对父记录有编辑权。所以门户对供应商、报价单都授予编辑权,再用字段级 +权限把父记录上门户不该改的字段设为只读——表中「RE」带括号说明的就是这种情况。 ## 3. 供应商门户的数据隔离 @@ -148,20 +151,17 @@ flowchart LR | 供应商 | 本公司 | 只能改资料字段(§4.2);名称、地址、银行账户等关键信息走变更单 | RLS 在供应商自身的 `portal_position` 上;授予编辑权是为了让门户能维护证书等子记录 | | 联系人、证书、银行账户、品类资格 | 跟随供应商 | 证书可增改;联系人和银行账户仅门户管理员可增 | `controlled_by_parent` | | 准入申请 | 本公司 | 「退回补充」状态时可改 | | -| 变更单 | 本公司 | 只经「提交变更申请」screen flow(门户管理员) | 二期 | +| 变更单 | 本公司 | 只经「提交变更申请」screen flow(门户管理员) | v0.6 | | 寻源邀请 | 本公司 | 可改 `status`(接受 / 拒绝)与拒绝原因 | 邀请上有寻源单的快照,门户不读寻源单本身 | | 报价单 | 本公司 | `status in ['draft','submitted'] && bid_opened == false` 的本公司报价 | 写策略 `using` 限定可改哪些行,`check` 限定改完仍属本公司;上一轮的 `superseded` 报价不可改 | | 报价明细 | 跟随报价单 | 跟随报价单;只能改单价、交期、税率、起订量、备注 | 截止后由校验规则锁定(BR-06);金额、中标字段、快照字段只读 | | 价格记录 | 本公司 | — | | | 合同 | 本公司且 `status in ['signing','active','expired','terminated']` | — | 草稿与审批中的合同不可见 | -| 采购订单 / 订单行 | 本公司 | 订单行的答复字段 | 订单头授予编辑权但字段全部 FLS 只读,订单行除答复字段外只读 | -| 送货单 / 明细 | 本公司 | 只经「创建送货单」screen flow | | -| 收货记录、检验 | 本公司 | — | | +| 交付记录 | 本公司 | — | 供应商看到的是用于算分的交付结果 | | 整改单 | 本公司 | 供应商回复字段 | `sqe_comment`、`claim_amount` 只读 | | 考评单 / 评分明细 | 本公司且 `status == 'published'` | 只经「申诉」screen flow | 未发布的考评不可见 | -| 对账单 / 明细 | 本公司且 `status != 'draft'` | 确认、标记差异 | 草稿阶段不可见 | -| 发票 | 本公司 | 只经「提交发票」screen flow | | -| 寻源单、寻源明细、审核、风险事件 | 不可见 | — | 门户权限集不授予这些对象 | +| 采购订单 / 订单行、送货单 / 明细 | 预留(ERP 集成后) | 订单行的答复字段;送货单只经 screen flow | 订单头授予编辑权但字段全部 FLS 只读 | +| 寻源单、寻源明细、审核、风险事件、门户邀请 | 不可见 | — | 门户权限集不授予这些对象 | ### 3.3 门户账号的开通与回收 @@ -172,12 +172,15 @@ flowchart LR 1. 在组织成员页按联系人邮箱发出邀请,角色为普通成员; 2. **该供应商第一次开通门户时**,由管理员在 Setup 新建岗位 `srm_vendor_<编号>`,并在 岗位定义里挂上门户权限集。平台把岗位视为环境级的**定义**(元数据),不是数据行, - 所以这一步不能由 flow 完成,需要持有元数据编辑权限的管理员操作; + 所以这一步不能由 flow 完成,需要持有元数据编辑权限的管理员操作(已向平台提出 + 「按外部方在运行时建岗位并任命」,objectstack#25443;存量供应商批量开通时管理员 + 按清单批量建); 3. 运行「开通门户」screen flow:选择联系人、已加入的用户和刚建的岗位 → 写入供应商的 `portal_position`,并把它回填到该供应商已有的单据上 → 把用户任命到该岗位(任命是 - 数据行,flow 以系统身份写入,第 0 期验证)→ 在联系人上写 `portal_user`;联系人 - 角色含 `admin` 时,再把门户管理员权限集**直接授予该用户**(同一家供应商的用户共用 - 一个岗位,管理员能力只能按人授予); + 数据行,flow 以系统身份写入是否放行按 07 §6 V3 实测,objectstack#25251;不放行时 + 由管理员在成员页任命,flow 只做回填)→ 在联系人上写 `portal_user`;联系人 + `contact_function` 含 `admin` 时,再把门户管理员权限集**直接授予该用户**(同一家供应商 + 的用户共用一个岗位,管理员能力只能按人授予); 4. 同一供应商以后再开通账号,只需第 1、3 步。 岗位定义随开通门户的供应商数量增长(几百到上千个),设置界面的岗位列表会变长。 @@ -189,7 +192,7 @@ flowchart LR | 场景 | 动作 | |---|---| | 联系人离职 / 停用 | 撤销岗位任命,移出组织;联系人 `active = false` | -| 供应商冻结 | 账号与门户功能保持不变:在途订单仍要确认、送货、对账;冻结只阻止新的询价邀请和新订单(BR-03 与 ERP 侧冻结标志) | +| 供应商冻结 | 账号与门户功能保持不变:整改单仍要回复,资料仍要维护;冻结只阻止新的询价邀请(BR-03),新订单由 ERP 侧冻结标志拦截 | | 供应商淘汰 / 黑名单 | 处置 flow 撤销该岗位的全部任命,账号移出组织 | | 季度复核 | 报表列出每家供应商的门户账号与在职联系人,差异由采购主管确认 | @@ -279,11 +282,10 @@ export const PortalSupplier = definePermissionSet({ 门户权限集只能放宽或收窄 SRM 自己的对象,用户目录由平台的成员权限决定。因此: -1. 第 0 期在目标部署上实测门户界面和 REST API 上用户目录的实际可见范围,纳入 - §3.7 的验收用例; -2. 不满足上述要求时,由部署方在平台层面解决(例如为外部用户使用独立的成员类型); -3. 若必须在解决前上线,由业务方书面接受该风险,并把门户用户的显示名统一为 - 「公司简称-角色」,减少个人信息暴露。 +1. 已实测:门户用户在界面和 REST 上能列出全组织用户(objectstack#25233,P1,已补充 SRM + 场景);纳入 §3.7 的验收用例,v0.6 开工前复测; +2. 平台修复前不开门户;若必须在解决前上线,由业务方书面接受该风险,并把门户用户的 + 显示名统一为「公司简称-角色」,减少个人信息暴露。 ### 3.7 隔离验收测试 @@ -321,7 +323,10 @@ export const PortalSupplier = definePermissionSet({ - **数量可见、内容不可见**:寻源单上的 `submitted_quote_count` 由平台在报价写入时重算, 内部能看到「已报价 N 家」; - **开标由 flow 以系统身份执行**:它需要更新内部尚不可见的报价,这是唯一被允许的 - 系统身份写入,flow 本身留有运行记录。 + 系统身份写入,flow 本身留有运行记录; +- **价格记录不受封标约束**:`srm_supplier_admin`、`srm_buyer` 对价格记录可读,但价格记录 + 在定标后才由 flow 产生,与中标报价一一对应,不泄露封标期间的任何报价; +- **平台管理员的数据库级访问**是已知例外,写进运维制度(GL-10)而不是应用权限。 ### 4.2 字段级权限(FLS) @@ -333,14 +338,16 @@ export const PortalSupplier = definePermissionSet({ | `srm_sourcing_item.target_price` / `last_price` | 同上 | 寻源 | 同上 | | `srm_quotation.technical_score` / `commercial_score` / `total_score` / `rank` | 内部评标相关角色(开标后) | 寻源、评标 flow | 门户不可见,防止供应商据此调价 | | `srm_quotation.bid_opened` / `quote_deadline` | 所有可读报价的人 | 仅 flow | 封标开关与锁价依据 | -| `srm_po_line.unit_price` / `quantity` / `required_date` | 内部、本公司门户 | 仅 ERP 集成 | 订单以 ERP 为准 | +| `srm_delivery_record` 全部字段 | 内部、本公司门户 | 仅导入与质检员录入 | 交付结果以 ERP / 质量系统为准 | +| `srm_sourcing_event.budget_amount`、`srm_sourcing_item.target_price` / `last_price` | 寻源、采购总监、内控 | 寻源 | 寻源单 OWD 为 `public_read`,预算类字段靠 FLS 保护,不另做按品类的共享规则 | +| `srm_po_line.unit_price` / `quantity` / `required_date`(预留) | 内部、本公司门户 | 仅 ERP 集成 | 订单以 ERP 为准 | | `srm_quality_issue.claim_amount` | 内部、本公司门户 | SQE | | | `srm_performance_review.*_score` | 内部、本公司门户(已发布) | 算分 flow、评分人 | | | `*.portal_position` | 所有可读该记录的人 | 仅 flow | 隔离锚点,门户不可改 | | `srm_supplier` 的 `name`、`country`、`credit_code`、`registration_no`、`address`、`legal_representative`、`registered_capital`、`status`、`grade`、`qualification_alert`、`erp_vendor_code` | 内部、本公司门户 | 内部(关键信息变更走变更单) | 门户只读;门户可直接改的只有 `short_name`、`website`、`supplier_type`、`taxpayer_type`、`established_date` 等资料字段 | | `srm_supplier_certificate.status` / `is_mandatory` / `verified` | 内部、本公司门户 | 仅 flow 与「核验证书」screen flow | 防止供应商自行解除资质异常 | | `srm_quotation_line` 的 `amount`、`is_awarded`、`award_quantity`、`award_ratio` 及快照字段 | 所有可读报价的人 | 仅 flow | 防止供应商改金额或自报中标 | -| `srm_purchase_order` 全部字段 | 内部、本公司门户 | 内部与集成 | 门户对订单头有编辑权只为写订单行,字段全部只读 | +| `srm_purchase_order` 全部字段(预留) | 内部、本公司门户 | 内部与集成 | 门户对订单头有编辑权只为写订单行,字段全部只读 | ## 5. 多法人与多工厂 @@ -359,15 +366,15 @@ export const PortalSupplier = definePermissionSet({ 一份。开墙后每个法人各有一份供应商档案,正是 SRM 要消除的痛点 T1; 2. **门户用户只需加入一个组织**:在多组织隔离下,同一家供应商的用户要加入它供货的 每个法人组织,账号管理成本成倍增加; -3. **法人维度用字段表达**:订单、对账单、合同、发票上都有 `legal_entity` / `plant` - 字段,报表按法人出数,对账按「供应商 × 法人」生成,不需要墙。 +3. **法人维度用字段表达**:合同、交付记录上有 `legal_entity` / `plant` 字段,报表按法人 + 出数,不需要墙;订单、对账在 ERP(ADR-0008)。 内部「只看本工厂」的可见性有两种做法: | 做法 | 版本 | 适用 | |---|---|---| | 共享规则:按 `plant` 字段把单据共享给对应工厂的业务单元(criteria 规则,接收方为 `business_unit`) | 开源 | 工厂数量少且稳定 | -| 层级范围:内部权限集对订单、对账单声明 `readScope: 'unit_and_below'` | 企业版(`hierarchySecurity`) | 组织层级多、需要「集团看全部、工厂看本厂」的逐级可见 | +| 层级范围:内部权限集对合同、交付记录声明 `readScope: 'unit_and_below'` | 企业版(`hierarchySecurity`) | 组织层级多、需要「集团看全部、工厂看本厂」的逐级可见 | **什么时候改为开墙**:先问三个问题——这个法人需要自己的管理员班子独立管理用户和 权限吗?有监管或合资方要求的数据隔离吗?未来可能被整体出售或分立吗?三问都是「否」 @@ -380,12 +387,12 @@ export const PortalSupplier = definePermissionSet({ | 发起寻源 ↔ 审批定标 | 寻源工程师岗位不挂审批岗位;定标审批 flow 的第 1 级审批人用 `expression` 计算:品类经理若就是寻源单所有者,则改为采购总监 | | 维护银行账户 ↔ 核验银行账户 | 门户管理员或采购录入,应付会计核验;变更单两级审批人分属采购与财务两个岗位 | | 准入资料审核 ↔ 准入批准 | 第 1 级审批人是 `reviewer`(品类经理),第 2 级为采购总监岗位 | -| 录入收货 ↔ 确认对账 | 收货来自 ERP / WMS,SRM 内无人可改收货数量;对账由应付会计确认 | +| 录入交付记录 ↔ 评价绩效 | 交付记录来自 ERP 导出或质检员录入,采购员和品类经理不能改;绩效由 flow 算分、采购总监审定 | | 修改价格 ↔ 下单 | 价格记录只经定标 flow 产生,任何角色无直接编辑权限;订单价格以 ERP 为准 | | 系统配置 ↔ 业务数据 | `srm_admin` 不授予报价读权限、不参与任何审批 | 上表的「岗位分离 + `expression` 改派」在应用层保证发起人不审批本人单据,不依赖平台 -提供专门的开关(见 [07 §6](./07-delivery-plan.md#6-平台依赖与待验证项))。 +提供专门的开关(见 [07 §6](./07-delivery-plan.md#6-平台依赖与验证结果))。 ## 7. 审计、合规与数据保护 @@ -397,10 +404,15 @@ export const PortalSupplier = definePermissionSet({ | AI 操作可审计 | 企业版 AI 治理:每次工具调用记录提问者、问题与触达的数据 | | 个人信息保护 | 注册表单展示个人信息处理告知并要求勾选同意;只收集业务必需的联系人信息;联系人停用后按保留期限清理 | | 导出控制 | 报价、银行账户所在对象的导出权限只给内控与应付会计;导出动作留痕 | +| 客户层定制不越权 | 客户在 Studio 覆盖层新增的字段、视图不得放宽门户 RLS 与封标 RLS;核心升级前跑「核心 + 客户层」组合构建复核([ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md)) | ## 8. 公开注册表单的防护 -准入申请通过公开表单匿名提交,是整个系统唯一对互联网开放的写入口。 +v0.6 的默认注册方式是**邀请注册**(01 FR-202):供应商以受邀成员身份进门户后填申请,不 +依赖匿名门。公开注册表单(FR-201)在多组织托管云上会落入部署默认组织(objectstack +ADR-0138 D4),且公开表单不能带附件(objectstack#25445),待 07 §6 V1 实测与 +objectstack#25447 后再启用。启用时它是整个系统唯一对互联网开放的写入口,按下表防护; +另外提交后不直接建供应商主数据,由品类经理推进到「资料审核」时才建档(03 §3 第 2 步)。 | 风险 | 控制 | |---|---| diff --git a/docs/design/05-experience-and-analytics.md b/docs/design/05-experience-and-analytics.md index 92ed951..6414f58 100644 --- a/docs/design/05-experience-and-analytics.md +++ b/docs/design/05-experience-and-analytics.md @@ -14,44 +14,39 @@ 采购协同工作台 ├── 首页 我的待办 · 我负责品类的关键指标 ├── 供应商 -│ ├── 供应商 合格名录 / 全部 / 资质异常 / 按生命周期看板 +│ ├── 供应商 合格名录 / 全部 / 资质异常 / 存量待复核 / 按生命周期看板 │ ├── 准入申请 待我审核 / 进行中 / 已结束 -│ ├── 供应商审核 │ ├── 资质证书 30 天内到期 / 已过期 -│ └── 变更与处置 (二期) -├── 寻源 +│ ├── 变更单 (v0.2) +│ ├── 处置单 (v0.3) +│ └── 门户邀请 (v0.6) +├── 合同 (v0.3)合同 · 到期提醒 +├── 质量 (v0.4) +│ ├── 交付记录 按月导入 / 不合格 +│ ├── 整改单 看板 / 逾期 +│ └── 供应商审核 计划 / 问题项 +├── 绩效与风险 (v0.5) +│ ├── 考评单 本期 / 待评分 +│ └── 风险事件 +├── 寻源 (v0.7) │ ├── 寻源单 我的 / 报价中 / 待开标 / 评标中 / 定标审批中 │ ├── 报价 (开标后可见) -│ ├── 价格库 当前有效 / 即将失效 -│ └── 合同 (二期) -├── 订单协同 (二期) -│ ├── 采购订单 待确认 / 交期风险 / 变更待确认 -│ ├── 送货单 -│ └── 收货记录 -├── 质量 (三期) -│ ├── 来料检验 -│ └── 整改单 看板 / 逾期 -├── 结算 (四期) -│ ├── 对账单 -│ └── 发票 -├── 绩效与风险 (三、四期) -│ ├── 考评单 -│ └── 风险事件 +│ └── 价格库 当前有效 / 即将失效 +├── 订单协同 (ERP 集成后的门户镜像,现阶段不显示) ├── 分析 仪表盘(见 §4) └── 设置 品类 · 物料 · 工厂 · 绩效指标(管理员) ``` -### 1.2 供应商门户 `srm_portal` +### 1.2 供应商门户 `srm_portal`(v0.6) ``` 供应商门户 ├── 首页 我的待办(见 01 §5.10)· 最新绩效 · 即将到期的证书 -├── 公司资料 本公司档案 · 联系人 · 资质证书 · 银行账户 · 变更申请 -├── 询价与报价 收到的邀请 · 我的报价(草稿 / 已提交 / 历史) -├── 订单与送货 待确认订单 · 全部订单 · 送货单 -├── 质量 整改单 · 检验结果 -├── 对账与发票 待确认对账单 · 发票与付款状态 -└── 绩效 历次考评结果 +├── 公司资料 本公司档案 · 联系人 · 资质证书 · 银行账户 · 变更申请 · 准入申请进度 +├── 质量 整改单 · 交付结果 +├── 绩效 历次考评结果 +├── 询价与报价 (v0.7)收到的邀请 · 我的报价(草稿 / 已提交 / 历史) +└── 订单与付款 (ERP 集成后的门户镜像)待确认订单 · 送货单 · 付款进度 ``` 门户的设计原则:**每个页面只有一个主要动作**(确认订单、提交报价、回复整改),按钮 @@ -77,12 +72,11 @@ | 报价明细 | 比价表 | 列表 | 过滤到某寻源单本轮,按寻源明细分组、组内按 `unit_price` 升序 | 评标小组 | | 报价明细 | 比价矩阵 | 矩阵报表 | 行 = 寻源明细,列 = 供应商,值 = 单价;另一块为总价与交期 | 评标小组、审批人 | | 价格记录 | 当前有效价格 | 列表 | `status == 'active'`,按物料分组 | 采购员 | -| 采购订单 | 待供应商确认 | 列表 | `status == 'released'`,按 `released_at` 升序,显示已等待小时数 | 采购员 | -| 订单行 | 交期风险 | 列表 | `delivery_risk == true` 且未收齐 | 采购员 | -| 订单行 | 交货排程 | 甘特 | 起止为 `required_date` / `promised_date` | 计划员 | +| 交付记录 | 本月不合格 | 列表 | `inspection_result == 'fail'`,按供应商分组 | SQE | | 整改单 | 整改看板 | 看板 | 按 `status` 分列,逾期卡片标红 | SQE | -| 对账单 | 本月对账 | 列表 | 本月生成,按 `status` 分组 | 应付会计 | +| 供应商审核 | 审核计划 | 日历 | 日期字段 `planned_date` | SQE | | 考评单 | 本期考评 | 列表 | 当前期间,按 `grade` 分组 | 采购总监 | +| 采购订单、订单行 | 待供应商确认、交期风险、交货排程 | 列表 / 甘特 | 预留(ERP 集成后的门户镜像) | 采购员、计划员 | 门户侧的视图是上述视图的子集,由 RLS 自动限定到本公司,**不需要**为门户单独写过滤 条件——写了也只是体验,不能替代 RLS。 @@ -97,8 +91,11 @@ 下半部分在开标前显示邀请与响应状态,开标后切换为比价表与比价矩阵;页头按钮随状态 变化:发布 → 开标 → 下一轮 → 提交定标。 -**订单确认页**(门户):订单头只读;订单行表格内联编辑「答复交期 / 答复数量 / 延期 -原因」,一个「确认全部」按钮处理交期与需求一致的常见情况。手机上表格折叠为卡片。 +**整改回复页**(门户):按 8D 步骤分段显示,当前待填的步骤展开,其余折叠;逾期倒计时在 +页头;SQE 的退回意见直接显示在被退回的步骤上。 + +**订单确认页**(门户,ERP 集成后的门户镜像):订单头只读;订单行表格内联编辑「答复交期 / +答复数量 / 延期原因」,一个「确认全部」按钮处理交期与需求一致的常见情况。手机上表格折叠为卡片。 **报价页**(门户):显示截止倒计时;明细表格内联填写单价、交期、税率;提交前汇总 总价;截止后整页只读并提示「已截止」。 @@ -112,15 +109,16 @@ | 指标 | 口径 | 数据来源(存储字段) | 计算时机 | |---|---|---|---| -| 交付准时率 OTD | 准时收货行数 ÷ 收货行数;退货行不计;无答复交期时按需求日期判定 | 收货记录 `on_time`;考评单 `otd_rate` | 收货写入时判定,季度考评时汇总 | -| 批次合格率 | 判定为合格的检验批次 ÷ 检验批次;让步接收计为不合格 | 检验 `result`;考评单 `lot_pass_rate` | 同上 | -| PPM | 不良数 ÷ 收货数 × 1,000,000 | 检验 `defect_quantity`、收货 `received_quantity`;考评单 `ppm` | 季度考评时 | -| 订单响应及时率 | 下发后 24 小时内被确认的订单数 ÷ 下发订单数 | 订单 `released_at`、`confirmed_at`;考评单 `ack_on_time_rate` | 同上 | +| 交付准时率 OTD | 准时交付行数 ÷ 交付行数;无承诺交期时按需求日期判定 | 交付记录 `on_time`;考评单 `otd_rate` | 交付记录写入时判定,考评时按期汇总 | +| 批次合格率 | 检验结论为合格的交付行 ÷ 已检验的交付行;让步接收计为不合格 | 交付记录 `inspection_result`;考评单 `lot_pass_rate` | 同上 | +| PPM | 不良数 ÷ 实收数 × 1,000,000 | 交付记录 `defect_quantity`、`received_quantity`;考评单 `ppm` | 考评时 | +| 订单响应及时率 | 下发后 24 小时内被确认的订单数 ÷ 下发订单数 | 订单 `released_at`、`confirmed_at`;考评单 `ack_on_time_rate` | ERP 集成后 | | 寻源节约额 | Σ(预算价或上次价格 − 定标价)× 定标数量 | 寻源单 `savings_amount` | 定标时 | -| 线上寻源覆盖率 | 线上定标金额 ÷ 新增定价总金额(含 ERP 中手工定价) | 寻源单 `awarded_amount` + ERP 数据 | 月度 | +| 线上寻源覆盖率 | 线上定标金额 ÷ 新增定价总金额(含 ERP 中手工定价) | 寻源单 `awarded_amount` + ERP 导出数据 | 月度(v0.7) | | 准入周期 | 准入申请从提交到批准的天数,取中位数 | 准入申请 `created_at` 与批准时间 | 批准时写 `cycle_days` | | SCAR 按期关闭率 | 按期关闭的整改单 ÷ 到期的整改单 | 整改单 `is_overdue`、`status` | 每日扫描 | -| 采购支出 | Σ 收货金额,按供应商 / 品类 / 法人 | 收货记录 `amount`(数量 × 订单行单价,flow 写入) | 收货写入时 | +| 采购支出 | Σ 交付金额,按供应商 / 品类 / 法人 | 交付记录 `amount`(导入表格带单价时写入) | 导入时 | +| 审核与 SCAR 关闭率 | 按期关闭的审核问题项与整改单 ÷ 到期数 | 审核问题项、整改单 `status` / `is_overdue` | 每日扫描 | | 资质合规 | 资质异常但仍为合格状态的供应商数 | 供应商 `qualification_alert` | 每日扫描 | ### 4.2 仪表盘清单 @@ -130,8 +128,8 @@ | 采购总览 | 采购总监、总经理 | 本年支出(按品类)、Top 10 供应商支出、寻源节约额、供应商等级分布、资质异常数 | | 寻源 | 品类经理、寻源工程师 | 进行中寻源单(按状态)、本月定标金额、平均有效报价家数、单一来源占比 | | 供应商 | 品类经理、SQE | 供应商按生命周期分布、30 天内到期证书数、准入申请积压、风险事件(按严重度) | -| 交付 | 采购员、计划员 | 待确认订单数、交期风险行数、按月准时 / 不准时收货行数(堆叠柱) | -| 质量 | SQE、质量经理 | 本月不合格批次、未关闭整改单(按状态)、逾期整改单、按供应商的 PPM 排名(季度) | +| 交付 | 采购员、品类经理 | 按月准时 / 不准时交付行数(堆叠柱)、按供应商的 OTD(取考评单存储值);待确认订单数、交期风险行数在 ERP 集成后加 | +| 质量 | SQE、质量经理 | 本月不合格交付行、未关闭整改单(按状态)、逾期整改单、按供应商的 PPM 排名、审核问题项关闭率 | | 门户首页 | 供应商 | 待办计数卡片、最新等级与总分、近 4 期得分趋势 | 两个平台约束会影响卡片设计: @@ -146,20 +144,20 @@ ## 5. 通知 -| 事件 | 接收人 | 通道 | 期次 | +平台的 `notify` 节点只能发给组织内用户(objectstack#25444):v0.6 前供应商侧的通知发给 +内部经办人(品类经理 / SQE),由其转告;v0.6 起发给供应商的门户用户。 + +| 事件 | 接收人 | 通道 | 版本 | |---|---|---|---| -| 准入申请已受理 / 已驳回 / 已通过 | 申请联系人 | 邮件 | 一期 | -| 待你审核的准入申请、待你审批的定标 | 审批人 | 站内 + 邮件 | 一期 | -| 新的询价邀请 | 受邀供应商 `sales` 联系人 | 邮件 + 门户待办 | 一期 | -| 报价截止前 24 小时仍未提交 | 受邀供应商 | 邮件 | 一期 | -| 中标 / 未中标 | 参与报价的供应商 | 邮件 | 一期 | -| 证书即将到期 / 已过期 | 供应商联系人、SQE | 邮件 + 站内 | 一期 | -| 新订单待确认、订单变更 | 供应商 `sales` 联系人 | 邮件 + 门户待办 | 二期 | -| 交期风险 | 采购员 | 站内 | 二期 | -| 订单 24 / 48 小时未确认 | 供应商 / 采购主管 | 邮件 / 站内 | 二期 | -| 新整改单、整改退回、整改逾期 | 供应商 `quality` 联系人 / SQE 主管 | 邮件 + 门户待办 | 三期 | -| 绩效结果发布 | 供应商 `admin` 联系人 | 邮件 | 三期 | -| 对账单待确认、付款完成 | 供应商 `finance` 联系人 | 邮件 + 门户待办 | 四期 | +| 待你审核的准入申请 | 审批人 | 站内 + 邮件 | v0.1 | +| 证书即将到期 / 已过期 | SQE(v0.6 起加供应商联系人) | 邮件 + 站内 | v0.1 | +| 银行账户变更待复核、变更已生效 | 应付会计 / 采购员 | 站内 | v0.2 | +| 合同待审批、合同即将到期 | 审批人、合同所有者、品类经理 | 站内 + 邮件 | v0.3 | +| 新整改单、整改退回、整改逾期 | SQE、SQE 主管(v0.6 起加供应商 `quality` 联系人) | 邮件 + 站内 / 门户待办 | v0.4 | +| 待你评分、绩效结果发布 | 评分人;采购总监(v0.6 起加供应商 `admin` 联系人) | 站内 + 邮件 | v0.5 | +| 门户邀请、准入申请已受理 / 已驳回 / 已通过 | 受邀联系人、申请联系人 | 邮件 | v0.6 | +| 新的询价邀请、报价截止前 24 小时仍未提交、中标 / 未中标、待你审批的定标 | 受邀供应商 `sales` 联系人;审批人 | 邮件 + 门户待办 | v0.7 | +| 新订单待确认、订单变更、交期风险、订单 24 / 48 小时未确认、付款完成 | 供应商 / 采购员 / 采购主管 | 邮件 / 站内 | ERP 集成后 | 通知模板统一放在应用包里,按中文 / 英文两套维护;邮件只给出摘要和门户链接,**不在 邮件正文里放报价金额、银行账号等敏感内容**。 diff --git a/docs/design/06-integration-and-ai.md b/docs/design/06-integration-and-ai.md index 6909986..6516dfd 100644 --- a/docs/design/06-integration-and-ai.md +++ b/docs/design/06-integration-and-ai.md @@ -1,8 +1,25 @@ -# 06 · 集成与 AI +# 06 · 预留集成点与 AI > 所属:[SRM 设计总览](./README.md) · 上一篇:[05 界面与分析](./05-experience-and-analytics.md) · 下一篇:[07 交付计划](./07-delivery-plan.md) -## 1. ERP 集成 +## 0. 现阶段:不集成 ERP,用导入 + +按 [ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md),ERP 集成在客户明确型号时立项,是 v0.7 +之后由客户驱动的主题。在此之前 SRM 与 ERP 之间只有两条**表格导入**和一条**手工同步**: + +| 数据 | 方向 | 方式 | 频率 | 版本 | +|---|---|---|---|---| +| 物料(编码、名称、规格、单位、品类) | ERP 导出 → SRM | 平台导入,按 `erp_material_no` 匹配,可重复执行 | 初始化 + 按需 | v0.2 | +| 存量供应商、联系人、证书 | 客户台账 → SRM | 平台导入,按身份标识查重;导入的供应商标记「存量导入、待复核」 | 一次 + 补充 | v0.2 | +| 交付记录(收货与检验结果) | ERP / 质量系统导出 → SRM | 平台导入,按 `erp_order_no` + `erp_line_no` 匹配;没有质量系统时质检员逐条录入 | 每月 | v0.4 | +| 供应商编码、冻结标志、价格 | SRM → ERP | 采购员按 SRM 的审批结果在 ERP 手工维护;`erp_vendor_code` 可手工回填 | 事件 | v0.1 起 | + +导入在 CI 用样例表格跑两遍验证幂等([docs/engineering](../engineering/README.md))。 + +## 1. 预留的 ERP 集成点 + +本节是 ERP 集成立项时的设计基线,现阶段**不实现**;对象上只保留外部单号字段,同步状态 +三字段在立项时再加。 ### 1.1 原则 @@ -10,7 +27,7 @@ 寻源、价格、协同过程数据以 SRM 为准。一个字段只有一个「主人」(§1.3)。 2. **入站幂等**:ERP 写入 SRM 一律走批量 API 的 `upsert`,按 `erp_*_id` 匹配。重复 消息、乱序重放都不会产生重复单据。 -3. **出站可补偿**:SRM 推 ERP 的每类数据(I3、I5、I6、I7、I10、I11、I14),在源记录上 +3. **出站可补偿**:SRM 推 ERP 的每类数据(I3、I5、I6、I7、I10、I11),在源记录上 带三个同步字段(对象清单见 [02 §1](./02-domain-model.md#1-建模原则) 第 8 条)—— `erp_sync_status`(`pending` / `synced` / `failed`)、`erp_sync_error`、 `erp_synced_at`。推送失败只改状态、不回滚业务;追赶式扫描 flow 定时重推 @@ -22,33 +39,39 @@ ### 1.2 数据流清单 -| # | 数据 | 方向 | 触发 | 频率 | 期次 | +「状态」列:**预留** 表示集成立项时实现;**镜像** 表示随 ERP 集成一起建的门户镜像对象 +(ADR-0008 第 5 条);**不做** 表示对象已移出核心。 + +| # | 数据 | 方向 | 触发 | 频率 | 状态 | |---|---|---|---|---|---| -| I1 | 物料(编码、名称、规格、单位、品类) | ERP → SRM | ERP 变更推送 + 每晚全量校对 | 准实时 / 每日 | 一期 | -| I2 | 工厂 / 收货地点、法人 | ERP → SRM | 初始化 + 变更 | 低频 | 一期 | -| I3 | 供应商主数据 | SRM → ERP | 准入批准;关键信息变更审批通过 | 事件 | 一期 | -| I4 | 供应商编码回写 | ERP → SRM | ERP 建档成功 | 事件 | 一期 | -| I5 | 银行账户 | SRM → ERP | 应付会计核验通过 | 事件 | 一期 | -| I6 | 价格信息记录 | SRM → ERP | 定标审批通过 | 事件 | 一期 | -| I7 | 冻结 / 解冻标志 | SRM → ERP | 处置单审批通过 | 事件 | 二期 | -| I8 | 采购申请(可选) | ERP → SRM | 需要寻源的申请 | 事件 | 二期 | -| I9 | 采购订单与变更 | ERP → SRM | 订单下达 / 变更 | 事件 | 二期 | -| I10 | 订单确认交期 | SRM → ERP | 供应商确认 | 事件 | 二期 | -| I11 | 送货通知(ASN) | SRM → ERP / WMS | 送货单发运 | 事件 | 二期 | -| I12 | 收货 / 退货 | ERP / WMS → SRM | 过账 | 事件 | 二期 | -| I13 | 检验结果 | QMS / ERP → SRM | 判定 | 事件 | 三期 | -| I14 | 对账结果、发票 | SRM → ERP | 双方确认、发票校验通过 | 事件 | 四期 | -| I15 | 付款结果 | ERP → SRM | 付款过账 | 事件 / 每日 | 四期 | +| I1 | 物料(编码、名称、规格、单位、品类) | ERP → SRM | ERP 变更推送 + 每晚全量校对 | 准实时 / 每日 | 预留(现为导入) | +| I2 | 工厂 / 收货地点、法人 | ERP → SRM | 初始化 + 变更 | 低频 | 预留 | +| I3 | 供应商主数据 | SRM → ERP | 准入批准;关键信息变更审批通过 | 事件 | 预留 | +| I4 | 供应商编码回写 | ERP → SRM | ERP 建档成功 | 事件 | 预留(现为手工回填) | +| I5 | 银行账户 | SRM → ERP | 应付会计核验通过 | 事件 | 预留 | +| I6 | 价格信息记录 | SRM → ERP | 定标审批通过 | 事件 | 预留 | +| I7 | 冻结 / 解冻标志 | SRM → ERP | 处置单审批通过 | 事件 | 预留 | +| I8 | 采购申请(可选) | ERP → SRM | 需要寻源的申请 | 事件 | 不做 | +| I9 | 采购订单与变更 | ERP → SRM | 订单下达 / 变更 | 事件 | 镜像 | +| I10 | 订单确认交期 | SRM → ERP | 供应商确认 | 事件 | 镜像 | +| I11 | 送货通知(ASN) | SRM → ERP / WMS | 送货单发运 | 事件 | 镜像 | +| I12 | 收货 / 退货 | ERP / WMS → SRM | 过账 | 事件 | 预留:写入交付记录(现为按月导入) | +| I13 | 检验结果 | QMS / ERP → SRM | 判定 | 事件 | 预留:写入交付记录(现为按月导入) | +| I14 | 对账结果、发票 | SRM → ERP | — | — | 不做 | +| I15 | 付款结果 | ERP → SRM | 付款过账 | 事件 / 每日 | 镜像(付款进度) | ### 1.3 字段归属 | 对象 | ERP 拥有(SRM 只读) | SRM 拥有 | |---|---|---| -| 物料 | 全部字段 | — | +| 物料 | 全部字段 | 品类关联 | | 供应商 | `erp_vendor_code`、ERP 侧冻结状态 | 其余全部(档案、状态、等级、资质) | -| 采购订单 / 行 | 订单号、物料、数量、单价、需求日期、行状态(关闭 / 取消) | 供应商答复交期与数量、延期原因、交期风险、确认时间 | -| 收货 / 检验 | 全部字段 | `on_time`、`amount`、`reconciled`(SRM 计算) | -| 发票 | 应付凭证号、付款金额与日期 | 发票信息、查验结果 | +| 交付记录 | 订单号、行号、数量、日期、检验结论、不良数 | `on_time`、`period`(SRM 计算) | +| 采购订单 / 行(镜像) | 订单号、物料、数量、单价、需求日期、行状态(关闭 / 取消) | 供应商答复交期与数量、延期原因、交期风险、确认时间 | +| 付款进度(镜像) | 应付凭证号、付款状态、付款金额与日期 | — | + +集成账号写入带 `portal_position` 的对象时不写该字段,由对应的 record_change flow 从供应商 +档案复制(04 §3)。 ### 1.4 与主流 ERP 的对照 @@ -75,16 +98,19 @@ - **出站**:flow 的 `http` 节点调用 ERP 或中间件接口,凭据以平台的密钥 / 连接器机制 保存,不写进 flow 定义;或用 webhook 把事件推给中间件订阅。 - **回调**:电子签、付款等异步结果通过 `api` 类型的 flow 接收。 +- **连接器**:用友、金蝶、SAP 各做一个连接器,映射见 §1.4;每个连接器一份 `docs/integration/` 规格。 ## 2. 外部服务 -| 服务 | 用途 | 接入点 | 期次 | +除平台通知通道外,外部服务都是客户驱动主题,字段已预留(签章单号、风险事件的 `external_ref`)。 + +| 服务 | 用途 | 接入点 | 状态 | |---|---|---|---| -| 企业信息服务(工商、司法、经营异常) | 注册时核对名称与信用代码;每周风险扫描。只适用于中国供应商,境外供应商先人工核验 | `http` 节点,按批调用 | 一期(核对),四期(扫描) | -| 电子签章 | 合同、质量协议、廉洁协议在线签署 | `http` 发起 + `api` 回调 | 二期 | -| 对公账户验证 | 银行账户真实性核验(四要素 / 小额打款) | `http` | 二期 | -| 发票查验 | 专票 / 数电票真伪与状态 | `http` | 四期 | -| 邮件 / 短信 | 通知 | 平台通知通道 | 一期 | +| 邮件 / 短信 | 通知 | 平台通知通道(`notify` 现只能发给组织内用户,objectstack#25444) | v0.1 | +| 企业信息服务(工商、司法、经营异常) | 登记时核对名称与信用代码;每周风险扫描。只适用于中国供应商,境外供应商先人工核验 | `http` 节点,按批调用 | 客户驱动 | +| 电子签章 | 合同、质量协议、廉洁协议在线签署 | `http` 发起 + `api` 回调 | 客户驱动 | +| 对公账户验证 | 银行账户真实性核验(四要素 / 小额打款) | `http` | 客户驱动 | +| 发票查验 | 不做(发票留在 ERP) | — | 不做 | 所有外部服务按「调用失败不阻断主流程」设计:失败时记录到业务字段,人工可重试或 转人工核验。 @@ -106,20 +132,22 @@ ObjectStack 的定位是**让 AI agent 安全执行真实业务**的后端:AI ### 3.2 用例 -| 用户 | 用例 | 读写 | 期次 | +| 用户 | 用例 | 读写 | 版本 | |---|---|---|---| -| 采购员 | 「列出本周所有交期风险订单,按缺料紧急程度排序,并起草催办消息」 | 读订单行;起草通知(需确认) | 二期 | -| 寻源工程师 | 「为这张询价单推荐 5 家合格供应商,说明依据(等级、近期 OTD、价格竞争力)」 | 读名录与绩效 | 一期 | -| 评标小组 | 「开标后汇总比价,标出低于均价 30% 的异常报价和交期偏离」 | 读报价(开标后才有数据) | 一期 | -| SQE | 「汇总这家供应商近 4 个季度整改单的根因分类和重复问题」 | 读整改单 | 三期 | +| 品类经理 | 「列出资质即将过期且近两期绩效下滑的供应商,起草提醒」 | 读供应商、证书、考评单;起草通知(需确认) | v0.5 | +| SQE | 「汇总这家供应商近 4 期整改单的根因分类和重复问题」 | 读整改单 | v0.4 | +| 采购总监 | 「按品类列出 D 级供应商和对应的处置进度」 | 读考评单、处置单 | v0.5 | +| 寻源工程师 | 「为这张询价单推荐 5 家合格供应商,说明依据(等级、近期 OTD、价格竞争力)」 | 读名录与绩效 | v0.7 | +| 评标小组 | 「开标后汇总比价,标出低于均价 30% 的异常报价和交期偏离」 | 读报价(开标后才有数据) | v0.7 | +| 采购总监 | 「今年电子类物料的节约额是多少,比去年如何」 | 读寻源与价格数据 | v0.7 | | 品类经理 | 「对比上传的营业执照与申请表填写的信用代码、有效期是否一致」 | 读附件,需要文档识别能力,先做可行性验证 | 待评估 | -| 采购总监 | 「今年电子类物料的节约额是多少,比去年如何」 | 读寻源与价格数据 | 一期 | -| 供应商(外部 agent) | 「确认所有需求日期在两周以后的订单行,交期按需求日期答复」 | 写本公司订单行答复(需确认) | 二期 | +| 采购员 / 供应商 agent | 交期风险催办、订单行批量确认 | 订单镜像 | ERP 集成后 | ### 3.3 用 AI 搭建 SRM 本身 平台的 AI 搭建助手适合**原型验证**:用一句话描述某个模块(例如「供应商准入」), 它会先给出 3–5 个对象的方案,确认后生成对象、视图和应用外壳,便于业务方尽早 -看到样子。但完整的 SRM 应以**代码仓里的应用包**为唯一事实来源:35 个对象、 +看到样子。但完整的 SRM 应以**代码仓里的应用包**为唯一事实来源:27 个对象、 二十多条 flow、精细的 RLS 需要版本管理、代码评审和回归测试。建议做法是用 AI 搭建 -产出原型 → 业务确认 → 按本设计在应用包里正式实现。 +产出原型 → 业务确认 → 按本设计在应用包里正式实现。客户落地时的个性化同样由 AI 在 +**客户层**生成(Studio 覆盖层、客户私有包),不改核心源码([ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md))。 diff --git a/docs/design/07-delivery-plan.md b/docs/design/07-delivery-plan.md index 043f64b..1f6a88d 100644 --- a/docs/design/07-delivery-plan.md +++ b/docs/design/07-delivery-plan.md @@ -1,188 +1,242 @@ # 07 · 交付计划、风险与待决策事项 -> 所属:[SRM 设计总览](./README.md) · 上一篇:[06 集成与 AI](./06-integration-and-ai.md) +> 所属:[SRM 设计总览](./README.md) · 上一篇:[06 预留集成点与 AI](./06-integration-and-ai.md) + +> 版本:2026-10-23 按 [ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md)、[ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md) +> 重排:先做内部管理核心,再做门户,最后做寻源;ERP 集成与扩展包在 v0.7 之后由客户驱动。 +> 旧的「第 0–五期」分期作废。 ## 1. 分期路线图 -按模块分期上线,每期结束都有一个业务上能独立使用的闭环。工期按 2–3 人的开发小组 -(含实施)估算,第 0 期结论出来后再细化。 +按版本交付,每个版本结束都有一个业务上能独立使用的闭环,对象数累计到核心 27 个。 +工期按 1–2 人加 AI 的开发方式估算,每个版本 2–3 周;两个门槛由田騏确认后才进入下一段。 -| 期次 | 周期 | 范围 | 新增对象 | 本期闭环 | +| 版本 | 范围 | 新增对象(累计) | 本版闭环 | 前置条件 | |---|---|---|---|---| -| 第 0 期 调研与原型 | 2–3 周 | 确认 §5 的决策;实测基线指标;清洗存量供应商数据;用 AI 搭建做准入模块原型;确认 ERP 接口 | — | 业务方签字确认的范围与决策清单 | -| 第一期 MVP | 8 周 | 供应商主数据、注册与准入、资质到期预警、询价比价定标、价格库、门户基础;集成 I1–I6 | 16 个:品类、物料、工厂、供应商及其 4 个子对象、准入申请、供应商审核、寻源单、寻源明细、寻源邀请、报价单、报价明细、价格记录 | 供应商从注册到合格,再到参与询价、定标、价格进 ERP | -| 第二期 | 8 周 | 合同、订单协同、送货、收货回传、信息变更与处置、采购申请;集成 I7–I12 | 9 个 | PO 下发 → 供应商确认 → 送货 → 收货,交付准时率可出数 | -| 第三期 | 6 周 | 来料检验、质量整改、绩效指标库与季度考评;集成 I13 | 5 个 | 不合格自动开整改单;第一次季度考评自动生成并发布 | -| 第四期 | 6 周 | 对账、发票、付款回写、外部风险监控;集成 I14–I15 | 4 个 | 月度对账线上闭环;风险事件自动发现 | -| 第五期 | 按需 | 反向竞价、邀请招标增强、货源清单与配额、AI 用例深化、高级支出分析 | 1 个(货源清单) | 按业务价值排序选做 | +| v0.1 内部工作台 | 供应商主数据、两级准入审批、证书到期提醒 | 7:品类、工厂、供应商、联系人、证书、供货品类资格、准入申请 | 供应商从登记到合格;证书到期前有提醒 | 已交付(PR #5) | +| v0.2 主数据补齐 | 银行账户、信息变更申请、法人(业务单元)、物料与存量供应商导入 | +3 = 10:物料、银行账户、信息变更单 | 存量供应商导入后能复核;关键信息变更走审批 | — | +| v0.3 合同与处置 | 合同与合同行、处置单(暂停 / 冻结 / 解除)、供应商自助重新申请 | +3 = 13:合同、合同行、处置单 | 合同到期前提醒;冻结后不能被邀请 | — | +| v0.4 质量 | 交付记录导入、质量问题与整改单、供应商审核与年度审核计划 | +3 = 16:交付记录、质量问题、供应商审核 | 不合格交付能开整改单并闭环;OTD、合格率、PPM 出数 | 客户能按月导出交付数据 | +| v0.5 绩效与风险 | 指标库、按周期考评、风险事件与扫描、黑名单 | +4 = 20:绩效指标、考评单、考评明细、风险事件 | 第一次考评自动生成并发布;D 级进入处置 | 门槛 1:内部 MVP 验收(§2.1) | +| v0.6 供应商门户 | 邀请注册、门户补资料与证书、整改回复、通知 | +1 = 21:供应商邀请 | 供应商自己维护资料并回复整改 | objectstack#25233 修复;V1–V5 实测通过(§6) | +| v0.7 寻源 | 询价 / 竞价、封标、比价、定标审批、价格记录 | +6 = 27:寻源单、寻源明细、寻源邀请、报价单、报价明细、价格记录 | 封标询价到定标,价格记录生效 | 门槛 2:核心 27 个对象冻结(ADR-0009 第 5 条) | +| 之后(客户驱动) | ERP 连接器与门户镜像(订单确认、送货通知、付款进度)、电子签、工商数据、扩展包 | 镜像对象另计 | — | 客户明确型号或需求 | ```mermaid gantt - title SRM 分期计划(示意,以第 0 期结论为准) + title hotsrm 版本路线(示意,每版 2–3 周) dateFormat YYYY-MM-DD axisFormat %m月 - section 准备 - 第0期 调研与原型 :p0, 2026-11-02, 3w - section 建设 - 第一期 MVP :p1, after p0, 8w - 第二期 订单协同 :p2, after p1, 8w - 第三期 质量与绩效 :p3, after p2, 6w - 第四期 结算与风险 :p4, after p3, 6w - section 运营 - 第一期试运行(2 个品类) :after p1, 4w + section 内部核心 + v0.1 内部工作台(已交付) :done, v1, 2026-10-13, 2w + v0.2 主数据补齐 :v2, after v1, 2w + v0.3 合同与处置 :v3, after v2, 2w + v0.4 质量 :v4, after v3, 3w + v0.5 绩效与风险 :v5, after v4, 3w + 门槛 1 内部 MVP 验收 :milestone, g1, after v5, 0d + section 门户与寻源 + v0.6 供应商门户 :v6, after g1, 3w + v0.7 寻源 :v7, after v6, 3w + 门槛 2 核心冻结 :milestone, g2, after v7, 0d ``` -### 1.1 第一期的拆分 +**上线策略**:v0.5 验收后先选 **2 个品类、20–30 家供应商**在内部试运行 4 周;v0.6 门户 +从这批供应商里挑配合度高的 5 家先开;推广按品类分批,而不是按工厂。 + +## 2. 验收标准 + +### 2.1 门槛 1:内部 MVP(v0.5 出口) + +按下面的剧本在内部工作台完整走一遍,不涉及门户和 ERP。 + +1. 品类经理为供应商 X 登记准入申请,选择「电子元器件」品类(A 类物资、高风险),上传 + 营业执照;系统查重通过; +2. 采购员收齐 ISO9001 证书与银行账户;应付会计核验银行账户; +3. SQE 完成现场审核并上传报告,审核通过; +4. 准入审批按矩阵走品类经理、采购总监两级,A 类加质量经理会签;审批人与发起人为同一人 + 时自动改派;通过后 X 变为「合格」; +5. 导入上月交付记录表格两遍,结果一致;其中一条不合格记录开出整改单,X 的整改回复由 + 采购员代录,SQE 验证关闭; +6. 月初考评 flow 为 X 生成本期考评单(A 类按月),OTD、合格率、PPM 与导入数据一致; + 采购总监审定发布; +7. 把 X 的考评改成 D 级并连续两期,处置单自动建议暂停;处置单审批通过后 X 不能再被 + 关联新的合同; +8. 将 X 的 ISO9001 证书有效期改为昨天,次日扫描后 X 被标记「资质异常」,列表上有提示; +9. 为 X 新建合同,到期前 30 天提醒到采购员待办。 + +### 2.2 门槛 2:门户与寻源(v0.7 出口) -第一期按可独立验收的小版本推进,每个版本一个次版本号。按 2026-10-23 的产品决定(面向已有 ERP 的大型企业,只做基础核心包,暂不集成 ERP),v0.3 完成即为当前第一期的终点: +在 2.1 的基础上增加: -| 版本 | 范围 | 随版本落地的红线测试 | +1. 品类经理邀请 X 的联系人加入门户;X 在门户补齐证书并回复一张整改单;X 看不到其他 + 供应商的任何数据([04 §3.7](./04-security-and-portal.md#37-隔离验收测试)); +2. 寻源工程师建询价单(3 个物料),邀请 X、Y、Z 三家;截止前内部只能看到「已报价 N 家」; + Y 在截止后尝试改价被拒绝; +3. 开标,比价矩阵显示三家价格;定标金额 50 万,走两级审批;通过后价格记录生成、旧价格 + 被截断,三家收到结果通知。 + +### 2.3 量化标准 + +| 项 | 标准 | 门槛 | |---|---|---| -| v0.1 | 内部工作台:品类、工厂、供应商及联系人 / 证书 / 供货品类资格、准入申请与两级审批、资质到期扫描;由内部人员代录 | — (无面向供应商的对象,无报价) | -| v0.2 | 供应商门户:门户岗位与 RLS、公开注册表单、门户补录、供应商审核 | 04 §3.7 隔离测试 | -| v0.3 | 寻源:寻源单 / 明细 / 邀请、报价、开标、比价矩阵、定标审批、价格库 | 封标测试 | -| 暂缓 | ERP 集成 I1–I6、物料、银行账户:等客户需要时再排期;银行与付款始终留在 ERP | — | - -**上线策略**:第一期先选 **2 个品类、20–30 家供应商**试运行 4 周,跑通准入与至少 5 张 -询价单后再全面推广;推广按品类分批,而不是按工厂。 - -## 2. MVP 验收标准 - -### 2.1 端到端剧本 - -验收时按下面的剧本完整走一遍,每一步都要在内部工作台、门户、ERP 三处核对结果。 - -1. 潜在供应商 X 通过公开表单注册,选择「电子元器件」品类,上传营业执照; -2. 系统自动查重通过,生成「潜在」供应商,品类经理收到待办; -3. 品类经理邀请 X 的联系人加入,开通门户;X 在门户补齐 ISO9001 证书与银行账户; -4. 应付会计核验银行账户;SQE 完成现场审核(电子元器件为高风险品类); -5. 准入评审两级审批通过,X 变为「合格」,ERP 中出现该供应商并回写编码; -6. 寻源工程师建询价单(3 个物料),通过 screen flow 邀请 X、Y、Z 三家; -7. 截止前内部只能看到「已报价 N 家」,看不到任何价格;三家都在截止前提交了报价;Y 在 - 截止后尝试改价被拒绝; -8. 开标,比价矩阵显示三家价格;寻源工程师提交定标,金额 50 万,走两级审批; -9. 定标通过:价格记录生成、旧价格被截断、ERP 价格信息记录更新,三家收到结果通知; -10. 将 X 的 ISO9001 证书有效期改为昨天,次日扫描后 X 被标记「资质异常」,无法被新的 - 询价邀请。 - -### 2.2 量化标准 - -| 项 | 标准 | -|---|---| -| 隔离测试 | [04 §3.7](./04-security-and-portal.md#37-隔离验收测试) 全部用例通过,零例外 | -| 封标测试 | 截止前经界面、API、导出、仪表盘、AI 助手五个通道均取不到报价内容 | -| 数据迁移 | 存量供应商、联系人、证书、有效价格两轮迁移演练,抽检准确率 ≥ 99% | -| 性能 | 01 §7 的列表与比价视图响应时间达标 | -| 集成 | I1–I6 每类接口:正常、重复消息、失败重推三种情况各验证一次 | -| 可用性 | 5 家试点供应商在无培训的情况下完成「接受邀请 → 提交报价」 | +| 导入幂等 | 物料、存量供应商、交付记录三张样例表格各跑两遍,结果一致 | 1 | +| 数据迁移 | 存量供应商、联系人、证书两轮迁移演练,抽检准确率 ≥ 99% | 1 | +| 审批矩阵 | [03 §12](./03-processes-and-automation.md#12-审批矩阵) 每一行各有一条通过用例,自审被拒一条 | 1 | +| 性能 | 01 §7 的列表视图响应时间达标 | 1 | +| 可用性 | 2 名采购员在无培训的情况下完成「登记申请 → 审批通过」 | 1 | +| 隔离测试 | 04 §3.7 全部用例通过,零例外 | 2 | +| 封标测试 | 截止前经界面、API、导出、仪表盘、AI 助手五个通道均取不到报价内容 | 2 | +| 可用性 | 5 家试点供应商在无培训的情况下完成「接受邀请 → 提交报价」 | 2 | ## 3. 应用包结构与工程规范 ### 3.1 目录结构 -核心的源码放在仓库的 `src/core/`(`type: app`,命名空间 `srm`);扩展包和组合方式见 -仓库根目录的 [README](../../README.md) 与 [ADR-0002](../adr/0002-packs-composed-into-one-app.md)。 +核心的源码放在仓库的 `src/core/`(`type: app`,命名空间 `srm`);现阶段只有核心,扩展包 +目录和桥接模块在第一个包立项时再建([ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md)), +组合方式见仓库根目录的 [README](../../README.md) 与 [ADR-0002](../adr/0002-packs-composed-into-one-app.md)。 ``` src/core/ ├── index.ts # defineStack:manifest(type: app,namespace: srm) ├── objects/ # 每个对象一个文件:supplier.object.ts … ├── picklists/ # 共享选项列表,供扩展包追加选项(02 §1 第 13 条) -├── flows/ # 按流程分目录:admission/、sourcing/、order/ … +├── flows/ # 按流程分目录:admission/、quality/、performance/、sourcing/ … ├── security/ │ ├── positions.ts # 内部岗位 │ ├── permission-sets.ts # 内部权限集 │ └── portal.ts # 门户权限集与 RLS(见 04 §3.4) -├── apps/ # srm_workbench、srm_portal 两个应用外壳(导航按分组,供扩展包挂菜单) +├── apps/ # srm_workbench、srm_portal 两个应用外壳(导航按分组) ├── views/ # 列表、看板、日历、甘特 -├── reports/ # 比价矩阵等 +├── reports/ # 比价矩阵等(v0.7) ├── dashboards/ -├── forms/ # 公开注册表单 +├── forms/ # 公开注册表单(待平台 #25445) ├── notifications/ # 中英文通知模板 ├── translations/ -└── data/ # 种子数据:品类、指标库、演示供应商 +└── data/ # 种子数据:品类、指标库、演示供应商、导入样例表格 -test/ # 仓库根目录,覆盖核心与各种扩展包组合 -├── portal-isolation.test.ts # 04 §3.7 的交叉越权用例 -├── sealed-bid.test.ts # 封标与截止锁价 -├── composition.test.ts # 每种扩展包组合都能构建、校验通过 +test/ # 仓库根目录 +├── import-idempotency.test.ts # 样例表格跑两遍(v0.2 起) +├── approval-matrix.test.ts # 03 §12 每一行(v0.1 起) +├── portal-isolation.test.ts # 04 §3.7 的交叉越权用例(v0.6) +├── sealed-bid.test.ts # 封标与截止锁价(v0.7) └── flows/*.test.ts # 每条 flow 的正向与异常路径 ``` ### 3.2 规范 +建模规范、分支与 PR、CI 门禁、测试策略、版本与升级,见 [docs/engineering](../engineering/README.md)。 +要点: + - **契约优先**:元数据以 `@objectstack/spec` 为唯一契约,发布前跑平台 lint 与构建校验, 校验报错一律改元数据,不在运行时打补丁; -- **测试**:用平台的 verify 工具在进程内启动整个应用包做端到端断言,隔离与封标测试 - 进 CI,失败即阻断发布; - **环境**:开发、预发、生产三套环境,配置与元数据通过应用包版本推进,不在生产环境 手工改元数据; -- **版本**:应用包按语义化版本发布,每期一个次版本号,破坏性变更(删字段、改选项值) - 必须附数据迁移。 +- **客户个性化放客户层**:参数、体系文件实例、Studio 覆盖层、客户私有包;不改核心源码。 ## 4. 风险与应对 | # | 风险 | 可能性 | 影响 | 应对 | |---|---|---|---|---| -| R1 | 门户用户可见的用户目录范围不满足隔离要求(04 §3.6) | 待第 0 期验证 | 中:暴露竞争对手与员工联系方式 | 第 0 期实测;不满足时在平台层面解决,或书面接受并规范显示名 | -| R2 | 同一环境其他应用的默认权限集把数据开放给供应商用户 | 中 | 高 | 上线前逐个审查环境内所有 `isDefault` 权限集;新应用上线纳入同一审查 | -| R3 | 定时任务延迟或漏跑 | 中 | 中:提醒延迟 | 追赶式扫描 + 关键扫描的外部心跳(03 §2.3);强制规则不依赖计时器 | -| R4 | 每家供应商首次开通门户都要管理员新建岗位定义;flow 写任命也可能不被允许 | 高(建岗位必然手工) | 低:效率 | 开通流程写成管理员操作清单;第 0 期验证 flow 写任命;平台提供声明式成员集合后改用方案 B,取消逐家建岗位 | +| R1 | 门户用户可见的用户目录范围不满足隔离要求(04 §3.6) | 已确认存在(objectstack#25233) | 中:暴露竞争对手与员工联系方式 | v0.6 以 #25233 修复为前提;不能按期则按 D8 处理 | +| R2 | 同一环境其他应用的默认权限集把数据开放给供应商用户 | 中 | 高 | v0.6 上线前逐个审查环境内所有 `isDefault` 权限集;新应用上线纳入同一审查 | +| R3 | 定时任务延迟或漏跑(objectstack#25442 待平台给出保证) | 中 | 中:提醒延迟 | 追赶式扫描(03 §2.3);强制规则不依赖计时器 | +| R4 | 每家供应商首次开通门户都要管理员新建岗位定义;flow 写任命也可能不被允许(objectstack#25443) | 高(建岗位必然手工) | 低:效率 | 开通流程写成管理员操作清单;v0.6 前验证 V2/V3;平台提供声明式成员集合后改用方案 B | | R5 | 供应商不愿用门户,继续用邮件和微信 | 中 | 高:协同价值落空 | 试点选配合度高的供应商;邮件只给链接不给内容;在采购合同中约定门户为正式渠道 | -| R6 | 存量供应商数据质量差(重复、缺信用代码) | 高 | 中 | 第 0 期专项清洗;导入时按信用代码查重;缺失项在门户里让供应商自行补齐 | -| R7 | ERP 接口改造排期慢 | 中 | 高 | 第 0 期确认接口清单与 ERP 团队排期;一期只依赖 I1–I6,其中 I3 / I5 / I6 可先以导出文件过渡 | -| R8 | 每期对象与 flow 较多,回归成本上升 | 中 | 中 | 隔离、封标、关键 flow 的自动化测试进 CI | -| R9 | 月度对账、季度绩效在 flow 里批量处理,供应商多时运行时间长 | 低 | 中 | 按法人或品类错峰拆分;规模继续增长时评估自托管与服务端函数 | -| R10 | 审批人与发起人为同一人(职责分离失效) | 中 | 中 | 岗位分离 + `expression` 审批人改派(04 §6) | +| R6 | 存量供应商数据质量差(重复、缺信用代码) | 高 | 中 | v0.2 导入前专项清洗;导入时按信用代码查重;标记「存量导入」待复核 | +| R7 | ERP 集成推迟后,交付数据靠每月导入,客户不按时导出则绩效断档 | 中 | 中 | 导入模板与操作清单写进实施手册;考评 flow 发现本期无交付记录时标记「数据不全」而不是给零分 | +| R8 | 每版对象与 flow 较多,回归成本上升 | 中 | 中 | 审批矩阵、导入幂等、关键 flow 的自动化测试进 CI(docs/engineering §3) | +| R9 | 考评在 flow 里批量处理,供应商多时运行时间长 | 低 | 中 | 按法人或品类错峰拆分;规模继续增长时评估服务端函数 | +| R10 | 审批人与发起人为同一人(职责分离失效) | 中 | 中 | 岗位分离 + `expression` 审批人改派(04 §6);平台开关见 objectstack#25446 | +| R11 | 客户落地时要求改核心字段,覆盖层与核心升级冲突(平台目前不检测,objectstack ADR-0005) | 中 | 中 | 客户层规则(ADR-0009 第 4 条);核心升级前跑「核心 + 客户层」组合构建 | ## 5. 待决策事项(附推荐) -每项都给出推荐和理由;请在第 0 期结束前确认。 +### 5.1 设计决策 D1–D9 + +「状态」列记录结论和日期;已决的项不再重复讨论,改结论要附 ADR 或更新本表。 + +| # | 决策 | 推荐 | 理由与其他选项的代价 | 状态 | +|---|---|---|---|---| +| D1 | 部署形态与门户账号模式 | **托管云;供应商用户以受邀组织成员身份登录,按「每家供应商一个门户岗位」隔离** | 本设计全部用元数据实现,托管云今天即可运行,运维成本最低。平台只有托管安装(ADR-0131 D6),自托管不是现实选项 | 已决(2026-10-23,ADR-0002 补充) | +| D2 | 多法人是否隔离 | **单组织 + 业务单元树,不开墙** | 供应商主数据集团共享、门户用户只加入一个组织;开墙会让每个法人各有一份供应商档案,并让门户账号成倍增加(04 §5) | 已决(2026-10-23,ADR-0006 补充) | +| D3 | ERP 集成方式 | **现阶段不集成,用表格导入;立项时有中间件走中间件,没有则 SRM 直连 + 同步状态字段** | 见 ADR-0008;直连的可靠性靠追赶式重推保证(06 §1.1) | 已决(2026-10-23,ADR-0008) | +| D4 | 准入是否都要现场审核 | **按品类风险等级:高风险必须,中低风险免** | 一刀切会把准入周期拉长到 6 周以上,与目标 G3 冲突 | 已决(2026-10-23,03 §3 步骤 5) | +| D5 | 定标审批金额阈值 | **先用 10 万 / 100 万两档,实施时按企业授权手册替换** | 阈值放在参数 `award_approval_tiers` 里,调整不需要改流程 | 已决(v0.7 实现) | +| D6 | 封标强度 | **所有询价默认封标,仅单一来源可关闭;100 万以上的寻源启用监标人开标** | 全量封标的成本几乎为零;监标只在大额启用,避免小额寻源被流程拖慢 | 已决(v0.7 实现) | +| D7 | 电子签 | **v0.3 合同模块先支持上传盖章扫描件,电子签在客户提出时接入** | 合同模块不阻塞在电子签选型上;字段已预留(06 §2) | 已决(2026-10-23,ADR-0008 第 6 条) | +| D8 | 用户目录可见范围(R1)不满足时的处理 | **等 objectstack#25233 修复;若不能按期,业务方书面接受风险并规范门户用户显示名** | 用户目录由平台成员权限决定,应用层无法完全控制,需要明确的责任人 | 待平台(#25233) | +| D9 | 绩效等级与结果应用 | **A ≥ 90 / B 80–89 / C 70–79 / D < 70;C 级改善、连续两期 D 级进入淘汰评审** | 行业常见做法;首年可以只发布不自动处置,跑满两期再启用自动处置;阈值在参数 `perf_grade_min`、`perf_d_exit_periods` | 已决(v0.5 实现) | + +### 5.2 计划决策 P-D1–P-D5 + +开发计划(2026-10-23)提出的决策,本 PR 按推荐先行,待田騏确认。 -| # | 决策 | 推荐 | 理由与其他选项的代价 | +| # | 决策 | 推荐 | 状态 | |---|---|---|---| -| D1 | 部署形态与门户账号模式 | **托管云(选择支持定时任务的套餐);供应商用户以受邀组织成员身份登录,按「每家供应商一个门户岗位」隔离** | 本设计全部用元数据实现,托管云今天即可运行,运维成本最低。自托管可以启用代码增强(membership resolver、服务端函数),代价是许可、运维和升级都要自己承担;只在数据驻留或规模有硬要求时选 | -| D2 | 多法人是否隔离 | **单组织 + 业务单元树,不开墙** | 供应商主数据集团共享、门户用户只加入一个组织;开墙会让每个法人各有一份供应商档案,并让门户账号成倍增加(04 §5) | -| D3 | ERP 集成方式 | **有中间件走中间件;没有则 SRM 直连 + 同步状态字段** | 中间件在映射、重试、监控上更成熟;直连的可靠性靠追赶式重推保证(06 §1.1) | -| D4 | 准入是否都要现场审核 | **按品类风险等级:高风险必须,中低风险免** | 一刀切会把准入周期拉长到 6 周以上,与目标 G3 冲突 | -| D5 | 定标审批金额阈值 | **先用 10 万 / 100 万两档,实施时按企业授权手册替换** | 阈值放在配置常量里,调整不需要改流程 | -| D6 | 封标强度 | **所有询价默认封标,仅单一来源可关闭;100 万以上的寻源启用监标人开标** | 全量封标的成本几乎为零;监标只在大额启用,避免小额寻源被流程拖慢 | -| D7 | 电子签 | **二期合同模块上线时先支持上传盖章扫描件,电子签在二期末或三期接入** | 合同模块不阻塞在电子签选型上;选型可从第一期开始并行 | -| D8 | 用户目录可见范围(R1)不满足时的处理 | **由部署方在平台层面解决;若不能按期,业务方书面接受风险并规范门户用户显示名** | 用户目录由平台成员权限决定,应用层无法完全控制,需要明确的责任人 | -| D9 | 绩效等级与结果应用 | **A ≥ 90 / B 80–89 / C 70–79 / D < 70;C 级改善、连续两期 D 级进入淘汰评审** | 行业常见做法;首年可以只发布不自动处置,跑满两期再启用自动处置 | - -## 6. 平台依赖与待验证项 - -本设计依赖的平台能力,以及第 0 期需要在目标部署上验证的事项。✅ 本设计按已有能力 -使用;⚠️ 使用时有约束,对策见右列;❓ 第 0 期验证。 - -| 能力 | 状态 | SRM 中的用法 | 约束 / 对策 | +| P-D1 | 审批矩阵的单一来源 | **以 03 §12 为准,体系文件模板(ZC-02、QP-01、GL-02)跟着改** | 已按推荐改文档,待确认 | +| P-D2 | 物资 A/B/C 分类放在哪里 | **品类上的 `material_class` 字段,共享选项列表 `srm_material_class`;决定质量经理会签、审核频次、考评周期** | 已按推荐改文档,待确认 | +| P-D3 | 寻源在门户之前还是之后 | **门户(v0.6)先于寻源(v0.7)**,寻源依赖供应商在门户报价 | 已决(2026-10-23) | +| P-D4 | 源语言(中文源英文译,还是英文源中文译) | **中文源、英文译**,v0.3 前确认 | 待确认 | +| P-D5 | 扩展包何时立项 | **按 ADR-0009 准入标准,第一个客户出现时再定** | 已决(2026-10-23,ADR-0009) | + +## 6. 平台依赖与验证结果 + +本设计依赖的平台能力。✅ 本设计按已有能力使用;⚠️ 使用时有约束,对策见右列;❓ 待实测。 +「验证结果」列记录对照平台源码或 ADR 的结论和日期,以及已提交的平台 issue。 + +### 6.1 能力依赖 + +| 能力 | 状态 | SRM 中的用法 | 约束 / 对策 | 验证结果(日期) | +|---|---|---|---|---| +| 对象、字段(含 `currency`、`autonumber`、`summary`、`address`、`file`) | ✅ | 全部对象 | — | 2026-10-23 对照平台契约确认 | +| 带条件的汇总字段 | ✅ | 有效报价数、过期证书数 | 在设计时声明 `filter`(对象式条件) | 2026-10-23 确认 | +| `state_machine` 校验(含 `initialStates`) | ✅ ⚠️ | 所有单据状态 | `stageField` 的选项必须内联并带 `kind`,不能用共享选项列表 | 2026-10-23 确认(迁移 `stage-field-option-kind-required`) | +| `script` 校验规则(CEL,含 `now()`) | ✅ ⚠️ | 截止后锁价、开标时限、邀请兜底 | 能读本记录和一跳关联记录;更远或需汇总的依据冗余到本记录,或改走 screen flow | 2026-10-23 确认 | +| 字段谓词(`requiredWhen` 等) | ⚠️ | 条件必填 | 不能经引用字段读关联记录(ADR-0137 D2) | 2026-10-23 确认;规范见 docs/engineering §1 | +| `controlled_by_parent` 子对象 | ✅ ⚠️ | 证书、合同行、报价明细 | 写子记录要求对父记录有编辑权 → 父记录授编辑权 + 字段级权限全部只读 | 2026-10-23 确认 | +| flow:record_change / schedule / time_relative / api / screen | ✅ ⚠️ | 全部自动化 | 定时触发可能延迟或漏跑 → 追赶式扫描(03 §2.3) | 2026-10-23;延迟保证待平台(PF1 objectstack#25442) | +| 审批节点 | ✅ ⚠️ | 全部审批 | 超时按日历小时计算 → 工作日口径的时限存为业务字段,由扫描判断 | 2026-10-23 确认 | +| 公开表单(匿名提交) | ⚠️ | 供应商自助注册 | 不支持附件上传(PF4 objectstack#25445);防刷由前置网关限流保证(04 §8) | 2026-10-23;FR-201 降为 P2 | +| 岗位、权限集、OWD、字段级权限 | ✅ | 内部角色、门户 | `role` 为保留字(ADR-0090 D3) | 2026-10-23 确认 | +| RLS(CEL 谓词,`current_user.positions`) | ✅ ⚠️ | 门户隔离、封标 | 不能跨对象引用 → 冗余 `portal_position`、`bid_opened` | 2026-10-23 确认 | +| criteria 共享规则(接收方含业务单元) | ✅ | 按工厂共享单据 | — | 2026-10-23 确认 | +| 层级可见范围(`unit_and_below` 等) | ✅(企业版) | 集团 / 工厂逐级可见(可选) | 需企业版许可 | — | +| 唯一约束 | ✅ | 信用代码、`country` + `registration_no` | 空值安全的组合唯一(ADR-0120) | 2026-10-23 确认 | +| 报表(含矩阵) | ✅ | 比价矩阵(v0.7) | — | — | +| 仪表盘 | ✅ ⚠️ | 各类看板 | 求和 / 平均只能落在存储数值字段;多值字段不能做维度 | 2026-10-23 确认 | +| 平台导入(表格) | ✅ | 物料、存量供应商、交付记录 | 按外部编号匹配,可重复执行 | v0.2 用样例表格验证 | +| 批量 API `upsert`、`http` 节点、webhook | ✅ ⚠️ | ERP 集成(预留) | 业务字段记同步状态 + 追赶式重推(06 §1.1) | ERP 立项时验证 | +| 通知(`notify`) | ⚠️ | 全部通知 | 只能发给组织内用户,外部联系人的邮件待平台(PF3 objectstack#25444) | 2026-10-23 | +| 字段历史、审批历史 | ✅ | 审计 | — | 2026-10-23 确认 | +| AI 治理(工具调用审计、回答级权限) | ✅(企业版) | AI 用例的审计 | 需企业版许可 | — | +| 应用包代码(钩子、插件、函数) | ⚠️ | 不依赖 | 平台支持 QuickJS 沙箱内的事务型钩子(ADR-0034/0102/0119),可被 `OS_DISABLE_AUTHORED_HOOKS` 关闭;本设计按 ADR-0001 不依赖 | 2026-10-23 更正(原文「托管云不执行代码」有误) | +| 岗位定义 | ⚠️ | 每家供应商一个门户岗位 | 岗位是环境级元数据,由管理员新建,flow 不能创建;运行时建岗位待平台(PF2 objectstack#25443) | 2026-10-23 | +| 审批人与发起人相同的控制 | ⚠️ | 职责分离 | `expression` 审批人改派 + 岗位分离(04 §6);平台开关待(PF5 objectstack#25446) | 2026-10-23 | + +### 6.2 v0.6 前的实测项 + +| # | 项 | 用法 | 不满足时 | 结果 | +|---|---|---|---|---| +| V1 | 门户用户的用户目录可见范围 | 门户隔离(04 §3.6) | 见 D8 | ❓ 已确认缺陷,待修复(PF6 objectstack#25233) | +| V2 | flow 以系统身份写岗位任命(`sys_user_position`) | 门户开通自动化 | 管理员手工任命,flow 只做回填 | ❓ 待平台(objectstack#25251) | +| V3 | flow 发起组织邀请 | 门户开通自动化 | 管理员在成员页邀请 | ❓ | +| V4 | 门户用户对 `controlled_by_parent` 子记录的写入 | 证书、整改回复 | 父记录授编辑权 + 字段级只读 | ❓ | +| V5 | 环境内其他应用的 `isDefault` 权限集 | R2 | 逐个审查 | ❓ | + +### 6.3 已提交的平台 issue + +| # | issue | 影响 | 不修复时的做法 | |---|---|---|---| -| 对象、字段(含 `currency`、`autonumber`、`summary`、`address`、`file`) | ✅ | 全部对象 | — | -| 带条件的汇总字段 | ✅ | 有效报价数、过期证书数、已收货数量 | 在设计时声明 `filter`(对象式条件) | -| `state_machine` 校验(含 `initialStates`) | ✅ | 所有单据状态 | — | -| `script` 校验规则(CEL,含 `now()`) | ✅ ⚠️ | 截止后锁价、开标时限、邀请兜底 | 能读本记录和一跳关联记录;更远或需汇总的依据冗余到本记录,或改走 screen flow | -| `controlled_by_parent` 子对象 | ✅ ⚠️ | 订单行、证书、报价明细 | 写子记录要求对父记录有编辑权 → 父记录授编辑权 + 字段级权限全部只读 | -| flow:record_change / schedule / time_relative / api / screen | ✅ ⚠️ | 全部自动化 | 定时触发可能延迟或漏跑 → 追赶式扫描 + 外部心跳(03 §2.3);确认所选套餐支持定时任务 | -| 审批节点 | ✅ ⚠️ | 全部审批 | 超时按日历小时计算 → 工作日口径的时限存为业务字段,由扫描判断 | -| 公开表单(匿名提交) | ✅ ⚠️ | 供应商注册 | 防刷由前置网关限流保证(04 §8) | -| 岗位、权限集、OWD、字段级权限 | ✅ | 内部角色、门户 | — | -| RLS(CEL 谓词,`current_user.positions`) | ✅ ⚠️ | 门户隔离、封标 | 不能跨对象引用 → 冗余 `portal_position`、`bid_opened` | -| criteria 共享规则(接收方含业务单元) | ✅ | 按工厂共享单据 | — | -| 层级可见范围(`unit_and_below` 等) | ✅(企业版) | 集团 / 工厂逐级可见(可选) | 需企业版许可 | -| 报表(含矩阵) | ✅ | 比价矩阵 | — | -| 仪表盘 | ✅ ⚠️ | 各类看板 | 求和 / 平均只能落在存储数值字段;多值字段不能做维度 | -| 批量 API `upsert`(外部编号匹配) | ✅ | ERP 入站 | — | -| `http` 节点、webhook | ✅ ⚠️ | ERP 出站、外部服务 | 业务字段记同步状态 + 追赶式重推(06 §1.1) | -| 字段历史、审批历史 | ✅ | 审计 | — | -| AI 治理(工具调用审计、回答级权限) | ✅(企业版) | AI 用例的审计 | 需企业版许可 | -| 应用包代码(钩子、插件、函数) | ⚠️ | — | 托管云上安装的应用包不执行代码 → 本设计不依赖;自托管时可启用 membership resolver 等增强(04 §3.5) | -| 岗位定义 | ⚠️ | 每家供应商一个门户岗位 | 岗位是环境级元数据,由管理员新建,flow 不能创建;数量随供应商增长 | -| flow 以系统身份写岗位任命 | ❓ | 门户开通自动化 | 不行则管理员手工任命,flow 只做回填 | -| flow 发起组织邀请 | ❓ | 门户开通自动化 | 不行则管理员在成员页邀请 | -| 门户用户的用户目录可见范围 | ❓ | 门户隔离 | 按 04 §3.6 实测;不满足时见 D8 | -| 审批人与发起人相同的控制 | ⚠️ | 职责分离 | `expression` 审批人改派 + 岗位分离(04 §6) | +| PF1 | objectstack#25442 定时 flow 的延迟与漏跑保证 | 提醒、考评、扫描 | 追赶式扫描 | +| PF2 | objectstack#25443 运行时创建岗位 | 门户开通 | 管理员手工建岗位 | +| PF3 | objectstack#25444 通知组织外联系人 | 供应商邮件通知 | 门户内通知 + 人工邮件 | +| PF4 | objectstack#25445 公开表单附件 | 供应商自助注册 | 内部登记 + 邀请注册 | +| PF5 | objectstack#25446 禁止自审开关 | 职责分离 | `expression` 改派 | +| PF6 | objectstack#25233 门户用户可列出全组织用户 | 门户隔离 | v0.6 阻塞;见 D8 | +| PF7 | objectstack#25447 ADR-0138 D5(多组织环境下公开表单绑定到指定组织) | 多法人客户的自助注册 | 邀请注册;多法人按 ADR-0006 单组织时不受影响 | --- -*本设计的下一步:确认 §5 的 D1–D9 → 第 0 期调研与原型 → 按第一期范围在应用包中实现。* +*本设计的下一步:v0.2 主数据补齐 → … → v0.5 门槛 1 验收 → v0.6 门户 → v0.7 寻源与门槛 2。 +每个版本出口时更新 §1 的路线表。* diff --git a/docs/design/README.md b/docs/design/README.md index a48ba4c..e9efb5b 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1,6 +1,6 @@ # hotsrm 核心设计 · 需求分析与设计 -> 状态:设计草案 v0.1(2026-10-22) +> 状态:设计草案 v0.2(2026-10-23):按 [ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md)、[ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md) 收窄范围并按版本重排;审核修正见各篇标注 > 适用:hotsrm 的通用核心,即在 ObjectStack(ObjectOS 元数据驱动运行时)上构建的 SRM 应用包。 > 行业差异见 [扩展包](../packs/README.md),管理制度模板见 [体系文件](../../governance/README.md) > 受众:产品、实施顾问、开发,以及采购 / 质量 / 财务业务方 @@ -8,13 +8,15 @@ ## 1. 一页纸结论 -**定位**:SRM 负责企业**与供应商协同**的那一半——供应商全生命周期、寻源定价、 -订单与送货协同、质量整改、对账开票、绩效与风险。物料、库存、应付凭证和付款 -仍由 ERP 记账(system of record),SRM 不做第二套账。 +**定位**:SRM 负责企业**与供应商协同**的那一半——供应商全生命周期、合同、质量整改、 +绩效与风险、寻源定价、供应商门户。采购订单、收货、对账、发票、付款留在 ERP +(system of record),SRM 只记结论、不做第二套账;交付与质量结果按月导入用于算分 +([ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md))。 **形态**:一个用 TypeScript 元数据定义、编译成单一制品发布的应用包 `srm`(命名空间 -`srm`),约 35 个业务对象,分 5 期上线;两个应用外壳——内部的「采购协同工作台」和面向外部的「供应商门户」, -两者读写同一份数据,靠权限区分各自能看到什么。 +`srm`),核心 **27 个业务对象**,按 v0.1–v0.7 七个版本交付([07 §1](./07-delivery-plan.md#1-分期路线图)); +两个应用外壳——内部的「采购协同工作台」(v0.1 起)和面向外部的「供应商门户」(v0.6), +两者读写同一份数据,靠权限区分各自能看到什么。现阶段只做核心包,扩展包保留为设计(ADR-0009)。 **六个关键设计决定**: @@ -29,19 +31,19 @@ 3. **封标**:报价截止前,内部任何角色(包括 AI 助手)都读不到报价。报价上有一个 开标时才写入的 `bid_opened` 标志,内部 RLS 只放行 `bid_opened == true` 的报价; 截止后供应商的修改由校验规则用 `now()` 比较冗余在报价上的截止时间来拒绝, - 不依赖定时任务准时运行。详见 [03 §4](./03-processes-and-automation.md#4-p3-寻源询价--比价--定标)。 + 不依赖定时任务准时运行。详见 [03 §4](./03-processes-and-automation.md#4-p3-寻源询价--比价--定标v07)。 4. **流程就是 flow**:审批用 flow 的 `approval` 节点;单据状态是主对象上的 `select` 字段,非法跳转由 `state_machine` 校验规则拦截;**不建**「审批记录表」,审批历史 由平台保存且不可篡改。需要跨对象判断的写操作(邀请供应商、建送货单、提交发票) 只开放为以系统身份运行的 `screen` flow。 -5. **ERP 集成按外部编号幂等 upsert**:物料、订单、收货、检验、付款按 `erp_*_id` - 写入 SRM;SRM 产出的供应商、价格、对账结果用 flow 的 `http` 节点推回 ERP。 -6. **分期交付,MVP 先跑通「供应商进来 → 询价定价」**:第一期只做供应商主数据、 - 准入、资质到期预警、门户基础功能、询价比价定标和价格库,约 16 个对象。 +5. **预留集成点,现阶段不集成 ERP**:物料和交付记录用表格导入;供应商、价格、合同上 + 保留 `erp_*` 外部单号字段空着;ERP 连接器在客户明确型号时立项([06](./06-integration-and-ai.md))。 +6. **内部优先,MVP 是内部版**:v0.1–v0.5 先做供应商生命周期、合同、质量、绩效、风险, + 20 个对象试运行通过后(门槛 1)再开门户(v0.6),然后寻源(v0.7,门槛 2:核心冻结)。 -**实施时要确认的事**:见 [07 §5 待决策事项](./07-delivery-plan.md#5-待决策事项附推荐), -每项都附了推荐方案。最影响后续工作的是 D1(部署形态与门户账号模式)、D2(多法人 -是否隔离),以及 D8(门户用户的用户目录可见范围不满足要求时怎么处理)。 +**待确认的事**:见 [07 §5 待决策事项](./07-delivery-plan.md#5-待决策事项附推荐)。原 D1–D9 +大多已随 v0.1 开工采纳;2026-10-23 新增的 P-D1(审批矩阵以设计为准)、P-D2(物资 A / B / C +分类进系统)按推荐方案先行,P-D4(核心源语言)在 v0.3 前定。 ## 2. 文档导航 @@ -52,9 +54,10 @@ | [03-processes-and-automation.md](./03-processes-and-automation.md) | 10 条端到端流程、审批矩阵、自动化清单、定时任务可靠性设计 | 业务方、开发 | | [04-security-and-portal.md](./04-security-and-portal.md) | 角色与权限矩阵、组织级默认可见性(OWD)、供应商门户隔离、封标、字段级权限、职责分离 | 安全、实施、开发 | | [05-experience-and-analytics.md](./05-experience-and-analytics.md) | 两个应用的导航、视图、表单、仪表盘与指标口径、通知 | 产品、设计 | -| [06-integration-and-ai.md](./06-integration-and-ai.md) | ERP 集成方案与字段映射、外部服务、AI 助手用例与治理 | 开发、架构 | -| [07-delivery-plan.md](./07-delivery-plan.md) | 分期路线图、MVP 验收、应用包结构、风险、待决策事项、平台依赖与待验证项 | 项目经理、全体 | -| [../packs/](../packs/README.md) | 行业扩展包:大宗物料包、危化品包、国企采购合规包 | 产品、实施 | +| [06-integration-and-ai.md](./06-integration-and-ai.md) | 预留的 ERP 集成点与字段映射(现阶段不实现)、导入方式、外部服务、AI 助手用例与治理 | 开发、架构 | +| [07-delivery-plan.md](./07-delivery-plan.md) | 版本路线图与门槛、验收、应用包结构、风险、待决策事项、平台依赖与验证结果 | 项目经理、全体 | +| [../packs/](../packs/README.md) | 行业扩展包(设计保留,未排期):大宗物料包、危化品包、国企采购合规包 | 产品、实施 | +| [../engineering/](../engineering/README.md) | 建模规范、CI 门禁、测试与版本策略 | 开发 | | [governance/](../../governance/README.md) | 体系文件(管理制度)模板与参数 | 实施顾问、客户体系工程师 | ## 3. 默认业务画像(设计假设) @@ -67,7 +70,7 @@ | 行业 | 离散制造(机械 / 电子 / 汽配),直接物料为主,兼顾 MRO 等间接采购 | 准入审核项、绩效指标、质量模块深度;大宗原料按批次化验计价的行业见大宗物料包,涉及危险化学品的见危化品包 | | 规模 | 年采购额 5–50 亿元,活跃供应商 300–2000 家,采购相关内部用户 30–150 人 | 门户并发、数据量、审批层级 | | 组织 | 1 个集团、2–5 个法人、多个工厂(收货地点) | 多法人隔离姿态(D2)、对账维度 | -| ERP | 已有 ERP(SAP / 用友 / 金蝶之一),负责物料、PO 记账、收货、应付、付款 | 集成范围(06) | +| ERP | 已有 ERP(SAP / 用友 / 金蝶之一),负责物料、PO 记账、收货、应付、付款;现阶段不集成,物料与交付记录按月表格导入 | 预留集成点(06)、交付记录(02 §4.6) | | 供应商 | 以国内供应商为主,增值税专票,用统一社会信用代码建档;境外供应商按「国家 / 地区 + 注册号」建档;全部界面中英文([ADR-0007](../adr/0007-china-first-with-overseas-seams.md)) | 字段、发票模型、国际化 | | 招标 | 企业自主采购,不涉及《招标投标法》意义上的依法必须招标项目 | 国有企业的采购方式、限额与监督要求见国企采购合规包;依法必须招标的项目仍需专业电子招投标平台(范围外) | diff --git a/docs/engineering/README.md b/docs/engineering/README.md new file mode 100644 index 0000000..74adef2 --- /dev/null +++ b/docs/engineering/README.md @@ -0,0 +1,52 @@ +# hotsrm 工程规范 + +> 状态:首版(2026-10-23)。随 v0.1 W3 建立;建模规范来自平台契约与 2026-10-23 的设计审核, +> 测试与版本策略来自开发计划第 11 节。规则与 [AGENTS.md](../../AGENTS.md) 冲突时以 AGENTS.md 为准。 + +## 1. 建模规范 + +补充 [核心 02 §1](../design/02-domain-model.md#1-建模原则) 的建模原则,都是平台校验会直接拒收、 +或能发布但运行时不对的写法。 + +| 规则 | 说明 | 出处 | +|---|---|---| +| 字段谓词只读本记录 | `requiredWhen`、`readonlyWhen`、选项的 `visibleWhen` 若经 lookup / master_detail / user / tree 字段读关联记录,`objectstack validate` 直接拒绝;`previous.*`、`parent.*` 在任何地方都没有一跳 | objectstack ADR-0137 D2,迁移 `field-predicate-reference-traversal-refused` | +| 关联记录只在 `script` 校验规则里读 | `validations[]` 的 `script` 规则会预加载一跳关联记录,可用 `now()` / `today()`;两跳以上的依据冗余到本记录,或改走 screen flow | 核心 02 §1 第 12 条 | +| 字段名不含 `role` | `role` 是平台保留禁用词;联系人的角色字段叫 `contact_function` | objectstack ADR-0090 D3 | +| `stageField` 不用共享选项列表 | 状态字段的每个选项必须带 `kind`,只能内联定义;其他可被扩展的枚举才做成 picklist | 迁移 `stage-field-option-kind-required` | +| 唯一约束按组织作用域、空值安全 | 声明索引用 `unique: 'organization'`;允许多条空值的组合唯一(如境外供应商的 `country` + `registration_no`)用平台的空值安全写法 | objectstack ADR-0120 | +| 跨记录规则不写校验规则 | 「每家供应商至多一位主联系人」这类规则由 screen flow 以系统身份处理,不写成单条校验 | 审核 F-29 | +| 外部单号字段预留、空着 | `erp_vendor_code`、`erp_material_no` 等字段保留在对象上,ERP 集成前不写 | [ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md) | +| 中国特有字段单独分组 | 统一社会信用代码、纳税人类型等放在「工商与税务」分组,便于将来拆中国本地化包 | [ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md) | + +## 2. 分支与 PR + +- 每个工作项一个 PR,标题带版本和编号(如 `feat(core): v0.2 M2 bank account`);一个 PR 不跨版本。 +- PR 描述列出改动的对象、flow、权限集和对应的设计文档章节;设计与实现不一致时同一 PR 改文档。 +- 改对象名、字段名、字段类型必须附 ADR;门槛 2(核心 27 个对象冻结)之后还要附迁移说明。 + +## 3. CI 门禁(全部必须绿) + +| 检查 | 要求 | 起始版本 | +|---|---|---| +| `os validate` | 元数据合法,无自定义 hook(ADR-0001) | v0.1 | +| `os i18n check --strict` | zh / en 全部键齐全(ADR-0007) | v0.1 | +| `governance/scripts/build.py --check` | 体系文件模板无待确认占位,参数引用全部已定义 | v0.1 | +| 文档链接检查 | docs 内部链接与锚点无失效 | v0.1 | +| 导入幂等 | 样例表格跑两遍结果一致 | v0.2 | +| 隔离测试 | 门户跨公司访问七条路径(列表、详情 URL、关联搜索、报表、文件下载、API、用户目录)全部拒绝 | v0.6 | +| 封标测试 | 截止前内部任何岗位(含管理员视图、报表、导出、API)读不到报价 | v0.7 | + +## 4. 测试策略 + +- **元数据级**:每个对象一组种子数据;每条校验规则一正一反。 +- **流程级**:每条审批流覆盖通过、驳回、退回、升级;定时 flow 用追赶式测试(漏跑一次后下一次补上)。 +- **权限级**:每个岗位一份「能看到什么」的快照,权限变更时对比。 +- 用平台的 verify 工具在进程内启动整个应用包做端到端断言,失败即阻断发布。 + +## 5. 版本与升级 + +- 应用包按语义化版本发布,每个版本(v0.1 … v0.7)一个次版本号。 +- 破坏性变更(删字段、改选项值、改 API 名)必须附 ADR 和数据迁移;核心字段只能隐藏,不能删除。 +- 核心升级前跑一次「核心 + 客户层」组合构建,补平台尚未检测的覆盖层冲突(ADR-0009)。 +- 每个版本出口时更新 [07 §1](../design/07-delivery-plan.md#1-分期路线图) 的路线表和根 README 的对象数。 diff --git a/docs/packs/README.md b/docs/packs/README.md index c871ec6..9a08fe5 100644 --- a/docs/packs/README.md +++ b/docs/packs/README.md @@ -1,6 +1,7 @@ # hotsrm 行业扩展包 -> 状态:设计草案 v0.1(2026-10-22) +> 状态:**设计保留,未排期**(2026-10-23,[ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md))。 +> 三个包的设计草案保留,v0.7 前不开发;第一个客户出现时按 §3.5 的准入标准决定做包还是进核心。 > 上位文档:[核心设计](../design/README.md) ## 1. 三层结构 @@ -9,16 +10,16 @@ hotsrm 面向不同行业的企业,但不为每个客户做一套系统。客 | 层 | 内容 | 谁会用 | 放在哪里 | |---|---|---|---| -| **通用核心** | 所有企业都需要的供应商管理功能与管理制度:供应商生命周期、寻源定价、合同、订单协同、质量整改、绩效、对账、门户 | 所有客户 | 设计在 `docs/design/`,源码在 `src/core/` | -| **行业扩展包** | 某一类企业共有的做法,作为模块在构建时合进应用 | 同类客户 | 设计在 `docs/packs/`,源码在 `src/bulk/`、`src/hazmat/`、`src/soe/` | -| **客户配置** | 某个客户的参数取值、组织结构、物资目录、审批权限、文件编号与样式,以及少量专属段落 | 单个客户 | 客户的私有仓库与客户环境,**不进本仓库** | +| **通用核心** | 所有企业都需要的供应商管理功能与管理制度:供应商生命周期、合同、质量整改、绩效、风险、门户、寻源定价(27 个对象;订单到付款留在 ERP,[ADR-0008](../adr/0008-order-to-pay-stays-in-erp.md)) | 所有客户 | 设计在 `docs/design/`,源码在 `src/core/` | +| **行业扩展包** | 某一类企业共有的做法,作为模块在构建时合进应用;**现阶段只有设计** | 同类客户 | 设计在 `docs/packs/`;源码目录(`src/bulk/`、`src/hazmat/`、`src/soe/`)在立项时再建 | +| **客户层** | 某个客户的参数取值、组织结构、物资目录、审批岗位称谓、文件编号与样式、Studio 覆盖层(标签、必填、选项、新增字段、隐藏字段、视图、流程)、AI 生成的客户私有包 | 单个客户 | 客户的私有仓库与客户环境,**不进本仓库** | 客户提出一个新需求时,按下面的顺序决定它落在哪一层: 1. 别的客户也会需要吗?会 → 做进**通用核心**; -2. 同一类客户(同行业、同类物料、同类所有制)会需要吗?会 → 做进**扩展包**; -3. 只是取值不同吗?是 → 做成**参数**,在客户配置里赋值; -4. 以上都不是 → 才算**客户定制**。定制要尽量少,并且定期评估能否上提到前三层。 +2. 同一类客户(同行业、同类物料、同类所有制)会需要吗?会,且满足 §3.5 的准入标准 → 做进**扩展包**; +3. 只是取值不同吗?是 → 做成**参数**,在客户层赋值; +4. 以上都不是 → 放**客户层**(Studio 覆盖层或客户私有包),不改核心源码。客户层的规则见 ADR-0009 第 4 条。 ## 2. 扩展包清单 @@ -50,8 +51,8 @@ ObjectStack 的安装单位是**应用**(`type: app`):客户安装、打 | 源码目录 | 包类型 | 说明 | |---|---|---| | `src/core/` | `app` | 核心,也是应用的身份:客户安装的就是它 | -| `src/bulk/`、`src/hazmat/`、`src/soe/` | `module` | 三个扩展包 | -| `src/bridges/<包A>-<包B>/` | `module` | 两个扩展包同时组合时才需要的联动(见 §3.3) | +| `src/bulk/`、`src/hazmat/`、`src/soe/` | `module` | 三个扩展包(未建) | +| `src/bridges/<包A>-<包B>/` | `module` | 两个扩展包同时组合时才需要的联动(见 §3.3;暂不做) | 根目录的 `objectstack.composition.ts` 按扩展包开关选出要组合的模块, `objectstack.config.ts` 把它们合成一个发布制品: @@ -67,7 +68,10 @@ ObjectStack 的安装单位是**应用**(`type: app`):客户安装、打 ### 3.2 扩展包怎么接入核心 -扩展包不修改 `src/core/` 下的任何文件,只通过平台提供的三种扩展方式接入: +扩展包不修改 `src/core/` 下的任何文件,只通过平台提供的三种扩展方式接入。按 ADR-0009 +第 3 条收窄:包主要新增**自己的对象**;对核心对象的 `objectExtensions` 每个包不超过 2–3 个 +字段,只放关联键和开关,业务字段放包自己的对象(否则核心对象在 Studio 里分成多层,客户 +难以设计)。 | 方式 | 用途 | 例子 | |---|---|---| @@ -80,6 +84,8 @@ ObjectStack 的安装单位是**应用**(`type: app`):客户安装、打 ### 3.3 扩展包之间的联动:桥接模块 +> 暂不做:两个包之间的联动等两个包都有客户时再设计(ADR-0009 第 3 条)。下面是设计基线。 + 两个扩展包同时组合时才有意义的联动(例如大宗物料包的到货车次关联危化品包的入厂预约), 不能写在任何一个包里,否则只组合其中一个包时会引用不存在的对象。这类联动放在 **桥接模块** `src/bridges/<包A>-<包B>/` 里,用 `objectExtensions` 给两边的对象加关联字段; @@ -99,6 +105,19 @@ ObjectStack 的安装单位是**应用**(`type: app`):客户安装、打 | 体系文件模板 | 扩展包对应的管理办法与表单模板,放在 `governance/templates/<包>/`,见 [体系文件](../../governance/README.md) | | 集成 | 扩展包需要的外部系统接口(如地磅、化验系统、电子招标平台) | +### 3.5 准入标准与依赖顺序 + +满足任一条件才立项为扩展包(ADR-0009 第 2 条):受法规约束、有明确合规要求;三家以上 +客户复用同一套做法;需要保护专门的测试资产。只是一家客户的做法,放客户层。 + +| 包 | 依赖 | 可立项时点 | +|---|---|---| +| 国企采购合规包 | 核心寻源(v0.7)与合同(v0.3) | v0.7 之后最早可做;受法规约束,满足准入标准 | +| 大宗物料包 | 订单、收货、结算(都在 ERP),需要 ERP 集成和门户镜像 | ERP 集成落地之后;月度订单 SRM → ERP 的反向数据流(I9b)要先补进 06 §1.2 | +| 危化品包 | 入厂预约依赖订单镜像;承运商、许可范围只依赖核心供应商 | 承运商与许可部分可在 ERP 集成前做,预约部分在 ERP 集成之后 | + +组合构建测试在第二个包出现时才加入 CI,在此之前按单个应用开发。 + ## 4. 编写约定 - **不写客户名,也不写能认出客户的组合**:示例用行业通行做法,不照搬某个客户的物料 diff --git a/docs/packs/bulk-materials.md b/docs/packs/bulk-materials.md index ac7dec2..b832b96 100644 --- a/docs/packs/bulk-materials.md +++ b/docs/packs/bulk-materials.md @@ -1,6 +1,6 @@ # 大宗物料包 -> 状态:设计草案 v0.1(2026-10-22) +> 状态:设计草案 v0.1(2026-10-22);**设计保留,未排期**(2026-10-23,[ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md),立项条件见[扩展包总览 §3.5](./README.md#35-准入标准与依赖顺序)) > 包前缀:`srm_bulk_` · 上位文档:[扩展包总览](./README.md) ## 1. 适用场景 @@ -134,7 +134,7 @@ flowchart LR | 地磅 / 一卡通 / 物流园区系统 | 车次、毛重、皮重、过磅时间 | 外部系统调用批量 API 按车次号 upsert | | 化验室信息系统(LIMS) | 样品编号、指标实测值 | 同上,按样品编号 upsert | | 价格资讯数据源 | 价格参照的日度数据 | 手工导入或接口获取;注意数据源的使用许可 | -| ERP | 月度订单下推;收货按结算重量过账 | 沿用核心集成方式 | +| ERP | 月度订单下推;收货按结算重量过账 | 本包由 flow 创建月度订单并推送 ERP,方向与核心「订单由 ERP 下发」相反:立项前先在核心 06 §1.2 补「I9b 月度订单 SRM → ERP」数据流及字段归属,并确认客户 ERP 接受外部创建的订单(审核 F-24) | ## 8. 体系文件模板 diff --git a/docs/packs/hazmat.md b/docs/packs/hazmat.md index da0cfcd..5fd52aa 100644 --- a/docs/packs/hazmat.md +++ b/docs/packs/hazmat.md @@ -1,6 +1,6 @@ # 危化品包 -> 状态:设计草案 v0.1(2026-10-22) +> 状态:设计草案 v0.1(2026-10-22);**设计保留,未排期**(2026-10-23,[ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md),立项条件见[扩展包总览 §3.5](./README.md#35-准入标准与依赖顺序)) > 包前缀:`srm_hz_` · 上位文档:[扩展包总览](./README.md) ## 1. 适用场景 @@ -98,7 +98,7 @@ flowchart TD | 安全环保部 | 危化属性、许可范围、承运商档案的核验;安全事件的增改 | | 门岗 / 安保 | 只读当天的入厂预约,填写门岗查验记录;看不到价格、订单金额等商务信息 | | 收货单位 | 读预约与查验结果,填写卸车作业记录 | -| 承运商门户用户 | 维护本承运商的车辆与人员,提交预约;隔离方式与供应商门户相同 | +| 承运商门户用户 | 维护本承运商的车辆与人员,提交预约;隔离方式与供应商门户相同。第三方承运商同时服务多家供应商,入厂预约既要供应商看也要承运商看:预约上冗余两个岗位字段(`portal_position`、`carrier_portal_position`),门户 RLS 用 `||` 连接(审核 F-23) | ## 6. 参数(示例默认值) diff --git a/docs/packs/soe-procurement.md b/docs/packs/soe-procurement.md index 068e8fb..ed8e791 100644 --- a/docs/packs/soe-procurement.md +++ b/docs/packs/soe-procurement.md @@ -1,6 +1,6 @@ # 国企采购合规包 -> 状态:设计草案 v0.1(2026-10-22) +> 状态:设计草案 v0.1(2026-10-22);**设计保留,未排期**(2026-10-23,[ADR-0009](../adr/0009-core-first-pack-criteria-and-customer-layer.md),立项条件见[扩展包总览 §3.5](./README.md#35-准入标准与依赖顺序)) > 包前缀:`srm_soe_` · 上位文档:[扩展包总览](./README.md) ## 1. 适用场景 diff --git a/governance/README.md b/governance/README.md index c2964f2..d6674b4 100644 --- a/governance/README.md +++ b/governance/README.md @@ -1,6 +1,7 @@ # hotsrm 体系文件(管理制度)模板 -> 状态:v0.2(2026-10-22)。生成脚本、参数文件首版和 QP-01 模板已完成;其余模板按 §6 的计划陆续补齐。 +> 状态:v0.3(2026-10-23)。生成脚本、参数文件首版和 12 份核心模板(QP-01、QP-02、ZC-01~ZC-03、SP-01、GL-01、GL-02、GL-04、GL-05、WI-01)已完成; +> 其余模板按 §6 的计划随核心版本补齐。审批权限以核心设计 03 §12 的审批矩阵为唯一来源,ZC-02 等按它编写(2026-10-23,P-D1)。 > 模板代号、名称和编写状态以 [`templates/index.yaml`](./templates/index.yaml) 为准。 ## 1. 为什么要有体系文件模板 @@ -37,7 +38,7 @@ hotsrm 把管理制度和系统放在一起维护: |---|---|---|---|---|---| | ZC-01 | 采购与供应商管理政策 | 政策 | 基本原则、管理架构、核心管理要求、制度与系统的分工、过渡安排、风险管理与监督、管理目标、体系文件构成 | ISO 9001 5.2、ISO 20400 | 01、07 | | ZC-02 | 采购授权审批表 | 政策 | 供应商管理、采购寻源、结算付款的全部审批事项与权限;各文件附录的权限以本表为准 | COSO 控制活动 | 03 | -| ZC-03 | 供应商管理风险控制矩阵 | 政策 | 主要风险、控制措施、执行方式与上线期次、责任部门与出处;同时作为内控检查清单和系统控制验收清单 | COSO、《企业内部控制应用指引第 7 号》 | 01 §4、07 §1 | +| ZC-03 | 供应商管理风险控制矩阵 | 政策 | 主要风险、控制措施、执行方式与上线版本、责任部门与出处;同时作为内控检查清单和系统控制验收清单 | COSO、《企业内部控制应用指引第 7 号》 | 01 §4、07 §1 | | SP-01 | 供应商行为准则 | 对外 | 商业道德、劳工与人权、健康与安全、环境保护、管理体系、核查与处理、举报渠道;附供应商确认书 | 联合国全球契约、国际劳工组织核心劳工标准 | 04 §6 | | QP-01 | 供应商管理控制程序 | 二级 | 分类分级、注册、准入、合格名录、信息变更、资质动态管理、绩效、整改、冻结淘汰与黑名单、廉洁 | ISO 9001 8.4.1、8.4.2 | 01、03 §3、§5、§10、§11 | | QP-02 | 采购控制程序 | 二级 | 需求、采购方式、寻源定价、合同、订单、验收、对账结算、付款 | ISO 9001 8.4.2、8.4.3 | 03 §4、§6、§7、§9 | @@ -55,7 +56,7 @@ hotsrm 把管理制度和系统放在一起维护: | GL-09 | 供应商对账与付款管理办法 | 三级 | 对账周期、差异处理、发票、付款 | QP-02 | 03 §9 | | GL-10 | 供应商门户账号与信息安全管理规定 | 三级 | 账号开通与回收、权限、报价保密 | QP-01 | 04 §3 | -### 3.2 扩展包模板(组合了对应扩展包时启用) +### 3.2 扩展包模板(组合了对应扩展包时启用;扩展包设计保留、未排期) | 扩展包 | 代号 | 模板 | |---|---|---| @@ -135,7 +136,8 @@ governance/ ### 4.2 参数定义 参数定义的每一项包括:键、中文名、单位、示例默认值、使用它的文件与条款、对应的系统 -配置位置,以及可选的渲染格式。例如: +配置位置,以及可选的渲染格式。`system` 写「制度要求」的参数只进制度文本,系统不强制、 +也不要求在应用包里配置;写了系统位置的参数,应用包配置必须取同一个值。例如: ```yaml scar_containment_hours: @@ -209,11 +211,12 @@ python3 /governance/scripts/build.py --instance governance --check # ## 6. 编写计划 -| 批次 | 模板 | 说明 | +| 批次 | 模板 | 随核心版本 | |---|---|---| -| 第一批 | QP-01、ZC-01~ZC-03、SP-01、QP-02、GL-01、WI-01、GL-02、GL-04、GL-05(已完成);BK-01、SP-02、HZ-01 | 支撑核心第一期(准入、寻源定价)及两个扩展包的主流程 | -| 第二批 | QP-03、QP-04、GL-03、GL-06、GL-07、GL-08;各扩展包其余模板 | 支撑核心第二、三期 | -| 第三批 | GL-09、GL-10 | 支撑核心第四期与门户全面推广 | +| 已完成 | QP-01、QP-02、ZC-01~ZC-03、SP-01、GL-01、WI-01、GL-02、GL-04、GL-05 | v0.1–v0.3 已有依据;GL-02 的系统控制在 v0.7 落地 | +| 第二批 | GL-03(合同)、GL-08(处置)、GL-07(整改)、QP-03、QP-04 | v0.3 合同与处置、v0.4 质量 | +| 第三批 | GL-06(绩效)、GL-10(门户账号与信息安全) | v0.5 绩效、v0.6 门户 | +| 暂不编写 | GL-09(对账与付款):对账、发票、付款留在 ERP(ADR-0008),只在客户要求把 ERP 侧流程写进体系文件时编写;各扩展包模板随扩展包立项 | — | -已完成:生成脚本、`params/` 参数文件首版、模板登记表、QP-01、政策层三份(ZC-01~ZC-03)、供应商行为准则(SP-01)、QP-02、GL-01、WI-01、GL-02、GL-04、GL-05。扩展包的表单代号在编写 -对应模板时登记。 +已完成:生成脚本、`params/` 参数文件首版、模板登记表和上表第一行的 12 份模板。扩展包的表单 +代号在编写对应模板时登记。 diff --git a/governance/org.example.yaml b/governance/org.example.yaml index aac0d6b..6b81ea9 100644 --- a/governance/org.example.yaml +++ b/governance/org.example.yaml @@ -39,6 +39,17 @@ role: vp_procurement: 分管采购的副总经理 gm: 总经理 +# 审批岗位的称谓。核心设计 03 §12 的审批矩阵按这些岗位解析审批人,SRM 中的岗位(position) +# 与之一一对应;客户按本企业的叫法改称谓,不改矩阵。 +position: + category_manager: 品类经理 + buyer_lead: 采购主管 + procurement_director: 采购总监 + quality_manager: 质量经理 + sqe: 供应商质量工程师 + ap_accountant: 应付会计 + legal: 法务 + # 本企业对行业物资的称呼,用在扩展包段落里 terms: bulk: 大宗原料 diff --git a/governance/templates/core/GL-01.md b/governance/templates/core/GL-01.md index 6fcc2d1..f7c69b1 100644 --- a/governance/templates/core/GL-01.md +++ b/governance/templates/core/GL-01.md @@ -259,5 +259,5 @@ SRM 系统上线后,上述记录以系统电子记录为主。 | 资料审核 | {{org.dept.procurement}}、核验部门 | 资料齐全后 {{param.doc_review_days}} 个工作日 | 资料审核 → 准入评审(或退回补充) | | 现场审核 | {{org.dept.quality}} | 资料审核通过后 {{param.site_audit_days}} 日内 | 录入审核结论 | | 样品检验与试用 | {{org.dept.quality}}、{{org.dept.production}} | 按试用通知 | 录入样品结论 | -| 准入评审 | 审批人 | 每级 3 个工作日 | 准入评审 → 已批准 / 已驳回 | +| 准入评审 | 审批人 | 每级 {{param.admission_approval_days}} 个工作日 | 准入评审 → 已批准 / 已驳回 | | 试供期评价 | {{org.dept.procurement}} | 试供期满后 15 日内 | 试供 → 合格(或暂停) | diff --git a/governance/templates/core/GL-02.md b/governance/templates/core/GL-02.md index 9b8263e..c8d03b5 100644 --- a/governance/templates/core/GL-02.md +++ b/governance/templates/core/GL-02.md @@ -97,7 +97,7 @@ a) **最低价法**:适用于规格标准统一的物资,在满足全部实 b) **综合评分法**:适用于技术或服务差异较大的项目,由技术评分和商务评分加权得出总分。商务评分按「最低报价 ÷ 本家报价 × 100」计算,技术评分由评审小组成员按寻源文件载明的评分标准打分;技术与商务的权重在寻源文件中载明,技术权重一般不超过 {{param.tech_weight_max}}。 -7.2 采用综合评分法、竞争性谈判和招标的,组成评审小组。评审小组由采购、需求、技术、质量等部门人员组成,人数不少于 {{param.panel_min_size}} 人且为单数;金额达到附录 A 第三档的,评审小组成员从公司评审专家库中抽取。 +7.2 采用综合评分法、竞争性谈判和招标的,组成评审小组。评审小组由采购、需求、技术、质量等部门人员组成,人数不少于 {{param.panel_min_size}} 人且为单数;金额达到附录 A 第三档的,评审小组成员从公司评审专家库中抽取由{{org.dept.procurement}}负责人指定,并至少有一名采购部门以外的成员。 7.3 评审小组成员与参与报价的供应商存在利益冲突的,应主动申报并回避,按 {{doc.GL-05}}执行。 @@ -178,13 +178,14 @@ c) {{org.terms.bulk}}按市场价联动定价,按 {{doc.BK-01}}执行。 ;涉及危险化学品的加{{org.dept.hse}}负责人) | +| 冻结 / 解冻 | 全部 | {{org.position.category_manager}} → {{org.position.procurement_director}} | +| 淘汰 | 全部 | {{org.position.category_manager}} → {{org.position.procurement_director}} → {{org.role.gm}} | +| 列入 / 解除黑名单 | 全部 | {{org.position.category_manager}} → {{org.position.procurement_director}} → {{org.role.gm}}({{org.dept.discipline}}、{{org.dept.audit}}会签) | +| 关键信息变更 | 全部 | {{org.position.buyer_lead}} | +| 收款账户新增 / 变更 | 全部 | {{org.position.buyer_lead}} → {{org.position.ap_accountant}}(两级不得为同一人) | +| 绩效结果发布 | 每期 | {{org.position.procurement_director}} | + +审批权限以{{doc.ZC-02.title}}和公司现行授权文件为准;同一事项的发起人不得作为其审批人。物资类别只决定是否会签{{org.position.quality_manager}}、现场审核频次和绩效评价周期(附录 A),不再区分审批层级。 # 附录 D 绩效评价指标(示例,A 类) diff --git a/governance/templates/core/ZC-02.md b/governance/templates/core/ZC-02.md index 033a8ad..0b5b382 100644 --- a/governance/templates/core/ZC-02.md +++ b/governance/templates/core/ZC-02.md @@ -12,7 +12,7 @@ title: 采购授权审批表 1.1 本表汇总采购与供应商管理中需要审批的全部事项。各程序文件和管理办法附录中的审批权限与本表不一致的,以本表为准;修订时先改本表,再同步修订相关文件附录和 SRM 系统的审批流程配置。 -1.2 本表所列金额档与审批人是依据现行文件整理的建议,须与{{org.superior}}的授权规定和公司现行授权文件核对后定稿。 +1.2 本表所列金额档与审批人是依据现行文件整理的建议,须与{{org.superior}}的授权规定和公司现行授权文件核对后定稿。本表与 SRM 核心设计的审批矩阵(03 §12)一致:审批岗位的称谓按本公司叫法填写,系统中按岗位解析审批人。采购申请、付款等在 ERP 或 OA 中审批的事项只列出口径,不在 SRM 中配置。 1.3 所有审批适用下列通用规则: @@ -32,35 +32,35 @@ f) 各级审批均在 SRM 系统中进行,系统审批记录为正式记录。 | 事项 | 条件 | 审批 | 依据 | |----------------------|------------------|--------------------------------------------|----------------| -| 准入 | C 类物资 | {{org.dept.procurement}}负责人 | {{doc.QP-01.number}} 附录 C | -| 准入 | B 类物资 | {{org.dept.procurement}}负责人 → {{org.dept.quality}}负责人 | {{doc.QP-01.number}} 附录 C | -| 准入 | A 类物资 | {{org.dept.procurement}}负责人 → {{org.dept.quality}}负责人(涉及危险化学品的会签{{org.dept.hse}}负责人)→ {{org.role.vp_procurement}} | {{doc.QP-01.number}} 附录 C | +| 准入 | B 类、C 类物资,且品类风险等级非高 | {{org.position.category_manager}} → {{org.position.procurement_director}} | {{doc.QP-01.number}} 附录 C | +| 准入 | A 类物资或高风险品类 | {{org.position.category_manager}} → {{org.position.procurement_director}}({{org.position.quality_manager}}会签;涉及危险化学品的加{{org.dept.hse}}负责人) | {{doc.QP-01.number}} 附录 C | | {{org.unit_term}}本地供应商纳入名录 | 限 C 类及允许的 B 类 | 公司{{org.dept.procurement}}审核,再按上列准入权限 | {{doc.QP-01.number}} 6.1.3 | -| 试供转合格 | 试供期满评价合格 | {{org.dept.procurement}}负责人 | {{doc.GL-01.number}} 6.7.3 | -| 现场复审以资料审核代替 | 上年绩效 A 级且无质量、安全环保事件的 A 类供应商 | {{org.dept.quality}}负责人 | {{doc.WI-01.number}} 6.9.2 | -| 冻结 / 解冻 | C 类、B 类 | {{org.dept.procurement}}负责人 | {{doc.QP-01.number}} 附录 C | -| 冻结 / 解冻 | A 类 | {{org.role.vp_procurement}} | {{doc.QP-01.number}} 附录 C | -| 淘汰 | 全部 | {{org.role.vp_procurement}} | {{doc.QP-01.number}} 附录 C | -| 列入 / 解除黑名单 | 全部 | {{org.role.gm}}({{org.dept.discipline}}、{{org.dept.audit}}会签) | {{doc.QP-01.number}} 附录 C | -| 关键信息变更(名称、法定代表人、地址、信用代码或注册号) | 全部 | {{org.dept.procurement}}(涉及主体变更的会签{{org.dept.legal}}) | {{doc.GL-04.number}} 附录 A | -| 收款账户变更 | 全部 | {{org.dept.procurement}} → {{org.dept.finance}}(核实后生效,两级审核人不得为同一人) | {{doc.GL-04.number}} 6.3 | +| 试供转合格 | 试供期满评价合格 | {{org.position.category_manager}} | {{doc.GL-01.number}} 6.7.3 | +| 现场复审以资料审核代替 | 上年绩效 A 级且无质量、安全环保事件的 A 类供应商 | {{org.position.quality_manager}} | {{doc.WI-01.number}} 6.9.2 | +| 冻结 / 解冻 | 全部 | {{org.position.category_manager}} → {{org.position.procurement_director}} | {{doc.QP-01.number}} 附录 C | +| 淘汰 | 全部 | {{org.position.category_manager}} → {{org.position.procurement_director}} → {{org.role.gm}} | {{doc.QP-01.number}} 附录 C | +| 列入 / 解除黑名单 | 全部 | {{org.position.category_manager}} → {{org.position.procurement_director}} → {{org.role.gm}}({{org.dept.discipline}}、{{org.dept.audit}}会签) | {{doc.QP-01.number}} 附录 C | +| 关键信息变更(名称、法定代表人、地址、信用代码或注册号) | 全部 | {{org.position.buyer_lead}}(涉及主体变更的会签{{org.position.legal}}) | {{doc.GL-04.number}} 附录 A | +| 收款账户新增 / 变更 | 全部 | {{org.position.buyer_lead}} → {{org.position.ap_accountant}}(核实后生效,两级审核人不得为同一人) | {{doc.GL-04.number}} 6.3 | +| 绩效结果发布 | 每期 | {{org.position.procurement_director}} | {{doc.QP-01.number}} 6.7 | +| 整改措施审核 | 全部 | {{org.position.sqe}} | {{doc.QP-01.number}} 6.8 | # 3 采购与寻源 | 事项 | 条件 | 审批 | 依据 | |----------------------|------------------|--------------------------------------------|----------------| -| 采购申请 | 全部 | 按公司现行授权;超出预算的先经{{org.dept.finance}}确认预算调整 | {{doc.QP-02.number}} 6.1.3 | +| 采购申请 | 全部 | 在 ERP / OA 中按公司现行授权审批;超出预算的先经{{org.dept.finance}}确认预算调整 | {{doc.QP-02.number}} 6.1.3 | | 采购方案 | 达到公开采购标准或须集体决策的项目 | 按{{org.superior}}和公司现行授权 | {{doc.GL-02.number}} 4.2 | -| 定标 | 不足 {{param.award_approval_tiers.mid}} 万元 | {{org.dept.procurement}}负责人 | {{doc.GL-02.number}} 附录 A | -| 定标 | {{param.award_approval_tiers.mid}} 万元及以上、不足 {{param.award_approval_tiers.high}} 万元 | {{org.dept.procurement}}负责人 → {{org.role.vp_procurement}} | {{doc.GL-02.number}} 附录 A | -| 定标 | {{param.award_approval_tiers.high}} 万元及以上 | {{org.dept.procurement}}负责人 → {{org.role.vp_procurement}} → {{org.role.gm}} | {{doc.GL-02.number}} 附录 A | +| 定标 | 不足 {{param.award_approval_tiers.mid}} 万元 | {{org.position.category_manager}} | {{doc.GL-02.number}} 附录 A | +| 定标 | {{param.award_approval_tiers.mid}} 万元及以上、不足 {{param.award_approval_tiers.high}} 万元 | {{org.position.category_manager}} → {{org.position.procurement_director}} | {{doc.GL-02.number}} 附录 A | +| 定标 | {{param.award_approval_tiers.high}} 万元及以上 | {{org.position.category_manager}} → {{org.position.procurement_director}} → {{org.role.gm}} | {{doc.GL-02.number}} 附录 A | | 采用低于规定层级的采购方式 | 全部 | 按同金额定标的权限 | {{doc.GL-02.number}} 3.3 | -| 单一来源 | 全部 | {{org.dept.procurement}}负责人 → {{org.role.vp_procurement}};{{param.award_approval_tiers.high}} 万元及以上加{{org.role.gm}} | {{doc.GL-02.number}} 附录 A | +| 单一来源 | 全部 | {{org.position.category_manager}} → {{org.position.procurement_director}};预算 {{param.award_approval_tiers.high}} 万元及以上加{{org.role.gm}} | {{doc.GL-02.number}} 附录 A | | 紧急采购(名录外供应商) | 生产急需,临时一次 | {{org.role.vp_procurement}},{{param.emergency_backfill_days}} 日内补办准入 | {{doc.QP-01.number}} 6.3.7 | | 紧急采购(名录内,来不及寻源) | 生产急需 | {{org.role.vp_procurement}} | {{doc.QP-02.number}} 6.10.1 | | 价格调整 | 合同约定调价机制的 | 按原定标权限 | {{doc.GL-02.number}} 9.3 | | 价格调整 | 合同未约定的 | 重新寻源或议价,按定标权限 | {{doc.GL-02.number}} 9.3 | -| 采购合同 | 全部 | {{org.dept.legal}}审查后,按同金额定标的权限;框架协议按年度预计金额 | {{doc.QP-02.number}} 6.4.2 | +| 采购合同 | 全部 | {{org.position.legal}}审查 → 按同金额定标的权限;框架协议按年度预计金额 | {{doc.QP-02.number}} 6.4.2 | **{{org.terms.bulk}}的专项审批事项** @@ -79,8 +79,8 @@ f) 各级审批均在 SRM 系统中进行,系统审批记录为正式记录。 | 事项 | 条件 | 审批 | 依据 | |----------------------|------------------|--------------------------------------------|----------------| -| 对账差异调整 | 全部 | {{org.dept.procurement}} → {{org.dept.finance}} | {{doc.QP-02.number}} 6.8 | -| 付款 | 全部 | 按公司现行资金管理制度 | {{doc.QP-02.number}} 6.9.1 | +| 对账差异调整 | 全部 | 在 ERP 中:{{org.dept.procurement}} → {{org.dept.finance}} | {{doc.QP-02.number}} 6.8 | +| 付款 | 全部 | 在 ERP / 资金系统中,按公司现行资金管理制度 | {{doc.QP-02.number}} 6.9.1 | # 5 维护 diff --git a/governance/templates/core/ZC-03.md b/governance/templates/core/ZC-03.md index e2e5f5a..b24c5d6 100644 --- a/governance/templates/core/ZC-03.md +++ b/governance/templates/core/ZC-03.md @@ -21,7 +21,7 @@ c) **信息化**:「系统」方式的控制即 SRM 系统必须实现并开 1.2 控制方式分三种:**系统**,由 SRM 系统强制执行,人工无法绕过;**系统 + 人工**,系统提供流程、提醒或留痕,判断由人完成;**人工**,按文件规定人工执行,以记录为证。 -1.3 「期次」是该控制随 SRM 系统哪一期上线:一期至四期为核心功能,「大宗包」「危化品包」「国企包」为对应扩展包的功能,上线期次在实施计划中确定。对应功能上线前,按{{doc.ZC-01}} 4.6.4 的过渡安排执行。 +1.3 「期次」是该控制随 SRM 系统哪个版本上线:v0.1–v0.7 为核心功能(版本范围见实施计划);「系统(ERP)· 不在 SRM」表示该控制在 ERP 中执行,SRM 不重复实现;「大宗包」「危化品包」「国企包」为对应扩展包的功能,上线时间在扩展包立项时确定。对应功能上线前,按{{doc.ZC-01}} 4.6.4 的过渡安排执行。 1.4 风险等级为固有风险的初步评估(高、中、低),由{{org.dept.procurement}}会同{{org.dept.audit}}每年复核。 @@ -31,56 +31,56 @@ c) **信息化**:「系统」方式的控制即 SRM 系统必须实现并开 | 编号 | 风险与等级 | 控制措施 | 方式 · 期次 | 责任部门 | 出处 | |----------|----------------|----------------------------|------------|----------|------------------| -| R1-01 | 不合格或失信企业进入供应体系(高) | 注册受理时按统一社会信用代码(境外供应商按注册号)查重、黑名单比对,命中自动不予受理;人工核查失信记录 | 系统 + 人工 · 一期 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.2.3;{{doc.GL-01.number}} 6.1.2 | -| R1-02 | 高风险物资供应商未经现场审核即准入(高) | 未录入通过或有条件通过的现场审核结果,不能提交准入评审 | 系统 · 一期 | {{org.dept.quality}} | {{doc.QP-01.number}} 6.3.1;{{doc.WI-01.number}} 6.8.2 | -| R1-03 | 准入越权审批(中) | 按物资类别逐级审批,发起人不得审批本人发起的申请 | 系统 · 一期 | {{org.dept.procurement}} | {{doc.GL-01.number}} 6.6.2;{{doc.ZC-02.number}} 第 2 节 | -| R1-04 | 资质过期仍在供货或报价(高) | 每日扫描证书有效期,提前 {{param.cert_reminder_days}}提醒;过期自动标记资质异常,不能被邀请报价;核验后才能解除 | 系统 · 一期 | {{org.dept.quality}} | {{doc.QP-01.number}} 6.6;{{doc.GL-01.number}} 6.8 | -| R1-05 | 证书信息被篡改(中) | 证书编号、有效期或附件被修改时,核验结论自动重置并通知核验人 | 系统 · 一期 | {{org.dept.quality}} | {{doc.GL-01.number}} 6.2.4 | -| R1-06 | 名录外采购(中) | 只能邀请名录内、资格有效且无资质异常的供应商;名录外紧急采购须审批并 {{param.emergency_backfill_days}} 日内补办准入 | 系统 + 人工 · 一期 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.3.7、6.4.2 | -| R1-07 | 冻结、淘汰、黑名单未执行到位(中) | 审批通过后系统更新供应商状态并推送 ERP,冻结后不能被邀请、不能新下单 | 系统 · 二期 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.9.4 | +| R1-01 | 不合格或失信企业进入供应体系(高) | 注册受理时按统一社会信用代码(境外供应商按注册号)查重、黑名单比对,命中自动不予受理;人工核查失信记录 | 系统 + 人工 · v0.1 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.2.3;{{doc.GL-01.number}} 6.1.2 | +| R1-02 | 高风险物资供应商未经现场审核即准入(高) | 未录入通过或有条件通过的现场审核结果,不能提交准入评审 | 系统 · v0.4 | {{org.dept.quality}} | {{doc.QP-01.number}} 6.3.1;{{doc.WI-01.number}} 6.8.2 | +| R1-03 | 准入越权审批(中) | 按物资类别逐级审批,发起人不得审批本人发起的申请 | 系统 · v0.1 | {{org.dept.procurement}} | {{doc.GL-01.number}} 6.6.2;{{doc.ZC-02.number}} 第 2 节 | +| R1-04 | 资质过期仍在供货或报价(高) | 每日扫描证书有效期,提前 {{param.cert_reminder_days}}提醒;过期自动标记资质异常,不能被邀请报价;核验后才能解除 | 系统 · v0.1 | {{org.dept.quality}} | {{doc.QP-01.number}} 6.6;{{doc.GL-01.number}} 6.8 | +| R1-05 | 证书信息被篡改(中) | 证书编号、有效期或附件被修改时,核验结论自动重置并通知核验人 | 系统 · v0.1 | {{org.dept.quality}} | {{doc.GL-01.number}} 6.2.4 | +| R1-06 | 名录外采购(中) | 只能邀请名录内、资格有效且无资质异常的供应商;名录外紧急采购须审批并 {{param.emergency_backfill_days}} 日内补办准入 | 系统 + 人工 · v0.7 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.3.7、6.4.2 | +| R1-07 | 冻结、淘汰、黑名单未执行到位(中) | 审批通过后系统更新供应商状态,冻结后不能被邀请、不能新签合同;ERP 中的冻结标志由采购员按审批结果维护(集成后自动推送) | 系统 · v0.3 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.9.4 | | R1-08 | 危险化学品许可范围不覆盖所供品名(高) | 许可证录入许可范围并核验;不覆盖时自动暂停该物资类别的供货资格;现场审核设否决项 | 系统 + 人工 · 危化品包 | {{org.dept.hse}} | {{doc.GL-01.number}} 6.3.4、6.8.5;{{doc.WI-01.number}} 6.6.3、附录 B | ## 2.2 寻源与价格风险 | 编号 | 风险与等级 | 控制措施 | 方式 · 期次 | 责任部门 | 出处 | |----------|----------------|----------------------------|------------|----------|------------------| -| R2-01 | 报价泄露、围标串标(高) | 报价截止前内部任何人不可见,只显示已报价家数;截止后拒绝写入;截止时间发布后锁定,只能延后;截止前不得开标 | 系统 · 一期 | {{org.dept.procurement}} | {{doc.GL-02.number}} 6.1–6.4;{{doc.QP-02.number}} 6.3.3 | -| R2-02 | 供应商之间信息泄露(高) | 门户中每家供应商只能看到本公司的报价、订单、对账、化验和结算数据 | 系统 · 一期 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.11.1;{{doc.GL-02.number}} 10.1 | +| R2-01 | 报价泄露、围标串标(高) | 报价截止前内部任何人不可见,只显示已报价家数;截止后拒绝写入;截止时间发布后锁定,只能延后;截止前不得开标 | 系统 · v0.7 | {{org.dept.procurement}} | {{doc.GL-02.number}} 6.1–6.4;{{doc.QP-02.number}} 6.3.3 | +| R2-02 | 供应商之间信息泄露(高) | 门户中每家供应商只能看到本公司的资料、整改单和报价 | 系统 · v0.6 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.11.1;{{doc.GL-02.number}} 10.1 | | R2-03 | 拆分采购规避招标或审批(高) | {{param.split_purchase_window_months}} 个月内同一需求按累计金额确定采购方式和审批层级;审计抽查 | 人工 | {{org.dept.procurement}}、{{org.dept.audit}} | {{doc.QP-02.number}} 6.2.4;{{doc.GL-02.number}} 3.5 | -| R2-04 | 滥用单一来源(中) | 单一来源须写明唯一性理由,审批通过后才能发布;按季度统计报告 | 系统 + 人工 · 一期 | {{org.dept.procurement}} | {{doc.GL-02.number}} 3.4;{{doc.QP-02.number}} 6.10 | -| R2-05 | 竞争不足仍定标(中) | 有效报价少于 {{param.min_valid_quotes}} 家须填写理由,审批增加一级 | 系统 · 一期 | {{org.dept.procurement}} | {{doc.GL-02.number}} 8.2 | -| R2-06 | 定标越权、自批自(高) | 按金额分档审批;审批人为发起人时改由上一级审批 | 系统 · 一期 | {{org.dept.procurement}} | {{doc.GL-02.number}} 8.2、8.3;{{doc.ZC-02.number}} 第 3 节 | -| R2-07 | 下单价格偏离定标价格(中) | 定标后生成有效价格并推送 ERP,旧价格自动截断;订单按有效价格下达 | 系统 · 一期 | {{org.dept.procurement}} | {{doc.GL-02.number}} 9.1;{{doc.QP-02.number}} 6.3.4 | +| R2-04 | 滥用单一来源(中) | 单一来源须写明唯一性理由,审批通过后才能发布;按季度统计报告 | 系统 + 人工 · v0.7 | {{org.dept.procurement}} | {{doc.GL-02.number}} 3.4;{{doc.QP-02.number}} 6.10 | +| R2-05 | 竞争不足仍定标(中) | 有效报价少于 {{param.min_valid_quotes}} 家须填写理由,审批增加一级 | 系统 · v0.7 | {{org.dept.procurement}} | {{doc.GL-02.number}} 8.2 | +| R2-06 | 定标越权、自批自(高) | 按金额分档审批;审批人为发起人时改由上一级审批 | 系统 · v0.7 | {{org.dept.procurement}} | {{doc.GL-02.number}} 8.2、8.3;{{doc.ZC-02.number}} 第 3 节 | +| R2-07 | 下单价格偏离定标价格(中) | 定标后生成有效价格,旧价格自动截断;ERP 中的价格信息记录由采购员按定标结果维护(集成后自动推送),订单按有效价格下达 | 系统 · v0.7 | {{org.dept.procurement}} | {{doc.GL-02.number}} 9.1;{{doc.QP-02.number}} 6.3.4 | | R2-08 | 应履行的国企程序缺失(中) | 采购方案未批准不能发布;定标前合规审议未完成不能提交定标审批 | 系统 · 国企包 | {{org.dept.procurement}}、{{org.dept.legal}} | {{doc.GL-02.number}} 4.2、8.5 | ## 2.3 资金与付款风险 | 编号 | 风险与等级 | 控制措施 | 方式 · 期次 | 责任部门 | 出处 | |----------|----------------|----------------------------|------------|----------|------------------| -| R3-01 | 收款账户被冒改、付款诈骗(高) | 关键信息只能经变更申请修改;账户变更经{{org.dept.procurement}}、{{org.dept.finance}}两级不同岗位审核,并{{param.bank_change_verification}}核实;推送 ERP 成功前不生效,旧账户停用 | 系统 + 人工 · 二期 | {{org.dept.finance}} | {{doc.GL-04.number}} 6.1、6.3–6.5;{{doc.QP-01.number}} 6.5.2 | -| R3-02 | 银行账号泄露(中) | 银行账号只对应付会计、采购管理员和该供应商的门户管理员可见 | 系统 · 一期 | {{org.dept.finance}} | {{doc.GL-04.number}} 6.5.4 | -| R3-03 | 对账结果被事后改动(中) | 供应商确认后对账单锁定,只能经差异流程修改 | 系统 · 四期 | {{org.dept.finance}} | {{doc.QP-02.number}} 6.8.2 | -| R3-04 | 发票金额不符或重复入账(中) | 登记发票时比较不含税金额和税额,超过容差拒绝;发票代码和号码唯一 | 系统 · 四期 | {{org.dept.finance}} | {{doc.QP-02.number}} 6.8.4 | +| R3-01 | 收款账户被冒改、付款诈骗(高) | 关键信息只能经变更申请修改;账户变更经{{org.dept.procurement}}、{{org.dept.finance}}两级不同岗位审核,并{{param.bank_change_verification}}核实;审批通过后生效并停用旧账户,ERP 中的账户由应付会计按审批结果维护(集成后自动推送) | 系统 + 人工 · v0.2 | {{org.dept.finance}} | {{doc.GL-04.number}} 6.1、6.3–6.5;{{doc.QP-01.number}} 6.5.2 | +| R3-02 | 银行账号泄露(中) | 银行账号只对应付会计、采购管理员和该供应商的门户管理员可见 | 系统 · v0.2 | {{org.dept.finance}} | {{doc.GL-04.number}} 6.5.4 | +| R3-03 | 对账结果被事后改动(中) | 供应商确认后对账单锁定,只能经差异流程修改 | 系统(ERP)· 不在 SRM | {{org.dept.finance}} | {{doc.QP-02.number}} 6.8.2 | +| R3-04 | 发票金额不符或重复入账(中) | 登记发票时比较不含税金额和税额,超过容差拒绝;发票代码和号码唯一 | 系统(ERP)· 不在 SRM | {{org.dept.finance}} | {{doc.QP-02.number}} 6.8.4 | | R3-05 | 付款未按约定或越权(中) | 发票校验通过、应付入账后按合同账期付款;付款审批按资金管理制度 | 人工 | {{org.dept.finance}} | {{doc.QP-02.number}} 6.9.1 | ## 2.4 廉洁与合规风险 | 编号 | 风险与等级 | 控制措施 | 方式 · 期次 | 责任部门 | 出处 | |----------|----------------|----------------------------|------------|----------|------------------| -| R4-01 | 利益输送、商业贿赂(高) | 供应商注册时签署廉洁承诺;员工礼品登记上交;违规供应商列入黑名单 {{param.blacklist_years}} 年 | 系统 + 人工 · 一期 | {{org.dept.discipline}} | {{doc.GL-05.number}} 6.1、6.4;{{doc.QP-01.number}} 6.9.3 | -| R4-02 | 利益冲突未回避(高) | 关联关系申报;关联供应商标记,寻源时提示评审人回避;应回避未回避的评审或审批结果无效 | 系统 + 人工 · 一期 | {{org.dept.procurement}}、{{org.dept.discipline}} | {{doc.GL-05.number}} 6.2、6.3 | -| R4-03 | 与供应商私下沟通(中) | 询价、澄清和报价通过供应商门户进行,门户记录为正式记录 | 系统 · 一期 | {{org.dept.procurement}} | {{doc.GL-05.number}} 6.5.1 | -| R4-04 | 违规行为难以追查(中) | 审批、变更、评审记录由系统保存,监督部门可直接调阅 | 系统 · 一期 | {{org.dept.audit}}、{{org.dept.discipline}} | {{doc.GL-05.number}} 6.8.3 | +| R4-01 | 利益输送、商业贿赂(高) | 供应商注册时签署廉洁承诺;员工礼品登记上交;违规供应商列入黑名单 {{param.blacklist_years}} 年 | 系统 + 人工 · v0.1 | {{org.dept.discipline}} | {{doc.GL-05.number}} 6.1、6.4;{{doc.QP-01.number}} 6.9.3 | +| R4-02 | 利益冲突未回避(高) | 关联关系申报;关联供应商标记,寻源时提示评审人回避;应回避未回避的评审或审批结果无效 | 系统 + 人工 · v0.7 | {{org.dept.procurement}}、{{org.dept.discipline}} | {{doc.GL-05.number}} 6.2、6.3 | +| R4-03 | 与供应商私下沟通(中) | 询价、澄清和报价通过供应商门户进行,门户记录为正式记录 | 系统 · v0.7 | {{org.dept.procurement}} | {{doc.GL-05.number}} 6.5.1 | +| R4-04 | 违规行为难以追查(中) | 审批、变更、评审记录由系统保存,监督部门可直接调阅 | 系统 · v0.1 | {{org.dept.audit}}、{{org.dept.discipline}} | {{doc.GL-05.number}} 6.8.3 | | R4-05 | 关联交易未履行审议与披露(高) | 定标前将拟中标供应商与关联方名单比对,命中的未完成审议不能进入定标审批 | 系统 + 人工 · 国企包 | {{org.dept.board_office}} | {{doc.GL-05.number}} 6.2.4 | ## 2.5 质量、交付与安全风险 | 编号 | 风险与等级 | 控制措施 | 方式 · 期次 | 责任部门 | 出处 | |----------|----------------|----------------------------|------------|----------|------------------| -| R5-01 | 订单未及时确认、交期失控(中) | 未确认订单在下发后 {{param.po_ack_remind_hours}} 小时提醒供应商、{{param.po_ack_escalate_hours}} 小时升级采购主管;答复交期晚于需求日期时标记风险 | 系统 · 二期 | {{org.dept.procurement}} | {{doc.QP-02.number}} 6.5.2、6.5.3 | -| R5-02 | 超订单送货(低) | 送货数量不得超过未交数量扣除已发未收数量 | 系统 · 二期 | {{org.dept.procurement}} | {{doc.QP-02.number}} 6.6.1 | -| R5-03 | 来料质量问题整改不到位(中) | 严重或主要不合格发出 8D 整改,{{param.scar_containment_hours}} 小时内提交临时措施、{{param.scar_final_days}} 日内提交永久措施,验证有效后关闭 | 系统 + 人工 · 三期 | {{org.dept.quality}} | {{doc.QP-01.number}} 6.8 | -| R5-04 | 供应商表现恶化未被发现(中) | 按周期评价绩效,交付、质量等指标由系统按收货、检验、订单数据计算;D 级暂停新增采购 | 系统 + 人工 · 三期 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.7 | +| R5-01 | 订单未及时确认、交期失控(中) | 未确认订单在下发后 {{param.po_ack_remind_hours}} 小时提醒供应商、{{param.po_ack_escalate_hours}} 小时升级采购主管;答复交期晚于需求日期时标记风险 | 系统 · ERP 集成后(门户镜像) | {{org.dept.procurement}} | {{doc.QP-02.number}} 6.5.2、6.5.3 | +| R5-02 | 超订单送货(低) | 送货数量不得超过未交数量扣除已发未收数量 | 系统(ERP)· 不在 SRM | {{org.dept.procurement}} | {{doc.QP-02.number}} 6.6.1 | +| R5-03 | 来料质量问题整改不到位(中) | 严重或主要不合格发出 8D 整改,{{param.scar_containment_hours}} 小时内提交临时措施、{{param.scar_final_days}} 日内提交永久措施,验证有效后关闭 | 系统 + 人工 · v0.4 | {{org.dept.quality}} | {{doc.QP-01.number}} 6.8 | +| R5-04 | 供应商表现恶化未被发现(中) | 按周期评价绩效,交付、质量等指标由系统按导入的交付记录计算;D 级暂停新增采购 | 系统 + 人工 · v0.5 | {{org.dept.procurement}} | {{doc.QP-01.number}} 6.7 | | R5-05 | 危险化学品运输与卸车事故(高) | 承运商、车辆和人员资质审核;入厂预约、门岗查验、卸车作业按规定执行 | 系统 + 人工 · 危化品包 | {{org.dept.hse}} | {{doc.HZ-02}} | diff --git a/params/core.yaml b/params/core.yaml index dd2c4e4..a4d37e8 100644 --- a/params/core.yaml +++ b/params/core.yaml @@ -53,7 +53,7 @@ perf_cycle: example: { A: 每月, B: 每季度, C: 每年 } display: A 类{A},B 类{B},C 类{C} used_in: [QP-01 6.7.1, QP-01 附录 A] - system: 考评计划的周期设置(核心 03 §10) + system: 考评生成 flow 按供应商所供最高物资类别(srm_category.material_class)取周期(核心 03 §10,v0.5) perf_grade_min: label: 绩效等级下限分 @@ -105,6 +105,13 @@ blacklist_years: used_in: [QP-01 6.9.3] system: 制度要求;黑名单状态由处置单设置,解除需单独审批(核心 03 §5) +change_review_days: + label: 信息变更审核时限 + unit: 工作日 + example: 5 + used_in: [GL-04 6.3.5] + system: 变更审批 flow srm_change_approval 审批节点的 timeoutHours(核心 03 §5) + record_retention_years: label: 供应商管理记录保存期限 unit: 年 @@ -125,14 +132,14 @@ po_ack_remind_hours: unit: 小时(下发后) example: 24 used_in: [QP-02] - system: 追赶式扫描 srm_po_ack_sweep(核心 03 §7) + system: 制度要求;订单镜像在 ERP 集成后才有(核心 03 §7 预留,ADR-0008) po_ack_escalate_hours: label: 订单未确认升级采购主管 unit: 小时(下发后) example: 48 used_in: [QP-02] - system: 同上 + system: 同上(ERP 集成后) # ---- 准入与现场审核(GL-01、WI-01) ---- @@ -150,6 +157,13 @@ cert_min_remaining_months: used_in: [GL-01 6.2.2] system: 制度要求;核验证书时由核验人判断 +admission_approval_days: + label: 准入评审每级审批时限 + unit: 工作日 + example: 3 + used_in: [GL-01 附录 B] + system: 准入审批 flow 各审批节点的 timeoutHours(按日历小时换算,核心 03 §3);到期提醒审批人 + doc_return_limit: label: 准入资料退回补充的次数上限 unit: 次 @@ -206,7 +220,7 @@ award_approval_tiers: example: { mid: 10, high: 100 } display: 不足 {mid} 万元、{mid} 万元至不足 {high} 万元、{high} 万元及以上三档 used_in: [ZC-02 3, GL-02 附录 A] - system: 定标审批 flow 按定标金额选择审批层级;单一来源达到 high 档时加一级(核心 01 FR-308、03 §4) + system: 定标审批 flow 按定标金额选择审批层级,单一来源寻源达到 high 档时加总经理一级(核心 03 §12 审批矩阵,v0.7) min_valid_quotes: label: 定标所需的有效报价家数 @@ -236,7 +250,7 @@ invoice_tolerance: unit: 元(不含税金额和税额分别比较) example: 1 used_in: [QP-02 6.8.4] - system: 发票登记校验,超出容差拒绝提交(核心 01 FR-804) + system: 制度要求;发票在 ERP 中处理,SRM 不做(ADR-0008) open_tender_threshold: label: 公开招标的金额标准