卡片 CM-2515(FR-132 T-1.5)。唯讀盤點,不改程式、不改 DB。
api/ai_quota/ 1 支(7)、api/ai_call_log/ 1 支(5)、api/support/ 2 支(2)。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 系統設定,不列。localhost:5432/guidant_ai_dev)。範圍內舊能力點 16 個;全庫能力點 123 個,其中 is_platform = true 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 能力點」。platform_admin_required)、支援頁(service 層 require_platform_admin())、AI 額度上限(同上)三塊,沒有一支 route 檢查能力點;log.read 只決定選單看不看得到。平台層要不要也改成能力點守門,見待裁第 4 條。POST /bulletins 只驗登入,「看哪些公告」由請求帶不帶 auth: true 決定。不帶、且使用者沒有所屬部門時,service 不下任何條件,等於看到本租戶全部公告(不受發送範圍限制)。見「確認要補的守門缺口」第 1 條。feedback.export 不是孤兒:匯出端點 POST /feedback/export/<type> 由它守(jedi_issue/api/routes/feedback_route.py:140),DEV 有 5 個角色持有。它只是沒綁任何頁面選單;FE 匯出鈕不判權限、一律顯示,沒權限的人按了才 403。模組歸屬依決策者 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。欄位: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/。
| 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),宿主沒接線一律拒絕,不放行。
| 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,跟使用歸同一個 |
| 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 列在不受授權照管制的清單,改名時這個字串要跟著改。
| 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)。
| 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 守,只綁選單。
| 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 軸。
| 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。
| 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 條。
| 舊名 | 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 |
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 條「拆兩個資源」就沒有實質意義,可以直接合併。請首腦一併確認。
本卡只讀,修正另開卡。第 1 條(公告列表)已併入 T-4.6(CM-2542);第 2、3 條屬改名時順手修,由 A.2/A.5 帶走。
POST /bulletins 只驗登入;請求不帶 auth: true 就走管理模式,而管理模式只有在使用者有所屬部門時才限定「自己建的」(jedi_bulletin/app/service/bulletin_service.py:246-251)。沒有部門的登入者直接打 API 不帶旗標,看得到本租戶全部公告,不受發送範圍限制(RLS 仍限在本租戶內)。可能是刻意給沒有部門的管理員看全部,但沒有能力點檢查,任何人都能用。建議:管理模式要求 workspace.bulletin.update(或 create),讀者模式要求 workspace.bulletin.read,由後端依能力點決定模式,不吃前端旗標。SystemFeedbackManage.vue:265 的匯出鈕一律顯示,沒有 feedback.export 的人按了才 403。不是安全缺口(後端有守),是「按鈕按了沒反應」型的體驗問題,改名時 FE 補一個 hasCap。storage-config.*:見待裁第 5 條。不是安全缺口(FE 路由與後端都另驗平台管理員),但選單綁定是錯的。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:34common/authz/license.py:116-118(基礎設施豁免清單的 ai-call-log、ai-quota)——這是 resource_type 字串,模組改名後 license 軸怎麼對要一起定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:22core/role_templates.py:19-21、:26-29route_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 九頁的綁定SystemFeedbackManage.vue 匯出鈕補判斷;AiQuotaPage.vue 依 can_adjust 顯示(後端回的,不用改)決策者 2026-10-06 逐條裁決,第 1~7 條照盤點建議,第 8 條決策者補了理由。
ai 模組,收 ai.dashboard、ai.call-log、ai.quota、ai.assistant 四個資源,不放 platform。AI 儀表板是賣給租戶的加值包,硬規則要求整包落在單一模組;另外三個客戶會當「AI 相關」一組來授權,放同一模組最符合客戶的想法(模組可以比加值包大,混進不收費項目不違規)。ai.quota;原廠「各租戶上限」三支端點歸 platform.ai-quota-ceiling(is_platform = true);/system/ai-quota/me 不掛能力點。理由:ai-quota.read/update 管的是本租戶自己的額度,每個租戶管理員都要能設,放 platform 會被 is_platform 擋掉;/me 是額度黃條,一般成員也要看。platform 只留 api-log、support、ai-quota-ceiling 三個資源;公告與意見回饋開 workspace 模組(名字沿用 workspace)。理由:公告與意見回饋是租戶內部使用,is_platform 為 false,放原廠名下會讓人誤解。is_platform 能力點被誤配給客戶角色就直接開門(診斷包含跨租戶資料),第二道是安全網。platform.support.read(最近錯誤)與 platform.support.export(診斷包),/system/support 改綁 platform.support.read,拆掉借用的 storage-config.*。診斷包屬對外送出類,獨立成 export 才能分給不同人。ai.assistant.*,聊天與清除紀錄要求 ai.assistant.read,出貨範本一般成員給 read(行為不變)。理由:每次聊天都花 AI 錢,客戶要做「只有某些部門能用 AI」目前沒有任何開關。workspace.bulletin。 bulletin-list.read → workspace.bulletin.read;bulletin.read 刪除,管理頁改綁 workspace.bulletin.create;後端依能力點決定管理/讀者模式,不吃前端旗標(對應缺口第 1 條,併入 T-4.6)。feedback.* → workspace.feedback.*(建立並看自己送的回饋);feedback-view.read → workspace.feedback-review.read(系統人員或管理員收集全公司意見用)。決策者理由:「兩個功能意義不同,一個是建立自己的回饋,一個是系統人員或管理員來收集意見」。連帶兩個決定:
feedback-review.read 從一般成員出貨範本拿掉(本意不是讓全員看全公司回饋)。feedback-review 這種範圍型讀取權限破例只開 read,不補 create/update/delete 空殼;T-1.6 把此寫成通則。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。