# 变更审计记录（Change Audit Record）

- 日期/时间：2026-03-23 08:00:00
- Prompt-ID：P20260323-role-routing
- 原始原因：用户要求按角色区分登录后跳转页面、tab-bar 可见性、全页面权限守卫，新增 head_coach（教练）和 manager（管理员）两个角色
- 直接原因：小程序原有逻辑所有用户统一跳转同一页面，无角色区分；页面无权限守卫，手动输入路径可绕过

## 变更范围（Changed）

- 数据库：`auth.roles` 新增 head_coach、manager 两条角色记录及对应 `auth.role_permissions` 映射
- 后端 API：`/api/xcx/me`、`/api/xcx/login`、`/api/xcx/dev-login` 返回 `role` 字段
- 后端 Schema：`WxLoginResponse`、`UserStatusResponse` 增加 `role` 字段
- 小程序全局：`app.ts` checkAuthStatus 按状态路由，disabled 强制登出
- 小程序权限守卫：新建 `utils/auth-guard.ts`，包含角色→tab 映射、角色→首页映射、页面→角色权限矩阵、checkPageAccess 函数
- 小程序 tab-bar：从 `globalData.visibleTabs` 动态读取可见 tab
- 小程序登录页：登录成功后保存 role、syncVisibleTabs、按角色跳转
- 小程序 15 个业务页面：onShow 添加 checkPageAccess 守卫
- 小程序 3 个状态页（apply/reviewing/no-permission）：approved 跳转改为 getRoleHome(role)
- 全局类型：`authUser` 增加 `role`，`globalData` 增加 `visibleTabs`
- BD 手册：更新 `BD_Manual_auth_tables.md` 角色从 4 条到 6 条

## 风险与回滚（Risk & Rollback）

- 风险点：
  - checkPageAccess 每次 onShow 都请求 `/api/xcx/me`，高频页面切换可能增加后端压力（后续可加缓存/节流）
  - 角色为空时 tab 只显示"我的"，新用户首次登录如果后端未返回 role 会只看到我的页
  - 迁移脚本依赖 `auth.roles` 和 `auth.permissions` 表已存在
- 回滚要点：
  - 数据库：执行 `DELETE FROM auth.role_permissions WHERE role_id IN (SELECT id FROM auth.roles WHERE code IN ('head_coach','manager')); DELETE FROM auth.roles WHERE code IN ('head_coach','manager');`
  - 后端：移除 schema 中 role 字段、路由中角色查询逻辑
  - 小程序：移除 auth-guard.ts、各页面 checkPageAccess 调用、恢复 app.ts/login.ts/apply.ts/reviewing.ts/no-permission.ts 原有跳转逻辑

## 验证（Verification）

1. 数据库验证：`SELECT code, name FROM auth.roles ORDER BY id;` 应返回 6 条（coach, staff, head_coach, manager, site_admin, tenant_admin）
2. 后端验证：调用 `GET /api/xcx/me`，approved 用户响应应包含 `role` 字段
3. 小程序验证：
   - coach 角色登录 → 跳转任务页，tab 只显示"任务+我的"
   - staff 角色登录 → 跳转看板页，tab 只显示"看板+我的"
   - head_coach/manager 角色登录 → 跳转看板页，tab 显示"任务+看板+我的"
   - coach 手动访问看板页 → 被守卫拦截跳回任务页
   - staff 手动访问任务页 → 被守卫拦截跳回看板页
   - 账号被禁用 → 任何页面 onShow 触发强制登出

## 文件清单（Files changed）

| 文件 | 操作 |
|------|------|
| `db/zqyy_app/migrations/2026-03-23__add_head_coach_manager_roles.sql` | 新建 |
| `apps/backend/app/schemas/xcx_auth.py` | 修改 |
| `apps/backend/app/routers/xcx_auth.py` | 修改 |
| `apps/miniprogram/typings/index.d.ts` | 修改 |
| `apps/miniprogram/miniprogram/utils/auth-guard.ts` | 新建 |
| `apps/miniprogram/miniprogram/custom-tab-bar/index.ts` | 修改 |
| `apps/miniprogram/miniprogram/app.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/login/login.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/apply/apply.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/reviewing/reviewing.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/no-permission/no-permission.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/task-list/task-list.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/task-detail/task-detail.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/notes/notes.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/performance/performance.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/performance-records/performance-records.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/board-finance/board-finance.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/board-customer/board-customer.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/board-coach/board-coach.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/customer-detail/customer-detail.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/customer-service-records/customer-service-records.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/coach-detail/coach-detail.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/chat/chat.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/chat-history/chat-history.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/my-profile/my-profile.ts` | 修改 |
| `apps/miniprogram/miniprogram/pages/dev-tools/dev-tools.ts` | 修改 |
| `docs/database/BD_Manual_auth_tables.md` | 修改 |
