aps-agent/docs/product/masterdata-configuration.md

91 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 主数据配置与数据来源约定
## 约束
主数据业务流程不得通过客户名称、固定源文件路径、订单/设备编码、样本数量或固定日期选择执行行为。布局差异进入适配配置,业务参数从本次已确认数据或明确配置读取。缺项需提示核对,不用貌似合理的默认值掩盖。
标准角色、协议版本、错误码、状态枚举及单位换算常量属于程序合同。真实验收的固定数量、SHA和场景参数属于独立测试预期,集中保存于测试manifest,不能由被测解析器的输出生成预期结果。
## 工作簿格式
默认配置:[default-planning.json](../../server/importers/profiles/workbooks/default-planning.json)。
`APS_WORKBOOK_PROFILE_DIR` 可指定部署配置目录;设置后只加载该目录中的JSON。目录不存在、配置无效、重复ID、重复字段及匹配歧义会明确报错,不悄悄回到另一个客户格式。
每个profile包含:
- `id`、`schemaVersion` 与 `capabilities`:格式标识和支持的流程能力。业务通过注册能力判断,不比较某个客户ID。
- `sheets`:标准业务角色到物理表名、标准字段到物理列名的映射;每个角色可声明 `requiredColumns`(必填的物理列)。旧配置省略该字段时按“该表全部可选”加载,不影响已部署目录的可移植性。
- `enums`、`metadataKeys`、`separators`:源状态/字段词汇、参数名称和分隔符到标准语义的转换。
- `planning`:工厂时区、技能等级顺序及排序模式别名。周期、冻结窗口和资料日期仍从源表读取。
- `provenance`:演示/未确认来源识别规则。配置不能将未确认资料直接声明为生产事实,也不能加载任意Python代码。
当前支持完整规划工作簿的标准角色集合;这不等同于已经支持任意Excel、任意ERP/MES模型。新工厂使用这些标准角色时,可以新增配置,不修改业务条件分支。超出角色合同的能力需要明确实现后才能开放。
旧 `ruiyang_aps.py` 保留公开接口的兼容导出,实际实现由 `planning_workbook.py` 和注册配置负责。旧格式ID只在配置中登记,避免破坏已保存来源记录。
## 规划参数
- 完整日期时间使用明确给定值。只调整日期时保留已配置的开工时钟;没有该时钟时从启用班次取得,不能固定为08:00。
- 计划周期、冻结时长来自 `planningContext`,或者已有明确 `scheduleParams` 配置。缺失、负数、无限值等会拒绝,零冻结时长不会被默认值替换。
- 技能等级按 `skillLevelOrder`,未知必需等级不能被当成最低要求放行。
- 班次未声明工作日,不假定周一至周五。
- 工厂时区来自配置/源字段,不在主数据投影代码中固定为某地区。
## 配置版本与旧资料
profile规范化JSON计算摘要,随预览、批次、确认、已采用来源和规划上下文保存。确认期间配置发生变化,旧卡被拒绝,返回“资料未采用,请重新检查”,写失败审计,主数据不变。
同文件SHA但不同配置摘要不属于同一次采用,不会静默返回幂等成功。原有未记录配置摘要的资料可以继续读取和使用已保存的标准主数据;页面明确标为旧映射,不能借此按当前新配置重新导入。旧数据的回放和新映射的重新采用是不同动作。
## 采集模板与排产导出模板
采集模板和排产工作簿都有版本化合同,字段、表头、行号与来源不得散落在业务代码里。
### 数据采集模板(intake-template.v1)
- 模板由当前 profile 直接生成,不维护第二份字段清单:Sheet 名称、物理列名、列顺序、必填声明、枚举词汇、能力与映射摘要全部取自 `default-planning.json`(或 `APS_WORKBOOK_PROFILE_DIR` 指定的配置)。
- `GET /api/import/template` 下载当前配置的模板并返回 `ETag`、`X-APS-Template-Id`、`X-APS-Profile-Id`、`X-APS-Profile-Digest`;未注册的 `profileId` 返回 404,不静默换用其他配置。带 `If-None-Match` 且摘要一致时返回 304,不重传整份 Excel。
- 模板与现场工作簿(`湖南锐扬APS精简演示数据.xlsx`)逐表逐列同构:Sheet 顺序与每张表的物理表头都由同一份 profile 校验,不一致即报缺陷,见 `tests/golden/test_schedule_template_contract.py::test_intake_template_contract_matches_the_authorized_workbook`。
- 不带 `profileId` 时使用当前配置目录的兼容默认配置(`compatibilityDefault`):唯一标记为默认的配置优先,目录里只注册一份配置时即用该配置,多份配置且默认标记缺失或重复时直接报错,不按目录顺序猜测客户格式。
- 模板第一张表 `数据采集说明` 逐字段声明角色、工作表、字段顺序、必填/可选、类型、**填写要求(允许取值与格式)** 和映射摘要;允许取值直接来自解析器使用的枚举配置(例如订单分类的「正式订单→FORMAL;沙盒插单→SANDBOX」),因此模板不会和导入逻辑各写一套取值。其余工作表表头与导入解析器读取的物理列逐字一致,模板是可直接回填的机器可读合同。
- 默认下载空白模板,不写任何业务行;只有显式传入样例世界时才生成示例行。生成字节是确定性的,同一配置与同一输入得到同一 SHA-256。
- 模板结构与 profile 的往返校验见 `validate_intake_template`:表头与配置不一致时直接报出缺陷,不靠人工核对。
### 排产工作簿合同
| 合同 | 报表 | 主表 | 表头行 | 数据起始行 |
| --- | --- | --- | --- | --- |
| `schedule-plan.v1` | `plan` / `schedule-plan` / `flex-plan` | 工作计划 | 4 | 5 |
| `schedule-order.v1` | `schedule-order` | 排产工单 | 4 | 5 |
| `schedule-equipment.v1` | `schedule-equipment` | 设备负荷 | 4 | 5 |
| `schedule-blocked.v1` | 无工单可排时的 `plan` | 阻断分析 | 4 | 5 |
- 每列声明 `key`、中文表头、类型、单位、必填情形和取值来源;`build_plan_report`、`build_schedule_order_export`、`build_schedule_equipment_export` 和阻断工作簿统一引用同一合同,生成后由 `validate_workbook_contract` 复核工作表、表头、行号、冻结窗格和筛选区域。
- 合同本身可下载为空白模板:`GET /api/reports/schedule-template`(柔性工作台「排产模板」按钮,默认 `schedule-plan.v1`,`reportType` 支持 `schedule-plan` / `schedule-order` / `schedule-equipment` / `schedule-blocked.v1`)。模板只有标题行、表头行、冻结窗格与筛选区域,不含业务行;生成后同样通过 `validate_workbook_contract`,因此现场拿到的模板与真正导出的文件是同一份声明。响应带 `ETag`、`X-APS-Template-Id`、`X-APS-Contract-Digest` 与 `X-APS-Template-Sheets`,`If-None-Match` 命中返回 304,未注册类型返回 404。
- 没有柔性排产版本时是显式空态:`xlsxBytes`/`filename` 为 `None`,不产出一份看似成功但没有业务数据的工作簿;有版本但没有可执行工单时产出 `schedule-blocked.v1` 阻断清单。
- 工作计划、工单、设备三个导出都做 ZIP 归一化,同一输入重复导出字节一致,便于交付与验收比对。
- 合同摘要与摘要值由 `contract_summary()` / `contract_digest()` 提供;模板合同由 `template_contract()` 提供,作为文档、诊断和测试的共同来源。
## 验收配置
- `ROUND87_SOURCE` / `--source`:实际文件位置,必须显式提供,不含本机默认路径。
- `ROUND87_EXPECTATIONS` / `--expectations`:独立验收manifest位置,默认仓库 `tests/fixtures/planning-workbook-acceptance.json`。
- `ROUND87_REQUIRED=1`:正式验收模式,缺文件、未指定或SHA不符即失败;普通开发测试未提供外部文件时明确跳过对应外部样本,不影响其他测试收集。
```text
python scripts/round87_masterdata_e2e.py --source <工作簿路径> --expectations <验收manifest> --output <验证结果>
```
禁止把本机路径重新放入测试helper。测试故障输入和标准期望保留在单元测试或测试manifest,不能用修改业务代码的方式凑出预期数量。
## 本次验证
- 扩展回归644项通过,含原始工作簿、通用导入、主数据维护、确认、排产、配置可移植性。
- 第二套配置更换全部16表名、列名、状态/参数名、格式ID、设备/订单编码、技能等级及工厂时区;实际HTTP上传→检查→确认采用→复查→试排通过。
- 桌面和手机浏览器2项通过,完整文件上传、采用及维护后刷新验证正常。
- 独立审查31项通过,配置漂移HTTP500问题已修复;Ruff新增模块检查和Web构建通过。
- Sidecar构建声明已加入配置文件;本次环境无PyInstaller,未重新构建桌面安装包,不能将源码构建检查当作冻结包运行验收。
本次范围是第87轮主数据链路及相关验收工具。仓库其他历史功能中的默认策略或演示样例不属于本次全面审查结论。