# FR-038 框架維護 2a/2b 再啟用 — 驗收報告

> 自主執行（2026-06-16，user 不在場）完成。決策全用建議值並記錄於
> [`docs/analysis/2026-06-16-framework-maintenance-2a2b-decisions.md`](../../../analysis/2026-06-16-framework-maintenance-2a2b-decisions.md)。
> 本報告供隔日驗收。**所有 commit 已落地、未 push**。

## 0. 一句話結論

框架管理整條（框架 CRUD/刪除 → 版本管理 → catalog 文章式編輯 → 兩階段 PDF 匯入）
**全部接回 v2 底層、路由註冊在舊 URL、FE 零改動**。BOOT OK、真實 CMMC L2 PDF e2e 通過、
pytest 零新回歸。**FE 不需改任何一行**，重啟 BE 即可驗。

## 1. 完成範圍

| 區塊 | FE 頁面 | 狀態 | 端點（舊 URL，FE 既有）|
|------|---------|------|------|
| 框架 CRUD + 刪除 | `ComplianceFrameworkManage` | ✅ | `POST /oscal-frameworks`(list)、`GET /oscal-frameworks/menu`、`POST /oscal-framework`(create)、`GET/PUT/DELETE /oscal-framework/<uid>` |
| **P1 版本管理 2a** | `ComplianceFrameworkVersionManage` | ✅ | `POST /oscal-framework-versions`(list)、`GET/POST/PUT/DELETE /oscal-framework-version[/<uid>]` |
| **P2 catalog 編輯 2b** | `FrameworkVersionEditView` | ✅ | `GET /oscal-framework-version/<uid>/catalog-tree`、`PUT/DELETE /oscal-catalog-group|control|control-assessment/<uid>` |
| **P3 兩階段 PDF 匯入** | `FrameworkImportPage` | ✅ | `GET /oscal-framework-parse-jobs`、`POST /oscal-framework-parse-jobs/parse`、`GET/DELETE /oscal-framework-parse-jobs/<uid>`、`POST .../<uid>/confirm` |

## 2. 核心做法

- **FE 零改動原則**：底層全換 jedi_oscal_v2，但路由註冊回**舊 URL** + 主專案 app service 當 adapter 對齊舊 request/response shape。
- **不 import v1 jedi_oscal**（撞 v2 MetaData 會炸 boot）：三組 service 全部 v1-clean 重寫，只接 v2。
- **v2 套件異動**（dev path-dep，未發 Nexus）：
  - `FrameworkService`：補 `delete_framework`（靠 CASCADE）、`update_version`、`delete_version`
  - `framework_versions` 加回 `release_date` 欄（model/entity/mapper）
- **不需新增 v2 method 的部分**：P2 直接用 v2 catalog repos；P3 重用 `get_oscal_parser_adapter` + `CatalogService.add_catalog`。

## 3. 驗證結果

| 項目 | 結果 |
|------|------|
| `create_app()` BOOT | ✅ OK（含全部 16 條框架路由註冊在舊 URL）|
| P1 read/write smoke | ✅ 版本 list（樹/parent/children）+ create/update/delete（含 release_date）round-trip |
| P2 read/write smoke | ✅ catalog-tree（control desc 從 statement part、AO 從 parts）+ control/AO 改寫還原 |
| **P3 真實 CMMC L2 PDF e2e** | ✅ parse=14 groups/110 controls/320 AO → confirm 全落地 + release_date → catalog 持久化數量一致 → cleanup |
| pytest（全套）| ✅ 42 failed + 50 errors ≤ baseline 47f/50e（**零新回歸**，失敗反少 5）|

## 4. 已知限制（v2 正規化結構無對應欄位 → 讀回 None、寫入忽略）

OSCAL v2 是正規化模型，下列 v1 扁平欄位在 v2 無對應 slot，**刻意不臆造儲存位置**（避免埋髒資料）：

| 欄位 | 說明 |
|------|------|
| control `guidance` | CMMC catalog 無 guidance part |
| group `description` | v2 catalog_groups 無 description 欄 |
| AO `description` | v2 AO part 單一 prose（AO 文字對映到 `name`↔prose）|

> 影響：FE 這些欄位編輯後不會保存（顯示空白）。控制項主要描述（control.description ↔ statement part）、
> 控制標題、AO 文字、群組名稱**都正常可編可存**。若客戶需要 guidance/group-description，需另開 FR
> 在 v2 catalog 加欄或 part（schema 變更）。

## 5. ⚠️ 待辦（需 user 處理）

1. **stg / poc / prod 跑兩支 migration**（DEV 已套）：
   - `scripts/sql/2026-06-16-fr038-framework-versions-add-release-date.sql`
   - `scripts/sql/2026-06-16-fr038-recreate-framework-parse-jobs.sql`
   - 一律 `psql --single-transaction -v ON_ERROR_STOP=1 -f <檔>` 用 cmmgr。**BE 必須同步上新版**（含 v2 套件 path-dep 改動）否則炸。
2. **v2 套件發 Nexus**：整個框架維護 + 既有 import-ssp 完成後，user 明示才 bump + 推（dev path-dep 期間勿發）。`pyproject.toml` path-dep 勿 commit。
3. **push**：BE + 套件 commit 都**未 push**，等 user 明示。
4. **重啟 BE** 才會生效（無 hot reload）。

## 6. Commit 清單（未 push）

**主專案 BE**（branch `feature/oscal-refactor`）：
- `ef600abf` 框架 CRUD 接回舊 URL + 補 delete + 版本管理 2a
- `c7f962d5` 框架維護 2b — catalog 文章式編輯
- `9973fc55` 框架維護 — 兩階段 PDF 匯入 parse-job
> 註：log 中 `acc72361` / `6388a1dc`（SSP 匯入相關）非本次工作，疑來自平行 session；本次框架維護僅上述 3 commit。

**v2 套件**（`jedi-oscal-v2`，branch `feature/oscal-refactor`，dev path-dep）：
- `ceb1b3a` FrameworkService delete/version CRUD + framework_versions.release_date
- `1427956` delete_framework 改靠 CASCADE（修 FK）

## 7. 隔日手測 checklist（重啟 BE 後）

進「合規框架」頁逐項點：
1. **框架**：列表載入 / 新增 / 編輯 / 刪除（draft）
2. **版本管理**（點框架名進入）：版本列表（樹狀父子）/ 新增版本（含發行日期）/ 編輯 / 刪除
3. **catalog 編輯**（版本「編輯內容」）：tree 載入 / 改 control 標題+描述 / 改 AO 文字 / 存檔
4. **兩階段 PDF 匯入**：上傳 CMMC L2 PDF → 預覽（14 領域/110 控制/320 AO）→ 確認 → 新版本帶 catalog
5. 確認上述操作 FE 無需改 code、無 console error

## 8. 決策索引

完整決策（含取捨理由、反悔成本）見
[`docs/analysis/2026-06-16-framework-maintenance-2a2b-decisions.md`](../../../analysis/2026-06-16-framework-maintenance-2a2b-decisions.md)：
D0~D1（共用方向）、P1-1~6（版本管理）、P2-1~8（catalog 編輯，含 uid=str(id)、part 對映）、P3-1~7（parse-job）。
