# 📅 2026-05-08 日报 · lijian

## 概览

审计模块 P0 全套优化落地（详情页防篡改/字段 diff/业务跳转/UA 解析 + 13 个控制器补 `@Sensitive`），同时撞上 4 套环境 Node 升级 + Temporal 容器 + JWT env 同步等一连串运维坑（6 条 ERR 沉淀）。

## 一、产出（按价值排序）

### 🔴 审计详情页 4 项 P0 优化 + 防篡改链路打通
- **方案**：详情页加防篡改校验、字段级 diff、业务路由跳转、UA 解析；后端 `verifyHashChain` 把 `expectedHash`/`actualHash` 透传出来对齐前端契约
- **关键文件**：[backend/src/core/observability/audit/services/hash-chain.service.ts](backend/src/core/observability/audit/services/hash-chain.service.ts)、[frontend/src/app/(core)/audit/logs/[id]/page.tsx](frontend/src/app/(core)/audit/logs/%5Bid%5D/page.tsx)、[frontend/src/lib/audit-business-routes.ts](frontend/src/lib/audit-business-routes.ts)
- **影响**：详情页 +582 -89；业务跳转覆盖组织/审批/工单等 12+ 实体（[245d7ec5](#))

### 🔴 13 个控制器补齐 `@Sensitive()` + IAM 治理域写操作覆盖
- **背景**：装饰器覆盖度扫描脚本跑出缺口报告（21 个未标接口）
- **方案**：[testing/scripts/audit-coverage-scan.ts](testing/scripts/audit-coverage-scan.ts)、[testing/scripts/audit-sensitive-gap.ts](testing/scripts/audit-sensitive-gap.ts)、[testing/scripts/audit-sensitive-patch.ts](testing/scripts/audit-sensitive-patch.ts) 三脚本闭环（扫描→分析→批量补丁）
- **影响**：13 文件 +44 -9（[9585032b](#))；IAM 治理域 +10 -3（[1b66c027](#))；新增双防线 pre-commit + skill 强约束（[35494c26](#))

### 🟡 审计 L1 集成测试套件 21/21 通过
- **方案**：[6b4391eb](#) 新增 5 文件 +644 -17，配 [seed 脚本](backend/prisma/seeds/audit-log.seed.ts) 和 report 权限补齐
- **影响**：横切模块的 createTestApp 拦截器 override 坑沉淀到 [.learnings/2026-05-08-test-app-interceptor-override.md](.learnings/2026-05-08-test-app-interceptor-override.md)

### 🟡 PR #247 review 三处反馈收敛
- 修复 + 文档收敛两次提交（[2c37f6fd](#) +32 -8，[581e6144](#) +8 -6）

### 🟡 一系列契约/枚举对齐修复
- list/detail formatter 补 C1/C2 缺失字段（[47638538](#)）
- integrity-check scope 枚举对齐 + report 权限 seed（[5dd18de7](#) +399 -4）
- entityType 查询大小写不敏感（[1e2c5246](#)）
- 拦截器 region 写入统一小写（[3a8bfbc5](#)）
- failure 结构补 type 收敛与哈希字段（[8757f66d](#) +76 -25）

### 🛠 daily-report skill + 团队 allowlist 扩容
- 新增 daily-report skill 与每日日报落盘约定（[15fda59b](#) 14 文件 +1095 -9）
- Claude 团队级 allowlist 扩容 + pre-commit 排除 settings（[68882aa0](#) +135 -2）

### 📝 audit README v1.1.0 同步、learnings 沉淀踩坑

## 二、今日合入的 PR

| PR | 标题 | 状态 | 备注 |
|---|---|---|---|
| #247 | feat(audit): 详情页 4 项 P0 优化 + Sensitive 覆盖补齐 + 业务跳转扩展 | merged 2026-05-08 | 见 commit 85ecda78 |

⚠️ Gitea API token 未配置，PR 数据从 git log merge commit 推断。

## 三、Git 活动

22 个 commit（含 2 个 develop merge），覆盖 audit 模块 + skill 基建：

```
83e1690e 11:30 feat(audit): 详情页增加防篡改校验/字段级 diff/业务跳转/UA 解析   +582 -89
8757f66d 11:33 fix(audit): 完整性校验 failure 结构补 type 收敛与哈希字段        +76 -25
3a8bfbc5 11:34 fix(audit): 拦截器 region 写入时统一小写                         +1 -1
9285d456 11:35 feat(audit): 新增审计日志种子脚本与沉淀梳理踩坑                  +386
10f6f395 11:35 docs(audit): README 版本号与日期同步至 v1.1.0                    +5 -3
15fda59b 11:35 feat(skill): 新增 daily-report skill                             +1095 -9
1e2c5246 11:52 fix(audit): entityType 查询大小写不敏感                          +44 -5
5dd18de7 13:01 fix(audit): integrity-check scope 枚举对齐 + report 权限 seed    +399 -4
47638538 13:17 fix(audit): list/detail formatter 补齐前端契约缺失字段           +7 -2
6b4391eb 13:37 test(audit): L1 集成测试套件 21/21 通过                          +644 -17
36796d78 13:38 docs(learnings): createTestApp 拦截器 override 坑                +89
68882aa0 14:23 chore(claude): 团队级 allowlist 扩容                              +135 -2
35494c26 14:44 chore(audit): 双防线（pre-commit 检查 + skill 强约束）           +118 -2
1b66c027 15:32 chore(audit): IAM 治理域 + 岗位写操作 @Sensitive                  +10 -3
245d7ec5 15:58 feat(audit): 业务路由跳转覆盖 12+ 实体                            +100 -27
d0e05797 16:02 test(audit): 装饰器覆盖度扫描脚本与报告                          +1761
9585032b 16:02 chore(audit): 13 控制器补 @Sensitive                              +44 -9
2c37f6fd 16:48 fix(audit): PR #247 review 三处反馈                               +32 -8
581e6144 17:01 docs(audit): 收敛 PR #247 review 三处建议                         +8 -6
```

热点目录：[backend/src/core/observability/audit/](backend/src/core/observability/audit/)、[frontend/src/locales/audit/](frontend/src/locales/audit/)、[testing/scripts/audit-*](testing/scripts/)

## 四、Claude session 摘要

8 个 session 共 77 个用户回合：

- **session 66302c5f** (36 turns): audit 列表/详情两个页面的 P0 优化主战场（风险等级、筛选、字段 diff、防篡改、业务跳转）
- **session 6c06037a** (14 turns): "测试审计整体模块" — 跑 test-main 三层测试，B1+B2 优先修
- **session 402c38b2** (8 turns): 设计 daily-report skill；调整命令 auto-approve 配置
- **session c569298a** (6 turns): 启动前后端、统计审计接入模块、修 `AuditIntegrityPage` substring 崩溃
- **session 884d4117 / 9e1f4f06** (各 5 turns): "我想学习 claude code 功能制定学习计划"；模块覆盖率全量重扫
- **session f4b28180** (2 turns): 续接 audit 优化需求清单
- **session 754c1e5a** (1 turn): 噪声 session

## 五、事故 & 教训

### ⚠️ ERR-20260508-001 (audit-integrity-failures-shape): 完整性页面 substring 崩溃 = 后端/前端/文档三方契约漂移
- **现象**：`failure.expectedHash.substring(0, 32)` 抛 undefined
- **根因**：文档声明 `expectedHash/actualHash`，后端没产出，前端当必填渲染
- **缓解**：后端 `verifyHashChain` 按 type 补字段透传 → 以文档为契约源
- **教训**：契约面三方对齐必须有自动检查（L0a/L0c），不能靠人眼
- 详见 [.learnings/ERRORS/ERR-20260508-001-audit-integrity-failures-shape.md](.learnings/ERRORS/ERR-20260508-001-audit-integrity-failures-shape.md)

### ⚠️ ERR-20260508-001 (Node 升级连环坑): nvm 切版本后 pm2 / npm global / prisma generate / .env 全要单独处理
- **现象**：UAT 升 Node 20→22，撞 4 个看似 ESM 实际是环境的坑
- **教训**：每个 Node 版本独立 `npm install -g`，PM2 daemon 必须 `pm2 kill` 才会跟着切
- 详见 [.learnings/ERRORS/ERR-20260508-001.md](.learnings/ERRORS/ERR-20260508-001.md)

### ⚠️ ERR-20260508-002: AIxC UAT/PROD 同样的 ESM 炸弹（同日修复）
- **现象**：otplib + @scure/base 2.x ESM + Node 20，PM2 长 uptime 一旦 reload 就炸
- **缓解**：当天授权直接升 Node 22.21.1
- 详见 [.learnings/ERRORS/ERR-20260508-002.md](.learnings/ERRORS/ERR-20260508-002.md)

### ⚠️ ERR-20260508-003: nvm 的 npm 误读 system 级 `prefix=/usr` 致 EACCES
- **根因**：`npm config get prefix` 返回 `/usr` 而非 `~/.nvm/...`
- 详见 [.learnings/ERRORS/ERR-20260508-003.md](.learnings/ERRORS/ERR-20260508-003.md)

### ⚠️ ERR-20260508-004: 4 套环境 JWT env 同步漏一个（AIxC-UAT）
- **现象**：实测 `/api/v1/auth/login` 的 `expiresIn`，AIxC-UAT 仍是 1800（兜底 30min）
- **教训**：多环境一致性必须**实测接口**而不是 grep .env
- 详见 [.learnings/ERRORS/ERR-20260508-004.md](.learnings/ERRORS/ERR-20260508-004.md)

### ⚠️ ERR-20260508-005: Temporal auto-setup 三重坑 + crash loop 9 天没人管
- **根因**：auto-setup 时序竞争 + custom namespace 不自动建 + healthcheck 只看端口
- 详见 [.learnings/ERRORS/ERR-20260508-005.md](.learnings/ERRORS/ERR-20260508-005.md)

### ⚠️ ERR-20260508-006: 新 worktree 首次 db push 失败的真因是 citext 扩展缺失
- **教训**：之前的 learning 给的是绕行方案，根因是 PG container 缺 citext extension
- 详见 [.learnings/ERRORS/ERR-20260508-006.md](.learnings/ERRORS/ERR-20260508-006.md)

## 六、新增 learnings

| 文件 | 类型 | 适用场景 |
|---|---|---|
| [audit-entity-type-dual-style](.learnings/2026-05-08-audit-entity-type-dual-style.md) | feedback | entityType 大小写双形态查询统一 |
| [claude-permission-allowlist-batch](.learnings/2026-05-08-claude-permission-allowlist-batch.md) | reference | 团队级 allowlist 扩容方法 |
| [coverage-survey-by-schema-name-misleads](.learnings/2026-05-08-coverage-survey-by-schema-name-misleads.md) | feedback | 模块覆盖率应按 docs/modules 目录扫，不按 schema 名 |
| [decorator-coverage-via-mechanism-testing](.learnings/2026-05-08-decorator-coverage-via-mechanism-testing.md) | feedback | 装饰器覆盖度用机制扫描而非单测 |
| [dingtalk-tenure-confirm-source-with-hr](.learnings/2026-05-08-dingtalk-tenure-confirm-source-with-hr.md) | project | 钉钉工龄字段以 HR 数据源为准 |
| [ffai-aixc-servers-nopasswd-sudo](.learnings/2026-05-08-ffai-aixc-servers-nopasswd-sudo.md) | reference | FFAI/AIxC 服务器 NOPASSWD sudo 配置 |
| [node-version-drift-across-envs](.learnings/2026-05-08-node-version-drift-across-envs.md) | reference | 4 套环境 Node 版本漂移盘点方法 |
| [test-app-interceptor-override](.learnings/2026-05-08-test-app-interceptor-override.md) | feedback | 横切模块集成测试 createTestApp 拦截器 override |

## 七、未提交改动

（工作区干净，所有改动已 commit；当前在 `feature/daily-report-optimization` 分支做后续优化）

## 八、待决策 / 明日计划

- **PR 节奏**：用户提过"我之前的 pr 还没有通过，现在还要在提 pr 吗" — 关注 #247 后续是否有衍生 PR 需要拆
- **审计 L2 / L3 验收**：L1 21/21 已过，但 E2E 留给 UAT 兜底，需走 test-frontend skill 安排
- **AIxC 两机 Node 22 升级回归**：已修但需观察 PM2 reload 后是否还有边角 ESM 包炸（ERR-20260508-002 长期跟踪）
- **citext 扩展根因修复**（ERR-20260508-006）：当前是绕行，应在 setup-worktree.sh 或 PG image 层固化
