系統管理 功能群總覽
本檔放「本功能群多個頁面共用的知識」:頁面地圖、三層 RBAC 權限模型、租戶/部門/使用者組織模型、
system_configskey-value 慣例、角色權限基調、核心資料模型。各頁面 spec 引用本檔,只寫自己頁面的差異——改共用邏輯時改這裡一份。
事實基準:2026-07-05 從 FE
src/config/router/index.js+ BE routes.json / db_schema.json +docs/system-design/permission/設計說明書掃出。
1. 頁面地圖
本功能群是產品的「後台設定層」,橫跨權限治理(角色 / 選單 / 使用者)、組織主檔(租戶 / 部門 / 設備 / 資訊系統)、系統參數(通知 / SMTP / LDAP / 議題整合 / 工具外掛)與稽核與個人(操作日誌 / 個人資料)四塊。
| 頁面 | FE route | 用途一句話 | spec |
|---|---|---|---|
| 角色權限管理 | /auth/role-manage(+ role-form) |
RBAC 樞紐:角色 CRUD + 綁能力點 / 選單授權 | ✅ 角色權限管理 |
| 使用者管理 | /auth/user-manage(+ user-form) |
帳號 CRUD、租戶/部門/角色指派、批次匯入、狀態切換 | ✅ 使用者管理 |
| 選單管理 | /system/system-menu-manage |
system_menus group/key 選單項維護 |
✅ 選單管理 |
| 部門管理 | /department/department-manage |
org_units 樹狀部門 CRUD |
✅ 部門管理 |
| 租戶管理 | /tenant/tenant-manage |
tenants 樹狀租戶 CRUD |
✅ 租戶管理 |
| 設備管理 | /device/device-manage |
devices 設備主檔 CRUD |
✅ 設備管理 |
| 資訊系統盤點 | /information-system/manage |
compliance.information_systems 稽核範圍系統主檔 |
✅ 資訊系統盤點 |
| 通知頻道設定 | /system/notify-config |
system_configs NOTIFY group(Telegram / Discord)+
測試寄送 |
✅ 通知頻道設定 |
| SMTP 伺服器設定 | /system/smtp-config(-manage) |
system_configs SMTP group + 測試寄送 |
✅ SMTP 伺服器設定 |
| LDAP 設定 | /system/ldap-config |
system_configs LDAP group + 連線測試 |
✅ LDAP 設定 |
| 議題整合設定 | /system/issue-integrate-config |
GitLab / GitHub 整合(餵回饋鏡像) | ✅ 議題整合設定 |
| 工具外掛管理 | /plugin/tool-plugin-manage |
外部檢測工具 / 外掛模組管理 | ✅ 工具外掛管理 |
| 操作日誌 | /log/user-log |
api_logs 稽核軌跡查詢(不含
system_logs,見頁面 spec §1) |
✅ 操作日誌 |
| 個人資料 | /user/user-profile |
自身資料 / 改密 / MFA(TOTP)設定 | ✅ 個人資料 |
| 背景服務與排程 | —(無 UI) | 全系統背景 job / 排程 / socket / 心跳盤點 | ✅ 背景服務與排程 |
sitemap(/sitemap,「網站導覽」)已除名:router 有孤兒條目 +menu.json有 label,但public.ui_routes無對應列(非選單項)、FE 全域零 nav 進入點,屬 dead route(比照已除名的project-task-setup)。功能本身(SiteMap.vue)只是把permissions[0].items畫成 OrganizationChart,未獨立成頁。
user-form-mtrbac(/auth/user-form)是使用者管理表單的 multi-tenant RBAC 變體,併入使用者管理 spec。smtp-config-manage是 SMTP 設定的列表 / 管理變體,併入通知 / SMTP spec。
2. 三層 RBAC 權限模型(全群樞紐,先讀)
Guidant AI 採 Role-Based Access Control
三層模型:使用者擁有角色、角色擁有能力點、能力點控制 UI
路由(選單)的可見性。權威設計文件:docs/system-design/permission/Permission-System-權限與選單系統設計說明書.md(11
章 + 5 圖)。
| 層級 | 表 | 說明 |
|---|---|---|
| 使用者 | public.users |
帳號本體 |
| 使用者 ↔︎ 角色 | public.user_roles |
N:M;帶 scope(tenant / org_unit)+
tenant_id / org_unit_id 授權邊界 +
starts_at / ends_at 有效期間 +
is_default |
| 角色 | public.roles |
權限群組;tenant_id IS NULL =
全租戶共用的系統預設角色,非 NULL = 各租戶自訂 |
| 角色 ↔︎ 能力 | public.role_capabilities |
N:M,由「角色權限管理」UI 維護 |
| 能力點 | public.capabilities |
細粒度權限,命名 <resource>.<action>(如
project.read);is_platform=true 者僅 root
tenant 角色可持有 |
| 路由 ↔︎ 能力 | public.route_capabilities |
N:M + requirement(ALL 需全擁有 /
ANY 有任一即可) |
| UI 路由 | public.ui_routes |
前端選單節點(pid
自參考樹狀、enable、sort);name
是前端 i18n key |
2.1
選單可見性規則(GET /user/web-menu)
前端登入後打 GET /api/1.0/user/web-menu(可帶
X-Tenant-ID 指定當前租戶),BE
依使用者「有效期間內、當前租戶」的角色算出能力集,再對每個
ui_routes 節點套用:
- 無需求(該 route 在
route_capabilities無設定)→ 預設可見 - ANY 命中(任一
requirement=ANY的能力使用者擁有)→ 可見 - ALL 滿足(所有
requirement=ALL的能力使用者全擁有)→ 可見
外加共同條件:ui_routes.enable=1、角色在有效期間、(帶
X-Tenant-ID
時)限縮該租戶角色。慣例:read 一律設
ALL(無讀權限完全看不到選單),寫操作(create/update/delete/export)設
ANY(有任一寫權限即可進頁,頁內再控制按鈕禁用)。回傳的每個節點附
capabilities 明細,供 FE 控制按鈕顯示 / 禁用。
呼叫鏈(設計文件
§四、§十):api/auth/routes/user_route.py → jedi-auth
UserService.get_user_web_ui_routes →
UiRouteDomainService.get_viewable_routes_by_user_uid →
UiRouteRepoImpl.get_viewable_by_user_uid(複合 SQL)。
新功能要進「角色權限管理」被勾選授權:走設計文件 §六 5 步 SOP(新增
capabilities→ui_routes→ 綁route_capabilities→ 配role_capabilities→ FE Vue Router)。memoryreference_permission_system_sop;範本 SQLscripts/sql/2026-04-27-add-audit-and-cloud-integration-permissions.sql。
3. 租戶 / 部門 / 使用者 組織模型
系統是多租戶架構:租戶(tenants)為頂層、可樹狀階層;部門(org_units)隸屬租戶、亦可樹狀。使用者可屬多租戶、多部門。
| 關係 | 表 | 說明 |
|---|---|---|
| 使用者預設歸屬 | users.tenant_id / users.org_unit_id |
單一預設值(欄位) |
| 使用者 ↔︎ 租戶 | public.user_tenants |
N:M;is_default 標預設租戶 |
| 使用者 ↔︎ 部門 | public.user_org_units |
N:M;is_primary 標主要部門 |
| 租戶樹狀 | tenants.parent_id /
tenants.path(/1/2/ 格式) |
多層租戶 |
| 部門樹狀 | org_units.parent_id / org_units.path |
部門內含子部門 |
RLS:DB 層以 PostgreSQL RLS 做租戶隔離,
session_scope()自動注入app.user_id/app.allowed_tenant_paths,Python 查詢不需另加 tenant filter(見專案 CLAUDE.md「RLS 注意事項」)。但功能定義表ui_routes/capabilities/route_capabilities不加 RLS(全租戶共用同一份功能定義),隔離改由user_roles.tenant_id處理。
4.
system_configs key-value 設定慣例
多個設定頁(通知 / SMTP / LDAP / 議題整合)不各自建表,而是共用
public.system_configs 這張 group / key /
value(jsonb) 的鍵值表:
| 欄位 | 說明 |
|---|---|
group |
設定群組(如 SMTP / NOTIFY /
LDAP / ISSUE;實際 group 名以各設定頁 spec
查證為準) |
key |
設定鍵名 |
value |
jsonb 設定值 |
tenant_id / org_unit_id |
設定的歸屬範圍(可為租戶級或全域) |
主要
endpoint:GET/POST/PUT/DELETE /api/1.0/system/config、GET /api/1.0/system/configs/<group>、GET/PUT/DELETE /api/1.0/system/config/<group>/<key>。設定頁不寫
value 明文憑證進 spec(密碼 / token 只描述欄位)。
選單項另有
public.system_menus(group / key / value / sort / enable / public)——這是「選單管理」頁維護的下拉 / 分類選單資料(如國家、產業別等 code table),與ui_routes(權限選單樹)是兩回事,別混。
5. 角色權限基調
角色是誰:
- 平台 admin(root tenant)——治理全系統的角色、能力點、選單結構,是所有其他角色權限的源頭。「身為平台 admin,我要新增一個角色、勾選它能看到哪些選單與能做哪些操作。」
- 租戶 admin——管理自己租戶內的使用者、部門、設備、資訊系統盤點等主檔資料。「身為租戶 admin,我要新增一個部門、把新進使用者分派進去並指派角色。」
- 一般使用者——管理自己的個人資料、密碼、MFA 設定,不涉及他人資料。「身為一般使用者,我要改自己的密碼、設定雙因子驗證。」
系統管理群整體是管理員 / 平台層功能,理應鎖後台角色。實務上各頁 BE 強制程度不一:
| 面向 | 應由誰 | 常見 BE 現況 |
|---|---|---|
| 角色 / 能力 / 選單治理 | 平台 / 租戶 admin | 部分端點有 is_platform
capability(GRC_NOT_PLATFORM_ADMIN / 403060)守門,部分僅
JWT |
| 使用者 / 租戶 / 部門 / 設備 CRUD | 租戶 admin | 依 route_capabilities
綁定的能力點控制選單可見性;BE
端點層是否再強制角色,逐頁查證 |
| 個人資料 / 改密 / MFA | 使用者本人 | 僅 JWT(操作自身) |
重要:
route_capabilities控制的是選單是否顯示(前端可見性),不等於 BE 端點強制。前次 Lane 多頁發現「寫入 API 僅 JWT、無 BE 角色守門」的安全缺口——各頁 §3 權限矩陣以 FE 判定 vs BE 強制分欄對照,發現不一致標 ⚠️ 收進該頁 §12。本群 spec 只記錄不修(修為另開 bug session)。
error code 前綴:權限 / 平台層多為
GRC_(如GRC_NOT_PLATFORM_ADMIN=403060),但各模組不保證同前綴——寫每頁 §6 前先 grep 該模組common/code/*_error_code.py查證,勿假設全GRC_。
6. 核心資料模型
| 表 | schema | 角色 |
|---|---|---|
users |
public | 帳號本體(login_name / nickname / status / 預設 tenant+org / mfa) |
roles |
public | 角色(tenant_id NULL=系統預設;is_admin /
enable / is_delete) |
capabilities |
public | 能力點(name UNIQUE / resource_type /
action / is_platform) |
role_capabilities |
public | 角色 ↔︎ 能力(複合 PK,無 requirement) |
route_capabilities |
public | 路由 ↔︎ 能力(複合 PK + requirement ALL/ANY) |
ui_routes |
public | 選單 / 路由樹(pid 自參考 / enable /
sort;name=i18n key) |
user_roles |
public | 使用者 ↔︎ 角色指派(scope / tenant_id /
org_unit_id / 有效期間 / is_default) |
tenants |
public | 租戶(parent_id / path 樹狀) |
org_units |
public | 部門(tenant_id / parent_id /
path 樹狀) |
user_tenants |
public | 使用者 ↔︎ 租戶(is_default) |
user_org_units |
public | 使用者 ↔︎ 部門(is_primary) |
system_configs |
public | 系統設定 key-value(group / key / value jsonb / tenant_id) |
system_menus |
public | 下拉 / 分類選單 code table(group / key / value;≠ ui_routes) |
devices |
public | 設備主檔 |
information_systems |
compliance | 稽核範圍資訊系統主檔 |
api_logs / system_logs |
public | 操作日誌(api_logs vs event_code 事件日誌,見操作日誌頁) |
user_auth_providers |
public | 使用者第三方登入綁定 |
user_change_password_request /
user_change_pwd_logs |
public | 改密請求 / 歷史 |
7. 本群共用的已知坑
ui_routesvssystem_menus別混:前者是權限選單樹(RBAC 可見性)、後者是下拉分類 code table(選單管理頁維護),兩張不同用途的表。ui_routes控可見性 ≠ BE 端點強制:能力點只決定選單顯不顯示,不保證 BE 端點層有角色守門;各頁 §3 分欄對照 FE 判定 vs BE 強制。ui_routes.name已加 UNIQUE(2026-07-08 FR-047 SCHEMA,DEV+STG 已套、POC 待部署):FE 功能樹強依賴 name 當 i18n key,原無 DB 約束、重名顯示錯亂;已加uq_ui_routes_name UNIQUE(name)(capabilities.name本就有 UNIQUE)。POC 未套前新增仍建議先 SELECT 確認沒重名(設計文件 §9.1)。- 跨環境 id 漂移:DEV / STG / POC 的
ui_routes.id/capabilities.id用 serial 各自編號、不一致,程式碼與 migration 一律用name查、勿 hardcode id(設計文件 §9.7)。 is_platform能力點:平台層能力(root tenant 專屬)在一般租戶角色矩陣隱藏、寫入端擋(GRC_NOT_PLATFORM_ADMIN/ 403060)。sort預留 gap:ui_routes.sort/system_menus.sort用 10/20/30 間隔,別連號(設計文件 §9.2)。- 設定頁共用
system_configs:通知 / SMTP / LDAP / 議題整合都是同一張 key-value 表的不同 group,非各自專表;改一個設定頁的讀寫慣例前,先確認沒影響同表其他 group。 - jedi-auth 套件擁有大半 RBAC
邏輯:
users/roles/ui_routes/ web-menu 的 service / repo 在 jedi-auth 套件內(~/Projects/Jedicogy/module/jedi-python-package/jedi-auth/),不在主專案;改行為要分清邊界(見 CLAUDE.md「外部套件異動規範」)。