本章目標與前置條件
回答「有哪些功能、在哪裡開發、如何判斷完成度」。先閱讀技術架構,並取得與目前工作區相符的前後端來源。此索引核對後端 4cdf9822、前端 85b7de0 所在工作區,不代表遠端或部署環境版本。
如何閱讀功能狀態
已實作(原始碼層級) 表示有可追蹤的路由/handler/service;下表「後端」欄只列這一層。測試檔存在不是測試已通過,flag 宣告不是環境已啟用,選單可見不是操作已授權。
「前端/限制」欄依前端 app/、features/、hooks/api/ 的非測試程式碼判斷,同樣只到原始碼層級:
- 已接 API:有頁面或 hook 呼叫已登錄的
/v1/**路由,不代表已聯調。 - 僅後端:路由已登錄,但前端沒有頁面,也沒有非測試引用。
- 前端 fixture/RoutePlaceholder:畫面存在,資料卻是示意資料或佔位頁。
待核實表示需要憑證、資料或實際環境才能確認,不等同「未開發」。沒有將舊計畫的完成率當作事實。
功能板塊地圖
| 板塊 | 後端(原始碼層級) | 前端/限制 | 開發入口 |
|---|---|---|---|
| 身分與 IAM | 目前身分與選單、授權判定與存取預覽、帳號目錄、角色、群組、角色綁定與可承擔者、升權會話、權限目錄與選單節點、欄位政策、資料範圍(唯讀) | 已接 API:/iam/roles、/iam/groups、/iam/access、/iam/catalog。僅後端:升權的申請/撤銷與欄位政策;HR 畫面連往的 /iam/elevation 沒有 page.tsx | IAM 指南 |
| 組織與人資 | 員工列表、建立、查詢與更新,個人資料、異動(transitions)、帳號啟用、密碼重設、批次調任、統計、員工請假紀錄;組織單位與組織圖、職位、流動分析;eHRMS 同步與 source-sync 設定/初始化 | 已接 API:/workspace/employees(含同步控制)、/hr/org、/hr/positions、/workspace/turnover。真實 eHRMS 上游連線待核實 | 人資指南 |
| 考勤 | 出勤制度(版本化 policy)、工作地點與地理圍欄、行事曆與匯入、打卡與打卡紀錄、每日投影(days、daily-records)、eHRMS 同步批次、Google Calendar 整合、摘要規則與月彙總。沒有排班(班表)管理 API:排班區間來自 policy、eHRMS 或行事曆 | 已接 API:首頁打卡、/workspace/clock、/workspace/attendance、/workspace/leave-policy(制度、地點、行事曆與整合)。僅後端:摘要規則、月彙總、eHRMS 同步批次;摘要 job 另需 ATTENDANCE_DIGEST_ENABLED(預設 false) | 考勤指南 |
| 假勤 | 假別政策、員工假別目錄、餘額、本人請假紀錄。請假與銷假以表單送審;考勤服務負責准入(admission,快照假別政策版本)、依餘額批次扣抵(lot allocation)與銷假(cancellation) | 已接 API:/myleave(餘額、紀錄,並帶範本進 /forms 申請)與 /workspace/leave-policy 的假別設定 | 假勤指南 |
| 表單 | 範本設計、驗證、發布與版本、欄位型別與資料來源;草稿、提交、撤回、複製、刪除草稿、清單、匯出;配額政策與用量、流程預覽、管理取消;approve/reject/return 簽核動作 | 已接 API:/forms(申請)、/workspace/forms(設計器) | 表單指南 |
| 審批與工作流 | 待辦審核與批次動作(/workflows/reviews,合併表單與 JML 卡片)、審核角色與解析預覽、JML 流程實例與動作(/workflow-runs)。表單審批用 PostgreSQL 內的審批引擎,只有 JML 走 Temporal | 已接 API:/notifications(待辦審核)、/workspace/approval-roles。僅後端:/workflow-runs;前端 review schema 只接受 source: 'form',出現 JML 卡片時會觸發 schema 錯誤 | 工作流指南 |
| 知識庫 | 文件與版本的發布/撤銷、空間與文件綁定、可見性政策與 override、受眾候選審核 | 僅後端:沒有頁面,前端也沒有引用 /v1/documents 或 /v1/knowledge | 知識庫指南 |
| AI Agent | run 建立、本人歷史與查詢;worker 依 outbox 事件執行 executor、工具與結果狀態 | 前端 fixture:聊天面板讀 app/(platform)/_fixtures/aiChat.ts,沒有呼叫 /v1/agents/runs;/assistants 是 RoutePlaceholder | Agent 指南 |
| 工作紀錄 | 工作項目、月摘要、選項、個人待辦;更新與刪除以 base_version 偵測版本衝突 | 已接 API:/tasks(features/worklog) | 工作紀錄指南 |
| 附件 | 兩段式上傳:POST /v1/attachments 建立 pending,PUT /v1/attachments/:id/content 串流上傳、定稿校驗後標記 stored;另有下載與 DELETE 撤銷。沒有獨立權限點,由 service 依宿主資源判定 | 已接 API:表單附件、員工大頭照(features/forms、features/hr-employees) | 附件指南 |
| 通知 | 收件匣、未讀數、單筆與全部已讀;worker 處理 outbox 事件寫入通知 | 已接 API:頂欄鈴鐺與收件匣(features/notifications)。/notifications 路由其實是待辦審核頁 | 通知指南 |
| 工作台 | 管理總覽與總覽待辦(/workspace/overview、/workspace/overview/todos)。registry 沒有審計查詢路由 | 已接 API:/workspace 總覽、首頁 / 的打卡與表單入口。前端 fixture:/workspace/audit-log。RoutePlaceholder:/dashboard | 工作台指南 |
| 平台整合 | internal/platform/:eHRMS、Keycloak、LLM(LiteLLM)、物件儲存(SFTPGo)、Google Calendar、Google 地理編碼、Redis、PostgreSQL、Temporal。多個開關預設為 false,如 TEMPORAL_ENABLED、REDIS_ENABLED、GOOGLE_GEOCODING_ENABLED | 前端自有整合:app/api/auth/*(Keycloak OIDC)、app/api/geo/current-context(Open-Meteo、Nominatim)與瀏覽器端 Google Maps JS。真實外部連線待核實 | 整合指南 |
「前端/限制」依非測試程式碼的 /v1/** 引用與 page.tsx 判斷,只證明原始碼接線,不是聯調結果。前端 components/chat/AiChatPanel.tsx 的註解仍寫 /v1/agents/** 不在 registry.golden,已與目前快照不符;以快照為準。
已登錄 API 清單
此表從 internal/route/testdata/registry.golden 產生,對照 internal/api/v1/routes.go 的註冊入口閱讀。它是程式碼契約快照,不是對 live server 執行探測。「授權宣告」欄就是 golden 的 policy 字串;api/openapi.yaml 沒有結構化的權限 metadata(沒有 x- 擴充欄位,只有少數 description 以文字提及),權限點、risk、page 與 tenant_wide 一律以 golden 為準。:id 是 Gin 參數表示法;完整欄位、分頁、錯誤碼以 api/openapi.yaml 為準,不由清單猜測。
GET /healthz、GET /readyz 歸在部署與排查。OPTIONS /v1/*path 是 CORS preflight 的萬用路由:只在設定 CORS origin 白名單時註冊、固定回 204;索引把它歸在「平台整合」,但它不是整合 API。與整合相關的業務路由(如 calendar-integration、/hr/ehrms/sync)歸在各自的業務板塊。
目前快照:201 筆路由(包含健康檢查及 OPTIONS),不是測試通過數。
AI Agent · 3 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
GET | /v1/agents/runs | point app=agent resource=agent.run action=read risk=normal page= target_employee= resource_id= tenant_wide=false |
GET | /v1/agents/runs/:runId | point app=agent resource=agent.run action=read risk=normal page= target_employee= resource_id=runId tenant_wide=false |
POST | /v1/agents/runs | point app=agent resource=agent.run action=create risk=normal page= target_employee= resource_id= tenant_wide=false |
附件與兩段式物件儲存 · 5 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
DELETE | /v1/attachments/:id | auth_only |
GET | /v1/attachments/:id | auth_only |
GET | /v1/attachments/:id/content | auth_only |
POST | /v1/attachments | auth_only |
PUT | /v1/attachments/:id/content | auth_only |
考勤與出勤 · 26 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
DELETE | /v1/attendance/calendar/days/:calendarDayId | point app=attendance resource=attendance.calendar action=delete risk=high page=attendance.policy target_employee= resource_id=calendarDayId tenant_wide=true |
GET | /v1/attendance/calendar | point app=attendance resource=attendance.calendar action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/calendar-integration | point app=attendance resource=attendance.calendar_integration action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/calendar/years | point app=attendance resource=attendance.calendar action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/clock-records | point app=attendance resource=attendance.clock action=read risk=normal page=attendance.clock target_employee= resource_id= tenant_wide=false |
GET | /v1/attendance/clock-status | point app=attendance resource=attendance.clock action=read risk=normal page=attendance.clock target_employee= resource_id= tenant_wide=false |
GET | /v1/attendance/daily-records | point app=attendance resource=attendance.day action=read risk=normal page=attendance.day target_employee= resource_id= tenant_wide=false |
GET | /v1/attendance/days | point app=attendance resource=attendance.day action=read risk=normal page=attendance.day target_employee= resource_id= tenant_wide=false |
GET | /v1/attendance/digest-rules | point app=attendance resource=attendance.digest action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/ehrms/sync-runs/:runId | point app=attendance resource=attendance.day action=sync risk=high page=attendance.day target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/ehrms/sync-runs/:runId/items | point app=attendance resource=attendance.day action=sync risk=high page=attendance.day target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/monthly-summary | point app=attendance resource=attendance.day action=read risk=normal page=attendance.day target_employee= resource_id= tenant_wide=false |
GET | /v1/attendance/policy | point app=attendance resource=attendance.policy action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/policy/options | point app=attendance resource=attendance.policy action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/worksites | point app=attendance resource=attendance.worksite action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
POST | /v1/attendance/calendar-integration/verify | point app=attendance resource=attendance.calendar_integration action=update risk=high page=attendance.policy target_employee= resource_id= tenant_wide=true |
POST | /v1/attendance/calendar/days | point app=attendance resource=attendance.calendar action=create risk=high page=attendance.policy target_employee= resource_id= tenant_wide=true |
POST | /v1/attendance/calendar/import | point app=attendance resource=attendance.calendar action=import risk=high page=attendance.policy target_employee= resource_id= tenant_wide=true |
POST | /v1/attendance/clock | point app=attendance resource=attendance.clock action=create risk=high page=attendance.clock target_employee= resource_id= tenant_wide=false |
POST | /v1/attendance/ehrms/sync-runs | point app=attendance resource=attendance.day action=sync risk=high page=attendance.day target_employee= resource_id= tenant_wide=true |
POST | /v1/attendance/ehrms/sync-runs/:runId/retry | point app=attendance resource=attendance.day action=sync risk=high page=attendance.day target_employee= resource_id= tenant_wide=true |
POST | /v1/attendance/worksites | point app=attendance resource=attendance.worksite action=create risk=high page=attendance.policy target_employee= resource_id= tenant_wide=true |
PUT | /v1/attendance/calendar-integration | point app=attendance resource=attendance.calendar_integration action=update risk=high page=attendance.policy target_employee= resource_id= tenant_wide=true |
PUT | /v1/attendance/digest-rules | point app=attendance resource=attendance.digest action=update risk=high page=attendance.policy target_employee= resource_id= tenant_wide=true |
PUT | /v1/attendance/policy | point app=attendance resource=attendance.policy action=update risk=high page=attendance.policy target_employee= resource_id= tenant_wide=true |
PUT | /v1/attendance/worksites/:worksiteId | point app=attendance resource=attendance.worksite action=update risk=high page=attendance.policy target_employee= resource_id=worksiteId tenant_wide=true |
表單與申請 · 30 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
DELETE | /v1/forms/:formInstanceId | point app=workflow resource=workflow.run action=delete risk=high page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
GET | /v1/forms | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id= tenant_wide=false |
GET | /v1/forms/:formInstanceId | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
GET | /v1/forms/:formInstanceId/definition | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
GET | /v1/forms/:formInstanceId/export | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
GET | /v1/forms/:formInstanceId/workflow | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
GET | /v1/forms/data-sources/:formDataSourceKey | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id= tenant_wide=false |
GET | /v1/forms/field-types | point app=workflow resource=workflow.form_definition action=read risk=normal page=workflow.form_definition target_employee= resource_id= tenant_wide=true |
GET | /v1/forms/templates | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id= tenant_wide=false |
GET | /v1/forms/templates/:formTemplateId | point app=workflow resource=workflow.form_definition action=read risk=normal page=workflow.form_definition target_employee= resource_id=formTemplateId tenant_wide=true |
GET | /v1/forms/templates/:formTemplateId/published | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=formTemplateId tenant_wide=false |
GET | /v1/forms/templates/:formTemplateId/quota | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=formTemplateId tenant_wide=false |
GET | /v1/forms/templates/:formTemplateId/quota-policy | point app=workflow resource=workflow.form_definition action=read risk=normal page=workflow.form_definition target_employee= resource_id=formTemplateId tenant_wide=true |
GET | /v1/forms/templates/:formTemplateId/versions | point app=workflow resource=workflow.form_definition action=read risk=normal page=workflow.form_definition target_employee= resource_id=formTemplateId tenant_wide=true |
POST | /v1/forms/:formInstanceId/admin-cancel | point app=workflow resource=workflow.run action=admin_cancel risk=high page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=true |
POST | /v1/forms/:formInstanceId/approve | point app=workflow resource=workflow.action action=approve risk=high page=workflow.approval target_employee= resource_id=formInstanceId tenant_wide=false |
POST | /v1/forms/:formInstanceId/duplicate | point app=workflow resource=workflow.run action=create risk=high page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
POST | /v1/forms/:formInstanceId/reject | point app=workflow resource=workflow.action action=reject risk=high page=workflow.approval target_employee= resource_id=formInstanceId tenant_wide=false |
POST | /v1/forms/:formInstanceId/return | point app=workflow resource=workflow.action action=return risk=high page=workflow.approval target_employee= resource_id=formInstanceId tenant_wide=false |
POST | /v1/forms/:formInstanceId/submit | point app=workflow resource=workflow.run action=start risk=high page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
POST | /v1/forms/:formInstanceId/withdraw | point app=workflow resource=workflow.run action=withdraw risk=high page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
POST | /v1/forms/:formInstanceId/workflow/preview | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
POST | /v1/forms/drafts | point app=workflow resource=workflow.run action=create risk=high page=workflow.form target_employee= resource_id= tenant_wide=false |
POST | /v1/forms/templates | point app=workflow resource=workflow.form_definition action=create risk=high page=workflow.form_definition target_employee= resource_id= tenant_wide=true |
POST | /v1/forms/templates/:formTemplateId/preview | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=formTemplateId tenant_wide=false |
POST | /v1/forms/templates/:formTemplateId/publish | point app=workflow resource=workflow.form_definition action=publish risk=high page=workflow.form_definition target_employee= resource_id=formTemplateId tenant_wide=true |
POST | /v1/forms/templates/:formTemplateId/validate | point app=workflow resource=workflow.form_definition action=update risk=high page=workflow.form_definition target_employee= resource_id=formTemplateId tenant_wide=true |
PUT | /v1/forms/:formInstanceId | point app=workflow resource=workflow.run action=update risk=high page=workflow.form target_employee= resource_id=formInstanceId tenant_wide=false |
PUT | /v1/forms/templates/:formTemplateId | point app=workflow resource=workflow.form_definition action=update risk=high page=workflow.form_definition target_employee= resource_id=formTemplateId tenant_wide=true |
PUT | /v1/forms/templates/:formTemplateId/quota-policy | point app=workflow resource=workflow.form_definition action=update risk=high page=workflow.form_definition target_employee= resource_id=formTemplateId tenant_wide=true |
組織與員工 · 27 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
DELETE | /v1/hr/positions/:positionId | point app=hr resource=hr.position action=delete risk=high page=hr.positions target_employee= resource_id= tenant_wide=true |
GET | /v1/hr/employees | point app=hr resource=hr.employee action=read risk=normal page=hr.employees target_employee= resource_id= tenant_wide=false |
GET | /v1/hr/employees/:employeeId | point app=hr resource=hr.employee action=read risk=normal page=hr.employees target_employee=employeeId resource_id= tenant_wide=false |
GET | /v1/hr/employees/:employeeId/leave-records | point app=hr resource=hr.employee action=read risk=normal page=hr.employees target_employee=employeeId resource_id= tenant_wide=false |
GET | /v1/hr/employees/:employeeId/profile | point app=hr resource=hr.employee action=read risk=normal page=hr.employees target_employee=employeeId resource_id= tenant_wide=false |
GET | /v1/hr/employees/stats | point app=hr resource=hr.employee action=read risk=normal page=hr.employees target_employee= resource_id= tenant_wide=false |
GET | /v1/hr/org-chart | point app=hr resource=hr.org_unit action=read risk=normal page=hr.org target_employee= resource_id= tenant_wide=true |
GET | /v1/hr/org-units | point app=hr resource=hr.org_unit action=read risk=normal page=hr.org target_employee= resource_id= tenant_wide=true |
GET | /v1/hr/positions | point app=hr resource=hr.position action=read risk=normal page=hr.positions target_employee= resource_id= tenant_wide=true |
GET | /v1/hr/positions/:positionId | point app=hr resource=hr.position action=read risk=normal page=hr.positions target_employee= resource_id= tenant_wide=true |
GET | /v1/hr/source-sync | point app=hr resource=hr.employee action=sync risk=high page=hr.employees target_employee= resource_id= tenant_wide=true |
GET | /v1/hr/turnover/annual | point app=hr resource=hr.turnover action=read risk=normal page=hr.turnover target_employee= resource_id= tenant_wide=true |
GET | /v1/hr/turnover/monthly | point app=hr resource=hr.turnover action=read risk=normal page=hr.turnover target_employee= resource_id= tenant_wide=true |
POST | /v1/hr/ehrms/sync | point app=hr resource=hr.employee action=sync risk=high page=hr.employees target_employee= resource_id= tenant_wide=true |
POST | /v1/hr/employees | point app=hr resource=hr.employee action=create risk=normal page=hr.employees target_employee= resource_id= tenant_wide=false |
POST | /v1/hr/employees/:employeeId/password-reset | point app=hr resource=hr.employee action=reset_password risk=high page=hr.employees target_employee=employeeId resource_id= tenant_wide=false |
POST | /v1/hr/employees/:employeeId/transitions | point app=hr resource=hr.employee action=transition risk=high page=hr.employees target_employee=employeeId resource_id= tenant_wide=false |
POST | /v1/hr/employees/activate-accounts | point app=hr resource=hr.employee action=activate_account risk=high page=hr.employees target_employee= resource_id= tenant_wide=false |
POST | /v1/hr/employees/bulk-reassign | point app=hr resource=hr.employee action=update risk=high page=hr.employees target_employee= resource_id= tenant_wide=true |
POST | /v1/hr/org-units | point app=hr resource=hr.org_unit action=create risk=normal page=hr.org target_employee= resource_id= tenant_wide=true |
POST | /v1/hr/positions | point app=hr resource=hr.position action=create risk=normal page=hr.positions target_employee= resource_id= tenant_wide=true |
POST | /v1/hr/source-sync/initialize | point app=hr resource=hr.employee action=sync risk=high page=hr.employees target_employee= resource_id= tenant_wide=true |
PUT | /v1/hr/employees/:employeeId | point app=hr resource=hr.employee action=update risk=normal page=hr.employees target_employee=employeeId resource_id= tenant_wide=false |
PUT | /v1/hr/employees/:employeeId/profile | point app=hr resource=hr.employee action=update risk=normal page=hr.employees target_employee=employeeId resource_id= tenant_wide=false |
PUT | /v1/hr/org-units/:orgUnitId | point app=hr resource=hr.org_unit action=update risk=normal page=hr.org target_employee= resource_id= tenant_wide=true |
PUT | /v1/hr/positions/:positionId | point app=hr resource=hr.position action=update risk=normal page=hr.positions target_employee= resource_id= tenant_wide=true |
PUT | /v1/hr/source-sync | point app=hr resource=hr.employee action=sync risk=high page=hr.employees target_employee= resource_id= tenant_wide=true |
身分、IAM 與權限目錄 · 42 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
DELETE | /v1/iam/catalog/groups/:section | point app=iam resource=iam.catalog action=delete risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
DELETE | /v1/iam/catalog/pages/:pageKey | point app=iam resource=iam.catalog action=delete risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
DELETE | /v1/iam/catalog/points/:id | point app=iam resource=iam.catalog action=delete risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
DELETE | /v1/iam/catalog/points/:id/binding | point app=iam resource=iam.catalog action=update risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
DELETE | /v1/iam/elevation-sessions/:id | point app=iam resource=iam.elevation_session action=delete risk=high page=iam.elevation target_employee= resource_id= tenant_wide=true |
DELETE | /v1/iam/roles/:id | point app=iam resource=iam.role action=delete risk=high page=iam.roles target_employee= resource_id= tenant_wide=true |
DELETE | /v1/iam/roles/:id/assumers/:accountId | point app=iam resource=iam.role_assumer action=delete risk=critical page=iam.roles target_employee= resource_id= tenant_wide=true |
DELETE | /v1/iam/roles/:id/members/:bid | point app=iam resource=iam.role_binding action=delete risk=high page=iam.roles target_employee= resource_id= tenant_wide=true |
DELETE | /v1/iam/user-groups/:id/members/:mid | point app=iam resource=iam.user_group_member action=delete risk=high page=iam.groups target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/accounts | point app=iam resource=iam.account action=read risk=normal page=iam.access target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/accounts/:id/access | point app=iam resource=iam.access action=read risk=normal page=iam.access target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/catalog | point app=iam resource=iam.catalog action=read risk=normal page=iam.catalog target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/data-scopes | point app=iam resource=iam.data_scope action=read risk=normal page= target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/elevation-sessions | point app=iam resource=iam.elevation_session action=read risk=normal page=iam.elevation target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/elevation-sessions/:id | point app=iam resource=iam.elevation_session action=read risk=normal page=iam.elevation target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/field-policies | point app=iam resource=iam.field_policy action=read risk=normal page=iam.catalog target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/roles | point app=iam resource=iam.role action=read risk=normal page=iam.roles target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/roles/:id/assumers | point app=iam resource=iam.role_assumer action=read risk=normal page=iam.roles target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/roles/:id/members | point app=iam resource=iam.role_binding action=read risk=normal page=iam.roles target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/user-groups | point app=iam resource=iam.user_group action=read risk=normal page=iam.groups target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/user-groups/:id/members | point app=iam resource=iam.user_group_member action=read risk=normal page=iam.groups target_employee= resource_id= tenant_wide=true |
GET | /v1/iam/user-groups/:id/roles | point app=iam resource=iam.role_binding action=read risk=normal page=iam.groups target_employee= resource_id= tenant_wide=true |
GET | /v1/me | auth_only |
GET | /v1/me/menus | auth_only |
POST | /v1/authz/check | auth_only |
POST | /v1/iam/access/preview | point app=iam resource=iam.access action=read risk=normal page=iam.access target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/catalog/conversions | point app=iam resource=iam.catalog action=delete risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/catalog/conversions/preview | point app=iam resource=iam.catalog action=read risk=normal page=iam.catalog target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/catalog/groups | point app=iam resource=iam.catalog action=create risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/catalog/pages | point app=iam resource=iam.catalog action=create risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/catalog/points | point app=iam resource=iam.catalog action=create risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/elevation-sessions | point app=iam resource=iam.elevation_session action=assume risk=critical page=iam.elevation target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/roles | point app=iam resource=iam.role action=create risk=high page=iam.roles target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/roles/:id/members | point app=iam resource=iam.role_binding action=create risk=high page=iam.roles target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/user-groups | point app=iam resource=iam.user_group action=create risk=normal page=iam.groups target_employee= resource_id= tenant_wide=true |
POST | /v1/iam/user-groups/:id/members | point app=iam resource=iam.user_group_member action=create risk=high page=iam.groups target_employee= resource_id= tenant_wide=true |
PUT | /v1/iam/catalog/groups/:section | point app=iam resource=iam.catalog action=update risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
PUT | /v1/iam/catalog/pages/:pageKey | point app=iam resource=iam.catalog action=update risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
PUT | /v1/iam/catalog/points/:id/binding | point app=iam resource=iam.catalog action=update risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
PUT | /v1/iam/field-policies | point app=iam resource=iam.field_policy action=update risk=high page=iam.catalog target_employee= resource_id= tenant_wide=true |
PUT | /v1/iam/roles/:id | point app=iam resource=iam.role action=update risk=high page=iam.roles target_employee= resource_id= tenant_wide=true |
PUT | /v1/iam/roles/:id/assumers/:accountId | point app=iam resource=iam.role_assumer action=update risk=critical page=iam.roles target_employee= resource_id= tenant_wide=true |
知識庫與內容治理 · 26 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
DELETE | /v1/documents/:documentId/visibility-override | point app=knowledge resource=knowledge.override action=delete risk=high page=knowledge.documents target_employee= resource_id= tenant_wide=true |
DELETE | /v1/knowledge/spaces/:spaceId/documents/:documentId | point app=knowledge resource=knowledge.space_document action=delete risk=high page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
DELETE | /v1/knowledge/visibility-policies/:policyId/selectors/:selectorId | point app=knowledge resource=knowledge.visibility_policy action=update risk=high page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
GET | /v1/documents | point app=knowledge resource=knowledge.document action=read risk=normal page=knowledge.documents target_employee= resource_id= tenant_wide=true |
GET | /v1/documents/:documentId | point app=knowledge resource=knowledge.document action=read risk=normal page=knowledge.documents target_employee= resource_id= tenant_wide=true |
GET | /v1/documents/:documentId/versions | point app=knowledge resource=knowledge.document action=read risk=normal page=knowledge.documents target_employee= resource_id= tenant_wide=true |
GET | /v1/documents/:documentId/versions/:versionId | point app=knowledge resource=knowledge.document action=read risk=normal page=knowledge.documents target_employee= resource_id= tenant_wide=true |
GET | /v1/documents/:documentId/visibility-override | point app=knowledge resource=knowledge.override action=read risk=normal page=knowledge.documents target_employee= resource_id= tenant_wide=true |
GET | /v1/knowledge/audience-candidates | point app=knowledge resource=knowledge.audience action=read risk=normal page=knowledge.documents target_employee= resource_id= tenant_wide=true |
GET | /v1/knowledge/spaces | point app=knowledge resource=knowledge.space action=read risk=normal page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
GET | /v1/knowledge/spaces/:spaceId | point app=knowledge resource=knowledge.space action=read risk=normal page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
GET | /v1/knowledge/spaces/:spaceId/audience-scopes | point app=knowledge resource=knowledge.audience action=read risk=normal page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
GET | /v1/knowledge/spaces/:spaceId/documents | point app=knowledge resource=knowledge.space_document action=read risk=normal page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
GET | /v1/knowledge/visibility-policies | point app=knowledge resource=knowledge.visibility_policy action=read risk=normal page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
GET | /v1/knowledge/visibility-policies/:policyId | point app=knowledge resource=knowledge.visibility_policy action=read risk=normal page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
POST | /v1/documents | point app=knowledge resource=knowledge.document action=create risk=normal page=knowledge.documents target_employee= resource_id= tenant_wide=true |
POST | /v1/documents/:documentId/versions/:versionId/publish | point app=knowledge resource=knowledge.document_version action=publish risk=high page=knowledge.documents target_employee= resource_id= tenant_wide=true |
POST | /v1/documents/:documentId/versions/:versionId/revoke | point app=knowledge resource=knowledge.document_version action=revoke risk=high page=knowledge.documents target_employee= resource_id= tenant_wide=true |
POST | /v1/knowledge/spaces | point app=knowledge resource=knowledge.space action=create risk=normal page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
POST | /v1/knowledge/spaces/:spaceId/documents | point app=knowledge resource=knowledge.space_document action=create risk=high page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
POST | /v1/knowledge/visibility-policies | point app=knowledge resource=knowledge.visibility_policy action=create risk=high page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
POST | /v1/knowledge/visibility-policies/:policyId/retire | point app=knowledge resource=knowledge.visibility_policy action=delete risk=high page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
POST | /v1/knowledge/visibility-policies/:policyId/revisions | point app=knowledge resource=knowledge.visibility_policy action=update risk=high page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
POST | /v1/knowledge/visibility-policies/:policyId/selectors | point app=knowledge resource=knowledge.visibility_policy action=update risk=high page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
PUT | /v1/documents/:documentId/visibility-override | point app=knowledge resource=knowledge.override action=update risk=high page=knowledge.documents target_employee= resource_id= tenant_wide=true |
PUT | /v1/knowledge/spaces/:spaceId | point app=knowledge resource=knowledge.space action=update risk=high page=knowledge.spaces target_employee= resource_id= tenant_wide=true |
假勤管理 · 8 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
GET | /v1/attendance/leave-type-form-options | point app=attendance resource=attendance.leave_type action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/leave-types | point app=attendance resource=attendance.leave_type action=read risk=normal page=attendance.policy target_employee= resource_id= tenant_wide=true |
GET | /v1/attendance/leave-types/:leaveTypeId | point app=attendance resource=attendance.leave_type action=read risk=normal page=attendance.policy target_employee= resource_id=leaveTypeId tenant_wide=true |
GET | /v1/leave/balances | point app=attendance resource=attendance.leave action=read risk=normal page=attendance.myleave target_employee= resource_id= tenant_wide=false |
GET | /v1/leave/records | point app=attendance resource=attendance.leave action=read risk=normal page=attendance.myleave target_employee= resource_id= tenant_wide=false |
GET | /v1/leave/types | point app=attendance resource=attendance.leave action=read risk=normal page=attendance.myleave target_employee= resource_id= tenant_wide=false |
POST | /v1/attendance/leave-types | point app=attendance resource=attendance.leave_type action=create risk=high page=attendance.policy target_employee= resource_id= tenant_wide=true |
PUT | /v1/attendance/leave-types/:leaveTypeId | point app=attendance resource=attendance.leave_type action=update risk=high page=attendance.policy target_employee= resource_id=leaveTypeId tenant_wide=true |
通知中心與持久化投遞 · 4 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
GET | /v1/me/notifications | auth_only |
GET | /v1/me/notifications/unread-count | auth_only |
POST | /v1/me/notifications/:notificationId/read | auth_only |
POST | /v1/me/notifications/read-all | auth_only |
工作流與審批 · 15 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
GET | /v1/workflow-runs | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id= tenant_wide=false |
GET | /v1/workflow-runs/:workflowRunId | point app=workflow resource=workflow.run action=read risk=normal page=workflow.form target_employee= resource_id=workflowRunId tenant_wide=false |
GET | /v1/workflows/approval-roles | point app=workflow resource=workflow.approval_role action=read risk=normal page=workflow.approval_role target_employee= resource_id= tenant_wide=true |
GET | /v1/workflows/approval-roles/:approvalRoleId | point app=workflow resource=workflow.approval_role action=read risk=normal page=workflow.approval_role target_employee= resource_id= tenant_wide=true |
GET | /v1/workflows/approval-roles/departments | point app=workflow resource=workflow.approval_role action=read risk=normal page=workflow.approval_role target_employee= resource_id= tenant_wide=true |
GET | /v1/workflows/reviews | point app=workflow resource=workflow.action action=read risk=normal page=workflow.approval target_employee= resource_id= tenant_wide=false |
POST | /v1/knowledge/audience-candidates/:candidateId/review | point app=knowledge resource=knowledge.audience action=approve risk=normal page=knowledge.documents target_employee= resource_id= tenant_wide=true |
POST | /v1/workflow-runs/:workflowRunId/approve | point app=workflow resource=workflow.action action=approve risk=high page=workflow.approval target_employee= resource_id=workflowRunId tenant_wide=false |
POST | /v1/workflow-runs/:workflowRunId/reject | point app=workflow resource=workflow.action action=reject risk=high page=workflow.approval target_employee= resource_id=workflowRunId tenant_wide=false |
POST | /v1/workflow-runs/:workflowRunId/return | point app=workflow resource=workflow.action action=return risk=high page=workflow.approval target_employee= resource_id=workflowRunId tenant_wide=false |
POST | /v1/workflow-runs/:workflowRunId/withdraw | point app=workflow resource=workflow.run action=withdraw risk=high page=workflow.form target_employee= resource_id=workflowRunId tenant_wide=true |
POST | /v1/workflows/approval-roles | point app=workflow resource=workflow.approval_role action=create risk=high page=workflow.approval_role target_employee= resource_id= tenant_wide=true |
POST | /v1/workflows/approval-roles/:approvalRoleId/preview | point app=workflow resource=workflow.approval_role action=read risk=normal page=workflow.approval_role target_employee= resource_id= tenant_wide=true |
POST | /v1/workflows/reviews/bulk-action | point app=workflow resource=workflow.action action=batch risk=high page=workflow.approval target_employee= resource_id= tenant_wide=false |
PUT | /v1/workflows/approval-roles/:approvalRoleId | point app=workflow resource=workflow.approval_role action=update risk=high page=workflow.approval_role target_employee= resource_id= tenant_wide=true |
工作紀錄與待辦 · 10 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
DELETE | /v1/me/todos/:todoId | point app=worklog resource=worklog.todo action=delete risk=high page=workflow.task target_employee= resource_id=todoId tenant_wide=false |
DELETE | /v1/me/worklogs/:entryId | point app=worklog resource=worklog.entry action=delete risk=high page=workflow.task target_employee= resource_id=entryId tenant_wide=false |
GET | /v1/me/todos | point app=worklog resource=worklog.todo action=read risk=normal page=workflow.task target_employee= resource_id= tenant_wide=false |
GET | /v1/me/worklog-options | point app=worklog resource=worklog.entry action=read risk=normal page=workflow.task target_employee= resource_id= tenant_wide=false |
GET | /v1/me/worklogs | point app=worklog resource=worklog.entry action=read risk=normal page=workflow.task target_employee= resource_id= tenant_wide=false |
GET | /v1/me/worklogs/summary | point app=worklog resource=worklog.entry action=read risk=normal page=workflow.task target_employee= resource_id= tenant_wide=false |
POST | /v1/me/todos | point app=worklog resource=worklog.todo action=create risk=normal page=workflow.task target_employee= resource_id= tenant_wide=false |
POST | /v1/me/worklogs | point app=worklog resource=worklog.entry action=create risk=normal page=workflow.task target_employee= resource_id= tenant_wide=false |
PUT | /v1/me/todos/:todoId | point app=worklog resource=worklog.todo action=update risk=normal page=workflow.task target_employee= resource_id=todoId tenant_wide=false |
PUT | /v1/me/worklogs/:entryId | point app=worklog resource=worklog.entry action=update risk=normal page=workflow.task target_employee= resource_id=entryId tenant_wide=false |
工作台、個人資訊與審計入口 · 2 筆路由
| 方法 | 路徑 | 授權宣告 |
|---|---|---|
GET | /v1/workspace/overview | point app=hr resource=hr.workspace_overview action=read risk=normal page= target_employee= resource_id= tenant_wide=false |
GET | /v1/workspace/overview/todos | point app=hr resource=hr.workspace_todo action=read risk=normal page= target_employee= resource_id= tenant_wide=false |
前端頁面清單
Route group 括號不構成 URL;例如 app/(platform)/iam/roles/page.tsx 的路徑是 /iam/roles。catch-all 會區分宣告頁待開發、目錄落點、未登錄節點與不存在路徑,不能把它渲染成功當成功能完成。
page.tsx 存在也不等於已接 API:/assistants、/dashboard、/history 是 RoutePlaceholder 佔位頁;/workspace/audit-log 讀 _fixtures/ 示意資料;/notifications 渲染的是待辦審核(features/reviews),通知收件匣在頂欄鈴鐺。
已找到 33 個 page.tsx,包括公開頁、設計系統與 catch-all。
app/(auth)/login/page.tsxapp/(auth)/register/page.tsxapp/(platform)/(home)/page.tsxapp/(platform)/[...segments]/page.tsxapp/(platform)/assistants/page.tsxapp/(platform)/dashboard/page.tsxapp/(platform)/forms/page.tsxapp/(platform)/history/page.tsxapp/(platform)/hr/org/page.tsxapp/(platform)/hr/positions/page.tsxapp/(platform)/iam/access/page.tsxapp/(platform)/iam/catalog/page.tsxapp/(platform)/iam/groups/page.tsxapp/(platform)/iam/roles/page.tsxapp/(platform)/myleave/page.tsxapp/(platform)/notifications/page.tsxapp/(platform)/tasks/page.tsxapp/(platform)/workspace/(overview)/page.tsxapp/(platform)/workspace/approval-roles/page.tsxapp/(platform)/workspace/attendance/page.tsxapp/(platform)/workspace/audit-log/page.tsxapp/(platform)/workspace/clock/page.tsxapp/(platform)/workspace/employees/page.tsxapp/(platform)/workspace/forms/page.tsxapp/(platform)/workspace/leave-policy/page.tsxapp/(platform)/workspace/turnover/page.tsxapp/(public)/403/page.tsxapp/(public)/404/page.tsxapp/(public)/privacy/page.tsxapp/(public)/terms/page.tsxapp/design-system/cards/page.tsxapp/design-system/feedback/page.tsxapp/design-system/page.tsx
更新索引的操作步驟
在文件站根目錄執行以下命令。兩個業務 checkout 必須位於相鄰目錄;命令僅讀取路由快照與檔案路徑,不啟動服務、不讀 .env。
node scripts/inventory.mjs --check若有漂移,先閱讀新路由實作、補上對應章節與狀態,再執行 node scripts/inventory.mjs 更新快照。新路徑若沒有章節映射會明確失敗,禁止把新功能偷偷塞進「其他」。
預期結果與驗證
每個登錄路由應能回到一篇開發指南;每個主要業務板塊都能在上表指出後端範圍、前端證據與限制,並在各章找到驗證案例。透過本站搜尋實際函式名或 API 路徑時,應能找到有正文說明的章節。查不到請先核對該路徑是否只有清單、尚未被教學提及。
清單中的 API 路徑也會進入對應章節的搜尋索引;這是檢索入口,不冒充逐端點教學。完整 wire schema 仍需讀 OpenAPI。--check 驗證快照與來源一致,內容測試驗證映射章節存在。
常見錯誤
- 看到知識庫空間或 JML run 的路由與資料表就認定有 UI:兩者目前僅後端,請再核對前端頁面與 hook。
- 把
RoutePlaceholder、fixture 頁面或 catch-all 的「待開發」畫面當成功能完成。 - 看到測試名稱就寫「聯調完成」:沒有本輪執行證據只能寫測試入口。
- 從 API 清單直接複製寫入請求到共享環境:先取得授權、確認租戶及可恢復測試資料。
- 因為過期任務板寫「未開始」就刪掉已有功能文件:以當前原始碼為準。