# OSCAL Schema 資料表分析文件

本文件整理 `jedi-oscal` 套件中所有 SQLAlchemy Model 的用途、欄位、關聯關係，以及在系統中的使用場景。

所有表皆位於 PostgreSQL `oscal` schema 下。

---

## 目錄

1. [整體架構 ER 圖](#整體架構-er-圖)
2. [OSCAL 共用基礎表（Base）](#1-oscal-共用基礎表base)
3. [框架管理（Framework）](#2-框架管理framework)
4. [控制項目錄（Catalog）](#3-控制項目錄catalog)
5. [基準線（Profile）](#4-基準線profile)
6. [系統安全計畫（SSP）](#5-系統安全計畫ssp)
7. [評估計畫（Assessment Plan）](#6-評估計畫assessment-plan)
8. [評估結果（Assessment Result）](#7-評估結果assessment-result)
9. [跨框架對應（Control Mapping）](#8-跨框架對應control-mapping)
10. [Metadata 關聯表（Association）](#9-metadata-關聯表association)
11. [Enum 狀態值對照](#10-enum-狀態值對照)
12. [資料流向與業務流程對應](#11-資料流向與業務流程對應)

---

## 整體架構 ER 圖

```
┌─────────────────────────────────────────────────────────────────────────┐
│                          Framework Layer                                │
│                                                                         │
│  oscal_frameworks ─1:N─► oscal_framework_versions                       │
│                                    │                                    │
│                              1:1   │   N:N                              │
│                                    ▼                                    │
│                         oscal_control_mapping                           │
│                     (source_version ↔ target_version)                   │
├─────────────────────────────────────────────────────────────────────────┤
│                          Control Layer (Catalog + Profile)               │
│                                                                         │
│  framework_version ─1:1─► catalogs ─1:N─► catalog_groups (self-ref)     │
│                                                  │                      │
│                                            1:N   │                      │
│                                                  ▼                      │
│                                        catalog_controls                 │
│                                         │    │    │                     │
│                                   1:N   │    │    │  1:N                │
│                                         ▼    │    ▼                     │
│                     catalog_control_parts     │  catalog_control_assessments │
│                                              │                          │
│                                        1:N   │                          │
│                                              ▼                          │
│                              catalog_control_parameters                 │
│                                                                         │
│  catalogs ─1:N─► profiles ─1:N─► profile_controls ──► catalog_controls  │
├─────────────────────────────────────────────────────────────────────────┤
│                          Implementation Layer (SSP)                      │
│                                                                         │
│  profiles ─1:N─► system_security_plans                                  │
│                       │         │         │                             │
│                  1:1  │   1:N   │   1:N   │                             │
│                       ▼         ▼         ▼                             │
│          ssp_system    ssp_system   ssp_control                         │
│        _characteristics _implementations _implementations               │
├─────────────────────────────────────────────────────────────────────────┤
│                          Assessment Layer (AP + AR)                      │
│                                                                         │
│  assessment_plans ─1:N─► assessment_plan_groups (self-ref)              │
│       │                         │                                       │
│       │                   1:N   │                                       │
│       │                         ▼                                       │
│       │              assessment_plan_controls                           │
│       │                         │                                       │
│       │                    N:N  │  (assessment_task_controls)            │
│       │                         ▼                                       │
│       ├──1:N──► assessment_plan_tasks                                   │
│       │                                                                 │
│       └──1:N──► assessment_results ─1:N─► assessment_result_datas       │
│                                                  │                      │
│                                            1:N   │                      │
│                                                  ▼                      │
│                                   assessment_result_controls            │
│                                         │         │                     │
│                                   1:N   │   1:N   │                     │
│                                         ▼         ▼                     │
│                          assessment_result   assessment_result           │
│                            _evidences          _findings                │
├─────────────────────────────────────────────────────────────────────────┤
│                          Shared (Metadata)                              │
│                                                                         │
│  oscal_metadatas ──N:N──► oscal_roles / parties / locations /           │
│                           links / props / remarks                       │
│                   (via oscal_metadata_* association tables)              │
│                                                                         │
│  oscal_documents     oscal_responsible_parties                          │
└─────────────────────────────────────────────────────────────────────────┘
```

---

## 1. OSCAL 共用基礎表（Base）

這些表實作 OSCAL 規範中**所有模型共用的元素**（Metadata、Props、Links 等），被 Catalog / Profile / SSP / AP / AR 共同引用。

### 1.1 `oscal_documents` — OSCAL 文件內容

儲存原始 OSCAL 文件的 YAML/JSON 內容，供匯入匯出使用。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | 文件唯一識別碼 |
| `hash` | String(255) | Yes | 內容雜湊值，用於完整性與變更偵測 |
| `yaml_content` | Text | Yes | 原始 OSCAL YAML 內容 |
| `json_content` | JSONB | No | 已解析的 OSCAL JSON 內容 |
| `created_at` / `updated_at` | DateTime | Yes | 稽核時間 |
| `created_user` / `updated_user` | String(50) | No | 稽核使用者 |

**使用場景**：每次建立 Catalog / Profile / SSP / AP / AR 都會建立一筆 document 記錄。

---

### 1.2 `oscal_metadatas` — OSCAL 中繼資料

儲存 OSCAL 文件的中繼資訊（標題、版本、發布日期），對應 OSCAL 規範中的 `metadata` 區塊。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | 唯一識別碼 |
| `title` | String(255) | Yes | 標題 |
| `version` | String(100) | Yes | 版本號（例如 v1.0） |
| `published` | DateTime | No | 正式發布日期 |
| `revision` | String(20) | No | 修訂版號（例如 1.1.1） |
| `last_modified` | DateTime | Yes | 最後修改時間 |
| `oscal_version` | String(20) | Yes | OSCAL 語法版本（預設 1.2.0） |

**Relationships**：透過 association tables 關聯 `roles`, `parties`, `locations`, `links`, `props`, `remarks`, `responsible_parties`。

**使用場景**：每個 OSCAL 文件實例（Catalog / Profile / SSP / AP / AR）都必須有一筆 metadata。

---

### 1.3 `oscal_props` — OSCAL 屬性

儲存 OSCAL 元素的擴展屬性鍵值對。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `name` | String(100) | Yes | 屬性名稱 |
| `value` | Text | Yes | 屬性值 |
| `prop_class` | String(100) | No | 屬性分類 |
| `ns` | String(255) | No | Namespace |

---

### 1.4 `oscal_remarks` — OSCAL 備註

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `content` | Text | Yes | 備註內容（markup-multiline） |

---

### 1.5 `oscal_roles` — OSCAL 角色

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `role_id` | String(100) | Yes | OSCAL 角色識別碼 |
| `title` | String(255) | Yes | 角色顯示名稱 |
| `description` | Text | No | 角色說明 |

---

### 1.6 `oscal_parties` — OSCAL 參與方

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | Party UUID |
| `party_type` | String(50) | Yes | `person` / `organization` |
| `name` | String(255) | Yes | 名稱 |
| `short_name` | String(100) | No | 簡稱 |
| `remarks` | Text | No | 補充說明 |

---

### 1.7 `oscal_locations` — OSCAL 地點

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | Location UUID |
| `title` | String(255) | No | 地點名稱 |
| `address` | Text | No | 地址資訊 |
| `remarks` | Text | No | 補充說明 |

---

### 1.8 `oscal_links` — OSCAL 連結

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `href` | String(500) | Yes | 連結網址 |
| `rel` | String(100) | No | 連結關係類型 |
| `media_type` | String(100) | No | 媒體類型 |

---

### 1.9 `oscal_responsible_parties` — OSCAL 負責方

記錄角色與參與方在特定情境下的關聯關係。使用多態模式（`context_type` + `context_id`）。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `role_id` | String(100) | Yes | 對應 `oscal_roles.role_id` |
| `party_uuid` | String(36) | Yes | 對應 `oscal_parties.uid` |
| `context_type` | String(50) | Yes | `metadata` / `system` / `control` / `task` / `assessment` |
| `context_id` | Integer | No | 對應 context 的資料 id |

---

## 2. 框架管理（Framework）

管理合規框架的基本資訊與版本。這是整個 OSCAL 資料的最頂層。

### 2.1 `oscal_frameworks` — 合規框架

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵（BaseModel） |
| `uid` | UUID | Yes | 框架唯一識別碼 |
| `code` | String(50) | Yes | 框架代碼（如 `CMMC_L2`） |
| `name` | String(255) | Yes | 框架名稱（如 `CMMC 2.0 Level 2`） |
| `authority` | String(255) | Yes | 發佈機關（如 DoD, NIST, ISO） |
| `description` | Text | Yes | 框架描述 |
| `publish_status` | String(20) | Yes | `draft` / `published` / `archived` |
| `main_version` | String(50) | Yes | 主要版號 |

**Relationships**：`versions` → 只列出頂層版本（`pid IS NULL`）。

**使用場景**：系統初始匯入合規框架時建立。例如 CMMC 2.0、ISO 27001、NIST SP 800-53 R5。

---

### 2.2 `oscal_framework_versions` — 框架版本

支援多版本管理，使用 `pid` 自參考建立版本階層。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵（BaseModel） |
| `uid` | UUID | Yes | 版本唯一識別碼 |
| `framework_id` | Integer FK | Yes | → `oscal_frameworks.id` CASCADE |
| `version` | String(50) | Yes | 版本號 |
| `release_date` | Date | No | 發布日期 |
| `publish_status` | String(20) | Yes | `draft` / `published` / `archived` |
| `pid` | Integer FK | No | → `oscal_framework_versions.id` SET NULL（父版本） |

**Unique Constraint**：`(framework_id, version, pid)`

**Relationships**：
- `framework` → 所屬框架
- `catalog` → 1:1 關聯的 Catalog
- `parent` / `children` → 自參考階層

**使用場景**：每個框架版本對應一份 Catalog。建立 Module Frame 時需要指定 `oscal_framework_version_uid`。

---

## 3. 控制項目錄（Catalog）

OSCAL Control Layer 的核心，儲存合規框架的所有控制項內容。

### 3.1 `catalogs` — Catalog 文件

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | Catalog UUID |
| `framework_version_id` | Integer FK | Yes | → `oscal_framework_versions.id` CASCADE |
| `document_id` | Integer FK | No | → `oscal_documents.id` CASCADE |
| `metadata_id` | Integer FK | Yes | → `oscal_metadatas.id` CASCADE |
| `status` | String(20) | Yes | `draft` / `published` / `deprecated` |
| `description` | Text | No | 文件描述 |

**Relationships**：
- `framework_version` → 所屬框架版本
- `groups` → Catalog 下的群組列表
- `controls` → 透過 groups 的所有控制項（viewonly secondary join）
- `oscal_metadata` / `oscal_document`

**使用場景**：匯入合規框架 PDF/Excel 時建立。例如匯入 CMMC 2.0 的所有控制項。

---

### 3.2 `catalog_groups` — 控制項群組

支援多層階層結構（self-ref `parent_group_id`）。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | 群組 UUID |
| `catalog_id` | Integer FK | Yes | → `catalogs.id` CASCADE |
| `name` | String(100) | Yes | 群組名稱（如 `A.5`、`AC`） |
| `description` | Text | No | 群組描述 |
| `order_no` | Integer | Yes | 排序序號 |
| `parent_group_id` | Integer FK | No | → `catalog_groups.id` CASCADE（自參考） |

**Relationships**：`catalog`, `parent`, `children`, `controls`

**使用場景**：跟隨 Catalog 匯入時自動建立。例如 ISO 27001 的 Annex A → A.5 → A.5.1。

---

### 3.3 `catalog_controls` — 控制項

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | 控制項 UUID |
| `group_id` | Integer FK | Yes | → `catalog_groups.id` CASCADE |
| `control_id` | String(100) | Yes | 控制項識別碼（如 `AC-1`、`A.5.1`） |
| `control_title` | Text | Yes | 控制項標題 |
| `description` | Text | No | 控制項敘述 |
| `guidance` | Text | No | 控制項指引 |
| `order_no` | Integer | Yes | 排序序號 |

**Relationships**：`group`, `parts`, `parameters`, `assessments`

**使用場景**：控制項是整個系統的核心資料。Profile 選取控制項子集，AP 複製控制項快照。

---

### 3.4 `catalog_control_parts` — 控制項組成部分

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `control_id` | Integer FK | Yes | → `catalog_controls.id` CASCADE |
| `part_name` | String(50) | Yes | `statement` / `objective` / `guidance` / `example` |
| `prose` | Text | Yes | 部分內容文字 |
| `order_no` | Integer | Yes | 排序順序 |

**使用場景**：控制項的詳細子結構。例如一個控制項的「聲明」、「目標」、「指引」分別儲存。

---

### 3.5 `catalog_control_parameters` — 控制項參數

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `control_id` | Integer FK | Yes | → `catalog_controls.id` CASCADE |
| `param_id` | String(100) | Yes | 參數識別碼 |
| `label` | String(255) | No | 參數標籤 |
| `default_value` | Text | No | 預設值 |

**Unique Constraint**：`(control_id, param_id)`

**使用場景**：NIST 類框架中，控制項含有可配置的參數（如密碼長度、審計頻率等）。Profile 可覆寫這些參數值。

---

### 3.6 `catalog_control_assessments` — 控制項評估樣板

**注意**：這**不是** OSCAL 標準模型，而是系統內部擴展。用來預定義每個控制項的評估任務範本。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵（BaseModel） |
| `uid` | UUID | Yes | UUID |
| `control_id` | Integer FK | Yes | → `catalog_controls.id` CASCADE |
| `name` | String(1000) | Yes | 樣板名稱 |
| `version` | String(50) | No | 樣板版本 |
| `description` | Text | No | 描述 |

**使用場景**：
- 建立 Module Frame 時，為每個 assessment 建立 BPMN workflow template
- 啟動專案時，assessment 轉化為 AP Task，並 clone 對應的 workflow template

---

## 4. 基準線（Profile）

Profile 代表從 Catalog 篩選的控制項子集，**不複製控制項內容**，僅記錄「選了哪些」。

### 4.1 `profiles` — Profile 文件

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | Profile UUID |
| `catalog_id` | Integer FK | Yes | → `catalogs.id` |
| `metadata_id` | Integer FK | Yes | → `oscal_metadatas.id` |
| `document_id` | Integer FK | Yes | → `oscal_documents.id` CASCADE |
| `status` | String(20) | Yes | `draft` / `published` / `deprecated` |
| `description` | Text | No | 描述 |

**Relationships**：`catalog`, `controls` (profile_controls), `oscal_metadata`, `oscal_document`

**使用場景**：
- **建立 Module Frame 時自動建立**：`POST /module-frame` → `ProfileService.add_profile()`
- 每個 Module Frame 對應一個 Profile（1:1 soft reference）
- Profile 是啟動專案的基礎，AP 從 Profile clone 控制項

---

### 4.2 `profile_controls` — Profile 控制項篩選

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `profile_id` | Integer FK | Yes | → `profiles.id` CASCADE |
| `catalog_control_id` | Integer FK | Yes | → `catalog_controls.id` |
| `include` | Boolean | Yes | 是否納入（預設 `true`） |
| `created_at` | DateTime | Yes | 建立時間 |
| `created_user` | String(50) | No | 建立者 |

**Unique Constraint**：`(profile_id, catalog_control_id)`

**使用場景**：User 在 Module Frame 介面勾選要納入的控制項，每勾選一個就建立一筆 profile_control。

---

## 5. 系統安全計畫（SSP）

SSP 描述一個系統的安全基線和控制項實施狀態。

### 5.1 `system_security_plans` — SSP 文件

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | SSP UUID |
| `profile_id` | Integer FK | Yes | → `profiles.id` |
| `metadata_id` | Integer FK | Yes | → `oscal_metadatas.id` |
| `document_id` | Integer FK | Yes | → `oscal_documents.id` |
| `description` | Text | No | 描述 |
| `status` | String(20) | Yes | `draft` / `ready` / `archived` |

**Relationships**：`profile`, `system_characteristic`（1:1）, `system_implementations`（1:N）, `control_implementations`（1:N）

**使用場景**：
- **啟動專案時建立**（`start_oscal_project` Step 3）
- 若 request 帶 `ssp_uid` 則使用既有 SSP，否則建立空白 SSP

---

### 5.2 `system_security_plans_system_characteristics` — 系統特性

1:1 對應 SSP，描述受評估系統的基本資訊。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `system_security_plan_id` | Integer FK | Yes | → `system_security_plans.id` CASCADE |
| `owner_uid` | String(50) | No | 系統擁有者 UID（soft ref → users.uid） |
| `name` | String(255) | Yes | 受評估系統名稱 |
| `description` | Text | No | 系統描述 |
| `system_identifier` | String(100) | Yes | 系統識別碼 |
| `security_sensitivity_level` | String(20) | Yes | FIPS 199 安全分類：`low` / `moderate` / `high` |
| `target_type` | String(50) | Yes | `it_system` / `management_system` / `logical_scope` |
| `scope_description` | Text | No | 評估範圍描述 |
| `status` | String(20) | Yes | `active` / `archived` |

**使用場景**：
- 啟動專案時（Step A），從 `information_systems` 建立快照到此表
- 透過 `project_system_characteristic_mapping` 關聯到專案

---

### 5.3 `system_security_plan_system_implementations` — 系統實施

描述 SSP 涵蓋的子系統或元件。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `system_security_plan_id` | Integer FK | Yes | → `system_security_plans.id` CASCADE |
| `name` | String(255) | Yes | 系統/元件名稱 |
| `description` | Text | No | 說明 |
| `implementation_type` | String(50) | Yes | `system` / `subsystem` / `service` / `component` / `hardware` |
| `responsible_party` | String(100) | No | 負責角色/單位 |

---

### 5.4 `system_security_plan_control_implementations` — 控制項實施

描述系統對每個控制項的實施狀態。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `system_security_plan_id` | Integer FK | Yes | → `system_security_plans.id` CASCADE |
| `catalog_control_id` | Integer FK | Yes | → `catalog_controls.id` |
| `implementation_status` | String(30) | Yes | 見下方狀態值 |
| `implementation_description` | Text | No | 實施說明 |
| `responsible_role` | String(100) | No | 負責角色 |

**Unique Constraint**：`(system_security_plan_id, catalog_control_id)`

**implementation_status 有效值**：
- `unknown` — 未知
- `implemented` — 已實作
- `partial` — 部分實作
- `inherited` — 繼承自上層系統
- `not_applicable` — 不適用
- `not_implemented` — 未實作

---

## 6. 評估計畫（Assessment Plan）

AP 是 GRC 專案的核心，代表一次具體的稽核計畫。AP 的結構是從 Profile 的控制項 **clone（快照）** 而來。

### 6.1 `assessment_plans` — AP 文件

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | AP UUID |
| `profile_id` | String(36) | No | 來源 Profile ID（**soft ref，非 FK**） |
| `metadata_id` | Integer FK | Yes | → `oscal_metadatas.id` CASCADE |
| `document_id` | Integer FK | Yes | → `oscal_documents.id` CASCADE |
| `ssp_id` | String(36) | No | 來源 SSP ID（**soft ref，非 FK**） |
| `title` | String(200) | Yes | 稽核計畫名稱 |
| `description` | Text | No | 說明 |
| `status` | String(30) | Yes | `draft` / `active` / `completed` / `archived` |
| `start_date` | Date | No | 稽核開始日期 |
| `end_date` | Date | No | 稽核結束日期 |
| `frozen_at` | DateTime | No | 凍結時間（AP 結構不可再異動） |

**Relationships**：`controls`, `groups`, `tasks`, `assessment_results`

**使用場景**：
- **啟動專案時建立**（`start_oscal_project` Step 4）
- 透過 `project_assessment_plan_mapping` 關聯到專案
- Step 7 呼叫 `init_ap_controls_from_profile` 初始化 groups/controls/tasks

---

### 6.2 `assessment_plan_groups` — AP 控制項群組（快照）

從 Catalog Groups 複製的結構快照，支援多層階層。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `assessment_plan_id` | Integer FK | Yes | → `assessment_plans.id` CASCADE |
| `name` | String(100) | Yes | 群組名稱（快照） |
| `description` | Text | No | 群組描述（快照） |
| `order_no` | Integer | Yes | 排序 |
| `parent_group_id` | Integer FK | No | → `assessment_plan_groups.id` CASCADE（自參考） |

**Relationships**：`assessment_plan`, `parent`, `children`, `controls`

**使用場景**：`init_ap_controls_from_profile` 時從 Catalog Groups clone。

---

### 6.3 `assessment_plan_controls` — AP 控制項（快照）

從 Catalog Controls 複製的快照，**不與 Catalog 建立 FK**。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `assessment_plan_id` | Integer FK | Yes | → `assessment_plans.id` CASCADE |
| `group_id` | Integer FK | Yes | → `assessment_plan_groups.id` CASCADE |
| `control_id` | String(50) | Yes | 控制項識別碼（快照，如 `AC-02`） |
| `control_title` | Text | No | 控制項標題（快照） |
| `description` | Text | No | 控制項描述 |
| `guidance` | Text | No | 控制項指引 |
| `include` | Boolean | Yes | 是否納入本次稽核 |
| `order_no` | Integer | No | 排序 |

**Relationships**：`assessment_plan`, `group`, `tasks`（via assessment_task_controls）

**設計重點**：AP Control 是**快照**，與 Catalog Control 解耦。Catalog 後續更新不影響已建立的 AP。

---

### 6.4 `assessment_plan_tasks` — AP 稽核任務

代表實際要執行的一個稽核行為（Assessment Object）。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `assessment_plan_id` | Integer FK | Yes | → `assessment_plans.id` CASCADE |
| `catalog_control_assessment_id` | Integer | No | 來源評估樣板 ID（soft ref） |
| `task_code` | String(50) | Yes | 人類可讀編碼（如 `AP-AC02-01`） |
| `title` | String(1000) | Yes | Task 標題 |
| `description` | Text | No | Task 說明 |
| `assessment_methods` | JSON | Yes | 稽核方式：`["examine", "interview", "test"]` |
| `task_type` | String(50) | Yes | `manual` / `automated` / `hybrid` |
| `status` | String(50) | Yes | `pending` / `in_progress` / `completed` |
| `sequence` | Integer | No | 執行順序 |

**Relationships**：`assessment_plan`, `controls`（via assessment_task_controls）

**使用場景**：
- `init_ap_controls_from_profile` 時從 `catalog_control_assessments` 轉化建立
- 啟動專案 Step 8 時，每個 task 會 clone 一份 workflow_template 並建立 workflow_execution
- 前端的「評估物件（AO）」概念

---

### 6.5 `assessment_task_controls` — Task ↔ Control 多對多

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `task_id` | Integer FK | PK | → `assessment_plan_tasks.id` CASCADE |
| `control_id` | Integer FK | PK | → `assessment_plan_controls.id` CASCADE |

**使用場景**：一個 Task 可以關聯多個 Control，一個 Control 也可以有多個 Task。

---

## 7. 評估結果（Assessment Result）

AR 儲存稽核執行的結果，包含每個控制項的判定、證據、發現事項。

### 7.1 `assessment_results` — AR 文件主檔

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | AR UUID |
| `metadata_id` | Integer FK | Yes | → `oscal_metadatas.id` RESTRICT |
| `document_id` | Integer FK | Yes | → `oscal_documents.id` RESTRICT |
| `assessment_plan_id` | Integer FK | Yes | → `assessment_plans.id` CASCADE |

**Relationships**：`assessment_plan`, `result_datas`

**使用場景**：啟動專案時（Step 4）建立空白 AR。一個 AP 對應一個 AR。

---

### 7.2 `assessment_result_datas` — 單次稽核執行結果

對應 OSCAL `assessment-results.results[]`，支援多次稽核（run 1, run 2...）。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `assessment_result_id` | Integer FK | Yes | → `assessment_results.id` CASCADE |
| `run_no` | Integer | Yes | 第幾次稽核執行 |
| `title` | String(200) | No | 執行標題（如 Initial Assessment） |
| `started_at` | DateTime | No | 開始時間 |
| `completed_at` | DateTime | No | 完成時間 |
| `remarks` | String(1000) | No | 備註 |

**Unique Constraint**：`(assessment_result_id, run_no)`

**Relationships**：`assessment_result`, `controls`

---

### 7.3 `assessment_result_controls` — 控制項稽核結果

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `assessment_result_data_id` | Integer FK | Yes | → `assessment_result_datas.id` CASCADE |
| `control_id` | String(50) | Yes | 控制項識別碼（快照） |
| `control_title` | String(300) | No | 控制項標題（快照） |
| `verdict` | String(30) | Yes | `pass` / `fail` / `partial` / `na` |
| `confidence` | Integer | No | 信心程度 0-100 |
| `rationale` | String(1000) | No | 判定理由 |
| `remarks` | String(1000) | No | 補充說明 |

**Relationships**：`result_data`, `evidences`, `findings`

---

### 7.4 `assessment_result_evidences` — 稽核證據

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `assessment_result_control_id` | Integer FK | Yes | → `assessment_result_controls.id` CASCADE |
| `evidence_type` | String(30) | Yes | `file` / `link` / `text` / `system` |
| `description` | String(1000) | No | 證據說明 |
| `file_id` | Integer | No | 關聯上傳檔案 ID（soft ref） |
| `reference_url` | String(500) | No | 外部連結 URL |

---

### 7.5 `assessment_result_findings` — 稽核發現事項

為 POA&M 的主要來源資料。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `id` | Integer | PK | 主鍵 |
| `uid` | UUID | Yes | UUID |
| `assessment_result_control_id` | Integer FK | Yes | → `assessment_result_controls.id` CASCADE |
| `category` | String(50) | Yes | `deficiency` / `observation` / `recommendation` |
| `severity` | String(20) | Yes | `low` / `medium` / `high` / `critical` |
| `title` | String(300) | No | 發現事項標題 |
| `description` | String(2000) | Yes | 發現事項描述 |
| `recommendation` | String(2000) | No | 改善建議（可直接轉 POA&M action） |

---

## 8. 跨框架對應（Control Mapping）

### 8.1 `oscal_control_mapping` — 控制項對應關係

用於跨框架版本的控制項對應（如 CMMC 2.0 ↔ NIST SP 800-171）。

| 欄位 | 類型 | 必填 | 說明 |
|------|------|------|------|
| `source_version_id` | Integer FK | PK | → `oscal_framework_versions.id` CASCADE |
| `source_control_id` | String(50) | PK | 來源控制項識別碼 |
| `target_version_id` | Integer FK | PK | → `oscal_framework_versions.id` CASCADE |
| `target_control_id` | String(50) | PK | 目標控制項識別碼 |

**Relationships**：`source_version`, `target_version`, `ref_control_mappings`（同 source 的其他 mapping）

---

## 9. Metadata 關聯表（Association）

所有 association table 為 composite PK，無額外欄位。

| 表名 | FK 1 | FK 2 |
|------|------|------|
| `oscal_metadata_roles` | `metadata_id` → `oscal_metadatas.id` | `role_id` → `oscal_roles.id` |
| `oscal_metadata_parties` | `metadata_id` → `oscal_metadatas.id` | `party_id` → `oscal_parties.id` |
| `oscal_metadata_locations` | `metadata_id` → `oscal_metadatas.id` | `location_id` → `oscal_locations.id` |
| `oscal_metadata_links` | `metadata_id` → `oscal_metadatas.id` | `link_id` → `oscal_links.id` |
| `oscal_metadata_props` | `metadata_id` → `oscal_metadatas.id` | `prop_id` → `oscal_props.id` |
| `oscal_metadata_remarks` | `metadata_id` → `oscal_metadatas.id` | `remarks_id` → `oscal_remarks.id` |

---

## 10. Enum 狀態值對照

### 文件生命週期（Catalog / Profile / SSP）

| 值 | 說明 |
|----|------|
| `draft` | 草稿 |
| `published` | 已發布 |
| `deprecated` | 已棄用 |

### Assessment Plan 狀態

| 值 | 說明 |
|----|------|
| `draft` | 草稿 |
| `active` | 進行中 |
| `completed` | 已完成 |
| `archived` | 已歸檔 |

### Assessment Plan Task 狀態

| 值 | 說明 |
|----|------|
| `pending` | 待處理 |
| `in_progress` | 執行中 |
| `completed` | 已完成 |

### Assessment Result 狀態

| 值 | 說明 |
|----|------|
| `pending` | 待處理 |
| `in_progress` | 執行中 |
| `completed` | 已完成 |

### 控制項判定結果（Verdict）

| 值 | 說明 |
|----|------|
| `pass` | 通過 |
| `fail` | 不通過 |
| `partial` | 部分通過 |
| `na` | 不適用 |

### 發現事項類型（Finding Category）

| 值 | 說明 |
|----|------|
| `deficiency` | 缺失 |
| `observation` | 觀察 |
| `recommendation` | 建議 |

### 發現事項嚴重程度（Finding Severity）

| 值 | 說明 |
|----|------|
| `low` | 低 |
| `medium` | 中 |
| `high` | 高 |
| `critical` | 嚴重 |

### 證據類型（Evidence Type）

| 值 | 說明 |
|----|------|
| `file` | 檔案 |
| `link` | 連結 |
| `text` | 文字 |
| `system` | 系統自動產生 |

### SSP 控制項實施狀態

| 值 | 說明 |
|----|------|
| `unknown` | 未知 |
| `implemented` | 已實作 |
| `partial` | 部分實作 |
| `inherited` | 繼承 |
| `not_applicable` | 不適用 |
| `not_implemented` | 未實作 |

### 系統實施類型

| 值 | 說明 |
|----|------|
| `system` | 系統 |
| `subsystem` | 子系統 |
| `service` | 服務 |
| `component` | 元件 |
| `hardware` | 硬體 |
| `software` | 軟體 |

---

## 11. 資料流向與業務流程對應

### 建立 Module Frame（`POST /module-frame`）

```
寫入順序：
1. oscal_metadatas          ← Profile metadata
2. oscal_documents          ← Profile document
3. profiles                 ← Profile 主記錄
4. profile_controls         ← 選取的控制項（N 筆）
5. module_frames            ← Module Frame 主記錄（public schema）
6. module_frames_trans      ← i18n（public schema）
7. workflow_templates       ← 每個 assessment 一個 BPMN（M 筆，public schema）
8. workflow_templates_trans  ← i18n（M 筆，public schema）
9. profile_assessment_workflow_mapping ← 三方關聯（M 筆）
```

### 啟動專案（`POST /oscal/projects/start`）

```
寫入順序：
Step 3.  oscal_metadatas + oscal_documents + system_security_plans    ← SSP
Step 4.  oscal_metadatas + oscal_documents + assessment_plans          ← AP
         oscal_metadatas + oscal_documents + assessment_results         ← AR
         assessment_result_datas                                        ← 初始 run
Step 5.  compliance.projects + compliance.project_extensions           ← 專案
Step 6.  compliance.project_assessment_plan_mapping                    ← 專案 ↔ AP
Step 7.  assessment_plan_groups                                        ← clone 群組快照
         assessment_plan_controls                                       ← clone 控制項快照
         assessment_plan_tasks                                          ← 評估任務
         assessment_task_controls                                       ← Task ↔ Control
Step 8.  workflow_templates（clone）                                    ← 定版流程
         workflow_executions                                             ← 流程實例
         job_executions                                                  ← 任務節點
         assessment_plan_task_workflow_mapping                           ← Task ↔ Template
         assessment_plan_task_workflow_execution_mapping                 ← Task ↔ Execution
Step A.  ssp_system_characteristics                                     ← 稽核系統快照
         compliance.project_system_characteristic_mapping
         compliance.project_information_systems
Step B.  compliance.project_participants                                ← 參與者
Step C.  compliance.project_device_mapping                              ← 設備
Step 9.  compliance.project_participants                                ← 建立者
```

### OSCAL 資訊流（下→上）

```
oscal_frameworks
  └→ oscal_framework_versions
       └→ catalogs → catalog_groups → catalog_controls
            │                              │
            │                    catalog_control_assessments
            │                              │
            └→ profiles → profile_controls │
                 │                         │
                 ├→ system_security_plans   │
                 │    └→ ssp_system_characteristics
                 │    └→ ssp_control_implementations
                 │                         │
                 └→ assessment_plans ◄─────┘（init_ap_controls_from_profile）
                      ├→ ap_groups → ap_controls
                      ├→ ap_tasks ←→ ap_controls（assessment_task_controls）
                      └→ assessment_results
                           └→ assessment_result_datas
                                └→ assessment_result_controls
                                     ├→ assessment_result_evidences
                                     └→ assessment_result_findings → (future) POA&M
```
