这些审计记录原本堆积在 docs/audit/changes/changes/ 嵌套误产物目录下(由开发机迁移
79d3c2e 前后的不明批量操作产生)。由于同期 .gitignore 屏蔽了 docs/audit/ 全目录,
它们从未入过 git 任何分支 history。删除即永久丢失。
按 docs/specs/audit-gap-recovery/tasks.md 阶段 1 执行,将全部 96 份 D 类孤本
(主目录无同名、git history 亦无记录)复制到 docs/audit/changes/ 主目录入仓。
涵盖主题: P1-P18 全栈集成 / 多模块累积变更 / ETL bug 修复 / 业务日切 /
召回与任务引擎改造 / 租户管理与审批 / 董事会财务 / 客户与助教详情 /
DDL 基线合并 / Kiro 到 Claude Code 迁移
阶段 2(B 类内容漂移 1 份)和阶段 4(嵌套目录删除)独立推进。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
103 lines
6.4 KiB
Markdown
103 lines
6.4 KiB
Markdown
# 变更审计记录:user_site_roles / user_assistant_binding 软删除实施
|
||
|
||
| 字段 | 值 |
|
||
|------|-----|
|
||
| 日期 | 2026-03-24 09:43:22 |
|
||
| Prompt-ID | P20260324-093259 |
|
||
|
||
## 操作摘要
|
||
|
||
在 `auth.user_site_roles` 和 `auth.user_assistant_binding` 两张表上实施软删除,替代原有物理删除。DDL 新增 `is_removed boolean DEFAULT false` 和 `removed_at timestamptz` 字段及部分索引。后端所有查询这两张表的位置(7 个文件、23+ 处)添加 `AND is_removed = false` 过滤条件,`remove_user` 操作改为 `UPDATE SET is_removed = true, removed_at = now()`。
|
||
|
||
## 本次对话文件变更
|
||
|
||
### 新增文件
|
||
- `docs/audit/prompt_logs/prompt_log_20260324_093259.md`
|
||
- `docs/audit/session_logs/2026-03/24/36_e6cfbf4c_085324/main_01_fd2ad307.md`
|
||
- `docs/audit/session_logs/2026-03/24/36_e6cfbf4c_085324/sub_01_39f5c47c.md`
|
||
- `docs/audit/session_logs/2026-03/24/41_cd5cdd22_091638/main_01_39f5c47c.md`
|
||
|
||
### 删除文件
|
||
- `docs/audit/session_logs/2026-03/24/36_e6cfbf4c_085324/main_01_22ae44a6.md`
|
||
- `docs/audit/session_logs/2026-03/24/41_cd5cdd22_091638/main_01_f4046b07.md`
|
||
|
||
## 涉及文件
|
||
|
||
| 文件 | 变更类型 | 风险等级 |
|
||
|------|----------|----------|
|
||
| `db/zqyy_app/migrations/20260324_soft_delete_user_site_roles_and_binding.sql` | 新增 | 高(DDL) |
|
||
| `apps/backend/app/routers/xcx_auth.py` | 修改 | 高 |
|
||
| `apps/backend/app/routers/tenant_users.py` | 修改 | 高 |
|
||
| `apps/backend/app/services/role.py` | 修改 | 高 |
|
||
| `apps/backend/app/services/task_manager.py` | 修改 | 高 |
|
||
| `apps/backend/app/services/task_generator.py` | 修改 | 高 |
|
||
| `apps/backend/app/services/performance_service.py` | 修改 | 高 |
|
||
| `docs/database/ddl/zqyy_app__auth.sql` | 修改 | 中(DDL 基线) |
|
||
| `docs/database/BD_Manual_soft_delete_user_site_roles.md` | 新增 | 低(文档) |
|
||
|
||
## 改动注解
|
||
|
||
### `db/zqyy_app/migrations/20260324_soft_delete_user_site_roles_and_binding.sql`
|
||
- 变更类型:新增
|
||
- 原始原因:用户要求"移除用户时,要有字段来标记此记录被移除/删除",需要在数据库层面支持软删除
|
||
- 思路分析:在 `auth.user_site_roles` 和 `auth.user_assistant_binding` 两张表各新增 `is_removed boolean DEFAULT false` 和 `removed_at timestamptz` 字段。创建部分索引 `ix_user_site_roles_active` 和 `ix_user_assistant_binding_active`(`WHERE is_removed = false`),确保活跃记录查询性能不受软删除数据膨胀影响
|
||
- 修改结果:DDL 已在测试库 `test_zqyy_app` 执行成功。现有数据默认 `is_removed = false`,无需数据迁移
|
||
|
||
### `apps/backend/app/routers/xcx_auth.py`
|
||
- 变更类型:修改
|
||
- 原始原因:软删除后,所有查询必须排除已移除记录,否则已移除用户仍能登录和操作
|
||
- 思路分析:在 7 处查询中添加 `AND is_removed = false` / `AND usr.is_removed = false` 过滤条件。涉及函数:`_get_user_roles_at_site`、`_get_user_default_site`、`get_my_status`(user_assistant_binding 查询)、`get_my_sites`、`switch_site`、`dev_context`(2 处:binding + site_roles)
|
||
- 修改结果:已移除用户的角色和门店绑定在所有小程序认证流程中被正确过滤。已移除用户登录时将获得受限令牌(无 site_id/roles),前端路由至相应状态页
|
||
|
||
### `apps/backend/app/routers/tenant_users.py`
|
||
- 变更类型:修改
|
||
- 原始原因:租户管理后台的用户列表、编辑、绑定更新等操作需排除已移除记录;`remove_user` 需改为软删除
|
||
- 思路分析:8 处查询添加过滤条件。`list_users` 的 COUNT 和列表查询(含 JOIN 条件)、`edit_user` 的验证/角色查询/角色更新/门店更新、`update_binding` 的验证/site_id 查询/更新子查询。`remove_user` 从 `DELETE` 改为 `UPDATE SET is_removed = true, removed_at = now()`,同时新增对 `user_assistant_binding` 的软删除(此前完全缺失)
|
||
- 修改结果:租户后台用户管理全链路正确过滤已移除记录。移除操作可追溯(保留 `removed_at` 时间戳),支持未来恢复
|
||
|
||
### `apps/backend/app/services/role.py`
|
||
- 变更类型:修改
|
||
- 原始原因:权限服务查询 `user_site_roles` 时需排除已移除记录
|
||
- 思路分析:3 处添加过滤:`get_user_permissions`、`get_user_sites`、`check_user_has_site_role`
|
||
- 修改结果:权限校验正确排除已移除用户的角色,防止已移除用户通过缓存令牌访问受保护资源
|
||
|
||
### `apps/backend/app/services/task_manager.py`
|
||
- 变更类型:修改
|
||
- 原始原因:任务管理器查询助教绑定时需排除已移除记录
|
||
- 思路分析:`_get_assistant_id` 添加 `AND is_removed = false`
|
||
- 修改结果:已移除的助教绑定不再被任务管理器使用,避免为已移除助教生成任务
|
||
|
||
### `apps/backend/app/services/task_generator.py`
|
||
- 变更类型:修改
|
||
- 原始原因:任务生成引擎查询助教绑定和门店列表时需排除已移除记录
|
||
- 思路分析:3 处添加过滤:门店列表查询、助教规模检查、入驻时间保护
|
||
- 修改结果:任务生成引擎正确排除已移除的助教绑定,不再为已移除助教生成或转移任务
|
||
|
||
### `apps/backend/app/services/performance_service.py`
|
||
- 变更类型:修改
|
||
- 原始原因:绩效服务查询助教信息时需排除已移除记录
|
||
- 思路分析:助教信息查询添加 `AND is_removed = false`
|
||
- 修改结果:绩效报表不再包含已移除助教的数据
|
||
|
||
### `docs/database/ddl/zqyy_app__auth.sql`
|
||
- 变更类型:修改
|
||
- 原始原因:DDL 基线需与实际数据库结构保持同步
|
||
- 思路分析:在 `user_site_roles` 和 `user_assistant_binding` 表定义中添加新字段和索引
|
||
- 修改结果:DDL 基线反映最新表结构
|
||
|
||
### `docs/database/BD_Manual_soft_delete_user_site_roles.md`
|
||
- 变更类型:新增
|
||
- 原始原因:数据库结构变更需配套 BD 手册文档
|
||
- 思路分析:记录软删除字段的用途、查询约定、索引策略
|
||
- 修改结果:为后续开发者提供软删除查询规范参考
|
||
|
||
## 合规检查
|
||
|
||
| 检查项 | 状态 |
|
||
|--------|------|
|
||
| DDL 迁移已执行 | ✅ 已在测试库执行(`new_migration_sql` 为空) |
|
||
| DDL 基线已更新 | ✅ `docs/database/ddl/zqyy_app__auth.sql` 已更新 |
|
||
| BD 手册已创建 | ✅ `docs/database/BD_Manual_soft_delete_user_site_roles.md` |
|
||
| API 文档同步 | ⚠️ `tenant_users.py` 变更需同步 `apps/backend/docs/API-REFERENCE.md` |
|
||
| OpenAPI Spec | ⚠️ 接口代码已变更但 OpenAPI spec 未同步,待手动导出 |
|