本卡屬 FR-114 資安修正(母卡 CM-2019),189 升級 1.21.0 手測撞到、首腦以升級前備份差集實證,收集卡 CM-2231 #42。每條升級路徑都會踩,b5 必修。只改 BE 主線一支模板+補守衛測試;189/190 資料還原由首腦另做。
安裝版每次升級尾端(migrate.sh 第三輪)會跑一支「角色回補」SQL,用意是:既有租戶的管理員角色補上新版才出現的能力點,不然升級後管理員看不到新功能。但它判斷「哪個角色是管理員」的方法是**「誰持有 flow_template.create(建流程範本)這個能力點」,而不是角色表本來就有的 roles.is_admin 旗標。任何一般角色只要曾被手動勾過那一個能力點,升級時就被當管理員,一次塞進全部**非平台能力點(含租戶/角色/使用者/LDAP/SMTP 的增刪改)。
首腦已核的證據:189 升級前備份(189:~/guidant-backup-1.19.0-before-1.21.0-20260928_1059.dump,首腦還原到本機 tmp_189_pre)比對升級後:IT Manager(id=4,is_admin=0)89→98 個能力點,多出 tenant./audit./feedback.export 等 15 個;專案管理員(PM)(id=5,is_admin=0)58→98,多出 45 個(含 role./ldap-config./smtp-config./storage-config. 全部)。兩者升級前都持有 flow_template.create。190 的專案管理員-PM(id=7)同樣 98。188 只有 System Manager(is_admin=1)持有,未中。新租戶建立時的邏輯(jedi-iam tenant_provisioning_service.py:149)本來就是用 roles.is_admin = 1,回補這支跟它不一致。
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/.claude/worktrees/wt-fix-security/scripts/init/migrate-capability-grants.sql:59-90 (b) 段::72 計數與 :81 INSERT 子查詢都用 b.name = 'flow_template.create' 推導管理員角色
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/.claude/worktrees/wt-fix-security/scripts/build/flatten_pkg_migrations.sh:261-285 模板 → scripts/sql/packages/_capability_grants.sql 產物(build 期產、不入版控)
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/.claude/worktrees/wt-fix-security/scripts/init/migrate.sh:38-70 第三輪:每次升級都跑、不登記
對照(正確判準):jedi-iam jedi_iam/app/service/tenant_provisioning_service.py:149 roles.is_admin = 1
SELECT ro.id FROM public.roles ro WHERE ro.tenant_id <> 1 AND ro.is_delete = 0 AND ro.is_admin = 1,不再 JOIN role_capabilities 找 flow_template.create。檔頭「前置」段提到 flow_template.create 要先存在那句一併刪掉,(b) 段註解改寫成「用 is_admin 旗標,與新租戶建立邏輯一致;曾用能力點反推,會把手動勾過該點的一般角色誤判成管理員(189 2026-09-28 實例)」。test/test_capability_grants_template_uses_is_admin.py:讀模板檔,斷言 (b) 段含 is_admin = 1 且不含 flow_template.create;再一條用 DEV 真跑:建一個 is_admin=0 但持有 flow_template.create 的臨時角色,套模板(先 sed 佔位符)後斷言它的能力點數不變、is_admin=1 的角色有補到;用完刪臨時角色。突變:把子查詢改回舊寫法要紅。scripts/build/flatten_pkg_migrations.sh 相關段(或手動 sed 佔位符)產出 _capability_grants.sql,用 cmmgr 對 DEV 套一次;套前後各查一次 select r.id,r.name,r.is_admin,count(rc.*) from roles r left join role_capabilities rc on rc.role_id=r.id where r.tenant_id<>1 group by r.id,is_admin=0 的角色數量不變、is_admin=1 的只增不減。docs/user-manual/onprem-html/)若有寫「回補會補齊管理員角色」,補一句判準是角色的「管理員」旗標。git add <檔名>,禁 -am。不發版、不 push、不切 branch。