Files
Neo-ZQYY/docs/audit/changes/2026-03-23__tenant-admin-review-modal-dynamic-roles.md
Neo 14a12342b5 chore(audit): 补追 96 份未入仓审计孤本 — 覆盖 2026-02-26 ~ 2026-04-08
这些审计记录原本堆积在 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>
2026-04-20 06:35:42 +08:00

7.4 KiB
Raw Blame History

变更审计记录:租户管理后台审核弹窗改造(角色动态化 + 人员列表联动 + 手机号自动匹配)

字段
日期 2026-03-23 17:00:00
Prompt-ID P20260323-164500
Session-ID 545eba0a
Session 路径 docs/audit/session_logs/2026-03/23/18_57a8dd3c_164506

操作摘要

改造 tenant-admin 审核弹窗实现角色下拉从数据库动态读取不硬编码、选择角色后联动查询人员列表coach→ETL 助教表其他→ETL 员工表)、手机号自动匹配、提供"无"选项。后端新增 2 个 API 端点(GET /api/tenant/rolesGET /api/tenant/site-staff)和 2 个 SchemaRoleItemStaffCandidate)。前端 ReviewModal 组件全面改造。修复前端语法错误(中文引号与 JSX 双引号冲突、filterOption 类型断言)。

关键技术决策:不用 FDW 视图(fdw_etl.v_dim_assistant),因为 FDW 视图的 RLScurrent_setting('app.current_site_id'))在跨库场景下不生效。改用 get_etl_readonly_connection(site_id) 直连 ETL 库查底层表 dwd.dim_assistant / dwd.dim_staff,手动加 site_id 过滤。

变更范围

  • 模块:apps/backend/FastAPI 路由 + Schemaapps/tenant-admin/React 前端)
  • 接口:新增 GET /api/tenant/rolesGET /api/tenant/site-staff
  • 数据源:auth.roles(业务库)、dwd.dim_assistant / dwd.dim_staffETL 库直连)

风险与回滚

  • 风险ETL 直连依赖 get_etl_readonly_connection 可用性;角色表数据变更影响下拉列表;site-staff 端点 site_code→site_id 转换依赖 biz.sites 数据一致性
  • 回滚:删除 2 个新端点(/roles/site-staff+ 2 个新 SchemaRoleItemStaffCandidate);前端恢复原 ReviewModal 硬编码版本

验证

  • 访问 tenant-admin http://localhost:5174 → 用户审批页 → 点击审核 → 确认角色下拉动态加载 4 个角色
  • 选择 coach 角色 → 确认人员列表从 ETL 助教表加载
  • 选择 staff/head_coach/manager → 确认人员列表从 ETL 员工表加载
  • 选择"无" → 确认可以提交
  • 前端无编译错误Vite HMR 正常)

文件清单

文件 变更类型 说明
apps/backend/app/routers/tenant_users.py 修改 新增 GET /rolesGET /site-staff 端点
apps/backend/app/schemas/tenant_users.py 修改 新增 RoleItemStaffCandidate schema
apps/tenant-admin/src/pages/UserApproval/index.tsx 修改 ReviewModal 组件改造(角色动态化、人员联动、手机号匹配、"无"选项、语法修复)

本次对话文件变更

新增文件

  • docs/audit/prompt_logs/prompt_log_20260323_165704.md
  • docs/audit/session_logs/2026-03/23/18_57a8dd3c_164506/main_01_545eba0a.md
  • docs/audit/session_logs/2026-03/23/18_57a8dd3c_164506/sub_01_545eba0a.md
  • docs/audit/session_logs/2026-03/23/17_bc427aef_161938/main_01_6c7c8174.md
  • docs/audit/session_logs/2026-03/23/17_bc427aef_161938/sub_01_545eba0a.md

修改文件

  • apps/backend/app/routers/tenant_users.py
  • apps/backend/app/schemas/tenant_users.py
  • apps/tenant-admin/src/pages/UserApproval/index.tsx
  • NeoZQYY.code-workspace

删除文件

  • docs/audit/session_logs/2026-03/23/17_bc427aef_161938/main_01_e69d704e.md

改动注解

apps/backend/app/routers/tenant_users.py

  • 变更类型:修改
  • 原始原因:原审核弹窗角色硬编码在前端,无法适应角色增减;人员列表无联动查询,审核时无法关联助教/员工。用户要求角色从数据库动态读取,并根据角色+门店查询对应人员列表。
  • 思路分析:新增 GET /api/tenant/roles 端点,从 auth.roles 表动态读取小程序可用角色(排除 tenant_admin/site_admin 管理类角色),返回 RoleItem 列表。新增 GET /api/tenant/site-staff 端点,接收 role + site_id/site_code 参数,根据角色类型分流查询:coach 查 ETL 库 dwd.dim_assistantscd2_is_current=1),其他角色查 dwd.dim_staff。关键决策:放弃 FDW 视图RLS 跨库不生效),改用 get_etl_readonly_connection(site_id) 直连 ETL 库底层表,手动加 site_id 过滤。site-staff 端点支持 site_code 参数(前端传球房编号),内部先查 biz.sites 转换为 site_id,再校验权限。
  • 修改结果:租户管理员审核时可动态获取角色列表和对应人员列表。site_adminmanaged_site_ids 权限限制,tenant_admin 可查所有店铺。ETL 直连方案绕过了 FDW RLS 跨库失效问题。

apps/backend/app/schemas/tenant_users.py

  • 变更类型:修改
  • 原始原因:后端新增 2 个端点需要对应的响应 Schema。
  • 思路分析:新增 RoleItem角色列表项id/code/name/descriptionStaffCandidate人员候选项id/identity_label/name/mobile/entry_time/sourceStaffCandidate.source 字段标识数据来源(assistant/staff),前端据此构造 staffBinding 值(格式 "source:id")。identity_label 统一承载助教的 level 和员工的 staff_identity 原始值。
  • 修改结果:两个新 Schema 继承 CamelModel,自动 snake_case→camelCase 转换,与前端 TypeScript 接口定义对齐。

apps/tenant-admin/src/pages/UserApproval/index.tsx

  • 变更类型:修改
  • 原始原因:前端 ReviewModal 组件角色下拉硬编码 3 个角色coach/staff/site_admin缺少 head_coach/manager且 site_admin 不应出现在小程序角色中。人员关联只有旧的 match-suggestions按手机号匹配无法列出全部人员供选择。
  • 思路分析:角色下拉改为弹窗打开时调用 GET /api/tenant/roles 动态获取。新增 handleRoleChange 回调:角色变化时调用 GET /api/tenant/site-staff 获取人员列表,加载后按申请者手机号自动选中匹配项(前端逻辑)。人员下拉展示格式 身份角色 - 姓名 - 手机号 - 入职时间,首项为"无(不关联)"。staffBinding 值格式 "source:id"(如 "assistant:123")或 "none",提交时解析为 assistantId/staffId。修复两个语法问题:中文引号 "无" 与 JSX 双引号冲突(改用单引号包裹);filterOptionoption?.label 类型断言(改用 String() 包装)。
  • 修改结果审核弹窗角色下拉动态化4 个小程序角色),人员列表按角色+门店联动查询,手机号自动匹配,支持"无"选项。前端编译通过Vite HMR 正常。

合规检查

文档同步

  • ⚠️ apps/backend/app/routers/tenant_users.py 新增 2 个端点后 apps/backend/docs/API-REFERENCE.mddocs/contracts/openapi/backend-api.json 需同步更新
  • 新增端点 GET /api/tenant/rolesGET /api/tenant/site-staff 需补充到 API 文档

OpenAPI Spec

  • 接口代码已变更OpenAPI spec 需重新导出(python scripts/ops/_export_openapi.py

DDL/迁移

  • 无新增迁移 SQL
  • ⚠️ DDL 基线待合并

DB 文档

  • 本次无数据库结构变更BD 手册无需更新