# SSP 匯入匯出 Phase 2

> **跨多 phase task arc，含 BE / FE / jedi-oscal / test 多 repo**
> 起始日期：2026-05-18
> 主要驅動需求：raymond
> 狀態：A0 brainstorm 收斂完成，準備寫 A0 design

## 概覽

讓「合規資源庫」與「專案 SSP 版本」雙向支援：

- **Excel 匯入**：含 metadata / 單位 / 人員 / 設備 / 資訊系統 / leveraged / 控制項 / AO / 程序書 9 大資料領域
- **SSP 匯出**：docx / pdf / odt + OSCAL JSON / XML / YAML 共 6 種格式

詳細需求：

- 原始需求（raymond 草稿）：[raw-requirement.md](raw-requirement.md)
- 完整需求理解（含全 phase scope）：[requirement-understanding.md](requirement-understanding.md)

---

## Phase 進度追蹤

> ⚠️ **規範**：每完成一階段請更新此表的狀態欄與對應連結欄；ship 後加 commit hash

### Track A：Excel 匯入

| Phase | 主題 | 級別 | 狀態 | brainstorm | design | plan | ship commit | changelog |
|-------|------|-----|------|-----------|--------|------|-------------|-----------|
| A0 | 既有表擴充（`system_security_plan_system_implementations`） | 重 | **shipped** ✅ | ✅ requirement-understanding §2 | ✅ design.md | ✅ implementation-plan-A0.md | BE: c4804d7 / a1b80cc / e73b1aa ; jedi-oscal: afe7035→dbb3d7c | ✅ 2026-05-18-tweak-ssp-system-impl-extension.md |
| **A0.1** | **結構重整補丁：rename items + 新 main + 新 join + column rename**（補丁 of A0）| 重 | **shipped** ✅ | ✅ requirement-understanding §2 v5 | ✅ design-A0.1.md | ✅ implementation-plan-A0.1.md | BE: eb9fa7e / 6deacef* ; jedi-oscal: 762d8fc / cc65e3b / c0fcae9 / d2178c1 / 8e3e58b / 4666091 | ✅ 2026-05-19-tweak-ssp-system-impl-restructure.md + 2026-05-19-fix-ssp-impl-item-device-id.md |
| A1 | Excel 樣板設計 + 下載 | 中 | **BE+FE shipped** ✅ (T0-T6 完成 + UX polish 3 輪；T7 cucumber E2E pending) | — | ✅ design-A1.md (v1.2 加 §3.3/§6.2.1/§15.1-15.3) | ✅ implementation-plan-A1.md | BE: b18db55→2b1e93c (16 commits) ; FE: e0ff8f1+00b6662 | ✅ 5 個 changelog (1 base + 1 BE-FW endpoint + 3 UX polish + 1 FE) + issue/pending/2026-05-19-person-role-cross-domain-inconsistency.md |
| A2 | Excel Parser + 解析 API | 中 | **BE shipped** ✅ (T0~T6 完成；T7 BE smoke / T8 cucumber pending) | — | ✅ design-A2.md (含 §15.1-15.3 reconciliation) | ✅ implementation-plan-A2.md | BE: f7b44ff → 43cc206 (7 commits) | ✅ 3 個 changelog (feat-ssp-excel-import + tweak-template-v1.2.0 + fix-fw-version-scoped-controls) |
| A3 | 共用 matcher 抽取（parties / org-units） | 重 | **BE shipped ✅** (5 session A→E 完成；T6 cucumber partial — env 配齊後跑) | ✅ Session A 完成（Q1~Q6 + Q3'/Q4' 8 題拍板）| ✅ design-A3.md (8e61def + 6e0f103；2-round spec review approved) | ✅ implementation-plan-A3.md | BE: b011f2f + 82f0dc8 + 854b238 + 773e108 + 761fd7c ; test: 27e52fe (compliance-manager-test/feature/a3-ssp-party-match-regression) | ✅ 2026-05-20-feat-party-matcher-shared.md |
| A4 | devices / info_systems / leveraged / 控制項 / AO 鉤稽 | 重 | **BE shipped ✅** (Session A→F 完成；T9 ✅ / T10 follow-up F-A4-cucumber / T11 收尾 ✅) | ✅ Session A 完成（D1~D8 + 13 sub-question 拍板） | ✅ design-A4.md (1de5f51；§11.1 含 Session C/D/E 共 16 條偏差紀錄) | ✅ implementation-plan-A4.md (57bcb2e；3466 行 / 11 task / 4 session) | BE: 57a9567 + 72ef229 + 7c2b860 + 8936aab + 9d7c102 + 40c4a12 + 579eb76 + 78118eb + 81073ef + 600f50a (T1-T9 + Session E 收尾 docs 共 10 commits) | ✅ 2026-05-20-feat-ssp-excel-import-phase2-a4-write-pipeline.md + 2026-05-20-tweak-a4-boundary-and-integration-tests.md |
| A5 | 預覽 UI + Confirm 寫入 | 中 | **BE+FE shipped ✅ + bugfix x3** (Session A→C 完成 + smoke 後 3 輪 bugfix；update flow 覆蓋語義 + parties cache + locale fix 已修) | — | ✅ design-A5.md (5d979bf + FE 偏差更新；§10.1 含 6 條 T0 偏差 / §10.2.1 decision propagation 已知限制 / §10.3 含 5 條 FE 偏差 / §10.4 跨 session 總覽) | ✅ implementation-plan-A5.md (5d979bf) | BE: 535b931 + 5852cca + 56edd30 + 7ed9363 + 6f926e0 + c61ef02 (T1+T2/T6+T3+T4+T7+T14 共 6 commits)。FE: c95d02a + 24622ee + 2412e74 + 0cf3058 + 332b393 (T9 service+store+router / T10 page shell / T11 sheet preview / T12 RowActionMenu / T13 confirm Dialog 共 5 commits) + bugfix s1: 5aac0d5 / bugfix s2: 5adb550 / bugfix s1: 5aac0d5 / bugfix s2: 5adb550 / bugfix s3 BE: 9b14200 + FE: bd92e2e | BE: 2026-05-21-feat-ssp-excel-import-phase2-a5-be.md。FE: 2026-05-21_a5-import-excel-preview-ui.md (FE repo `docs/changelog/ssp-import-export-phase2/`) + fix: 2026-05-21-fix-ssp-excel-import-overwrite-mode.md |

### Track B：SSP 匯出

| Phase | 主題 | 級別 | 狀態 | brainstorm | design | plan | ship commit | changelog |
|-------|------|-----|------|-----------|--------|------|-------------|-----------|
| B1 | Docx 樣板 + generator 骨架 | 中 | **BE shipped** ✅ | — | — | — | — | ✅ 2026-05-22-feat-ssp-docx-export-b1-generator-skeleton.md |
| B2 | 內容組裝（MF + SSP version 兩來源） | 中 | **BE shipped** ✅ | — | — | — | — | ✅ 2026-05-22-feat-ssp-export-b2-b3-b4-content-loader-api-converter.md |
| B3 | Docx Export API | 輕 | **BE shipped** ✅ | — | — | — | — | ✅ 同 B2 changelog |
| B4 | PDF + ODT 補上 | 輕 | **BE shipped** ✅ | — | — | — | BE: 062782d | ✅ 同 B2 changelog |
| B5 | OSCAL JSON / XML / YAML 匯出 | 重 | **BE shipped** ✅ | — | — | — | BE: 25909f2 | ✅ 2026-05-22-feat-ssp-export-b5-oscal-json-yaml-xml.md |
| B6 | 前端 UI + 格式選擇 + DOCX 格式升級 | 輕 | **BE+FE shipped** ✅ | — | — | docs/features/FR-011.2-2605-ssp-import-export-phase2/implementation-plan-docx-template-rebuild.md | BE: 8df2525 (template) / 8ee55f5 (LibreOffice) / 43a9389 (unicode filename) ; FE: 7231b6a (export button) / c21372c (unicode filename) | ✅ 2026-05-22-feat-ssp-export-b6-fe-export-button.md + 2026-05-22-feat-ssp-docx-template-rebuild.md + 2026-05-22-fix-ssp-export-libreoffice-binary-detect.md + 2026-05-22-fix-ssp-export-unicode-filename.md |

### Track C：SSP 在專案內直接編輯（Phase 2 延伸補強）

> Track A + B 測試後發現的架構問題；同 branch 繼續，**獨立 tracker** 在 [`docs/features/FR-011.3-2605-ssp-edit-in-project/README.md`](../FR-011.3-2605-ssp-edit-in-project/README.md)

| 主題 | 涵蓋範圍 |
|------|---------|
| **C1**：OSCAL SSP 角色 master data 化 | system_menus seed 9 個 OSCAL 角色 + FE i18n |
| **C2**：SSP-scoped endpoints 補齊 | 補 6 個 `/ssp/<uid>/...` endpoint（parties / resources / characteristic / leveraged / excel-import） |
| **C3**（重）：受評範圍遷移到 SSP | 廢 project_device_mapping / project_information_systems，全面 derive from SSP |
| **C4**：專案 CRUD 改造 | 拿掉 audit_systems / devices 欄位 |
| **C5**：專案規劃頁加 SSP tab | UI lazy load 設計 |
| **C6**：移除專案設定 UI 受評範圍 section | FE 表單調整 |
| **C7**：06_外部利用恢復（可選）| ALL_SHEETS 加回 + parser 改回 |
| **C8**：`_ROLE_LABEL_MAP` 清理 | 移除 manager/auditor/viewer，修 system-security-officer 對應 |

完整分析：[ssp-edit-in-project/analysis.md](../FR-011.3-2605-ssp-edit-in-project/analysis.md)

---

## 級別說明（決定流程深度）

| 級別 | 標準 | 流程 |
|-----|------|-----|
| **重型** | 跨層 refactor / 架構選型 / OSCAL spec 細節 | 完整 brainstorm → design → plan |
| **中型** | 新 service / endpoint 但模式已知 | design 段落 + plan，不獨立 brainstorm |
| **輕型** | UI 對齊既有 pattern / 單純 CRUD | 直接 plan + 實作 |

重型 phase 預判：**A0 / A3 / A4 / B5** 共 4 個 — 才需要單獨 brainstorm 收斂。

---

## Phase 依賴關係

```
              ┌── A1 ── A2 ── A3 ── A4 ── A5  (Excel 匯入完成)
              │
A0 ───────────┤
(基礎建設)    │
              │   B1 ── B2 ──┬── B3 ── B4 ──┐
              └──────────────┤              ├── B6 (SSP 匯出完成)
                             └── B5 ────────┘
```

- **A0 是 Track A + Track B（B2 起算）共同前置**，必須最先完成
- A0 完成後，A1 / B1 可平行起手
- B 內部 B3 / B4 / B5 皆依賴 B2，三者完成後接 B6 UI

---

## 關鍵架構決策

**不新建 OSCAL mirror 三表（v3 誤判），改擴充既有 `system_security_plan_system_implementations` 表**：

- 既有表已是「OSCAL system-implementation 多型鏡像」設計用意，`implementation_type` enum 已支援多型
- 既有 140 筆 hardware 資料 + jedi-oscal 完整 stack（ORM / repo / mapper / DTO / enum）已運作
- 既有 caller：`project_device_mapping_service` + `ssp_versioning_service` 正在寫入
- 擴充比新建務實 — 不破壞既有 caller、不做大規模 migration

詳見 [requirement-understanding.md §2](requirement-understanding.md)。

---

## 跨 repo 工作範圍

| Repo | 路徑 | 本期範圍 |
|------|------|---------|
| compliance-manager-be（主）| `~/Projects/Billows/Audit-Manager/compliance-manager-be/` | Schema migration / app service / api route / SQL |
| jedi-oscal（套件） | `~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal/` | ORM model 擴充 / repo / mapper / DTO / enum / OSCAL serialize |
| compliance-manager-fe | `~/Projects/Billows/Audit-Manager/compliance-manager-fe/` | Excel 匯入預覽頁 + SSP 匯出 UI + 樣板下拉 |
| compliance-manager-test | `~/Projects/Billows/Audit-Manager/compliance-manager-test/` | BDD scenario for Excel 匯入 / SSP 匯出 |

---

## 反斷層機制

1. **此 tracker 為單一事實來源** — 任何 session 開工前先讀這份
2. **每 phase ship 後三件事**：
   - 更新本表狀態欄 + commit hash + changelog 連結
   - 寫 changelog（`docs/changelog/`）依 CLAUDE.md 規範
   - 對應 requirement-understanding §6 階段表加 `✅ shipped (commit, date)` 標記
3. **重型 phase 開工前必先 brainstorm**（A0 / A3 / A4 / B5）
4. **memory 已記錄此 tracker 位置**，新 session 自動載入

---

## 最後更新

2026-05-18 — **A0 shipped** ✅
- BE migration: `c4804d7`
- jedi-oscal stack: 7 commits (`afe7035` → `dbb3d7c`)
- Caller fix: `a1b80cc`
- Regression test: `e73b1aa`
- Tracker docs: `60a4a2e`
- Changelog: `docs/changelog/2026-05-18-tweak-ssp-system-impl-extension.md`
- Analysis: `docs/analysis/2026-05-18-ssp-system-impl-extend-vs-new-tables.md`
- Handoff summary: `docs/conversation-history/2026-05-18/ssp-import-export-phase2/SUMMARY.md`

2026-05-19 — **A0.1 shipped** ✅
- BE Task 7 (caller + DI): `eb9fa7e`
- jedi-oscal 6 commits: `762d8fc` → `cc65e3b` → `c0fcae9` → `d2178c1` → `8e3e58b` → `4666091`
- SQL migration（已執行於 dev DB）: `scripts/sql/2026-05-19-ssp-system-implementation-restructure.sql`
- Design: `docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A0.1.md`（含 §11 reconciliation）
- Plan: `docs/features/FR-011.2-2605-ssp-import-export-phase2/implementation-plan-A0.1.md`
- Analysis (v4 → v5 校正): `docs/analysis/2026-05-19-ssp-system-impl-restructure-rationale.md`
- Changelog: `docs/changelog/2026-05-19-tweak-ssp-system-impl-restructure.md`
- Handoff summary: `docs/conversation-history/2026-05-19/ssp-import-export-phase2-A0.1/SUMMARY.md`

**A0.1 已 ship 變動**：
- 既有 `system_security_plan_system_implementations` rename → `ssp_system_implementation_items`
- 新建 `ssp_system_implementations`（main, 1:1 per scope, UNIQUE on scope）
- 新建 `ssp_inventory_item_components`（M:N join, UNIQUE on inventory_item+component）
- Column rename `information_system_id` → `system_characteristic_id`（鉤稽路徑統一走 SSP 內 characteristic 中介）
- Items 加 `system_implementation_id` NOT NULL FK 指向 main + relationship
- jedi-oscal items stack 全 rename `Ssp*Item*` + 新建 main / join 完整 DDD stack（共 24 個檔）
- yaml_mapper 從 main 出發 + inventory-item.implemented-components[] 從 join 填入
- 主 BE 兩個 caller (`project_device_mapping_service` / `ssp_versioning_service`) 改寫支援 main upsert flow
- 累計 ~126 個 unit test 全綠（包含 6 個新加的 yaml_mapper / main / join / FK / upsert test）

**已知 follow-up**（不阻 A0.1 ship）：
- jedi-oscal 套件 Nexus 發版（Phase 2 整體完工一次性 bump）
- 主 BE jedi-issue / python-gitlab + PyGithub 啟動環境問題（與 A0.1 無關，缺 GITLAB_*/GITHUB_PRIVATE_TOKEN env vars）
- 3 個 code review 建議的 robustness improvement（main audit trail / orphan main cleanup / yaml component-uuid 排序穩定性）
- 10 筆 hardware items device_id 無法 backfill（item.name 對不上當前 device — 可能 device 已刪 / 改名，需業務判斷）

**A0.1 e2e 驗證 follow-up（同日 ship）：**
- `6deacef` fix(associations): ProjectDeviceMappingService 寫 SSP item 補填 device_id soft FK + backfill SQL 對 135 筆既有資料補回（10 筆 unmatchable 保留 NULL）

下一步：A1（Excel 樣板）或 B1（Docx 樣板）— 兩條可平行。

---

2026-05-19 — **A1 BE partial shipped** ⏳（5/7 task）
- 8 commits 全在 `feature/ssp-import-export-phase2` branch：
  - `b18db55` docs(ssp-import-export-phase2): A1 phase docs — design + implementation plan
  - `f59c4ff` docs(ssp-import-export-phase2): A1 T0 verify 結果回填 design.md (4 處)
  - `d9d54c2` feat(ssp-import-template): A1 T1 skeleton — route + app service + DI 接通
  - `f68525f` feat(ssp-import-template): A1 T2 generator base — sheet defs + styles + lookup + DV helpers
  - `ffd5d63` feat(ssp-import-template): A1 T3 blank mode — generator 主邏輯 + lookup wiring + 30 tests
  - `f14a942` docs(ssp-import-export-phase2): A1 partial summary — T0-T3 收口 + 換 session 交接
  - `c3de9fa` feat(ssp-import-template): A1 T4 filled mode 非控制項 sheet — 6 領域預填 + DI + 12 tests
  - `419907d` feat(ssp-import-template): A1 T5 07_控制項與AO sheet — profile-scoped 父子 row + MF defaults 預填 + 6 tests
- Design: `docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A1.md`（含 §14 SemVer SOP）
- Plan: `docs/features/FR-011.2-2605-ssp-import-export-phase2/implementation-plan-A1.md`
- Changelog: `docs/changelog/2026-05-19-feat-mf-ssp-import-template-download.md`
- Handoff summary: `docs/conversation-history/2026-05-19/ssp-import-export-phase2-A1/SUMMARY.md`（T0-T3）— T4/T5/T7 handoff 待補
- TEMPLATE_VERSION = `v1.0.0`（A2 parser 讀此版本作為相容性 anchor）

**A1 已 ship 範圍**（T0-T6 完成 + 3 輪 UX polish）：

BE：
- `GET /api/1.0/module-frame/<uid>/ssp-import-template?mode=blank|filled&locale=...`（MF-scoped）
- `GET /api/1.0/ssp-import-template?framework_version_uid=<uid>&mode=blank`（**T6 新增** FW-version-scoped，supersetcontrols 走 catalog 全 controls，供 S1 訪談前下載）
- 9 sheet 結構（00_說明 + 01~08 資料）+ 6 個隱藏 lookup sheets
- blank mode 純結構 + 下拉資料源
- filled mode 預填 7 sheet
- 父 row CONTROL_ROW_FILL 灰底覆蓋（07 視覺區分）
- TEMPLATE_VERSION = `v1.1.0`

UX polish（3 輪）：
- Hidden columns：framework_version_uid / profile_uid / statement_id（user 看不到，A2 parser 仍可讀）
- 必填欄位：header 黃底 + body 套黃底到實際 filled rows 數量（空 sheet 不延伸）+ thin border 補回視覺分隔
- VLOOKUP autofill（限 blank mode 寫公式，filled mode 不覆蓋既有）：matched_user/device/info_system 選定後 email/name/IP 自動帶入（VLOOKUP 自動算 follow-up，Excel 開檔可能需 Ctrl+Alt+F9 強制重算）
- 程序書欄位對齊 schema：刪 doc_no/doc_type/version（系統 schema 無）
- 03_參與人員 role 對齊 `ParticipantRole`（manager/reviewer/auditor/viewer）+ required

FE：
- 列表頁右上「新增合規資源庫」menu 加「下載 SSP 匯入樣板」→ DownloadSspBlankTemplateDialog（framework + version 兩層 picker，stack layout 避免長框架名跑版）
- MF template-edit 頁批次維護 menu 加 2 項（下載空白/已填樣板）
- i18n zh-tw + en

測試：BE 106 unit test 全綠（81 base + 11 T6 endpoint + 14 polish + 4 修改 = 106）
- 71 個 unit test 全綠

**A1 未完項（partial ship 原因）**：
- T6 FE 下載按鈕（compliance-manager-fe）— MF 詳細頁加 SplitButton + axios blob + i18n
- T7 完整版（剩 cucumber e2e + 完整 BE smoke）— BE smoke 撞 A0.1 follow-up #7 jedi-issue GitLab env，user 端配齊環境後可跑

下一步：A1 收尾（T6 FE + T7 完整 E2E）或先推 B1（Docx 樣板）。
