GRC 專案 API 規格

Blueprint prefix/api/1.0/grc Fileapi/grc/routes/project_route.py Auth:JWT Required(Header:Authorization: Bearer <token>


API 列表

Method URL 說明
GET /api/1.0/grc/projects/menu 專案選單(無分頁)
POST /api/1.0/grc/projects/list 專案列表(分頁 + 篩選)
GET /api/1.0/grc/project/<uid> 單筆專案詳細(含稽核系統、設備)
PUT /api/1.0/grc/project/<uid> 更新專案設定
DELETE /api/1.0/grc/project/<uid> 刪除專案(軟刪除,僅 admin / owner)
POST /api/1.0/grc/project/<project_uid>/control-groups/list 控制群組列表(分頁)
GET /api/1.0/grc/project/<project_uid>/control-group/<group_uid> 單筆控制群組詳細
POST /api/1.0/grc/project/<project_uid>/control-group/<group_uid>/controls/list 控制項列表(分頁)
GET /api/1.0/grc/project/<project_uid>/control-group/<group_uid>/control/<control_uid> 單筆控制項詳細
POST /api/1.0/grc/project/<project_uid>/control-group/<group_uid>/control/<control_uid>/assessment-objects/list AO 列表(分頁)
POST /api/1.0/grc/project/<project_uid>/control-group/<group_uid>/control/<control_uid>/assessment-object/<ao_uid>/jobs/list AO 下的 Job 列表(分頁)
GET /api/1.0/grc/project/<project_uid>/job/<job_uid> 取得單筆 Job
PUT /api/1.0/grc/project/<project_uid>/job/<job_uid> 更新 Job(基本資料 + 指派人 / 部門 / 設備 / 問卷)
DELETE /api/1.0/grc/project/<project_uid>/job/<job_uid> 刪除 Job(硬刪除)
POST /api/1.0/grc/project/<project_uid>/assessment-object/<ao_uid>/jobs 新增 Job
POST /api/1.0/grc/jobs/my/list 取得目前登入使用者的所有 GRC 任務
GET /api/1.0/grc/project/<project_uid>/task-setup/tree Task Setup 樹狀結構

1. GET /api/1.0/grc/projects/menu

Route classProjectMenuResource 用途:取得精簡專案列表,供前端下拉選單或導覽使用。

Request

位置 欄位 必填 說明
Query search 名稱關鍵字模糊搜尋
GET /api/1.0/grc/projects/menu?search=CMMC

Response 200

{
  "status": true,
  "data": [
    { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "2026 CMMC 2.0 稽核", "status": "in_progress" },
    { "id": "660e9511-f30c-52e5-b827-557766551111", "name": "ISO 27001 評估", "status": "pending" }
  ]
}

Response 欄位說明

欄位 型別 說明
id string 專案 UID
name string 專案名稱
status string 專案狀態(見 Status Enum)

可見性規則

  • 管理員:回傳所有未軟刪除專案
  • 一般使用者:僅回傳自己為 owner 或 participant 的專案

2. POST /api/1.0/grc/projects/list

Route classProjectListResource 用途:取得分頁專案列表,支援排序、篩選,含 OSCAL AP 即時計算欄位。

Request Body

{
  "pager": { "page": 1, "page_size": 20, "with_total": true },
  "sort":  [{ "field": "name", "order": "asc" }],
  "filters": {
    "search": "CMMC",
    "status": "in_progress"
  }
}

filters 欄位說明

欄位 型別 必填 說明
search string | null 專案名稱關鍵字(ilike)
status string | null 篩選狀態(見 Status Enum)

可排序欄位(sort[].field

對應欄位
name compliance.projects.name
start_date compliance.projects.start_date
end_date compliance.projects.end_date
status compliance.projects.status

Response 200

{
  "status": true,
  "data": {
    "meta": {
      "paging": true,
      "page": 1,
      "page_size": 20,
      "total": 3,
      "total_pages": 1,
      "has_next": false,
      "has_prev": false
    },
    "data": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "2026 CMMC 2.0 Level 2 稽核",
        "description": "DoD 供應鏈合規年度評估",
        "status": "in_progress",
        "completion_rate": 42,
        "control_group_count": 14,
        "total_controls": 110,
        "total_assessment_objects": 110,
        "start_date": "2026-01-01",
        "end_date": "2026-12-31",
        "framework": {
          "id": "fw-uid-0001",
          "name": "CMMC 2.0",
          "short_name": "CMMC"
        },
        "compliance_resource": {
          "uid": "ap-uid-0001",
          "name": "2026 CMMC AP"
        },
        "owner": {
          "id": "u-uid-0001",
          "name": "Alice Chen",
          "avatar_url": null
        },
        "participants": [
          {
            "id": "u-uid-0002",
            "name": "Bob Wang",
            "is_admin": false,
            "role": null
          }
        ]
      }
    ]
  }
}

3. GET /api/1.0/grc/project/<uid>

Route classProjectDetailResource 用途:依 UID 取得單筆專案完整資料,包含稽核系統(audit_systems)與設備(devices)。

Request

無 Request Body,UID 從 URL path 取得。

GET /api/1.0/grc/project/550e8400-e29b-41d4-a716-446655440000

Response 200

{
  "status": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "2026 CMMC 2.0 Level 2 稽核",
    "description": "DoD 供應鏈合規年度評估",
    "status": "in_progress",
    "completion_rate": 42,
    "control_group_count": 14,
    "total_controls": 110,
    "total_assessment_objects": 110,
    "start_date": "2026-01-01",
    "end_date": "2026-12-31",
    "framework": {
      "id": "fw-uid-0001",
      "name": "CMMC 2.0",
      "short_name": "CMMC"
    },
    "compliance_resource": {
      "uid": "ap-uid-0001",
      "name": "2026 CMMC AP"
    },
    "owner": {
      "id": "u-uid-0001",
      "name": "Alice Chen",
      "avatar_url": null
    },
    "participants": [
      {
        "id": "u-uid-0002",
        "name": "Bob Wang",
        "is_admin": false,
        "role": null
      }
    ],
    "audit_systems": [
      {
        "id": "a1b2c3d4-0001-0000-0000-000000000001",
        "name": "核心業務系統",
        "abbreviation": "CBS"
      },
      {
        "id": "b2c3d4e5-0002-0000-0000-000000000002",
        "name": "人資管理系統",
        "abbreviation": "HRM"
      }
    ],
    "devices": [
      {
        "id": "dev-uid-0001",
        "name": "SSO Gateway",
        "device_type": "hardware"
      },
      {
        "id": "dev-uid-0002",
        "name": "API Server",
        "device_type": "server"
      }
    ]
  }
}

Response 欄位說明

頂層欄位

欄位 型別 說明
id string 專案 UID
name string 專案名稱
description string | null 專案描述
status string 專案狀態(見 Status Enum)
completion_rate integer 完成率 0–100(OSCAL AP tasks 完成比例即時計算)
control_group_count integer AP 下的 control group 數量(即時計算)
total_controls integer AP 下的 control 總數(即時計算)
total_assessment_objects integer AP 下的 assessment task 總數(即時計算)
start_date string YYYY-MM-DD | null 專案起始日期
end_date string YYYY-MM-DD | null 專案結束日期

framework

欄位 型別 說明
id string OscalFramework.uid
name string 框架全名(如 CMMC 2.0
short_name string 框架代碼(如 CMMC

來源:ModuleFrame.oscal_framework_version_uidOscalFrameworkVersionOscalFramework 若專案無對應 module frame,回傳 null

compliance_resource

欄位 型別 說明
uid string OscalAssessmentPlan.uid
name string AP 名稱

來源:compliance.project_assessment_plan_mappingoscal.assessment_plans

owner

欄位 型別 說明
id string users.uid
name string 使用者顯示名稱(nickname
avatar_url string | null 頭像 URL(目前固定 null

來源:compliance.project_extensions.owner_idpublic.users

participants[]

欄位 型別 說明
id string 使用者 UID
name string 使用者顯示名稱
is_admin boolean 是否為管理員
role string | null 角色名稱

來源:compliance.project_participants JOIN public.users

audit_systems[](稽核系統)

欄位 型別 說明
id string 資訊系統 UID(compliance.information_systems.uid
name string 系統全名
abbreviation string | null 系統縮寫

來源:compliance.project_information_systemscompliance.information_systems 為空陣列時表示此專案未關聯任何稽核系統。

devices[](設備)

欄位 型別 說明
id string 設備 UID
name string 設備名稱
device_type string | null 設備類型(如 hardwareserversoftware

來源:compliance.project_device_mappingdevices 為空陣列時表示此專案未關聯任何設備。


錯誤情境

200 — 找不到(回傳 status false)

{
  "status": false,
  "data": {}
}

找不到專案,或使用者無可見權限時回傳此格式(非 404)。


4. PUT /api/1.0/grc/project/<uid>

Route classProjectDetailResource.put 用途:更新 GRC 專案設定。所有欄位均為選填;audit_systems / participants / devices 提供時整組替換,不提供(null / 未傳)時保持不動。

Request Body

{
  "name": "Updated Project Name",
  "description": "更新說明",
  "start_date": "2026-01-01",
  "end_date": "2026-12-31",
  "status": "in_progress",
  "owner_uid": "u-uid-0001",
  "audit_systems": [
    { "information_system_uid": "a1b2c3d4-0001-0000-0000-000000000001" },
    { "information_system_uid": "b2c3d4e5-0002-0000-0000-000000000002" }
  ],
  "participants": [
    { "user_uid": "u-uid-0002", "is_admin": false },
    { "user_uid": "u-uid-0003", "is_admin": true }
  ],
  "devices": [
    { "device_uid": "dev-uid-0001" }
  ]
}

欄位說明

欄位 型別 必填 說明
name string | null 專案名稱,有值才更新
description string | null 專案描述,有值才更新
start_date string YYYY-MM-DD | null 起始日期,有值才更新
end_date string YYYY-MM-DD | null 結束日期,有值才更新
status string | null 狀態(見 Status Enum),有值才更新
owner_uid string | null 新 owner 的使用者 UID,有值才更新
audit_systems array | null 稽核系統清單,提供時全量替換[] 代表清空)
participants array | null 參與者清單,提供時全量替換;owner 不可被移除
devices array | null 設備清單,提供時全量替換[] 代表清空)

最簡更新(僅改名稱)

{ "name": "New Project Name" }

清空所有設備

{ "devices": [] }

Response 200

回傳更新後的專案完整資料,格式與 GET /api/1.0/grc/project/<uid> 相同(含 audit_systemsdevicesparticipants)。

{
  "status": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Updated Project Name",
    "...": "..."
  }
}

參與者同步規則

new_participants = 傳入的 participants 清單
current_participants = 目前 DB 中的參與者

新增:new_participants 中不在 current 的 → add_project_participant()
移除:current 中不在 new_participants 的 → delete_project_participant()
保護:owner(project_extensions.owner_id)即使不在 new_participants,也不會被移除

注意:owner 若想變更,需透過 owner_uid 欄位指定,不是從 participants 中判斷。

後端執行流程

PUT /api/1.0/grc/project/<uid>
│
├─ 可見性檢查(同 GET,非 admin 只能更新自己可見的專案)
├─ Step 1  更新基本資訊(compliance.projects)
│           name / description / start_date / end_date / status
├─ Step 2  更新 owner(compliance.project_extensions.owner_id)
│           owner_uid → users.id via UserDomainService
├─ Step 3  稽核系統替換(compliance.project_information_systems)
│           DELETE 全部舊的 → INSERT 新的(依 information_system_uid 查詢 id)
├─ Step 4  參與者同步(compliance.project_participants)
│           新增缺少的 → 刪除多餘的(owner 保護)
│           add_project_participant 同步更新 oscal_metadatas SSP parties
│           delete_project_participant 同步更新 oscal_metadatas SSP parties
├─ Step 5  設備替換(compliance.project_device_mapping)
│           新增缺少的 → ProjectDeviceMappingService.add()
│           刪除多餘的 → ProjectDeviceMappingService.delete()
│           同步更新 oscal.system_security_plan_system_implementations
└─ 回傳更新後的完整專案資料(同 GET)

錯誤情境

200 status false — 找不到或無權限

{ "status": false, "data": {} }

5. DELETE /api/1.0/grc/project/<uid>

Route classProjectDetailResource.delete 用途:軟刪除 GRC 專案(設定 project_extensions.deleted_at)。刪除後專案立即從所有列表消失,但 OSCAL AP 資料完整保留。

Request

無 Request Body,UID 從 URL path 取得。

DELETE /api/1.0/grc/project/550e8400-e29b-41d4-a716-446655440000

權限規則

身份 可刪除
is_admin = true 所有專案
is_admin = false AND owner 自己擁有的專案
is_admin = false AND 非 owner ❌ 403

查詢時 bypass 可見性限制(admin 可刪除任何專案,owner 可刪除自己的即使不在參與者清單)。

Response 200 — 成功

{
  "status": true,
  "data": {}
}

錯誤情境

HTTP 狀況 Body
404 專案不存在 {"status": false, "data": {}, "msg": "Not found"}
403 非 admin 且非 owner {"status": false, "data": {}, "msg": "Forbidden"}

後端執行流程

DELETE /api/1.0/grc/project/<uid>
│
├─ get_project(uid, is_admin=True)   ← bypass 可見性
│   找不到 → NotFound (404)
├─ not is_admin AND entity.owner_id != user_id → ForbiddenError (403)
└─ soft_delete_project(uid)
    └─ UPDATE project_extensions SET deleted_at = now()
        WHERE project_id = (SELECT id FROM projects WHERE uid = ?)
        AND deleted_at IS NULL

6. POST /api/1.0/grc/project/<project_uid>/control-groups/list

Route classProjectControlGroupListResource 用途:取得專案下的控制群組列表(分頁),含狀態分布與 URL 參數 project_id(為 project_uid,保持相容)。

Request Body

{
  "pager": { "page": 1, "page_size": 25, "with_total": true },
  "sort": [{ "field": "order_no", "order": "asc" }],
  "filters": {
    "keyword": "Access",
    "status": "in_progress"
  }
}

Response 200

{
  "status": true,
  "data": {
    "meta": { "paging": true, "page": 1, "page_size": 25, "total": 14 },
    "data": [
      {
        "id": "group-uid-0001",
        "name": "Access Control",
        "code": "AC",
        "description": "存取控制相關要求",
        "order_no": 1,
        "status": "in_progress",
        "total_controls": 8,
        "completed_controls": 3,
        "completion_rate": 37,
        "status_breakdown": {
          "not_started": 5,
          "in_progress": 3,
          "completed": 0
        }
      }
    ]
  }
}

7. GET /api/1.0/grc/project/<project_uid>/control-group/<group_uid>

Route classProjectControlGroupDetailResource 用途:取得單筆控制群組完整資料。

Response 200

同上方列表單筆欄位,加上 participant[](群組成員)。


8. POST .../control-group/<group_uid>/controls/list

完整 URL/api/1.0/grc/project/<project_uid>/control-group/<group_uid>/controls/list Route classProjectControlListResource 用途:取得控制群組下的控制項列表(分頁)。

Request Body

{
  "pager": { "page": 1, "page_size": 25, "with_total": true },
  "sort": [],
  "filters": { "keyword": null, "status": null }
}

Response 200

{
  "status": true,
  "data": {
    "meta": { "paging": true, "page": 1, "page_size": 25, "total": 8 },
    "data": [
      {
        "id": "ctrl-uid-0001",
        "workflow_execution_id": 1024,
        "control_id": "AC.1.001",
        "name": "Limit system access to authorized users",
        "description": "...",
        "status": "in_progress",
        "total_ao": 3,
        "completed_ao": 1,
        "completion_rate": 33
      }
    ]
  }
}

workflow_execution_id:此控制項對應的 workflow execution ID,更新 Job assignees 時須作為 control_id 傳入。


9. GET .../control/<control_uid>

完整 URL/api/1.0/grc/project/<project_uid>/control-group/<group_uid>/control/<control_uid> Route classProjectControlDetailResource 用途:取得單筆控制項完整資料。


10. POST .../assessment-objects/list

完整 URL/api/1.0/grc/project/<project_uid>/control-group/<group_uid>/control/<control_uid>/assessment-objects/list Route classProjectAOListResource 用途:取得控制項下的 Assessment Object 列表(分頁)。

Response 欄位說明

欄位 型別 說明
id string OscalAssessmentPlanTask.uid
code string AO 代碼(如 CMMC.AC.1.001.E1
name string AO 名稱
description string | null AO 描述
status string pending / in_progress / completed

11. POST .../jobs/list

完整 URL/api/1.0/grc/project/<project_uid>/control-group/<group_uid>/control/<control_uid>/assessment-object/<ao_uid>/jobs/list Route classProjectJobListResource 用途:取得指定 Assessment Object 下的 Job 列表(分頁)。

注意:URL 中的 project_uidgroup_uidcontrol_uid 僅作為路徑參數存在,實際查詢只使用 ao_uid

Request Body

{
  "pager": { "page": 1, "page_size": 100, "with_total": true },
  "sort": []
}

Response 200

{
  "status": true,
  "data": {
    "meta": { "paging": true, "page": 1, "page_size": 100, "total": 2 },
    "data": [
      {
        "id": "job-uid-0001",
        "name": "Upload MFA Configuration Evidence",
        "description": "Verify that MFA is implemented for all privileged accounts.",
        "guide": "Upload screenshots showing MFA is enabled on all administrator accounts.",
        "task_type": "general",
        "status": "not_started",
        "template_job_id": "UserTask_3a9f1c2b",
        "assignees": [
          { "id": "u-uid-0001", "name": "Alice Chen", "avatar": "AC" }
        ],
        "departments": [
          { "id": "dept-uid-0001", "name": "IT Security" }
        ],
        "devices": [
          { "id": "dev-uid-0001", "name": "SSO Gateway", "device_type": "hardware" }
        ],
        "questionnaires": []
      }
    ]
  }
}

Response 欄位說明

欄位 型別 說明
id string job_executions.uid
name string Job 名稱
description string | null Job 描述
guide string | null 操作指引(儲存於 job_executions.guide
task_type string general / questionnaire
status string not_started / in_progress / completed(由 JobExecution.status enum 轉換)
template_job_id string | null job_executions.template_job_id(BPMN 節點 ID),搭配 workflow_execution_uid 呼叫完成/退回任務 API
assignees[].id string users.uid
assignees[].name string 使用者顯示名稱
assignees[].avatar string | null 名字縮寫(如 "AC"
departments[].id string org_units.uid
departments[].name string 部門名稱
devices[].id string devices.uid
devices[].name string 設備名稱
devices[].device_type string | null 設備類型
questionnaires[].id string surveys.uid
questionnaires[].name string 問卷名稱
questionnaires[].question_count integer 題目數量

資料來源

資料 資料表
Jobs job_executions WHERE workflow_execution_id = (由 ao_uidassessment_plan_task_workflow_execution_mapping),且 type = 'USER'
Assignees compliance.task_assignees JOIN users
Departments compliance.job_execution_org_units JOIN org_units
Devices compliance.job_execution_devices JOIN devices
Questionnaires compliance.job_execution_surveys JOIN surveys

12. PUT /api/1.0/grc/project/<project_uid>/job/<job_uid>

Route classProjectJobDetailResource 用途:更新 GRC Job 基本資訊、指派人、部門、設備、問卷(陣列欄位為全量替換)。

Request Body

{
  "name": "Upload MFA Evidence",
  "description": "Verify that MFA is implemented.",
  "guide": "Upload screenshots showing MFA is enabled on all administrator accounts.",
  "task_type": "general",
  "control_uid": "wf-ctrl-uid-0001",
  "assignee_uids": ["u-uid-0001", "u-uid-0002"],
  "department_uids": ["dept-uid-0001"],
  "device_uids": ["dev-uid-0001"],
  "survey_uids": ["survey-uid-0001"]
}

欄位說明

欄位 型別 必填 說明
name string | null Job 名稱,有值才更新
description string | null Job 描述,有值才更新
guide string | null 操作指引,有值才更新
task_type "general" | "questionnaire" | null 任務類型,有值才更新
control_uid string | null 控制項層級的 workflow_execution.uid可省略,系統先嘗試 uid 查詢 id,失敗時再從 job → workflow_execution.parent_id 自動推算;兩者皆失敗才略過 assignee 更新
assignee_uids string[] | null 指派人 UID 清單;提供時全量替換[] = 清空,不需 control_id),null = 不動
department_uids string[] | null 部門 UID 清單;提供時全量替換
device_uids string[] | null 設備 UID 清單;提供時全量替換
survey_uids string[] | null 問卷 UID 清單;提供時全量替換

control_id 取得方式:呼叫 POST .../controls/list 時,回應中每筆控制項包含 workflow_execution_id 欄位,即為此處的 control_id

替換語意(陣列欄位共用)

傳入值 行為
null(未傳) 略過,保持現有關聯不動
[](空陣列) 清空所有現有關聯
["uid1", "uid2"] 刪除全部舊關聯,寫入新關聯

assignee_uids 特別說明control_id 可省略,系統自動從 job → workflow_execution.parent_id 推算控制項層級 ID。僅在系統無法自動推算時才會略過 assignee 更新。

最簡更新(僅改名稱)

{ "name": "New Job Name" }

清空所有指派人

{ "assignee_uids": [], "control_id": 1024 }

Response 200

{
  "status": true,
  "data": {
    "id": "job-uid-0001",
    "name": "Upload MFA Evidence",
    "description": "Verify that MFA is implemented.",
    "guide": "Upload screenshots showing MFA is enabled on all administrator accounts.",
    "task_type": "general",
    "status": "not_started",
    "assignees": [
      { "id": "u-uid-0001", "name": "Alice Chen", "avatar": "AC" },
      { "id": "u-uid-0002", "name": "Bob Wang", "avatar": "BW" }
    ],
    "departments": [
      { "id": "dept-uid-0001", "name": "IT Security" }
    ],
    "devices": [
      { "id": "dev-uid-0001", "name": "SSO Gateway", "device_type": "hardware" }
    ],
    "questionnaires": [
      { "id": "survey-uid-0001", "name": "MFA Compliance Survey", "question_count": 12 }
    ]
  }
}

後端執行流程

PUT /api/1.0/grc/project/<project_uid>/job/<job_uid>
│
├─ Step 1  查找 job_execution WHERE uid = job_uid AND type = 'USER'
│           找不到 → 404
├─ Step 2  更新 scalar 欄位(有值才更新)
│           name / description / guide / task_type → job_executions
├─ Step 3  替換 assignees(assignee_uids != null)
│           assignee_uids=[]  → DELETE task_assignees WHERE task_id = job.id
│           assignee_uids=[..] → 自動推算 control_id(若未傳):
│                                  job.workflow_execution_id → WorkflowExecution.parent_id
│                            → DELETE task_assignees WHERE task_id = job.id
│                            → INSERT 新 assignees(project_id + resolved_control_id + user_id)
├─ Step 4  替換 departments(department_uids != null)
│           DELETE compliance.job_execution_org_units WHERE job_execution_id = job.id
│           INSERT 新 org_unit 關聯
├─ Step 5  替換 devices(device_uids != null)
│           DELETE compliance.job_execution_devices WHERE job_execution_id = job.id
│           INSERT 新 device 關聯
├─ Step 6  替換 surveys(survey_uids != null)
│           DELETE compliance.job_execution_surveys WHERE job_execution_id = job.id
│           INSERT 新 survey 關聯
├─ flush + expire(job)
└─ get_job(job_uid) → 回傳最新完整資料

錯誤情境

404 — Job 找不到

{ "status": false, "data": {}, "msg": "Job not found" }

13. GET /api/1.0/grc/project/<project_uid>/job/<job_uid>

Route classProjectJobDetailResource.get 用途:依 UID 取得單筆 GRC Job 完整資料(含 assignees / departments / devices / surveys)。

Request

無 Request Body,UID 從 URL path 取得。

GET /api/1.0/grc/project/550e8400-e29b-41d4-a716-446655440000/job/job-uid-0001

Response 200

{
  "status": true,
  "data": {
    "id": "job-uid-0001",
    "name": "Upload MFA Configuration Evidence",
    "description": "Verify that MFA is implemented for all privileged accounts.",
    "guide": "Upload screenshots showing MFA is enabled on all administrator accounts.",
    "job_type": "general",
    "status": "not_started",
    "template_job_id": "UserTask_3a9f1c2b",
    "assignees": [
      { "id": "u-uid-0001", "name": "Alice Chen", "avatar": null }
    ],
    "departments": [
      { "id": "dept-uid-0001", "name": "IT Security" }
    ],
    "devices": [
      { "id": "dev-uid-0001", "name": "SSO Gateway", "device_type": "hardware" }
    ],
    "surveys": [
      { "id": "survey-uid-0001", "name": "MFA Compliance Survey", "question_count": 12 }
    ]
  }
}

錯誤情境

HTTP 狀況
404 {"status": false, "data": {}, "msg": "Job not found"}

14. POST /api/1.0/grc/project/<project_uid>/assessment-object/<ao_uid>/jobs

Route classProjectJobCreateResource 用途:在指定 Assessment Object 下新增一筆 Job。

Request Body

{
  "name": "Upload MFA Evidence",
  "description": "Verify that MFA is implemented.",
  "guide": "Upload screenshots showing MFA is enabled on all administrator accounts.",
  "job_type": "general",
  "control_uid": "wf-ctrl-uid-0001",
  "assignee_uids": ["u-uid-0001"],
  "department_uids": ["dept-uid-0001"],
  "device_uids": ["dev-uid-0001"],
  "survey_uids": []
}

欄位說明

欄位 型別 必填 說明
name string Job 名稱
description string | null Job 描述
guide string | null 操作指引
job_type "general" | "questionnaire" | null 任務類型,預設 "general"
control_uid string | null 控制項層級的 workflow_execution.uid;省略時略過 assignee 寫入
assignee_uids string[] | null 指派人 UID 清單
department_uids string[] | null 部門 UID 清單
device_uids string[] | null 設備 UID 清單
survey_uids string[] | null 問卷 UID 清單

Response 200

回傳新建立的 Job 完整資料,格式與 GET 單筆相同。

{
  "status": true,
  "data": {
    "id": "job-uid-new-0001",
    "name": "Upload MFA Evidence",
    "description": "Verify that MFA is implemented.",
    "guide": "Upload screenshots showing MFA is enabled on all administrator accounts.",
    "job_type": "general",
    "status": "not_started",
    "template_job_id": null,
    "assignees": [
      { "id": "u-uid-0001", "name": "Alice Chen", "avatar": null }
    ],
    "departments": [],
    "devices": [],
    "surveys": []
  }
}

template_job_id:手動新增的 Job 使用 UUID4 作為 template_job_id(非 BPMN 節點 ID)。

後端執行流程

POST /api/1.0/grc/project/<project_uid>/assessment-object/<ao_uid>/jobs
│
├─ 查找 ao_uid → assessment_plan_task_workflow_execution_mapping → workflow_execution_id
│   找不到 → 回傳 status false
├─ 建立 JobExecution(status=PROCESSING, type=USER, template_job_id=uuid4)
├─ 寫入 task_assignees(需 control_uid 解析 control_id;省略則略過)
├─ 寫入 job_execution_org_units
├─ 寫入 job_execution_devices
├─ 寫入 job_execution_surveys
└─ 回傳 get_job(new_uid)

錯誤情境

{ "status": false, "data": null }

AO 找不到或 workflow_execution 對應不到時回傳此格式。


15. DELETE /api/1.0/grc/project/<project_uid>/job/<job_uid>

Route classProjectJobDetailResource.delete 用途:硬刪除指定 Job(同時刪除所有關聯資料)。

Request

無 Request Body,UID 從 URL path 取得。

DELETE /api/1.0/grc/project/550e8400-e29b-41d4-a716-446655440000/job/job-uid-0001

Response 200

{
  "status": true,
  "data": true
}

後端執行流程

DELETE → job_execution WHERE uid = job_uid
  ├─ DELETE task_assignees WHERE task_id = job.id
  ├─ DELETE job_execution_org_units WHERE job_execution_id = job.id
  ├─ DELETE job_execution_devices WHERE job_execution_id = job.id
  ├─ DELETE job_execution_surveys WHERE job_execution_id = job.id
  └─ DELETE job_executions WHERE id = job.id

錯誤情境

HTTP 狀況
404 {"status": false, "data": {}, "msg": "Job not found"}

16. POST /api/1.0/grc/jobs/my/list

Route classMyJobListResource 用途:取得目前登入使用者的所有 GRC 任務(DB 層過濾 + 排序 + 分頁,資料來源為 vw_user_job_queue)。 注意:已固定排除 project.status = 'archived' 的專案資料。

Request Body

{
  "pager": { "page": 1, "page_size": 25, "with_total": true },
  "sort": [{ "field": "job_name", "order": "asc" }],
  "filters": {
    "keyword": "MFA",
    "status": "not_started",
    "exclude_status": null,
    "project_uid": "550e8400-e29b-41d4-a716-446655440000",
    "group_keyword": "Access",
    "control_code": "AC.1",
    "ao_keyword": "Examine"
  }
}

filters 欄位說明

欄位 型別 說明
keyword string | null 跨欄位模糊搜尋(job 名稱、專案名稱、控制群組名稱、控制項編號、AO 描述)
status string | null Job 狀態篩選(not_started / in_progress / completed),與 exclude_status 擇一使用
exclude_status string | null 排除指定狀態,與 status 擇一使用
project_uid string | null 篩選特定專案(精確比對)
group_keyword string | null 控制項群組名稱/描述模糊搜尋
control_code string | null 控制項編號模糊搜尋(如 "AC.1" 會匹配 AC.1.001
ao_keyword string | null AO 代碼或描述模糊搜尋

sort[].field 可排序欄位

說明
job_name Job 名稱
job_status Job 狀態
job_type Job 類型(general / questionnaire
project_name 專案名稱
group_name 控制項群組名稱
control_no 控制項編號
ao_code 評估物件代碼

Response 200

{
  "status": true,
  "data": {
    "meta": { "paging": true, "page": 1, "page_size": 25, "total": 5 },
    "data": [
      {
        "id": "job-uid-0001",
        "name": "Upload MFA Evidence",
        "task_type": "general",
        "status": "not_started",
        "project_uid": "550e8400-e29b-41d4-a716-446655440000",
        "project_name": "2026 CMMC 2.0 Level 2 稽核",
        "control_group_id": "group-uid-0001",
        "control_group_code": "AC",
        "control_group": "Access Control",
        "control_uid": "ctrl-uid-0001",
        "control_code": "AC.1.001",
        "control_name": "Limit system access to authorized users",
        "ao_code": "CMMC.AC.1.001.E1",
        "ao_name": "Examine: Access control policy",
        "ao_id": "ao-uid-0001",
        "workflow_execution_uid": "88072e77-56f2-4d4c-9197-f83a454ffa89"
      }
    ]
  }
}

Response 欄位說明(My Jobs)

欄位 型別 說明
id string job_executions.uid
name string Job 名稱
task_type string general / questionnaire
status string not_started / in_progress / completed
project_uid string | null 所屬專案 UID
project_name string | null 所屬專案名稱
control_group_id string | null 控制群組 UID
control_group_code string | null 控制群組代碼(group_name
control_group string | null 控制群組說明(group_description
control_uid string | null 控制項 UID
control_code string | null 控制項編號
control_name string | null 控制項名稱
ao_code string | null Assessment Object 代碼
ao_name string | null Assessment Object 說明
ao_id string | null Assessment Object UID
workflow_execution_uid string | null 對應的 workflow_executions.uid,供前端呼叫完成/退回任務 API 使用

workflow_execution_uid 來源job_executions.workflow_execution_idworkflow_executions.uid,由 get_user_task_queue SP 回傳。


Status Enum

說明
pending 待開始
in_progress 進行中
completed 已完成
suspended 暫停中
archived 已封存

可見性規則(所有 GRC 專案 API)

若 is_admin = true  → 可見所有專案
若 is_admin = false → 僅可見:
    ① 自己為 owner(project_extensions.owner_id = user.id)
    ② 自己為 participant(project_participants.user_id = user.id)

後端資料來源總覽(GET /project/<uid>

欄位 資料來源 查詢方式
基本資訊 compliance.projects + project_extensions JOIN
completion_rate oscal.assessment_plan_tasks correlated subquery
control_group_count oscal.assessment_plan_groups correlated subquery
total_controls oscal.assessment_plan_controls correlated subquery
total_assessment_objects oscal.assessment_plan_tasks correlated subquery(同 completion_rate 分子)
framework module_framesoscal_framework_versionsoscal_frameworks sequential fetch
compliance_resource project_assessment_plan_mappingassessment_plans sequential fetch
owner project_extensions.owner_idusers single fetch
participants project_participants JOIN users ProjectParticipantService
audit_systems project_information_systemsinformation_systems batch IN query
devices project_device_mappingdevices ProjectDeviceMappingService

相關 API

說明 API
啟動新專案 POST /api/1.0/oscal-project/start
取得稽核系統選單 GET /api/1.0/information-systems/menu
取得部門選單(供 Job 指派部門) GET /api/1.0/org-units/menu
取得設備選單(供 Job 指派設備) GET /api/1.0/devices/menu
取得問卷選單(供 Job 指派問卷) GET /api/1.0/surveys/menu