# 合規框架 PDF 匯入兩階段化 — 原始需求與 brainstorm 紀錄

> **狀態**：已精化為 [design.md](./design.md) / [api-spec.md](./api-spec.md) / [frontend-spec.md](./frontend-spec.md)
> **精化日期**：2026-05-03
>
> 以下為 Phase 0 白話需求 + Phase 1 brainstorm（共 8 題）紀錄，作為溯源參考。
> 最新可執行 spec 請見 design.md。

---

## Phase 0 — 白話需求（使用者 2026-05-03 口述）

> 「目前合規框架，也有匯入的功能，但是是用 PDF，這邊也希望比照 合規資源庫，匯入後還是可以逐條編輯修改再儲存。請你去分析匯入合規框架的前後端，這邊麻煩也給我計畫以及方案。URL 應該是在這 `/compliance-framework/compliance-framework-version-manage`，匯入版本的按鈕。」

**白話拆解**：
- 既有合規框架（Compliance Framework / Version）的匯入入口在 `ComplianceFrameworkVersionManage.vue` 列表頁的「匯入版本」按鈕
- 現況：點按鈕 → Dialog → 選 PDF → 一次寫入 catalog/profile/framework_version，沒有預覽 / 編輯機會
- 期望：比照 module_frame 既有的 SSP docx 兩階段流程（已上線於 `/module-frame/import-docx`），改為「上傳解析 → 預覽逐條編輯 → 確認儲存」三段
- 解析的範圍是「整本框架 catalog」（group / control / objectives 階層），不是 module_frame 的「使用者填寫的現況」

## Phase 1 — Brainstorm 紀錄（Q1–Q8）

| # | 議題 | 決策 |
|---|------|------|
| Q1 | 版本基本資料（version / release_date / publish_status / parent_version_uid）由誰決定？ | **A** — Step 1（上傳前）就填，跟現有 dialog 一樣，全部必填；Step 2 預覽只能編 catalog 內容 |
| Q2 | 誰可以操作匯入版本？ | **C** — 沿用 RBAC，BE 不再額外加角色檢查 |
| Q3 | parse_job 的可見性 / 隔離邊界 | **B** — 同 tenant 共享，同事可接手繼續編輯（不做使用者隔離） |
| Q4 | PDF parse 失敗時的行為 | **B** — 寫 `parse_job` 帶 `status=failed` + `error_code/error_message`，FE 顯示錯誤頁 + 重新上傳；保留 7 天供 debug |
| Q5 | 進入「匯入版本」頁面看到什麼？ | **C** — 預設進 Step 1 上傳頁，頁首 banner 顯示「目前有 N 筆未完成草稿（含 M 筆是您的）」可點開接手；TTL 7 天 |
| Q6 | 兩使用者同時編輯同一 parse_job 的 confirm 衝突 | **A** — Last-write-wins，靠 DB 唯一性約束擋真 race，使用情境不會密集到需要 lock |
| Q7 | 編輯粒度 | **B** — Update + Delete（移除誤抓的 group/control/AO），不開 Create；control 可跨 group 搬家 |
| Q8 | jedi-oscal 套件改動範圍 | **A** — 拆 `parse_pdf_to_dict()` 與 `import_from_dict()` 兩個 method；jedi-oscal 進版到 0.0.16 |

**Out of scope（明確不做）**：
- Excel 匯入（保留現有單階段流程不動）
- Per-control 評論 / review workflow
- PDF OCR / 自動 parser type 偵測
- 多人協同 real-time 編輯（lock / heartbeat / WebSocket）
- 獨立的匯入歷史審計表（parse_job 7 天 audit trail 已足夠）

---

## 對照表（現況 vs 目標）

| 面向 | 現況（單階段） | 目標（兩階段） |
|------|----------------|----------------|
| 入口 | Dialog | 路由 `/compliance-framework/import-version` |
| API | `POST /api/1.0/oscal-framework-version/import/<file_type>` 一次寫入 | parse / get / confirm / delete 四端點 |
| BE 中間表 | 無 | `oscal.framework_parse_jobs` |
| FE 預覽 | 無，response 後 reload 列表 | Splitter（左 PDF iframe / 右 TabView：Groups / Controls / AOs） |
| 編輯能力 | 無 | Update + Delete，跨 group 搬家允許 |
| jedi-oscal API | `import_or_update_oscal_from_pdf` 一次完成 | 拆 `parse_pdf_to_dict` + `import_from_dict` |

## 對 module_frame SSP docx import 的 reuse pattern

可直接參考 / 複製的元件：
- BE：`oscal.ssp_docx_parse_jobs` schema、`SspDocxImportAppService` 架構、Domain service / Repo pattern
- FE：`SspDocxImportPage.vue` wizard 結構、`SspDocxImportService.js` 三段式 API、`useSspDocxDraft` LocalStorage composable
- i18n：`ssp-docx-import.json` 的 step1/step2/parsing/expired 等鍵名規律
