本卡屬 FR-132(母卡 CM-2510),A.2 資料地基第 2 張。依賴:T-2.1。建議 model:fable。
角色今天存的是一筆一筆的能力點 id(role_capabilities)。新做法存的是 pattern 字串(萬用字元寫法,例 grc.project.*、*.*.read;一個完整名本身也是 pattern)。這張卡建新表 role_capability_patterns,把每個既有角色的每個能力點原樣轉成一筆完整名 pattern,角色能做的事一個都不能多、不能少。
另外依定案規則挑出每個租戶的「內建系統管理員」轉成 *.*.*。migration 結尾逐角色比對轉換前後的能力點集合,任何一個角色不一致就整支回滾——這是全案最關鍵的一支 migration,升級客戶舊資料靠它。
~/Projects/Billows/Audit-Manager/compliance-manager-be/scripts/sql/<日期>-fr132-role-capability-patterns.sql 新 migration
~/Projects/Jedicogy/module/jedi-python-package/jedi-iam/jedi_iam/infra/models/role_capability.py:14-23 舊表 role_capabilities(保留一版)
~/Projects/Jedicogy/module/jedi-python-package/jedi-iam/jedi_iam/infra/models/role.py:23-84 roles,is_admin int;加 is_system、is_template
~/Projects/Billows/Audit-Manager/compliance-manager-be/core/plugins/identity.py:89-95 TENANT_ADMIN_EXCLUDED_RESOURCE_TYPES(*.*.* 展開要扣)
role_capability_patterns(role_id int REFERENCES roles(id) ON DELETE CASCADE, pattern varchar(100) NOT NULL, PRIMARY KEY(role_id, pattern));GRANT ... TO cm_app;RLS 照 role_capabilities 現有 policy 抄(先 \d+ public.role_capabilities 看)。ORM 在 jedi-iam 新增 model。roles 加欄 is_system bool NOT NULL DEFAULT false(內建,不可刪不可改)、is_template bool NOT NULL DEFAULT false(出貨範例)。*,* 只能整段(不支援 grc.proj*)。加 CHECK 約束擋格式。role_capabilities 轉成一筆 pattern=該能力點的新名(T-2.1 已改名)。is_admin 角色轉換規則(定案):租戶內「能力點=該租戶全集」的 is_admin 角色轉內建系統管理員:pattern 換成單一 *.*.*、設 is_system = true;同一租戶有多個符合時取最早建(id 最小或 created_at 最早)的那個。其餘 is_admin 角色保留旗標、能力點原樣轉完整名,不升級成 *.*.*。*.*.* 展開的定義:非 root 租戶=全部能力點扣 is_platform = true 與 resource_type 在排除清單(cruise-project、dashboard、workflow、resource、report)的;root 租戶=全部。DEV 預期 123 − 16 − 4 = 103(以 T-2.1 後實際數為準)。授權照不在展開時扣。EXCEPT 雙向比對,任一角色不一致 RAISE EXCEPTION 列出角色 id 與差集——整支在 --single-transaction 內回滾。展開用 SQL 寫(* 段比對用 split_part)。role_capabilities 不刪不改,並存一版(D2)。*.*.*),確認自檢擋下並回滾。ROLLBACK,不要留痕。SELECT role_id, count(*) FROM role_capability_patterns GROUP BY 1 與舊表筆數相符(系統管理員除外為 1)。