# [LRN-20260408-001] 测试基建债务连锁暴露

**日期**: 2026-04-08
**触发**: SAP 采购同步功能提交后 CI 失败，逐层排查暴露多层基建问题
**严重度**: 高（阻塞所有 PR 合并）

## 经验总结

### 1. 测试不跑等于没有测试

CI 里 `backend-integration` 跑了但没配为分支保护必须检查，测试悄悄坏了几周没人发现。

**规则**: CI 检查必须配为分支保护的必须通过项，否则形同虚设。

### 2. catch(() => {}) 是 bug 的温床

cleanup helper 里所有 raw SQL 用 `.catch(() => {})` 吞掉错误。表名写错（`user_roles` 实际是 `user_role_rel`）、列名不存在（`is_built_in` 在 `workflow_roles` 表上不存在）都被静默忽略，导致 cleanup 看起来成功实际什么都没删。

**规则**: raw SQL 的 catch 至少要 `console.warn`，不能空 catch。

### 3. 测试数据必须随机化

硬编码 `'Test Organization'`、`'WF_DIRECT_MANAGER'`、`'testuser'` 等固定值，只要测试间共享数据库就一定冲突。本次 33 个 409 Conflict 全是这个原因。

**规则**: 所有测试数据的 code/name/username 必须带 `Date.now()` 随机后缀。已写入 CLAUDE.md。

### 4. Prisma model 名 ≠ SQL 表名

Prisma 用驼峰命名（`userRole`），但实际 PostgreSQL 表名由 `@@map` 决定（如 `user_role_rel`）。写 raw SQL 时必须查实际表名：
```sql
SELECT schemaname, tablename FROM pg_tables WHERE schemaname IN ('platform_iam', 'corp_hr');
```

### 5. package-lock.json 必须提交

`testing/.gitignore` 忽略了 `package-lock.json`，导致 CI 每次 `npm install` 解析到不同版本（TS 5.3 vs 5.9），`ignoreDeprecations: "6.0"` 在 5.9 报错但 5.3 不报。

**规则**: 应用级目录的 lockfile 必须提交。只有发布到 npm 的库才忽略。

### 6. API 变更和种子数据的隐形冲突

workflow-roles API 检查 code 和 name 两个字段的唯一性。种子创建了 `DIRECT_MANAGER`（名称"直属上级"），测试创建 `WF_DIRECT_MANAGER`（名称也是"直属上级"）——code 不同但名称冲突，409。

**规则**: 写测试数据时必须检查种子数据的名称，避免隐形冲突。最安全的做法是所有测试数据名称都带随机后缀。

## 修复方式

- cleanup: TRUNCATE → 精确 DELETE（保留种子角色/权限/岗位），正确表名
- test-setup: 每次创建临时 admin + cleanup 默认启用
- 所有测试文件: 随机化 code/name/username
- regions: PUT → PATCH 对齐实际 API
- lib-test-db: force-reset 改为 DROP+CREATE 数据库
- 删除过时 performance 测试，暂缓 organization-integration

## 最终效果

| 指标 | 修复前 | 修复后 |
|------|--------|--------|
| 通过率 | 63/125 (50%) | 125/125 (100%) |
| 耗时 | ~4 分钟 | ~65 秒 |
