本卡屬 FR-132(母卡 CM-2510),A.3 判定層第 9 張。來源:T-3.7(CM-2529)順帶發現、首腦 2026-10-07 實查屬實。依賴:T-3.2、T-3.7 已完成。建議 model:opus。優先度高:這是現在 DEV 上就在發生的功能壞掉,A.5 前端開工前必須修。
角色的權限現在存在兩張表:舊表 role_capabilities(逐顆能力點 id)與新表 role_capability_patterns(萬用字元 pattern,T-2.2 建)。T-3.3 之後「這個人有什麼權限」只看新表。但角色頁的「新增角色」「修改角色」兩個動作還是只寫舊表、沒寫新表——結果是:在畫面上新建的角色一顆權限都沒有;改了既有角色的勾選,判定照舊用改之前的 pattern。畫面看起來存成功了,實際上沒生效,而且不報錯。
目前只有三條路會寫新表:出貨 seed(T-2.4)、建新租戶(T-2.4)、角色 JSON 匯入(T-3.7)。UI 這條漏了。
~/Projects/Jedicogy/module/jedi-python-package/jedi-iam/jedi_iam/domain/service/role_domain_service.py:87-96 add_role:只呼叫 role_capability_repo.add(舊表)
~/Projects/Jedicogy/module/jedi-python-package/jedi-iam/jedi_iam/domain/service/role_domain_service.py:99-125 update_role:delete_by_role_id 再 add(舊表);最後已有 _invalidate_expansion()(T-3.2 接的)
~/Projects/Jedicogy/module/jedi-python-package/jedi-iam/jedi_iam/domain/repository/shipped_role_writer.py:13-17 write_shipped_role(role_uid, patterns, is_system, is_template, replace=False)——寫新表的唯一入口(T-2.4 建、T-3.7 加 replace)
~/Projects/Jedicogy/module/jedi-python-package/jedi-iam/jedi_iam/api/serializers/role.py:13 角色寫入 request 的 capabilities 是 List[Integer](能力點 id)
~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/views/role-manage/RoleForm.vue:104 FE 送 cap.id 清單
~/Projects/Billows/Audit-Manager/compliance-manager-be/app/auth/service/role_transfer_service.py:120-134 T-3.7 的覆蓋寫法:update_role 之後 write_shipped_role(replace=True)——照這個 pattern 做
add_role/update_role 在寫完舊表後,把 capability_ids 轉成完整能力點名(查 capabilities 表拿 name,一個 id 一條 pattern,不要自己合成萬用字元——UI 勾的是具體能力點,逐顆寫就是正確的 pattern),呼叫 write_shipped_role(role.uid, names, is_system=False, is_template=False, replace=True)。走既有寫入器,不另寫一支寫新表的方法。_is_admin 擋停用;補一條「is_system 角色的 capabilities 不接受修改」或維持 *.*.* 不動,回寫說明選哪個。add_role 寫完新表後也要清快取(現在只有 update_role 與 delete 有 _invalidate_expansion(),新角色沒人快取過理論上不用,但寫上去避免日後改成先建後指派時漏掉)。RoleDomainService.__init__ 多接 shipped_role_writer(或 capability repo 查 name 用的 service),主專案 di_containers/auth/auth_containers.py 跟著接;漏接要炸不要靜默——沒接線時 raise,不可以「沒 writer 就跳過寫新表」。write_shipped_role 的三個既有呼叫端(seed/tenant_provisioning/role_transfer)看簽名用法;capability_domain_service 有沒有「id 清單 → name 清單」的既有方法(T-3.7 的 _capability_ids 是反向,看它用的 catalog 怎麼拿)。SELECT pattern FROM role_capability_patterns WHERE role_id=<新角色> 剛好 3 列;把這角色指派給測試帳號,該帳號打對應端點 200、未勾的 403。修改勾選後新表同步變、判定同步變(T-3.2 快取清掉)。