# 变更审计记录:租户用户审核 — 软删除恢复 upsert 修复 | 字段 | 值 | |------|-----| | 日期 | 2026-03-25 01:54:19 | | Prompt-ID | P20260325-000112 | | Session-ID | 4627fd68 | | Session 路径 | docs/audit/session_logs/2026-03/24/79_de2a1755_235713 | ## 操作摘要 修复租户管理后台审核通过流程中 `ON CONFLICT DO NOTHING` 被已软删除记录阻塞的 bug。当用户曾被移除(`is_removed=true`)后重新申请并审核通过时,`user_site_roles` 写入被唯一约束上的已删除记录阻塞,导致 approved 用户无角色。改为 `DO UPDATE SET is_removed = false, removed_at = NULL` 恢复软删除记录。同步更新了前后端联调规范文档,将此模式记录为通用规则。 ## 风险标签 `dir:backend`、`root-file`、`dir:admin-web`、`dir:etl`、`dir:miniprogram`、`dir:db`、`db-schema-change` > 注:本次 session 实际只修改了 `tenant_users.py` 和联调文档。其余风险标签来自累积未审计的变更(DEMO-miniprogram 迁移、admin-web 重构、miniprogram 更新、ETL 调整等),这些变更在更早的提交中完成,本次审计一并覆盖标记清除。 ## 本次对话文件变更 ### 新增文件 - `docs/audit/prompt_logs/prompt_log_20260325_000112.md` - `docs/audit/session_logs/2026-03/24/78_ec0569d7_234840/main_01_a5bb4c10.md` - `docs/audit/session_logs/2026-03/24/79_de2a1755_235713/main_01_fe71cc2d.md` - `docs/audit/session_logs/2026-03/24/79_de2a1755_235713/sub_01_fe71cc2d.md` ### 删除文件 - `docs/audit/session_logs/2026-03/24/78_ec0569d7_234840/main_01_df41de21.md`(被替换为新版本) ## 合规检查 - ⚠️ 接口代码已变更但 OpenAPI spec 未同步(`api_changed: true`, `openapi_spec_stale: true`)— 需手动运行 `python scripts/ops/_export_openapi.py` 重新导出 - ⚠️ DDL 基线待合并(`has_ddl_baseline: false`)— 累积变更中含 db-schema-change - ⚠️ 文档同步缺失:`apps/backend/app/routers/tenant_users.py` 应同步更新 `apps/backend/docs/API-REFERENCE.md` 和 `docs/contracts/openapi/backend-api.json` - ✅ 迁移 SQL:无新增迁移(`new_migration_sql` 为空) ## 改动注解 ### `apps/backend/app/routers/tenant_users.py` - 变更类型:修改 - 原始原因:用户反馈审核通过时,后端用 `applied_role_text` 匹配 `auth.roles` 失败导致 `user_site_roles` 未写入。实际问题是 `ON CONFLICT DO NOTHING` 被已软删除的记录阻塞——唯一约束 `(user_id, site_id, role_id)` 上存在 `is_removed=true` 的旧记录,INSERT 触发冲突但 DO NOTHING 跳过,导致用户审核通过后无角色。 - 思路分析:将 `approve_application` 中 `user_site_roles` 的 INSERT 语句从 `ON CONFLICT DO NOTHING` 改为 `ON CONFLICT (user_id, site_id, role_id) DO UPDATE SET is_removed = false, removed_at = NULL`。这是软删除 + 唯一约束的标准处理模式(已记录在前后端联调规范中)。不影响其他端点,不改变表结构。 - 修改结果:审核通过流程可正确恢复已软删除的角色记录。影响范围仅限 `POST /api/tenant/applications/{id}/approve` 端点。 ### `docs/guides/FRONTEND-BACKEND-INTEGRATION.md` - 变更类型:修改(简要) - 同步更新联调规范,新增"软删除 + 唯一约束陷阱"通用规则条目。 ### `.kiro/steering/frontend-backend-integration.md` - 变更类型:修改(简要) - steering 规则同步更新,引用联调规范中的新增条目。 ## 回滚策略 代码回滚:revert `approve_application` 中的 upsert 改动,恢复为 `ON CONFLICT DO NOTHING`。 数据影响:若已有用户通过新逻辑恢复了角色,回滚后不影响已恢复的记录(`is_removed=false` 状态保持)。