A.1 盤點:platform 平台層端點 × 三段式能力點

卡片 CM-2515(FR-132 T-1.5)。唯讀盤點,不改程式、不改 DB。

§1

範圍與數量

  • 範圍:AI 儀表板(ai-dashboard)、AI 呼叫紀錄(ai-call-log)、AI 額度(ai-quota)、公告(bulletin、bulletin-list)、意見回饋(feedback、feedback-view)、操作紀錄(log)、支援頁(診斷包、最近錯誤)。另把卡片「怎麼做」列到的 AI 小幫手(jedi-ai-bot)一併盤。
  • 主專案 route 檔 4 支、15 個 method:api/ai_quota/ 1 支(7)、api/ai_call_log/ 1 支(5)、api/support/ 2 支(2)。
  • 外部套件 route 檔 6 支、20 個 method:jedi-ai-dashboard 1 支(2)、jedi-ai-bot 1 支(2)、jedi-bulletin 1 支(5)、jedi-issue 2 支(8,含標籤下拉)、jedi-log api_log 1 支(2)。讀的是 .venv/lib/python3.11/site-packages/ 內實際執行的版本(ai-dashboard 1.6.1、ai-bot 1.5.0、bulletin 1.2.1、issue 1.3.2、log 1.3.2)。jedi-log 的 forwarding(log 轉發設定)屬 T-1.4 系統設定,不列。
  • 合計 10 支檔、35 個 method。
  • DEV 查詢時間:2026-10-06 17:28(本機 localhost:5432/guidant_ai_dev)。範圍內舊能力點 16 個;全庫能力點 123 個,其中 is_platform = true 16 個。
§2

先看這幾點

  1. 「16 個平台層能力點」跟本卡的資源幾乎沒有交集。 DEV 的 16 個 is_platform 能力點只有 log.read 在本卡範圍;其餘 15 個是合規框架(3)、外部議題整合設定(4)、授權(1)、通用系統設定(3)、系統選單(4),分屬 T-1.2 與 T-1.4。本卡範圍的 16 個舊能力點裡,15 個是 is_platform = false。16 這個數字對(123 − 16 − 4 = 103 成立),但「平台層能力點集中在 platform 模組」這個前提不成立。逐一對照見文末「附錄:16 個 is_platform 能力點」。
  2. 所以「platform(原廠)」這個模組名放錯了大半內容。 AI 儀表板、AI 額度、AI 呼叫紀錄是租戶自己用、自己管的;公告是租戶對自己部門發的;意見回饋是租戶成員自己送、租戶管理員看全部。真正只有原廠(root 租戶)能碰的,只有操作紀錄、支援頁、AI 額度的「各租戶上限」三塊。建議見「待首腦裁清單」第 1~3 條。
  3. 原廠層的後端守門走的是「平台管理員」判定,不是能力點。 操作紀錄(platform_admin_required)、支援頁(service 層 require_platform_admin())、AI 額度上限(同上)三塊,沒有一支 route 檢查能力點;log.read 只決定選單看不看得到。平台層要不要也改成能力點守門,見待裁第 4 條。
  4. 公告列表有一個疑似缺口:POST /bulletins 只驗登入,「看哪些公告」由請求帶不帶 auth: true 決定。不帶、且使用者沒有所屬部門時,service 不下任何條件,等於看到本租戶全部公告(不受發送範圍限制)。見「確認要補的守門缺口」第 1 條。
  5. feedback.export 不是孤兒:匯出端點 POST /feedback/export/<type> 由它守(jedi_issue/api/routes/feedback_route.py:140),DEV 有 5 個角色持有。它只是沒綁任何頁面選單;FE 匯出鈕不判權限、一律顯示,沒權限的人按了才 403。
§3

新名總覽(定案)

模組歸屬依決策者 2026-10-06 的八條定案填(見文末「定案結論」)。

新資源 read create update delete 獨立動詞 取代的舊名 模組歸屬狀態
ai.dashboard ✓ ✓ ✓ ✓ — ai-dashboard.read ai 模組
ai.call-log ✓ ✓ ✓ ✓ export ai-call-log.read ai 模組
ai.quota ✓ ✓ ✓ ✓ — ai-quota.read、ai-quota.update ai 模組
ai.assistant ✓ ✓ ✓ ✓ — 無(小幫手今天只驗登入) ai 模組
workspace.bulletin ✓ ✓ ✓ ✓ — bulletin.*、bulletin-list.read workspace 模組
workspace.feedback ✓ ✓ ✓ ✓ export feedback.*(5 個) workspace 模組
workspace.feedback-review ✓ —(破例只開 read) —(破例只開 read) —(破例只開 read) — feedback-view.read workspace 模組
platform.api-log ✓ ✓ ✓ ✓ export log.read platform,is_platform = true
platform.support ✓ ✓ ✓ ✓ export 無(今天沿用 storage-config.* 綁選單) platform,is_platform = true
platform.ai-quota-ceiling ✓ ✓ ✓ ✓ — 無(今天只驗平台管理員) platform,is_platform = true
  • 「每個資源固定四個」照規則全開(feedback-review 例外,見定案第 8 條);今天沒有對應端點的動詞(例如 ai.call-log.create)仍要建出來。
  • is_platform 欄位:只有 platform.* 三組為 true,其餘 false。
§4

主表

欄位:route 路徑 | HTTP | 程式位置 | 現有守門 | 新三段名 | 現有能力點 | is_platform(新名)| 對應 UI | 可指派範圍層 | 備註。

守門縮寫:J=jwt_required;L(x)=require_license("x");C(x)=require_capability("x") 或套件的 capability_required;PA=平台管理員(require_platform_admin/platform_admin_required);S: 後面是 service 層的檢查。路徑前綴一律 /api/1.0。套件路徑省略 .venv/lib/python3.11/site-packages/。

AI 儀表板(ai.dashboard)

route 路徑 HTTP 程式位置 現有守門 新三段名 現有能力點 is_platform 對應 UI 範圍層 備註
/ai-dashboard/health GET 套件 jedi_ai_dashboard/api/routes/ai_dashboard_route.py:71 無(刻意免登入) 不開能力點 無 — DynamicDashboard.vue(useDashboardGenerator.js) — 頁面載入時還沒 token 也要能回「小幫手上線了沒」;套件 api/routing.py:17-27 與套件測試焊死這個分工,不要補守門
/ai-dashboard/auto-generate POST ai_dashboard_route.py:110 J(掛載期 _guarded)+L(ai-dashboard)+C(ai-dashboard.read) ai.dashboard.read ai-dashboard.read false DynamicDashboard.vue(選單 /dashboard/ai-dashboard) tenant 每次實打兩次外部 AI;能力點名由套件 jedi_ai_dashboard/plugin/contract.py:25 的 GENERATE_CAPABILITY 決定。生成是「看儀表板」的動作,維持 read

套件守門 jedi_ai_dashboard/api/guards.py:license 與能力點都委派宿主注入(core/plugins/ai_dashboard.py:89-91),宿主沒接線一律拒絕,不放行。

AI 小幫手(ai.assistant)

route 路徑 HTTP 程式位置 現有守門 新三段名 現有能力點 is_platform 對應 UI 範圍層 備註
/ai-chatbot POST 套件 jedi_ai_bot/api/routes/ai_bot_route.py:39 J(jedi_ai_bot/plugin/assembly.py:70,宿主 core/plugins/ai_bot.py:87) ai.assistant.read 無 false ChatBox.vue(AppLayout 右下角,全站) tenant 待裁第 6 條。只受 AI 額度限制;套件 CAPABILITIES 是空的(jedi_ai_bot/plugin/contract.py:35),也沒有 license 軸
/ai-chatbot DELETE ai_bot_route.py:71 J ai.assistant.read 無 false 同上(清對話紀錄) tenant 只清自己的 session,跟使用歸同一個

AI 呼叫紀錄(ai.call-log)

route 路徑 HTTP 程式位置 現有守門 新三段名 現有能力點 is_platform 對應 UI 範圍層 備註
/system/ai-call-logs POST api/ai_call_log/routes/ai_call_log_route.py:46 J+C(ai-call-log.read) ai.call-log.read ai-call-log.read false AiCallLogList.vue(選單 /system/ai-call-log) tenant 列表;租戶隔離靠 RLS
/system/ai-call-logs/<uid> GET ai_call_log_route.py:58 J+C(ai-call-log.read) ai.call-log.read ai-call-log.read false AiCallLogList.vue(明細) tenant
/system/ai-call-logs/export POST ai_call_log_route.py:68 J+C(ai-call-log.read) ai.call-log.export ai-call-log.read false AiCallLogList.vue tenant 今天跟 read 同一顆;建議拆出 export(對外送出類),客戶可做到「看得到但不能整批帶走」
/system/ai-call-logs/usage POST ai_call_log_route.py:91 J+C(ai-call-log.read);S: tenant_id 篩選限平台管理員 ai.call-log.read ai-call-log.read false AiUsageSummary.vue tenant 用量彙總
/system/ai-call-logs/usage/export POST ai_call_log_route.py:102 J+C(ai-call-log.read) ai.call-log.export ai-call-log.read false AiUsageSummary.vue tenant 同上 export

基礎設施豁免:common/authz/license.py:116 把 ai-call-log 列在不受授權照管制的清單,改名時這個字串要跟著改。

AI 額度(ai.quota/platform.ai-quota-ceiling)

route 路徑 HTTP 程式位置 現有守門 新三段名 現有能力點 is_platform 對應 UI 範圍層 備註
/system/ai-quota GET api/ai_quota/routes/ai_quota_route.py:28 J;S: C(ai-quota.read)(app/ai_quota/service/ai_quota_setting_service.py:88) ai.quota.read ai-quota.read false AiQuotaPage.vue(選單 /system/ai-quota) tenant route 層只驗登入(卡上說的「J 組」),守門在 service;本身不是缺口
/system/ai-quota PUT ai_quota_route.py:34 J;S: C(ai-quota.update)(:93) ai.quota.update ai-quota.update false 同上 tenant
/system/ai-quota DELETE ai_quota_route.py:40 J;S: C(ai-quota.update)(:107) ai.quota.update ai-quota.update false 同上(「還原預設」鈕) tenant HTTP 是 DELETE,語意是把設定改回繼承,歸 update
/system/ai-quota/me GET ai_quota_route.py:70 J;S: 無(只回自己的) 不掛守門 無 — AiQuotaBanner.vue、ChatBox.vue、AutoClassifyBatch.vue、AiQuotaUsageCards.vue(useAiQuota.js) tenant 個人視角:額度 80% 黃條。掛 ai.quota.read 的話一般成員會 403,見待裁第 2 條
/system/ai-quota/tenants GET ai_quota_route.py:48 J;S: PA(ai_quota_setting_service.py:118) platform.ai-quota-ceiling.read 無 true AiQuotaCeilingTable.vue(AiQuotaPage 內,平台管理員才顯示) tenant(root 限定) 跨租戶總覽
/system/ai-quota/tenants/<id>/ceiling GET ai_quota_route.py:56 J;S: PA(:151,_assert_ceiling_target) platform.ai-quota-ceiling.read 無 true 同上 tenant(root 限定)
同上 PUT ai_quota_route.py:62 J;S: PA(同上) platform.ai-quota-ceiling.update 無 true 同上 tenant(root 限定)

基礎設施豁免:common/authz/license.py:118(ai-quota)。

公告(workspace.bulletin)

route 路徑 HTTP 程式位置 現有守門 新三段名 現有能力點 is_platform 對應 UI 範圍層 備註
/bulletins POST 套件 jedi_bulletin/api/routes/bulletin_route.py:37 J;S: 依請求的 auth 旗標分兩種模式(jedi_bulletin/app/service/bulletin_service.py:234-251) workspace.bulletin.read 無(選單綁 bulletin-list.read/bulletin.read) false BulletinList.vue(view=true,帶 auth:true,選單 /bulletin/bulletin-list);BulletinManage.vue(管理模式,選單 /bulletin/bulletin-manage) org_unit 讀者模式只看發給自己部門的;管理模式只看自己建的。模式由前端決定,見缺口第 1 條
/bulletin/<uid> GET bulletin_route.py:58 J;S: 檢查發送範圍(帶 current_user_context()) workspace.bulletin.read 無 false BulletinView.vue org_unit
/bulletin POST bulletin_route.py:103 J+C(bulletin.create) workspace.bulletin.create bulletin.create false BulletinForm.vue org_unit 能力點名由套件 jedi_bulletin/plugin/contract.py:41-43 預設值決定
/bulletin/<uid> PUT bulletin_route.py:70 J+C(bulletin.update) workspace.bulletin.update bulletin.update false BulletinForm.vue org_unit
/bulletin/<uid> DELETE bulletin_route.py:81 J+C(bulletin.delete) workspace.bulletin.delete bulletin.delete false BulletinManage.vue org_unit

套件沒有 license 軸。bulletin.read 與 bulletin-list.read 兩顆舊名,後端沒有任何 route 守,只綁選單。

意見回饋(workspace.feedback/workspace.feedback-review)

route 路徑 HTTP 程式位置 現有守門 新三段名 現有能力點 is_platform 對應 UI 範圍層 備註
/feedbacks POST 套件 jedi_issue/api/routes/feedback_route.py:50 J+C(feedback.read 或 feedback-view.read 任一);S: 有 feedback-view.read 看全部,否則只看自己送的(jedi_issue/app/feedback/service/feedback_service.py:160-173) workspace.feedback.read;看全部要 workspace.feedback-review.read feedback.read、feedback-view.read false SystemFeedbackManage.vue(FeedbackManageTabView,選單 /feedback/system-feedback-manage 與 /feedback/system-feedback-view) tenant 「看自己的」與「看全部人的」在同一支端點,由能力點切範圍
/feedback/<uid> GET feedback_route.py:73 J+C(同上任一) workspace.feedback.read 同上 false SystemFeedbackView.vue、SystemFeedbackForm.vue tenant 單筆讀取有沒有檢查「是不是自己的」未逐行核
/feedback POST feedback_route.py:81 J+C(feedback.create) workspace.feedback.create feedback.create false SystemFeedbackForm.vue tenant
/feedback/<uid> PUT feedback_route.py:97 J+C(feedback.update);S: 只能改自己送的(_assert_owner) workspace.feedback.update feedback.update false SystemFeedbackForm.vue tenant
/feedback/<uid> DELETE feedback_route.py:115 J+C(feedback.delete);S: 只能刪自己的 workspace.feedback.delete feedback.delete false SystemFeedbackManage.vue tenant
/feedback/file/<uid>/<file_uid> DELETE feedback_route.py:127 J+C(feedback.update) workspace.feedback.update feedback.update false SystemFeedbackForm.vue tenant 刪附件=改回饋內容
/feedback/export/<type> POST feedback_route.py:141 J+C(feedback.export) workspace.feedback.export feedback.export false SystemFeedbackManage.vue(匯出鈕不判權限、一律顯示) tenant 不是孤兒,見「先看這幾點」第 5 條
/labels/menu/<scope> GET 套件 jedi_issue/api/routes/label_route.py:14 J workspace.feedback.read 無 false SystemFeedbackManage.vue、SystemFeedbackForm.vue(類別下拉) tenant 輔助端點

能力點名由套件 jedi_issue/plugin/contract.py:59-65 預設值決定(feedback-view.read 對應 feedback_read_all_capability)。套件沒有 license 軸。

操作紀錄(platform.api-log)

route 路徑 HTTP 程式位置 現有守門 新三段名 現有能力點 is_platform 對應 UI 範圍層 備註
/log/api-logs POST 套件 jedi_api_log/api_log/api/routes/api_log_route.py:27 J+PA platform.api-log.read log.read(只綁選單) true UserLogs.vue(選單 /log/user-log) tenant(root 限定) 後端不看能力點
/log/api-logs/export GET api_log_route.py:54 J+PA platform.api-log.export log.read(只綁選單) true UserLogs.vue tenant(root 限定)

資源名建議 api-log 不沿用 log:同模組還有 log 轉發設定(T-1.4 的 log-forwarding),單一個 log 會讓人分不出是哪個。log.read 宣告在套件 jedi_api_log/plugin/contract.py:22。

支援頁(platform.support)

route 路徑 HTTP 程式位置 現有守門 新三段名 現有能力點 is_platform 對應 UI 範圍層 備註
/support/recent-errors GET api/support/routes/recent_error_route.py:35 J;S: PA(app/support/service/recent_error_app_service.py:46) platform.support.read 無 true SupportPage.vue(FE 路由 requiresPlatformAdmin) tenant(root 限定) 整台機器的錯誤紀錄,跨租戶
/support/diagnostic-bundle POST api/support/routes/diagnostic_bundle_route.py:37 J;S: PA+稽核事件(app/support/service/diag_bundle_export_service.py:75-81) platform.support.export 無 true SupportPage.vue tenant(root 限定) 「J 組」只是 route 層看起來沒守,service 層有平台管理員判定與稽核,不是缺口。下載的是系統完整現場(跨租戶),必須留在原廠層

DEV ui_routes 把 /system/support 綁在 storage-config.read/storage-config.update,FE 路由註解也寫明「能力點擋不住(每個租戶管理員都有 storage-config),改靠 requiresPlatformAdmin」。改成 platform.support.read 後這個借用就可以拆掉,見待裁第 5 條。

§5

現有能力點反查(DEV 本卡範圍 16 個)

舊名 is_platform 主表有 route 守它? 新名 其他引用處
ai-dashboard.read false 有:/ai-dashboard/auto-generate ai.dashboard.read 套件 jedi_ai_dashboard/plugin/contract.py:25;選單 /dashboard/ai-dashboard;角色範本 core/role_templates.py:21(一般成員)
ai-call-log.read false 有:五支全部 ai.call-log.read(匯出兩支改 ai.call-log.export) core/host_capabilities.py:68;選單 /system/ai-call-log;common/authz/license.py:116
ai-quota.read false 有(service 層):GET /system/ai-quota ai.quota.read core/host_capabilities.py:73;選單 /system/ai-quota;common/authz/license.py:118
ai-quota.update false 有(service 層):PUT、DELETE /system/ai-quota;/me 回傳 can_adjust 也看它 ai.quota.update core/host_capabilities.py:74;選單 /system/ai-quota
bulletin.create false 有 workspace.bulletin.create 套件 contract;選單 /bulletin/bulletin-manage
bulletin.read false 無 併入 workspace.bulletin.read(見待裁第 7 條) 只綁選單 /bulletin/bulletin-manage
bulletin.update false 有 workspace.bulletin.update 選單同上
bulletin.delete false 有 workspace.bulletin.delete 選單同上
bulletin-list.read false 無 workspace.bulletin.read 只綁選單 /bulletin/bulletin-list;角色範本 core/role_templates.py:19(一般成員)
feedback.create false 有 workspace.feedback.create 選單 /feedback/system-feedback-manage;角色範本 :26
feedback.read false 有:列表、單筆 workspace.feedback.read 同上;角色範本 :27
feedback.update false 有:改回饋、刪附件 workspace.feedback.update 同上;角色範本 :28
feedback.delete false 有 workspace.feedback.delete 同上;角色範本 :29
feedback.export false 有:/feedback/export/<type> workspace.feedback.export 不綁選單;DEV 持有角色 5 個(Administrator、System Manager 等)
feedback-view.read false 有:列表、單筆(切成「看全部」) workspace.feedback-review.read 選單 /feedback/system-feedback-view;角色範本 :20(一般成員)
log.read true 無(route 用平台管理員判定) platform.api-log.read 套件 jedi_api_log/plugin/contract.py:22;選單 /log/user-log

沒有任何 route 用到的能力點(孤兒)

bulletin.read、bulletin-list.read、log.read,共 3 個。三個都有綁選單,孤兒不等於沒用:它們目前決定選單看不看得到。卡上懷疑的 feedback.export 不是孤兒。

角色範本要注意的

決策者已裁:feedback-view.read(新名 workspace.feedback-review.read)從一般成員範本拿掉,改由系統人員或管理員角色持有。以下為盤點原始觀察。

core/role_templates.py 給一般成員 bulletin-list.read、feedback-view.read、ai-dashboard.read、feedback.*(create/read/update/delete)。其中 feedback-view.read 給一般成員,意思是每個成員都看得到全公司的意見回饋——如果這不是本意,改名時順便從範本拿掉;如果是本意,第 8 條「拆兩個資源」就沒有實質意義,可以直接合併。請首腦一併確認。

§6

確認要補的守門缺口

本卡只讀,修正另開卡。第 1 條(公告列表)已併入 T-4.6(CM-2542);第 2、3 條屬改名時順手修,由 A.2/A.5 帶走。

  1. 公告列表的「管理模式」對沒有所屬部門的人不設範圍:POST /bulletins 只驗登入;請求不帶 auth: true 就走管理模式,而管理模式只有在使用者有所屬部門時才限定「自己建的」(jedi_bulletin/app/service/bulletin_service.py:246-251)。沒有部門的登入者直接打 API 不帶旗標,看得到本租戶全部公告,不受發送範圍限制(RLS 仍限在本租戶內)。可能是刻意給沒有部門的管理員看全部,但沒有能力點檢查,任何人都能用。建議:管理模式要求 workspace.bulletin.update(或 create),讀者模式要求 workspace.bulletin.read,由後端依能力點決定模式,不吃前端旗標。
  2. 意見回饋匯出鈕不判權限:SystemFeedbackManage.vue:265 的匯出鈕一律顯示,沒有 feedback.export 的人按了才 403。不是安全缺口(後端有守),是「按鈕按了沒反應」型的體驗問題,改名時 FE 補一個 hasCap。
  3. 支援頁選單借用 storage-config.*:見待裁第 5 條。不是安全缺口(FE 路由與後端都另驗平台管理員),但選單綁定是錯的。
§7

改名時要一起動的地方(給下一棒)

  • core/host_capabilities.py:66-75(AI_CALL_LOG、AI_QUOTA)
  • app/ai_quota/service/ai_quota_setting_service.py 的 _READ_CAPABILITY/_UPDATE_CAPABILITY;api/ai_call_log/routes/ai_call_log_route.py:34
  • common/authz/license.py:116-118(基礎設施豁免清單的 ai-call-log、ai-quota)——這是 resource_type 字串,模組改名後 license 軸怎麼對要一起定
  • 套件 contract:jedi_ai_dashboard/plugin/contract.py:25-30(另 api/guards.py 的 LICENSE_RESOURCE_TYPE = "ai-dashboard" 是授權照的模組名,不是能力點,FR-062 的加值包名要不要跟著改另議)、jedi_bulletin/plugin/contract.py:30-43、jedi_issue/plugin/contract.py:48-65、jedi_api_log/plugin/contract.py:22
  • core/role_templates.py:19-21、:26-29
  • DEV route_capabilities:/dashboard/ai-dashboard、/system/ai-call-log、/system/ai-quota、/bulletin/bulletin-manage、/bulletin/bulletin-list、/feedback/system-feedback-manage、/feedback/system-feedback-view、/log/user-log、/system/support 九頁的綁定
  • FE:SystemFeedbackManage.vue 匯出鈕補判斷;AiQuotaPage.vue 依 can_adjust 顯示(後端回的,不用改)
§8

定案結論

決策者 2026-10-06 逐條裁決,第 1~7 條照盤點建議,第 8 條決策者補了理由。

  1. 開 ai 模組,收 ai.dashboard、ai.call-log、ai.quota、ai.assistant 四個資源,不放 platform。AI 儀表板是賣給租戶的加值包,硬規則要求整包落在單一模組;另外三個客戶會當「AI 相關」一組來授權,放同一模組最符合客戶的想法(模組可以比加值包大,混進不收費項目不違規)。
  2. AI 額度拆兩半。 租戶自己的額度歸 ai.quota;原廠「各租戶上限」三支端點歸 platform.ai-quota-ceiling(is_platform = true);/system/ai-quota/me 不掛能力點。理由:ai-quota.read/update 管的是本租戶自己的額度,每個租戶管理員都要能設,放 platform 會被 is_platform 擋掉;/me 是額度黃條,一般成員也要看。
  3. platform 只留 api-log、support、ai-quota-ceiling 三個資源;公告與意見回饋開 workspace 模組(名字沿用 workspace)。理由:公告與意見回饋是租戶內部使用,is_platform 為 false,放原廠名下會讓人誤解。
  4. 原廠層後端維持平台管理員判定,再加能力點檢查,兩道都要過。 只看平台管理員,原廠內部分不出「客服能看錯誤、不能下載診斷包」;只看能力點,is_platform 能力點被誤配給客戶角色就直接開門(診斷包含跨租戶資料),第二道是安全網。
  5. 新建 platform.support.read(最近錯誤)與 platform.support.export(診斷包),/system/support 改綁 platform.support.read,拆掉借用的 storage-config.*。診斷包屬對外送出類,獨立成 export 才能分給不同人。
  6. 新建 ai.assistant.*,聊天與清除紀錄要求 ai.assistant.read,出貨範本一般成員給 read(行為不變)。理由:每次聊天都花 AI 錢,客戶要做「只有某些部門能用 AI」目前沒有任何開關。
  7. 公告合併成一個 workspace.bulletin。 bulletin-list.read → workspace.bulletin.read;bulletin.read 刪除,管理頁改綁 workspace.bulletin.create;後端依能力點決定管理/讀者模式,不吃前端旗標(對應缺口第 1 條,併入 T-4.6)。
  8. 意見回饋分開,不合併。 feedback.* → workspace.feedback.*(建立並看自己送的回饋);feedback-view.read → workspace.feedback-review.read(系統人員或管理員收集全公司意見用)。決策者理由:「兩個功能意義不同,一個是建立自己的回饋,一個是系統人員或管理員來收集意見」。連帶兩個決定:
    • feedback-review.read 從一般成員出貨範本拿掉(本意不是讓全員看全公司回饋)。
    • feedback-review 這種範圍型讀取權限破例只開 read,不補 create/update/delete 空殼;T-1.6 把此寫成通則。
§9

附錄:16 個 is_platform 能力點

DEV capabilities WHERE is_platform,共 16 個(查詢時間同上)。除 log.read 外都不在本卡範圍,這裡只對到守門位置與歸屬卡,逐 method 明細由該卡負責。

能力點 後端怎麼守 選單綁定 歸屬卡
log.read 不守;/log/api-logs* 用平台管理員判定 /log/user-log 本卡(T-1.5)
compliance-framework.create/.update/.delete(3) 後端零直呼(core/host_capabilities.py:28 註解) /compliance-framework/compliance-framework-manage T-1.2
issue-integrate-config.create/.read/.update/.delete(4) 通用系統設定端點依設定群組分流守門(core/plugins/system_core.py:70,ISSUE_INTEGRATE_CONFIG → issue-integrate-config) /system/issue-integrate-config T-1.4
license.read 不守;授權管理 route 用平台管理員判定(core/plugins/license.py:322-327) /license/manage T-1.4
system_config.create/.update/.delete(3) 通用系統設定端點,設定群組不在對照表時的備援(core/plugins/system_core.py:87-91) 無 T-1.4
system-menu.create/.update/.delete(3) 能力點+平台管理員兩道(套件 jedi_system_core/api/routes/system_menu_route.py:92、:112、:124) /system/system-menu-manage T-1.4
system-menu.read 不守;列表 route 只用平台管理員判定(同檔 :52、:74) /system/system-menu-manage T-1.4

合計 1+3+4+1+3+3+1 = 16。非 root 租戶 *.*.* 展開範圍 123 − 16 − 4(workflow)= 103 成立。

沿革見 FR-132-LOG.md 與 git log。