走查发现 manager(店长)进入小程序"任务"tab 收到 403 "权限不足"。
根因不在 require_permission(权限校验通过,missing=set()),而在
task_manager._get_assistant_id() 因 user_assistant_binding 无有效绑定
抛 403 "权限不足"(detail 与权限错误同名,误导走查方向)。
设计层冲突:task-list 是助教个人工作台业务概念,manager 没有"我自己
的任务"业务场景,监督需求由 board-coach 等汇总看板覆盖。
Neo 决策(2026-05-05):
> "任务的 tab 只有助教身份的用户可以进入并查看,让管理身份的用户
> 进入没有意义。因为他们使用业务场景中不存在任务方面的场景。"
→ 选 B 方案:权限矩阵层移除 manager 的 view_tasks。
变更:
- db/zqyy_app/migrations/20260505__remove_manager_view_tasks.sql
DELETE FROM auth.role_permissions WHERE role_id=manager AND permission_id=view_tasks
- docs/database/changes/2026-05-05__remove_manager_view_tasks.md
完整变更说明 + 兼容性 + 4 条校验 SQL + 幂等回滚
测试库执行 + 4 条校验全 PASS:
- manager 改前 5 项权限,改后 4 项(view_board* 保留)
- view_tasks 现绑定到 [coach, head_coach](manager 已剥离)
- coach / head_coach 助教工作台不受影响
- 典型 manager 用户 Neo (8778) 实际权限不再含 view_tasks
双口径走查(weixin-devtools-mcp):
- 4a live: relaunch 后 visibleTabs 从 [task, board, my] → [board, my]
小程序 tabBar"任务"tab 自动隐藏(getVisibleTabs 基于权限自动重算)
- 强制调 GET /api/xcx/tasks 仍 403,但根因从 _get_assistant_id 错位
转为 require_permission 正确拦截,语义清晰
不改的部分:
- task_manager._get_assistant_id() 不动(仍用于 coach/head_coach)
- require_permission("view_tasks") 路由保护不动(仍合理)
- 前端 auth-guard.ts 不改(getVisibleTabs 已基于 permissions 自动)
正式库同步说明:
- 本次仅在测试库执行,生产环境同步时 psql 执行 migration + 跑校验 SQL
审计:
- docs/audit/changes/2026-05-05__wave1_f1_5b_be1_task_list_403_root_cause.md
含完整证据链 + 三方案 ABC 业务影响对比 + B 实施记录
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
38 lines
1.7 KiB
PL/PgSQL
38 lines
1.7 KiB
PL/PgSQL
-- 2026-05-05
|
|
-- F1-5b BE-1: manager 角色去除 view_tasks 权限
|
|
--
|
|
-- 背景: Wave 1 走查发现 manager 角色用户进入 task-list 页面收到 403 "权限不足"。
|
|
-- 根因定位: require_permission 通过,但 task_manager._get_assistant_id 因
|
|
-- manager 在 user_assistant_binding 无有效绑定而抛 403,detail 与权限错误同名。
|
|
--
|
|
-- 设计决策(Neo 2026-05-05): task-list 是助教个人工作台业务概念,
|
|
-- manager(店长)角色没有"我自己的任务"业务场景,监督需求由 board-coach
|
|
-- 等汇总看板覆盖。从权限矩阵层面移除 manager 的 view_tasks。
|
|
--
|
|
-- 影响:
|
|
-- - manager 登录后小程序 tabBar 不再显示"任务" tab(getVisibleTabs 自动隐藏)
|
|
-- - manager 直接调用 GET /api/xcx/tasks 仍返回 403,但根因变为 require_permission
|
|
-- 拦截而非 _get_assistant_id 的语义错位
|
|
-- - coach / head_coach 角色 view_tasks 权限不变,助教工作台正常使用
|
|
--
|
|
-- 兼容性:
|
|
-- - 不改 schema,仅 seed 数据 DELETE
|
|
-- - 已登录的 manager 用户 access_token 中 roles=[manager] 不变,但下次请求
|
|
-- /api/xcx/me 拿到的 permissions 列表立即少了 view_tasks(get_user_permissions
|
|
-- 每次请求都查 DB,无缓存)
|
|
-- - 前端 tabBar 在 onShow 时调 checkPageAccess + getVisibleTabs 重算,自动隐藏
|
|
--
|
|
-- 回滚:
|
|
-- INSERT INTO auth.role_permissions (role_id, permission_id)
|
|
-- SELECT
|
|
-- (SELECT id FROM auth.roles WHERE code = 'manager'),
|
|
-- (SELECT id FROM auth.permissions WHERE code = 'view_tasks');
|
|
|
|
BEGIN;
|
|
|
|
DELETE FROM auth.role_permissions
|
|
WHERE role_id = (SELECT id FROM auth.roles WHERE code = 'manager')
|
|
AND permission_id = (SELECT id FROM auth.permissions WHERE code = 'view_tasks');
|
|
|
|
COMMIT;
|