|
858
|
83
|
15
|
5
|
|
0
|
feat(contracts): 出站事实来源域按事实类型收紧(V-04,PKG-004)
|
CHG-061 独立核验 V-04:通用 Intent 记录 Schema 把 `sourceDom CHG-061 独立核验 V-04:通用 Intent 记录 Schema 把 `sourceDomain` 写死为 `hr`,CHG-061 登记的组织事实(Catalog 与 04 Scope 要求 `source_domain = organization`)即使登记进注册表也无法出站。
## 改动(D-12 台账 PKG-004,`packages/*` 冻结字节链式放行)
- 通用记录 Schema 的 `sourceDomain` 只校验非空字符串;来源域由注册表条目的信封 Schema 按事实类型收紧,`ENTERPRISE_FACT_ENVELOPE_SCHEMAS` 的类型约束要求每个条目 `source_domain` 为字面量。
- `resolveEnterpriseFactEnvelopeSchema` / `buildEnterpriseFactEnvelope` 增加默认为生产注册表的可选注册表参数;relay 调用不变。
- 生产注册表仍只有 `EmploymentTransferred@1`,行为不变;未登记类型仍以 `FACT_TYPE_UNREGISTERED` 失败关闭。
- contracts 追加 4 例(测试用注册表下 organization 来源域封装通过、hr 来源域被拒;未登记组织事实失败关闭;EmploymentTransferred 仍只接受 hr)。负向:记录 Schema 改回 `z.literal("hr")`,新增 2 例判红。
- 文档:对接蓝图 H1 / H21 / P1 按 CHG-061 落地订正并新增 §4.15;`CLAUDE.md` 真源地图与 G23 动态区同步。
## 验证(本地工作区,clean `11adf0f`,一次性 PostgreSQL / Redis)
- `check:d3` 0 问题;contracts 219/219;`check:app-manifest` 通过;lint、typecheck 通过。
- `check:runtime` 466 / 0(地板 452);`check:ui` 46 / 46;报告回绑提交 `e51fd28`。
- `check:governance` 只剩 main 上既有的 O22(OS main 不含 0.19.6,H12 / D-8)。远端 CI 未查验。
## 未包含
生产注册表登记新事实、`app-manifest.json` 的 `facts.owns`、`@juhai/contracts` 升 pin(rc.7 的 Catalog 为 11 条)、组织 / 用工事实的 producer 与生效事务写意图。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
...
|
0
|
0
|
0
|
1
|
0
|
|
0
|
1793150819
|
1793150819
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
857
|
83
|
14
|
5
|
|
0
|
含五件事:H20 台账收敛的记录、H11 回灌、PKG-002 vitest 升级、D-9,以及这次 含五件事:H20 台账收敛的记录、H11 回灌、PKG-002 vitest 升级、D-9,以及这次的冻结测试放行加 PKG-003。...
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合当前生命周期规范:既有 Personnel Core 保持 `/api/personnel/*`,HR v2 领域使用 `/api/v2/{domain}/*`,身份协议使用标准 OIDC 端点
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 涉及页面或浏览器行为时,`pnpm check:ui` 与 `pnpm check:ui:fastify` 均通过,未只验证一个后端
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
0
|
1
|
0
|
|
0
|
1793147366
|
1793147366
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
856
|
83
|
13
|
5
|
|
0
|
docs(integration): 蓝图补服务级对接矩阵,按 04 CHG-061 订正镜像与 H docs(integration): 蓝图补服务级对接矩阵,按 04 CHG-061 订正镜像与 H1/H5/H21...
|
## 内容
- 对接蓝图新增 §2.5 服务级对接矩阵:HR 与 02/03/04 共 20 个对 ## 内容
- 对接蓝图新增 §2.5 服务级对接矩阵:HR 与 02/03/04 共 20 个对接点,HR 侧写到 file:line,并标明 dev 实际跑通过的只有 3 条:事实写入、Scope 来源、OS 装载产品包。
- 按 04 `e50aad416`(CHG-061)订正:
- 应用清单镜像已合到 0.19.6,工作区镜像剩 5 处差异(H1);
- 4 条 HR 事实已在 Catalog 登记为 draft,H5 的 Catalog 半边完成;
- Scope 改按 Catalog producer 接受 `juhai.hr` 组织事实,H21 部分关闭,剩载荷约束与投影器现场摄取。
- 新增缺口:
- H25:OS 清单契约仍强制双后端,HR 清单里的 Fastify 声明是占位,不能单方删除;
- H26:门店归属事实没有生产者;
- H27:IdP 令牌 `aud` 是生成的 UUID,不是 `juhai.hr`;
- H28:数字智能层自带一份 0.19.5 副本。
- §2.5 补本机现场读数(2026-10-28 00:35 UTC 前后):
- HR API 未运行;
- 04 runtime 开了事实受理但缺 `FACT_APPLICATION_BINDINGS_JSON`,IdP 签发的机器令牌会被拒;
- Scope 来源 65281 不可达;
- OS 0.19.6 分支只在本机、未推 Gitea。
- 已确认三项:
- client-fact rc.3 与 rc.8 摘要实现逐行相同(H7 只剩发布);
- EES 运行时以 `READ_ONLY_PROJECTION` 拒绝已撤回人域命令;
- Scope 证据 `owner: juhai.hr` 由 04 按 HR 签名组装。
- H22:本机开发基座容器已于 00:40 UTC 重建为只绑回环,数据卷沿用。
- **CI 修复**(`a174e46`):本 PR 首次运行 26581 停在「Build locked OS compatibility sources」,原因是兼容锁指向 D3 后的 OS `1b8ae0d7`,该步却仍写死 `--filter=api-fastify`。
- 现改为经 `scripts/lib/os-host-backends.mjs` 读锁定 OS 的 `backend-profile.json` 决定宿主范围;
- `check:docs-truth` 新增 `ci-os-host-backends` 断言防回潮,对旧工作流负向判红。
- 同步落地状态:CLAUDE.md G23 / G14、两份 CHG 草稿、人域对照表。
- 已合入 `main` `46da429`:CLAUDE.md 冲突以 main 为准,只叠加本分支的 H21 订正。
## 验证(本地,PR 头 `25aecd7`,报告绑定 `a174e46`、clean)
- 通过:`check:runtime` 462/462(地板 452)、`check:ui` 46/46。用的是一次性 PostgreSQL 16 / Redis 7,只绑回环,跑完已删。
- 静态链如实停在 O22(OS main 尚无 0.19.6)。其后 governance-docs、docs-truth、lint、typecheck 通过。`check:governance` 只剩 O22,`reportProvenanceViolations` 0。
- CI 构建步骤:本地覆盖 5 种情形(nestjs-production、D3 前双宿主、缺 profile、非法 profile、profile 与 Fastify 冲突),以及锁定 OS 快照上的 turbo dry-run。
- 远端 CI 见本页检查结果。
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
0
|
1
|
0
|
|
0
|
1793145750
|
1793194416
|
0
|
0
|
1
|
0
|
Edit
Delete
|
|
855
|
83
|
12
|
5
|
|
0
|
fix(os-product): D-9 发布审计沿快照本机远端解析到真实 OS 仓,只读 ls-r fix(os-product): D-9 发布审计沿快照本机远端解析到真实 OS 仓,只读 ls-remote 其发布远端...
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合当前生命周期规范:既有 Personnel Core 保持 `/api/personnel/*`,HR v2 领域使用 `/api/v2/{domain}/*`,身份协议使用标准 OIDC 端点
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 涉及页面或浏览器行为时,`pnpm check:ui` 与 `pnpm check:ui:fastify` 均通过,未只验证一个后端
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793145336
|
1793145343
|
1793145343
|
0
|
0
|
0
|
Edit
Delete
|
|
854
|
83
|
11
|
5
|
|
0
|
docs(os-product): 回灌 OS 侧 0.19.6 导入结果与 relay 整表授权放 docs(os-product): 回灌 OS 侧 0.19.6 导入结果与 relay 整表授权放宽原因(H11)...
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合当前生命周期规范:既有 Personnel Core 保持 `/api/personnel/*`,HR v2 领域使用 `/api/v2/{domain}/*`,身份协议使用标准 OIDC 端点
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 涉及页面或浏览器行为时,`pnpm check:ui` 与 `pnpm check:ui:fastify` 均通过,未只验证一个后端
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793143165
|
1793143171
|
1793143171
|
0
|
0
|
0
|
Edit
Delete
|
|
853
|
83
|
10
|
5
|
|
0
|
chore(deps): H23 根与 apps/* 对齐框架 0.27.0 安全基线
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合当前生命周期规范:既有 Personnel Core 保持 `/api/personnel/*`,HR v2 领域使用 `/api/v2/{domain}/*`,身份协议使用标准 OIDC 端点
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 涉及页面或浏览器行为时,`pnpm check:ui` 与 `pnpm check:ui:fastify` 均通过,未只验证一个后端
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793114286
|
1793115451
|
1793114295
|
0
|
0
|
0
|
Edit
Delete
|
|
852
|
83
|
9
|
5
|
|
0
|
fix(api): D-10 默认只监听 127.0.0.1,对外暴露须显式设 HOST
|
> 状态说明:本 PR 已于 2026-10-27 合入 `main`(合并提交 `7835e > 状态说明:本 PR 已于 2026-10-27 合入 `main`(合并提交 `7835e3b`),合并时 CI 检查尚未运行;远端 CI 结果以本 PR 的检查为准。
## 概要
执行蓝图 D-10(关闭 H22):HR API 默认只监听 `127.0.0.1`,需要容器或局域网访问时必须显式设 `HOST`(如 `0.0.0.0`,双栈用 `::`)。改动前后都实测了 04 runtime 容器的可达性。记录见 `docs/domain/enterprise-control-plane-integration-blueprint-2026-10-27.md` §4.7。
## 改动
- **监听地址单源** `apps/api-nestjs/src/listen-host.ts`:未设或空 `HOST` → `127.0.0.1`,否则用显式值。`main.ts` 只经 `resolveListenHost()` 取值,启动日志写明是否只在回环上监听。
- **Web 默认目标**:`next.config.ts` 代理与 `useRealtime` 的 WS 默认值从 `localhost:3001` 改为 `127.0.0.1:3001`,避免 `localhost` 先解析到 `::1` 时连不上只听 IPv4 回环的 API;`.claude/launch.json` 同步。
- **防回潮**:`check:dual-backend` 新增 `scripts/lib/listen-host-guard.mjs`(默认值必须是回环,`main.ts` 不得绕过解析函数),node 单测 9 个负例;把默认值改回 `0.0.0.0` 的变异探针判红 2 处。行为单测 `apps/api-nestjs/test/listen-host.test.ts` 3 例。
- **文档同步**:CLAUDE.md(常用命令、运行时拓扑、G23 中 H22 移为已关闭)、README、后端规范、Scope 来源接入、蓝图 §4.7 / H22 / D-10、给 04 的答复草稿、框架同步评估 F-7。
## 实测证据
证据文件:`docs/evidence/d10-listen-host-2026-10-27.json`(本机 Docker Desktop;对 04 容器只做只读 GET,未改 04 的容器或配置)。
**改动前**,用宿主上的最小 HTTP 探针:
| 绑定 | 宿主回环 | 本机局域网 IP | 04 容器经 `host.docker.internal` |
| --- | --- | --- | --- |
| `0.0.0.0` | 可达 | 可达 | 可达 |
| `127.0.0.1` | 可达 | 不可达 | 可达(宿主看到来源 `127.0.0.1`) |
结论:改为回环默认后,04 的 Scope 来源探针(`SCOPE_HR_SOURCE_URL` 指向 `host.docker.internal:65281`)仍可达。
**改动后**,用真实构建的 HR API 配本仓一次性 PostgreSQL/Redis(跑完已删除):
| `HOST` | lsof | 局域网 `/api/health` | 04 容器 `/api/health` |
| --- | --- | --- | --- |
| 未设 | `127.0.0.1` | 不可达 | 200,database/redis up |
| 空串 | `127.0.0.1` | 不可达 | 200,database/redis up |
| `0.0.0.0` | `*` | 200 | 200,database/redis up |
另外,Web 不设 `API_PROXY_TARGET` 时,经 Next 代理访问 `/api/health` 返回 200。
**全量验收**(本地,clean `9c53371`,一次性库,跑完已删,报告无口令命中):
- `check:runtime` 455/455:比 452 多出的是新增的 3 例;冻结行为、多实例 Outbox、依赖故障三项均通过。
- `check:ui` 46/46。
- `check:governance` 仅剩已知两项回退:O22(OS main 不含 0.19.6)、`osProductReleaseTargetRemotes` 2→1;来源指纹违规 0。
- 远端 CI 以本 PR 的运行为准。
**未覆盖**:
- 未用 Scope 来源真实凭据调用签名查询,只证明网络可达。
- Linux 原生 Docker 经 `host-gateway` 连不到宿主回环,这类部署必须显式设 `HOST`。
- 仓外 65281 实例当前无进程;它的源码 `326ae3e` 不读 `HOST`,恢复前须换到含本改动的提交。
- `apps/web` 的 `next dev` / `next start` 仍按 Next 默认监听全部网卡,不在本 PR 范围。
## 待裁:00 框架 F-7
00 框架 `apps/api-nestjs/src/main.ts:8` 仍是 `process.env.HOST ?? "0.0.0.0"`;`backend-standard.md:7`、`COMPATIBILITY.md:45`、ADR-0010 与迁移手册都把 `0.0.0.0` 写成默认,理由是容器内可达。HR 因此有意与框架不同。本 PR 未改框架仓,请框架 Owner 二选一:
- **(a)** 框架也改为回环默认,容器部署在 Dockerfile / compose 里显式设 `HOST=0.0.0.0`。
- **(b)** 维持 `0.0.0.0`,在 `COMPATIBILITY.md` 登记「消费者可偏离为回环」。
无论选哪个,下一次框架同步或叠加仓 `replace: true`(F-5)都不得把 HR 的回环默认冲回去。详见 `docs/framework-sync-assessment-2026-10-27.md` F-7。
## 另外发现(不在本 PR 范围)
- `apps/api-nestjs/docker-compose.yml` 的开发 PostgreSQL(口令为 `app`)与 Redis 映射到 `0.0.0.0`,属同类暴露。
- `CLAUDE.md` 基线表 runtime 行仍是 10-25 的读数 452:报告指纹包含文档,验收后改文档会使报告失效,留待下次改文档时一并更新。
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793111729
|
1793114019
|
1793111736
|
0
|
1
|
0
|
Edit
Delete
|
|
851
|
83
|
8
|
5
|
|
0
|
feat(integration): Web/开发基座只绑回环、D-12 packages/* 受控 feat(integration): Web/开发基座只绑回环、D-12 packages/* 受控通道与 H20 出站事实注册表...
|
## 改了什么
本 PR 有三部分;已合入 main 的 PR #9(D-10 API 回环)与 ## 改了什么
本 PR 有三部分;已合入 main 的 PR #9(D-10 API 回环)与 PR #10(H23 根与 apps/* 依赖)均已并入本分支。
### 1. Web / 开发基座只绑回环(蓝图 §4.9)
- Web `next dev` / `next start` 与 UI 验收的 `next start` 加 `-H 127.0.0.1`;开发基座 `apps/api-nestjs/docker-compose.yml` 的 PostgreSQL / Redis 端口只发布到回环(此前发布到全部网卡,PG 口令 `app`、Redis 无口令)。已在运行的基座容器须 `docker compose up -d` 重建才生效。
- 在 #9 的 `scripts/lib/listen-host-guard.mjs` 内新增 `exposureViolations`(同一守卫),接入 `check:dual-backend`;单测 9/9。
- 文档:owner-matrix 去掉 D3 前「双后端 / Fastify」措辞;Scope 来源接入文档改正 IdentityLink 归属(enterprise-idp 拥有)。
### 2. D-12:`packages/*` 受控升级通道(关 H24,蓝图 §4.10)
- D3 保护此前逐字节冻结全部 `packages/*`(215 个受保护文件),台账只放行产品目录。现在同一台账 `docs/post-d3-product-updates.json` 增加 `packageUpdates`:编号 `PKG-NNN` 递增,须写来源与理由,仅限 D3 冻结清单内的 `packages/*` 文件,逐文件从冻结 hash 链式放行;任一条目不合规即整体不放行。
- `check:d3` 30/30:新增登记后放行、未登记 / 台账缺失判红,以及断链、前后相同、非 hash、缺理由、缺来源、编号格式错、编号不递增、空文件、包外路径、非冻结文件、字段类型错均判红。变异探针:删掉「理由与来源」或「链式校验」规则,测试各判红 1 项,已还原。
### 3. H20:出站事实注册表(蓝图 §4.10)
- contracts 新增 `ENTERPRISE_FACT_ENVELOPE_SCHEMAS`(`factType@schemaVersion` → 信封 Schema,当前只有 `EmploymentTransferred@1`)与 `EnterpriseFactTypeUnregisteredError`;`buildEnterpriseFactEnvelope` 按注册表分派。EmploymentTransferred v1 的 Schema 不变。
- relay 去掉全部类型强转;未登记类型或版本记 `FACT_TYPE_UNREGISTERED`,立即进死信、不调用 Publisher(部署补登记后可经既有重放恢复)。
- contracts 两个文件经台账 **PKG-001** 放行(登记前 `check:d3` 对这两个文件判红)。
- `check:app-manifest` M6 新增注册表与 `facts.owns` 双向一致检查(3 个负例)。
- 测试:contracts 新增 4 例;新文件 `apps/api-nestjs/test/enterprise-fact-relay-registry.test.ts` 真实 DB 3 例。原 `enterprise-fact-relay.test.ts` 受 D3 冻结未改,12 例仍全绿。
## 验证(本地,2026-10-27,干净提交 `effed90`)
- `check:runtime` 462/462、`check:ui` 46/46(一次性 PostgreSQL / Redis,跑完删除)
- typecheck、lint、`check:d3`、`check:dual-backend`、`check:app-manifest`、`check:docs-truth`、`check:governance-docs`、`check:migrations`、`check:database-rls` 等静态门禁通过
- `check:governance` 剩 2 项,与 main 相同:O22(D-8,等 OS 写入授权)、`osProductReleaseTargetRemotes` 2→1(D-9)
## 未覆盖
- 远端 CI 未查验(本机无 Gitea API 令牌)
- 新事实(`OrganizationUnitMoved` 等)仍待 Catalog 登记;H21(Scope 消费端写死来源应用)仍开放
- `packages/*` 内的 vitest 2.1.9 与 `client-fact` rc.3 现可经台账升级,本 PR 未做
- 00 框架同一监听默认值(他层仓);README 第 3 步提到的 `.env.example` 不存在(既有不一致)
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
0
|
1
|
0
|
|
0
|
1793111425
|
1793124194
|
0
|
0
|
3
|
0
|
Edit
Delete
|
|
850
|
83
|
7
|
5
|
|
0
|
ci: per-run docker PostgreSQL/Redis for acceptance ci: per-run docker PostgreSQL/Redis for acceptance, with reports rebound to e8591c7...
|
Two commits:
- e8591c7 ci: the runtime job no l Two commits:
- e8591c7 ci: the runtime job no longer uses `services:` (never started on this host-mode runner; 127.0.0.1:5432 reached an unrelated PostgreSQL on the runner host in run 26519). scripts/ci-acceptance-services.sh fails without docker; otherwise it starts per-run PostgreSQL/Redis containers on docker-assigned high ports with a random masked password and removes them in an if: always() step. G14 updated.
- 8cf50a6 chore(reports): runtime, UI and static reports rerun on the clean final source e8591c7.
Local evidence (isolated containers, recreated database):
- check:runtime 452/452 (floor 452), frozen oracle 12, outbox 1 scenario / 0 duplicates, outage health 2.
- check:ui 46/46.
- pnpm check with DIGITAL_EMPLOYEE_OS_ROOT at e12d0f2: exit 0, provenance violations 0.
- Script checks: start/connect/stop with no leftovers, repeated stop, and failures for missing docker, a non-prefixed database name and an invalid run id.
Not yet verified: docker on the runner host and its ability to pull postgres:16 / redis:7 (override with CI_POSTGRES_IMAGE / CI_REDIS_IMAGE repository variables).
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
0
|
1
|
0
|
|
0
|
1793102531
|
1793190011
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
849
|
83
|
6
|
5
|
|
0
|
feat(integration): AI 人事系统与企业智能OS各层对接——0.19.6、OS D feat(integration): AI 人事系统与企业智能OS各层对接——0.19.6、OS D3 单宿主验收链、OS 装载器注册证据与各层对接材料...
|
## 概要
把 AI 人事系统(`juhai.hr`)与企业智能OS各层(02 业务中台 / ## 概要
把 AI 人事系统(`juhai.hr`)与企业智能OS各层(02 业务中台 / 03 数字员工 OS / 04 技术中台 / 00 工程框架)的对接推进到「HR 侧能独立完成的都已完成」,其余项给出材料并列为待裁。完整记录见 `docs/domain/enterprise-control-plane-integration-blueprint-2026-10-27.md` §4–§5(取代 09-26 版)。
## 主要改动
- **产品真源收回 HR 仓,发布 0.19.6**:回灌 OS 已登记的 0.19.5;逐字节收录 OS 已执行的整表授权迁移 `20261010000000`,并以 `20261027000000` 前向收窄回 relay 两张表的精确列授权。产品迁移治理按全序列模拟最终授权,缺少或绕过收窄都会判红。
- **D3 受控升级台账**:`docs/post-d3-product-updates.json` 让 D3 冻结的产品字节和 `readiness.json` 只能按链放行(readiness 自干净复验值起链),C4 历史锁不变。
- **验收链跟进 OS D3(单 NestJS)**:宿主范围以目标 OS `backend-profile.json` 为唯一来源(`scripts/lib/os-host-backends.mjs`),拒绝加载残留的 Fastify 构建物;兼容锁对齐 OS `1b8ae0d7`(contracts 3.0.0);D-6 按锚定换算表把 12 项按后端累加的宿主证据地板换算为单后端。
- **注册证据改接 OS 装载器(D-5)**:lock v2 目标的 O20/O24/O26 只认 `pnpm audit:os-product:loader` 的只读证据(plan / apply 预演 / reconcile、4 个负向探针、目标提交回滚测试、目标写入 0);HR v1 写入器只留给 lock v1 目标。
- **O27 与发布证据**:按锁定后端数与注册路径取证;O27 转绿。
- **各层对接材料(草案,未改他层仓)**:人域对照表、事实登记 CHG 草案、应用清单镜像同步材料、权限决策答复草稿、框架同步差额评估、给 OS Owner 的交接说明。
- **仓内不一致修正**:app-manifest 仓库路径用工作区别名 `企业领域应用层/AI人事系统`;`authoritativeEntities` 去掉 IdentityLink(enterprise-idp 拥有);补 `ees.domain.thing` 依赖;`governance/framework-consumer.json` 地板改为 D3 换算后的 471/452。
- 已合并当前 `main`(含 CI 与 O18 显式 OS 根目录改动),冲突处两边规则都保留。
## 验证(本地工作区)
- 静态子门禁、`check:d3`、`check:app-manifest`、lint、typecheck 通过。
- HR 全量验收在合并后 HEAD 上通过:`check:runtime` 452/452、`check:ui` 46/46(一次性 PostgreSQL/Redis,跑完已删)。
- OS 产品层证据在 OS `1b8ae0d7` 快照上:产品迁移 17/17、ProductSqlRuntime、宿主运行 1/1 后端、浏览器 1/1 后端、升级审计 READY、装载器审计 passed。真实 OS 仓 0 处改动。
- 远端 CI 结果以本 PR 的运行为准,本地结果不外推。
## 剩余两项回退(`check:governance`)
1. **`osProductLayerViolations` 0 → 1(O22)**:OS main 尚不含 0.19.6。需显式授权(`OS_PRODUCT_REGISTRATION_APPLY=1`)用 OS `product:apply` 写入并进入 OS main,再复跑装载器 / 升级 / 发布审计。
2. **`osProductReleaseTargetRemotes` 2 → 1**:快照只有一个本机 remote(09-23 的证据跑在带 Gitea/GitHub 两个远端的真实 OS 上)。
本地不带 `DIGITAL_EMPLOYEE_OS_ROOT` 跑时,O18 也会按 main 上的新规则提示需要显式 OS 根目录;CI 已传入该变量。
## 待裁决
| 编号 | 问题 | 建议 |
| --- | --- | --- |
| D-2 | Scope→HR 来源授权是否续期 | 续期是 01 BA-01 首片(HR→Scope→OS 组织视图复验)的前提 |
| D-3 | 如何答复 04「HR 先接权限决策」 | 维持 F1 权限自治;可做不切真源的只读决策对照实验(草稿见 `docs/domain/reply-draft-04-permission-decision-2026-10-27.md`) |
| D-4 | F2(平台模式试点)是否重议 | 前置条件不成立:OS 未用叠加仓、未接 platform 端口模式;暂不重议 |
| D-7 | O27「拒绝 4 个目标敏感投影」的历史语义 | 定性为历史决定,审计区分观测命中与待拒绝面 |
| D-8 | O22 写入前是否区分「目标落后、准备发布」 | 维持现规则,不放宽;随写入授权一起解 |
| D-9 | `osProductReleaseTargetRemotes` 2→1 | 发布审计改为只读读取真实 OS 的远端,不设为不计棘轮 |
| D-10 | HR API 默认监听 `0.0.0.0` | 默认改为 `127.0.0.1`、需暴露时显式设 `HOST`,同步 00 框架;改前实测 04 容器可达 |
| D-11 | 框架 0.27.0 安全基线差额 | 单独一片升级 next / vitest / Capacitor 与平台 rc 包;按框架 `COMPATIBILITY.md:36` 登记 Zod 3 残余风险 |
另有新登记缺口:H20 relay 写死事实类型(扩事实前须先改)、H21 04 Scope 消费端写死组织事实来源(需 04 改)。
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793102425
|
1793111425
|
1793103977
|
0
|
0
|
0
|
Edit
Delete
|
|
848
|
83
|
5
|
5
|
|
0
|
docs(governance): record first remote run past O18 docs(governance): record first remote run past O18 and the stale acceptance provenance...
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合当前生命周期规范:既有 Personnel Core 保持 `/api/personnel/*`,HR v2 领域使用 `/api/v2/{domain}/*`,身份协议使用标准 OIDC 端点
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 涉及页面或浏览器行为时,`pnpm check:ui` 与 `pnpm check:ui:fastify` 均通过,未只验证一个后端
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793099401
|
1793099408
|
1793099408
|
0
|
0
|
0
|
Edit
Delete
|
|
847
|
83
|
4
|
5
|
|
0
|
ci: stop pulling actions from github.com on the Gi ci: stop pulling actions from github.com on the Gitea runner...
|
The Gitea runner repeatedly timed out cloning acti The Gitea runner repeatedly timed out cloning actions/checkout from
github.com (once hanging Set up job for over 10 minutes), so jobs failed
or blocked the single runner before any repository code ran.
- Checkout: plain git with the Gitea task token as Basic credentials,
all branches and tags fetched (F5 provenance needs history), detached
at github.sha, workspace cleaned.
- Node: scripts/ci-setup-node.sh downloads an exact version from
npmmirror and verifies it against the mirror's SHASUMS256.txt; both
governance jobs and the platform job use 22.23.2.
- platform-governance: upload-artifact replaced by printing the gate
reports into the run log. This file now diverges from the
@juhai/governance consumer template.
Verified locally: the checkout snippet against a file:// copy of this
repository (detached at the requested SHA, stale files removed); the
Node script in a linux/arm64 container with a test-only curl stand-in
(install, cache reuse, tampered archive rejected, unknown version
rejected).
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793096895
|
1793096902
|
1793096902
|
0
|
0
|
0
|
Edit
Delete
|
|
846
|
83
|
3
|
5
|
|
0
|
fix(ci): fetch locked OS with a Gitea token header fix(ci): fetch locked OS with a Gitea token header and probe access first...
|
actions/checkout presented OS_REPO_READ_TOKEN as B actions/checkout presented OS_REPO_READ_TOKEN as Basic credentials and
Gitea answered 401 (git fell back to a username prompt) for two
different correctly scoped tokens. Fetch the locked SHA with plain git
and an "Authorization: token" header into RUNNER_TEMP instead, after a
Gitea API probe that prints only the HTTP status, so a missing secret,
unusable token or missing repository access fails with a clear reason.
This step also no longer downloads an action from github.com.
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793096204
|
1793096226
|
1793096226
|
0
|
0
|
0
|
Edit
Delete
|
|
845
|
83
|
2
|
5
|
|
0
|
fix(ci): re-hash O18 OS Web sources from an explic fix(ci): re-hash O18 OS Web sources from an explicit locked OS checkout...
|
O18 re-hashed OS Web sources through the osRoot re O18 re-hashed OS Web sources through the osRoot recorded inside the
host UI report, an ephemeral /tmp clone that never exists on a CI
runner and disappears locally after cleanup. governance.yml therefore
failed on every Gitea run and the runtime/UI job never executed.
- O18 now only trusts --os-root / DIGITAL_EMPLOYEE_OS_ROOT and fails
closed with an explicit message when neither is given; new negative
probe product-host-ui-without-explicit-os-root (258 probes).
- The static CI job resolves compatibilityLock.osGitSha from
readiness.json, checks out luoanwu/digital-employee-os at that SHA
with secret OS_REPO_READ_TOKEN, moves it to RUNNER_TEMP, builds the
compat packages and asserts a clean tree; Node 22 to satisfy the OS
engine-strict requirement.
- Docs: CLAUDE.md commands/G9/G14/ci-gate, README, acceptance-runner
and business-module-intake now state the OS checkout requirement.
Local evidence (dirty worktree): clean OS clone at e12d0f2 makes
check:os-product pass; missing root and a tampered OS Web file both
fail O18. Full pnpm check still fails check:governance on runtime/UI
report fingerprints, which predates this change and needs a rerun of
check:runtime and check:ui on the final tree.
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793094537
|
1793095912
|
1793095912
|
0
|
0
|
0
|
Edit
Delete
|
|
844
|
83
|
1
|
5
|
|
0
|
docs(governance): sync dynamic baseline with curre docs(governance): sync dynamic baseline with current D3 reports...
|
Refresh the GOVERNANCE-BASELINE section of CLAUDE. Refresh the GOVERNANCE-BASELINE section of CLAUDE.md from
reports/governance.latest.json, reports/baseline-d3.json and the
2026-10-25 runtime/UI/RLS reports plus the 2026-09-23 OS audits:
static governance now passes, runtime 452, UI 46, RLS 116 tables,
own tests 69/471, single-host outbox/health scenarios, OS product
0.19.4 upgrade ready and release blocked only by remote CI and
target sign-off. Retire the native Fastify UI row and keep earlier
dual-host figures labelled as history.
Verified with check:governance-docs, check:docs-truth and
check:dual-backend (all exit 0); regenerated gate reports were not
committed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合当前生命周期规范:既有 Personnel Core 保持 `/api/personnel/*`,HR v2 领域使用 `/api/v2/{domain}/*`,身份协议使用标准 OIDC 端点
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 涉及页面或浏览器行为时,`pnpm check:ui` 与 `pnpm check:ui:fastify` 均通过,未只验证一个后端
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793092331
|
1793092337
|
1793092337
|
0
|
0
|
0
|
Edit
Delete
|
|
720
|
67
|
1
|
5
|
|
0
|
治理: 关闭对抗性验收发现的假绿装置、导出层静默数据损坏与文档幽灵资产
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合 `/api/v1/{resources}` 规范
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1785285580
|
1785285593
|
1785285593
|
0
|
0
|
0
|
Edit
Delete
|
|
743
|
57
|
3
|
5
|
|
0
|
feat(script): 接入大语言模型——歌词/文案 → 拍摄脚本 → 角色确认 → 定格图
|
本仓此前零 LLM 接入(全仓只有 DashScope 的图像调用),「歌词成图」屏是纯前端
原型 本仓此前零 LLM 接入(全仓只有 DashScope 的图像调用),「歌词成图」屏是纯前端
原型(procedural.ts 画色块 + setTimeout 假装推理,不落库不接后端)。本轮把这条
动线升级为真链路 + 真持久化。
契约单源(packages/contracts/src/script.ts)
- 角色确认状态机 scriptRoleMachine、脚本状态机 shootingScriptMachine
- 景别/运镜用枚举而非自由文本:LLM 一旦自由发挥,下游 prompt 与统计就没有稳定口径
- scriptDraftSchema 是 LLM 输出的唯一判据;prompt 构造器单源,两后端禁止各拼一份
- evaluateRoleReadiness:本域核心不变量,双后端硬拦截 + 前端同源即时反馈
- 前端私有的 findBannedHits 上收为 contracts 的 findBannedWords(后端也要逐镜标记,
两份并行就是双真源)
LLM 不是权威
- sidecar /v1/script 只保证「返回长得像脚本的 JSON」,两个后端各自再 parse 一次才落库
- 模型引用未声明角色键 → 422 SCRIPT_ROLE_KEYS_DANGLING(幻觉护栏)
- 连续给不出合法 JSON → 502 LLM_OUTPUT_UNPARSEABLE,绝不返回占位脚本
- parse_json_object 只剥围栏、截首尾花括号,不做字段猜测或补齐
角色必须先确认才允许出定格图
- 判据 = status CONFIRMED 且有 referenceAssetId(没有参考图就没有一致性锚点)
- CONFIRMED --reset--> DRAFT 会解除参考图绑定:人确认的是那一张图,不是那个名字
- 出图时按 roleKeys 顺序喂参考图,与指令里「第 N 张参考图」编号严格对齐
写链纪律与物料链路同构:tenant 全覆盖、updateMany 带状态前置条件(0 行即 409)、
终态与 outbox 同 tx、能力不可用 → job BLOCKED + 诚实 reason,禁止静默降级。
品牌准绳只逐镜标记不拒绝整份脚本(脚本属创作内容),硬拦截点在出定格图这个受控出口,
显式放行需带参数且落审计事件。
顺带修掉三个既有缺陷
1. 合并遗留:sidecarEdit 用 sidecarGenerateResponseSchema 校验响应(要求 steps/
loadSeconds),但 run_hosted_edit 两个字段都不返回 —— 托管改字会在客户端边界
直接 Zod 抛错(本地路径返回这两个字段,所以一直没暴露)
2. check-migrations 的列检查只扫 CREATE TABLE,凡 ALTER TABLE ADD COLUMN 追加的
@map 列一律误报 drift(此前唯一的 ALTER 列 brand_kits.profile 没 @map 才没现形)
3. ktv-poster-master.png 血统在合并两侧打架,git log --all 证明该文件自初始化提交后
从未重新生成,取诚实标注 prototype-demo-master
验收
- 新增 pnpm check:script → reports/script-acceptance.latest.json(双后端各 8 passed
+ 1 skipped-live);own-tests floor 10→14,棘轮已收紧
- pnpm check / check:runtime 均 exit 0
- 浏览器实测:未确认角色 → 按钮 disabled 且提示缺哪个角色;绕过前端直打后端 → 422
ROLE_NOT_CONFIRMED;跨租户 404;无凭证生成 → UI 显示 503 且不产生占位脚本
诚实边界(已写入 CLAUDE.md)
- liveLlmAsserted=false:本机无 DASHSCOPE_API_KEY,真调 LLM 的 live 断言被 skip,
门禁成立 ≠ LLM 出脚本已验证
- check:inference 在本机为 failed(动手前即为 failed):本工作副本的模型权重是
git-lfs 指针存根,非本轮改动导致;基线表该行已从 GREEN 改为 OPEN
- ui-acceptance 报告早于本屏,未覆盖 script 屏,已标 STALE
- 新开缺口 G16(LLM 只做结构校验、无事实性校验)、G17(同步 HTTP 挂分钟级推理 /
render_jobs 索引非 CONCURRENTLY / 本地多图 I2I 未在本机验证)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合 `/api/v1/{resources}` 规范
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1787029791
|
1787032807
|
1787032807
|
0
|
0
|
0
|
Edit
Delete
|
|
731
|
57
|
2
|
5
|
|
0
|
chore: add material factory model weights
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合 `/api/v1/{resources}` 规范
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
0
|
1
|
0
|
|
0
|
1786603028
|
1786603028
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
692
|
57
|
1
|
5
|
|
0
|
feat(material-factory): 图像模型真实推理对接 + 双后端渲染管线闭环
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合 `/api/v1/{resources}` 规范
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1783381428
|
1783381594
|
1783381594
|
0
|
0
|
0
|
Edit
Delete
|
|
691
|
50
|
1
|
5
|
|
0
|
fix(web): update Lyra product labels
|
<!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的 <!--
PR 治理模板。提交前请逐项确认,确保符合 docs/standards 下的工程规范。
CI 会执行:pnpm check(命名 + 单源漂移 + 治理棘轮 + lint + typecheck);
有测试 DB 的流水线另执行 DATABASE_URL=... pnpm check:runtime。
-->
## 变更内容
<!-- 简述这次改了什么、为什么改(聚焦 why) -->
-
## 涉及业务概念
<!-- 列出涉及的业务词典英文名,例如 store / order / verification。参见 docs/domain-glossary.md -->
-
## 检查清单
### 命名一致性
- [ ] 业务概念使用了词典中的标准英文名(未出现 shop/branch/seller/voucher/writeOff 等禁用词)
- [ ] 数据库 snake_case + 复数表名;API/JSON 字段 camelCase;类型 PascalCase;常量 SCREAMING_SNAKE_CASE
- [ ] `pnpm check:naming` 通过
- [ ] `pnpm check:schema` 通过,未新增第二份状态/契约真源
### API / 契约
- [ ] 不涉及 API 变更
- [ ] 新增/修改了 API,路由符合 `/api/v1/{resources}` 规范
- [ ] 已更新 `packages/contracts` 中的 Zod schema / DTO / 类型(前后端共用同一份)
- [ ] 无破坏前端兼容的字段删除/重命名(如有,已在描述中说明迁移方案)
### 数据库
- [ ] 不涉及数据库变更
- [ ] 新增/修改了表或字段,已通过 migration review(表名复数、字段 snake_case、外键 xxx_id、时间 _at、状态 status)
- [ ] 高增长表已考虑分区;涉及多租户的表带 tenant_id
- [ ] 写链显式带 tenant_id;跨租户读写按 404/隔离口径处理
### 数据库迁移(迁移即代码:版本/顺序/内容/环境/发布/回滚一致)
- [ ] 改 schema.prisma 的同时**已生成并提交 migration**(`pnpm db:migrate:dev --name <change>`),未只改 schema 不落迁移
- [ ] **未修改已发布过的历史 migration 文件**(内容一致:历史不可变,新变更走新迁移)
- [ ] `pnpm check:migrations` 通过(迁移历史在位 / 无未豁免高危 DDL / schema 表、enum、`@map` 列均已落迁移)
- [ ] 破坏性变更(删表/删列/改名/改类型/加 NOT NULL/加唯一约束)走 **expand→migrate→contract** 三阶段,不一次切
- [ ] 大表加索引用 `CREATE INDEX CONCURRENTLY`;大批量回填走 BullMQ 分批任务,不塞进 migration
- [ ] 高危但确需的 DDL 已加 `-- migration-allow:<原因>` 留痕,并在下方回滚方案说明
- [ ] 非开发环境只用 `migrate deploy`(禁止 `db push` / 线上手动 ALTER);发布前 `pnpm db:migrate:status` 无 drift
### 实时 / 队列
- [ ] 不涉及
- [ ] 关键业务事件进入 BullMQ 或持久化事件表(未仅依赖 Redis Pub/Sub)
- [ ] 写库事件与真实写操作在同一 tx 写入 outbox,未在 commit 后旁路 publish
- [ ] 实时通道选型符合规范(订单/看板/通知用 SSE;设备在线/包间控制/IM 用 WebSocket)
### 质量与发布
- [ ] 通过 `pnpm lint` 与 `pnpm typecheck`
- [ ] 通过 `pnpm check:governance`,`reports/*.latest.json` 已刷新且无棘轮回退
- [ ] 涉及写链 / DB / 租户 / 状态机时,通过 `DATABASE_URL=... pnpm check:runtime`,`reports/runtime-acceptance.latest.json` 已刷新
- [ ] 已补充/更新必要的测试
- [ ] 不需要回滚方案
- [ ] 需要回滚方案,已在下方说明
## 回滚方案 / 其他说明
-
...
|
0
|
0
|
0
|
1
|
0
|
|
0
|
1783327279
|
1783431501
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
673
|
32
|
1
|
1
|
|
0
|
222
|
|
0
|
0
|
0
|
1
|
0
|
|
0
|
1781158798
|
1781158798
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
690
|
25
|
4
|
1
|
|
0
|
需求 时序设备api控制 16449
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1783048848
|
1783048853
|
1783048853
|
0
|
0
|
0
|
Edit
Delete
|
|
554
|
25
|
3
|
1
|
|
0
|
🔍 代码审查报告:api-260616 - 需求 时序设备api控制日志记录 16449
|
## 自动代码审查报告
**分支**: api-260616
**提交**: `7e447e7f3 ## 自动代码审查报告
**分支**: api-260616
**提交**: `7e447e7f32b5ff41344ec17d2fa199cbc015a5ae`
**提交人**: chenjunfeng (developer.jeff.c@gmail.com)
**时间**: 2026-06-05 13:27:14
---
⚠️ **重要提示**:您提供的输入中仅包含项目目录结构,**未包含具体的 `变更文件内容`**。根据约束要求,若代码片段缺失或过短,我将明确指出局限性并提供基于该架构的审查预案。请补充具体代码(Git Diff 或修改后的文件内容)后,我将立即输出精准到行号的深度审查报告。
以下为基于当前输入的标准审查报告模板:
## 1. 审查摘要
- **代码质量评分**:`N/A (待补充代码)`
- **总体评价**:当前输入仅展示项目结构,未提供实际变更代码。从目录特征判断,该系统采用典型的 MVC 架构(高度类似 CodeIgniter 3 或内部衍生的 `phpci` 框架),核心组件(数据库驱动、会话管理、缓存、辅助函数)划分清晰。待代码提交后,将立即开展五大维度的深度审查。
- **风险等级**:`待评估`
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| ⚪ 待补充 | 全局 | **未提供变更代码/Diff**,无法进行实质性逻辑、安全与性能审查。 | 请提交具体的修改文件路径、行号及变更代码片段。 | - |
| 🟠 警告 | `system/database/DB_driver.php` | *(架构通用预警)* 若新增查询逻辑使用字符串拼接而非参数绑定,将直接暴露 SQL 注入风险。 | 强制使用查询构造器或预处理语句,禁止直接拼接用户输入。 | `$this->db->query('SELECT * FROM users WHERE id = ?', [$id]);` |
| 🟠 警告 | `system/libraries/Session/Session.php` | *(架构通用预警)* 自定义会话驱动若未严格实现 `SessionHandlerInterface` 或未处理并发锁,可能导致会话覆盖或数据不一致。 | 完整实现标准接口,使用原子操作或文件/Redis 锁机制,避免直接 `unserialize` 不可信数据。 | `if (!flock($fp, LOCK_EX)) { throw new Exception('Session lock failed'); }` |
| 🟡 建议 | `system/helpers/*.php` | *(架构通用预警)* 辅助函数若依赖全局变量或隐式状态,将降低可测试性并可能引发内存泄漏。 | 遵循无状态设计,显式传参,避免使用 `global` 或静态缓存未清理的上下文。 | `function format_price($amount, $currency = 'USD') { return number_format($amount, 2); }` |
## 3. 总结与行动建议
- **优先修复**:请补充具体的变更代码内容。收到后我将立即输出包含精确行号、漏洞定位及可直接替换的修复代码的完整报告。
- **后续重构/优化方向**(基于当前架构预判):
1. **安全基线加固**:重点审查 `DB_driver.php`、`Form_validation.php`、`Security_helper.php` 中的输入过滤、输出转义(`htmlspecialchars`/`xss_clean`)及 CSRF Token 验证逻辑,确保符合 OWASP 防护标准。
2. **性能与资源管理**:针对 `Cache/` 与 `Session/` 驱动,建议引入连接复用、惰性加载与批量操作(如 `Cache::saveMany()`),避免在循环中重复建立数据库/缓存连接。
3. **规范与现代化**:若 `phpci` 为自研或 CI3 衍生框架,建议逐步对齐 PSR-12 规范,引入 PHP 7.4+ 类型声明(`declare(strict_types=1);`)、属性类型提示及命名空间,提升静态分析兼容性与可维护性。
4. **框架生命周期适配**:确保新增/修改的库或辅助函数正确接入框架的钩子(Hooks)或事件总线,避免破坏 `pre_system` → `post_controller` 的请求生命周期。
📥 **下一步**:请回复具体的变更代码(支持 Git Diff 格式或完整文件内容)。我将严格依照 PSR-12、安全编码规范及 `phpci` 框架最佳实践,为您生成精准、可落地的审查报告。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780637234
|
1780637234
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
412
|
25
|
2
|
1
|
|
0
|
🔍 代码审查报告:api-260616 - 需求 时序设备api控制 16449
|
## 自动代码审查报告
**分支**: api-260616
**提交**: `30d690ac9 ## 自动代码审查报告
**分支**: api-260616
**提交**: `30d690ac959cffb607e3e7aa6960476d839e5290`
**提交人**: chenjunfeng (developer.jeff.c@gmail.com)
**时间**: 2026-05-29 16:49:32
---
## 1. 审查摘要
- **代码质量评分**:5/10 分
- **总体评价**:代码实现了较为完整的包厢控制与状态管理业务,但存在多处**严重逻辑漏洞**(如响应重复输出、未定义变量、条件判断错位)、**数据一致性风险**(多表更新无事务)以及**代码规范问题**(命名混乱、魔法数字、死代码)。整体可维护性与生产环境稳定性较低,需优先修复核心逻辑缺陷并统一错误处理机制。
- **风险等级**:🔴 高
> 📌 **框架说明**:根据目录结构 (`system/`, `application/`, `$this->load->model()`, `FCPATH`) 判断,实际使用的应为 **CodeIgniter 3.x** 框架。若 `phpci` 为贵司内部定制/分支框架,请结合其官方文档对加载器、响应机制进行适配。以下审查基于 CI3 标准实践。
## 2. 问题详情
| 严重程度 | 文件/方法 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `showNotice()` / `closeNotice()` | **响应重复输出/不可达代码**:在 `if/else` 已调用 `success_response` 或 `error_response` 后,末尾又追加了 `$this->success_response([], "成功");`。若响应函数包含 `exit` 则死代码;若不含则会导致重复输出或 Header 已发送错误。 | 移除方法末尾的冗余响应调用,确保每个执行路径仅返回一次。 | `if ($success) { $this->success_response(); } else { $this->error_response(); } return;` |
| 🔴 严重 | `transferRoom()` | **逻辑错误/查询条件错位**:构建 `$new_room_data` 查询条件时,错误地使用了旧包厢变量 `$room_name` 和 `$family_server_id` 进行非空判断,导致新包厢可能查询失败或查错数据。 | 将判断条件修正为新包厢对应变量 `$new_room_name` 与 `$new_family_server_id`。 | `if (!empty($new_room_name)) { $where['_name'] = $new_room_name; }`<br>`if (!empty($new_family_server_id)) { $where['_family_server_id'] = $new_family_server_id; }` |
| 🔴 严重 | `upRoomQrcode()` | **未定义变量 & 死代码**:`$arr` 未定义即被访问;且 `$res` 赋值后未使用,直接调用了 `success_response`,后续 `if(isset($arr...))` 为无效逻辑。 | 删除未使用的 `$arr` 判断块,或正确解析 `$res` 结果后再响应。 | 移除末尾 `if (isset($arr['response'])...)` 整个代码块。 |
| 🔴 严重 | `updateRoomStatus()` / `transferRoom()` | **数据一致性风险**:涉及 `family_servers`、`open_room_log`、`bill` 等多表联动更新,但未使用数据库事务。若中途网络中断或逻辑报错,将产生脏数据(如已开房但无账单、状态不一致)。 | 使用 CI3 事务机制包裹核心写操作,失败时自动回滚。 | `$this->db->trans_start();`<br>`// 执行 insert/update`<br>`$this->db->trans_complete();`<br>`if ($this->db->trans_status() === FALSE) { $this->db->trans_rollback(); throwError("操作失败"); }` |
| 🟠 警告 | `updateRoomStatus()` | **死代码分支**:`elseif ($update_status == 3 && false)` 中的 `&& false` 导致该分支永远无法执行,疑似调试遗留。 | 移除 `&& false` 或根据业务需求恢复逻辑,清理无用代码。 | `elseif ($update_status == 3) { // 清扫逻辑 }` |
| 🟠 警告 | 全局多处 | **同步网络请求阻塞**:`send_web_socket()`、`send_room_msg()` 等为同步阻塞调用,未设置超时时间。若下游服务响应慢,将直接拖垮 PHP-FPM 进程池导致 API 超时。 | 为底层 Socket 请求添加 `timeout` 参数,或引入消息队列(如 Redis/RabbitMQ)异步下发指令。 | `send_room_msg($id, $data, $server, ['timeout' => 3]);` |
| 🟠 警告 | `RenewalReminder()` / `consumptionEnd()` 等 | **输入验证缺失**:直接信任 `$this->stream`,未对 `$params['title']`、`$params['img_url']` 等进行长度、格式或 XSS 过滤。 | 引入统一参数校验层(如 CI `form_validation` 或自定义 DTO),对字符串进行 `trim()`、`htmlspecialchars()` 或白名单校验。 | `$title = trim(htmlspecialchars($params['title'] ?? '', ENT_QUOTES, 'UTF-8'));` |
| 🟡 建议 | 全局方法命名 | **命名不规范**:方法名混用驼峰与下划线(如 `RenewalReminder`、`getSlefBill`、`reboot_room`),且存在拼写错误 (`Slef` -> `Self`)。 | 严格遵循 PSR-12,统一使用 `camelCase`,修正拼写错误。 | `public function renewalReminder()`<br>`public function getSelfBill()` |
| 🟡 建议 | 全局魔法数字 | **魔法数字泛滥**:`31`, `9063`, `0,1,2,3`, `86400`, `1440`, `100` 等硬编码散落在各处,降低可读性且易引发维护错误。 | 提取为类常量或配置文件,集中管理。 | `const STATUS_FREE = 0; const STATUS_OPEN = 1;`<br>`const MAX_VOICE_VOL = 100;` |
| 🟡 建议 | 全局模型加载 | **重复加载模型**:每个方法内部频繁调用 `$this->load->model()`,虽 CI 支持重复加载,但增加 I/O 开销且不符合最佳实践。 | 将高频使用的模型移至 `__construct()` 或 `config/autoload.php` 中预加载。 | `public function __construct() { parent::__construct(); $this->load->model('Ahead_family_servers_model'); }` |
## 3. 总结与行动建议
### 🚨 优先修复的关键问题(P0)
1. **修复响应逻辑漏洞**:立即清理 `showNotice`、`closeNotice`、`upRoomQrcode` 中的重复响应与未定义变量 `$arr`,避免 API 返回异常或触发 PHP Warning。
2. **修正 `transferRoom` 查询条件**:将新包厢查询的 `if (!empty($room_name))` 改为 `if (!empty($new_room_name))`,否则转房功能在特定参数组合下必然失败。
3. **引入数据库事务**:在 `updateRoomStatus` 和 `transferRoom` 的核心状态流转逻辑外层包裹 `$this->db->trans_start()` 与 `$this->db->trans_complete()`,保障业务数据强一致性。
### 🛠 后续重构与优化方向
1. **统一错误处理机制**:当前混用 `throwError()` 与 `$this->error_response()`。建议定义统一的 `ApiResponse` 基类或中间件,所有异常捕获后统一格式化为 JSON 输出,避免部分路径直接 `exit` 导致日志丢失或前端解析失败。
2. **构建参数校验层**:`$this->stream` 为自定义输入源,建议封装 `validateParams(array $rules)` 方法,集中处理类型转换(`intval`/`floatval`)、边界限制(`max/min`)与安全过滤,消除各方法中重复的 `if/empty` 校验块。
3. **异步化网络指令**:包厢控制指令(WebSocket/Socket)属于高延迟操作。建议将指令下发改为写入 Redis 队列,由独立 Worker 消费并处理重试/超时逻辑,API 仅返回“指令已接收”,大幅提升接口吞吐与稳定性。
4. **遵循 PSR-12 与 DRY 原则**:统一方法命名风格,提取重复的音量/倒计时校验逻辑为 `private function validateDuration()` 等私有方法;清理所有注释掉的废弃代码,保持代码库整洁。
> 💡 **提示**:若 `phpci` 框架对控制器生命周期、模型加载或响应机制有特殊约定,请优先查阅其官方文档。上述建议已兼容标准 PHP 生态与 CI3 架构,可直接平滑迁移。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780044572
|
1780044572
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
283
|
25
|
1
|
1
|
|
0
|
🔍 代码审查报告:api - 11
|
## 自动代码审查报告
**分支**: api
**提交**: `f1638c3adf2bcd34 ## 自动代码审查报告
**分支**: api
**提交**: `f1638c3adf2bcd34796a5bd8afe7ade89a6ec836`
**提交人**: zhangjunnan (121158035@qq.com)
**时间**: 2026-05-22 10:19:57
---
## 1. 审查摘要
- **代码质量评分**:4/10 分
- **总体评价**:代码实现了阿里云 MQTT 消息推送与基础 HTTP 请求封装,具备初步的业务可用性。但存在**严重的安全隐患**(硬编码云密钥)、**核心逻辑缺陷**(数组操作错误、异常吞没)、**规范缺失**(非标准函数调用、调试代码未清理、注释乱码)及**框架适配不足**。整体处于“可运行但不可投产”状态,需优先进行安全加固与逻辑修复。
- **风险等级**:🔴 高
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `Mqttapi.php` L10-11 | 硬编码阿里云 `AccessKey` 与 `Secret`。一旦代码提交至版本库,将直接导致云账号资源泄露与被恶意调用。 | 移除硬编码,改用环境变量或框架配置中心动态读取。 | `self::$accessKeyId = getenv('ALIBABA_CLOUD_ACCESS_KEY_ID') ?: config('mqtt.ak');` |
| 🔴 严重 | `HttpRequest.php` L118 | `removeSignHeader` 使用 `unset($this->signHeaders[$value])`,但 `$signHeaders` 是索引数组(值数组),`unset` 会尝试删除不存在的键,导致静默失败或误删。 | 使用 `array_search` 定位真实索引后再 `unset`。 | `$key = array_search($value, $this->signHeaders, true); if ($key !== false) unset($this->signHeaders[$key]);` |
| 🔴 严重 | `Mqttapi.php` L8 | `import()` 非 PHP 原生函数。若 `phpci` 框架未全局注册该辅助函数,将直接触发 `Fatal Error`。 | 改用标准 `require_once` 或依赖 Composer 自动加载机制。 | `require_once COMMONCLASS . 'AliCloudPHPSDK/vendor/autoload.php';` |
| 🟠 警告 | `Mqttapi.php` L45-51 | `catch (Exception $error)` 未加全局命名空间前缀 `\`,在 `use` 命名空间下可能捕获不到异常;且直接 `return false` 掩盖了真实错误堆栈,极难排查。 | 捕获 `\Exception`,记录日志并抛出或返回结构化错误对象。 | `catch (\Exception $e) { log_message('error', $e->getMessage()); throw $e; }` |
| 🟠 警告 | `HttpClient.php` L15-16 | 超时值设为 `30000`/`80000`,注释却标注 `30 second`。底层若使用 cURL,默认单位为秒,数值过大会导致请求长时间挂起。 | 统一单位。若底层支持毫秒请明确注释,否则改为秒级整数。 | `private static $connectTimeout = 30; // 单位:秒` |
| 🟠 警告 | `Demo.php` L12, L48, L50 | 文件被 `include` 时直接实例化并执行请求,且残留 `var_dump` 和 `print_r`。违反库文件“只定义不执行”原则,且调试信息会污染生产环境输出。 | 移除顶层执行逻辑与调试输出,将调用移至 `phpci` 控制器或 CLI 入口。 | 删除 `include` 后的 `$demo = new Demo(); ...` 代码块 |
| 🟡 建议 | `HttpRequest.php` L33, L43, L53... | 多处 `if (null == $this->headers) { $this->headers = array(); }` 属冗余代码。属性已在声明时初始化,且 PHP 数组赋值不会自动变为 `null`。 | 直接移除冗余判断,保持代码简洁。 | 删除所有 `if (null == $this->xxx)` 块 |
| 🟡 建议 | `Constants.php` 全文 | 注释出现大量乱码(如 `ͨó`, `ǩ㷨`),表明文件保存编码与声明编码不一致(疑似 GBK 混入 UTF-8)。 | 使用编辑器统一转换为 `UTF-8 无 BOM` 编码,并修正注释内容。 | 无 |
| 🟡 建议 | `Mqttapi.php` L38 | `$args` 参数未声明类型,且直接作为 `payload` 传入 SDK。若传入非字符串/数组,SDK 可能抛出类型异常。 | 补充类型提示,并在内部进行 JSON 序列化或类型校验。 | `public static function main(string $mqttTopic, array|string $payload)` |
## 3. 总结与行动建议
### 🔑 优先修复项(P0)
1. **密钥安全治理**:立即将 `Mqttapi.php` 与 `Demo.php` 中的硬编码 AK/SK 迁移至 `phpci` 的配置文件(如 `config/mqtt.php`)或服务器环境变量中,严禁明文提交至代码库。
2. **修复数组操作 Bug**:修正 `HttpRequest::removeSignHeader()` 的删除逻辑,避免签名头清理失败导致 API 鉴权报错。
3. **替换非标准函数**:将 `import()` 替换为 `require_once` 或接入 Composer 自动加载,确保代码在标准 PHP 环境中可独立运行。
### 🛠 后续重构与优化方向
1. **框架适配规范**:
- `apitest/` 目录结构不符合常规 MVC 框架规范。建议将其迁移至 `phpci` 的 `app/` 或 `application/` 目录下,利用框架的路由、配置加载与日志组件。
- 避免在类文件中直接执行逻辑(如 `Demo.php` 的顶层调用),应通过框架控制器接收请求并分发。
2. **代码规范升级**:
- 全面补充 PHP 7.4+/8.x 类型声明(参数类型、返回值类型、属性类型),提升静态分析能力。
- 遵循 PSR-12 规范:统一缩进(4空格)、移除冗余空行、规范命名空间与 `use` 语句顺序。
3. **健壮性增强**:
- `Mqttapi::main()` 建议改为返回 `Result` 对象或抛出业务异常,而非简单返回 `false`,便于上层统一处理成功/失败/重试逻辑。
- 统一超时单位,并在 `HttpClient` 中增加对 `HttpUtil` 底层实现的依赖注入或配置化,避免硬编码网络参数。
> 📌 **局限性说明**:本次审查未提供 `HttpUtil.php` 源码及 `phpci` 框架的具体生命周期/配置加载机制。若 `HttpUtil` 内部对 cURL 选项或签名算法有特殊处理,请结合实际底层实现进行二次验证。建议查阅 `phpci` 官方文档中关于“第三方 SDK 集成”与“配置管理”的章节,以确保架构一致性。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1779416397
|
1779416397
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
769
|
24
|
2
|
4
|
|
0
|
[Web前端] 按省市统计设备月度新增上线数量报表
|
## 关联 Issue
Related to laiqiaojie/jh-project#5
Re ## 关联 Issue
Related to laiqiaojie/jh-project#5
Related to laiqiaojie/jh-project#8 — 按省市统计设备月度新增上线数量报表(Web 前端)
## 变更说明
- 新增 页面组件
- 省份视图:横向柱状图展示各省份当月新增上线设备数,点击下钻城市
- 城市视图:横向柱状图展示选定省份各城市分布,面包屑返回全国
- 使用 CSS 自定义 bar(不引入 ECharts),保持项目依赖不变
- 更新 :注册 device_online_stats 组件
- 更新 :新增 路由规则
- **修复** : 在父菜单 为空时拼出 双斜杠,导致路由匹配失败
- **修复** : 同一根因的双斜杠问题
## 测试说明
- 月份切换后图表重新加载
- 点击省份柱子进入城市视图,面包屑显示「全国 › XX省」
- 点击「全国」/「返回全国」返回省份视图
- 无数据月份显示空状态
- 点击「数据」顶部菜单 → 侧栏「设备上线分布」→ 组件正常渲染(已端到端验证)
## DB 变更(需手动执行)
## 产物归档
- Plan:(在 jh-project 仓库)
- 设计文档:
🤖 Generated with [Claude Code](https://claude.com/claude-code)...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1788247154
|
1789379914
|
1789377273
|
0
|
3
|
0
|
Edit
Delete
|
|
767
|
24
|
1
|
4
|
|
0
|
[后台管理] 按省市统计设备月度新增上线数量报表
|
## 关联 Issue
Close #4 — [后台] 按省市统计设备月度新增上线数量报表
(I ## 关联 Issue
Close #4 — [后台] 按省市统计设备月度新增上线数量报表
(Issue 位于另一仓库 laiqiaojie/jh-project,Gitea 跨仓库 `Close #N` 不会自动关联,merge 后需手动去 jh-project 更新 Issue 状态)
## 变更说明
- 新增 `DeviceOnlineStats` 控制器,暴露 `getProvinceStats`(按月+省份汇总新增上线设备数)、`getCityStats`(指定省份后按城市下钻)两个接口
- `Ahead_authenticate_log_model` 新增对应查询方法:联表 `ahead_authenticate_log` → `ahead_family_servers` → `ahead_yc_shop`,权限过滤复用现有 `Ahead_manage_user_model::check_is_agent()`(超管看全国,运营商强制按 `shop._agent_id` 过滤)
- 与 plan.md 的偏差:实现与计划一致;另外在 `/code-review` 中发现并修复了两个问题(均已回归验证):
- `month` 参数只校验格式未校验取值范围,如 `2026-00` 会被 `strtotime` 静默接受为上一年 12 月而不报错 → 正则改为 `(0[1-9]|1[0-2])` 严格校验月份范围
- 未绑定门店的设备(`room._shop_id` 为 0/未匹配)会被计入 `total` 但在 `GROUP BY shop._province` 时产生一个 province 为 null 的脏分组 → 加 `room._shop_id > 0` 过滤
## 测试说明
- 本地起 PHPStudy,登录后手动调用两个接口验证:正常月份返回 `{code:0, result:{total, list}}`;缺 `month`/非法月份(`2026-00`、`2026-13`、`0000-00`)均正确返回 400
- 用只读 SQL 直接查了云端开发库确认 JOIN 链路正确——本地测试库 `ahead_authenticate_log` 表只有 1 条 2021 年的历史数据,所以当月查询返回空列表是预期行为,不是 bug
- `tests/api/smoke.mjs` 里补充了对应的自动化用例,但该冒烟测试框架整体依赖另一个尚未推送到 `admin` 分支的提交(`694e34c`,属于另一项未提交的工作,不在本 Issue 范围内),为保持本 PR 改动范围干净,本次未包含测试框架文件,仅代码改动
- 需要 Tech Lead 重点看:`check_is_agent()` 权限过滤范围是否符合预期;`room._shop_id > 0` 过滤是否会误伤合法数据
## 产物归档
- Plan:[plan/device-online-stats-by-region-admin.md](https://gitea.g-hi.com/laiqiaojie/jh-project/src/branch/design/device-online-stats-by-region/plan/device-online-stats-by-region-admin.md)(位于 laiqiaojie/jh-project 仓库)
...
|
0
|
0
|
1
|
1
|
1
|
|
0
|
1788244598
|
1788246926
|
1788245236
|
0
|
0
|
0
|
Edit
Delete
|
|
900
|
23
|
72
|
1
|
|
0
|
创建 Ahead_room_discontinue_rule_model.php
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793864270
|
1793864280
|
1793864280
|
0
|
0
|
0
|
Edit
Delete
|
|
899
|
23
|
71
|
1
|
|
0
|
创建 Ahead_room_discontinue_rule_model.php
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793864236
|
1793864246
|
1793864246
|
0
|
0
|
0
|
Edit
Delete
|
|
873
|
23
|
70
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793330583
|
1793330587
|
1793330587
|
0
|
0
|
0
|
Edit
Delete
|
|
872
|
23
|
69
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793330567
|
1793330572
|
1793330572
|
0
|
0
|
0
|
Edit
Delete
|
|
863
|
23
|
68
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793154047
|
1793154053
|
1793154053
|
0
|
0
|
0
|
Edit
Delete
|
|
862
|
23
|
67
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793153904
|
1793153911
|
1793153911
|
0
|
0
|
0
|
Edit
Delete
|
|
860
|
23
|
66
|
1
|
|
0
|
包厢列表导出改由前端生成Excel
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1793153586
|
1793153620
|
1793153620
|
0
|
0
|
0
|
Edit
Delete
|
|
830
|
23
|
65
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1791868652
|
1791868657
|
1791868657
|
0
|
0
|
0
|
Edit
Delete
|
|
829
|
23
|
64
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1791868475
|
1791868484
|
1791868484
|
0
|
0
|
0
|
Edit
Delete
|
|
828
|
23
|
63
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1791868451
|
1791868458
|
1791868458
|
0
|
0
|
0
|
Edit
Delete
|
|
798
|
23
|
62
|
1
|
|
0
|
客户满意度批量作废确定弹窗
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1790070070
|
1790070081
|
1790070081
|
0
|
0
|
0
|
Edit
Delete
|
|
797
|
23
|
61
|
1
|
|
0
|
客户满意度批量作废确定弹窗
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1790070042
|
1790070050
|
1790070050
|
0
|
0
|
0
|
Edit
Delete
|
|
788
|
23
|
60
|
1
|
|
0
|
需求 回访任务批量作废 16852
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1789718392
|
1789718403
|
1789718403
|
0
|
0
|
0
|
Edit
Delete
|
|
781
|
23
|
59
|
1
|
|
0
|
包厢续费小程序码
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1789436596
|
1789436624
|
1789436624
|
0
|
0
|
0
|
Edit
Delete
|
|
780
|
23
|
58
|
1
|
|
0
|
包厢续费小程序码
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1789436552
|
1789436571
|
1789436571
|
0
|
0
|
0
|
Edit
Delete
|
|
772
|
23
|
57
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1788426774
|
1788426780
|
1788426780
|
0
|
0
|
0
|
Edit
Delete
|
|
771
|
23
|
56
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1788426740
|
1788426764
|
1788426764
|
0
|
0
|
0
|
Edit
Delete
|
|
753
|
23
|
55
|
1
|
|
0
|
编译
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1787640140
|
1787640147
|
1787640147
|
0
|
0
|
0
|
Edit
Delete
|
|
752
|
23
|
54
|
1
|
|
0
|
编译
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1787640115
|
1787640123
|
1787640123
|
0
|
0
|
0
|
Edit
Delete
|
|
733
|
23
|
53
|
1
|
|
0
|
需求 增加包厢筛选参数 16722
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1786672377
|
1786672401
|
1786672401
|
0
|
0
|
0
|
Edit
Delete
|
|
730
|
23
|
52
|
1
|
|
0
|
111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1786438614
|
1786438619
|
1786438619
|
0
|
0
|
0
|
Edit
Delete
|
|
729
|
23
|
51
|
1
|
|
0
|
111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1786438592
|
1786438597
|
1786438597
|
0
|
0
|
0
|
Edit
Delete
|
|
724
|
23
|
50
|
1
|
|
0
|
111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1786339403
|
1786339409
|
1786339409
|
0
|
0
|
0
|
Edit
Delete
|