A5 Task Arc Final SUMMARY — 預覽 UI + Confirm 寫入

時程:2026-05-20 (Session A docs) → 2026-05-21 (Session B BE + Session C FE) 狀態:BE + FE shipped ✅;manual smoke checklist 待 user 跑 跨 repo:compliance-manager-be + compliance-manager-fe(jedi-* 不動)


1. 整段在幹嘛(一句話)

把 A4 ship 後的「parser 解析 + 自動配對 → 寫入 SSP」這條 BE pipeline,補上「user 預覽頁拍板 → 套到 confirm」這條 user-facing path — Track A Excel 匯入端到端完整可用。


2. 三個 Session 範圍

Session 時間 範圍 主要 commit
A (docs) 2026-05-20 design-A5.md + implementation-plan-A5.md + T0 6 verify 5d979bf (BE)
B (BE) 2026-05-21 上午 T1-T8:schema 結構化 + inline_creates + decisions + content_overrides + confirm 整合 + 54 個 pytest 535b931 → 6f926e0 + c61ef02 (BE)
C (FE) 2026-05-21 下午 T9-T14:service + store + router + 上傳頁 + 5 sheet preview + RowActionMenu + InlineCreateDialog + Confirm Dialog + i18n + smoke checklist c95d02a → 332b393 (FE)

3. Commit 清單

BE repo (feature/ssp-import-export-phase2)

c091824 docs(ssp-import-export-phase2): A5 Session B 收尾 - changelog + tracker + handoff B→C
6f926e0 test(oscal): A5 T7 unit + integration tests (54 個 a5 test)
7ed9363 feat(oscal): A5 T4 confirm_import 整合 + atomicity 保證
56edd30 feat(oscal): A5 T3 _apply_decisions + _apply_content_overrides
5852cca feat(oscal): A5 T2 inline_creates handling + 4 domain service DI
535b931 feat(oscal): A5 T1 confirm request schema 定稿
c61ef02 docs(ssp-import-export-phase2): A5 T14 manual smoke checklist
+ A5 SUMMARY commit(本檔)

6+ 個 BE commits (Session B T1-T7 + T8 收尾 + T14 smoke checklist + SUMMARY)。

FE repo (feature/ssp-import-export-phase2)

332b393 feat(fe): A5 T13 confirm Dialog + decision summary
0cf3058 feat(fe): A5 T12 RowActionMenu + InlineCreateDialog + EntityPickerDialog
2412e74 feat(fe): A5 T11 5 個 sheet preview + MatchStatusCell
24622ee feat(fe): A5 T10 ImportExcelPage + ImportExcelPreviewPage shell
c95d02a feat(fe): A5 T9 SspExcelImportService + Pinia store + 3 routes
+ A5 FE changelog commit(隨本 SUMMARY 一起 ship)

5+ 個 FE commits (T9-T13 + changelog)。

跨 repo 改動範圍

Repo 新檔 修改檔 行數
BE 0 程式碼新檔 + 1 docs(smoke checklist) 5 程式碼檔(serializers / app service / DI container / error code)+ 4 test 檔(54 test)+ 2 docs(design / changelog) ~1300+
FE 11 新檔(service / store + 2 page + 6 component + 2 i18n JSON)+ 1 changelog 5 修改檔(router / api.js / menu.json × 2 / locales index.js) ~1500+

4. 行為差異(user-facing)

4.1 ship 前(A4 ship 後 state)

  • Excel 匯入流程:BE 可解析、可寫 SSP,但無 user-facing UI
  • Confirm payload:BE 接 decisions = List[Dict] / overrides = Dict 彈性 schema,user decision 無路徑
  • 路由 /module-frame/import-excel 不存在

4.2 ship 後

功能 行為
路由 /module-frame/import-excel (create) + /module-frame/:uid/import-excel (update) + /module-frame/import-excel/preview/:parseUid (preview) 三條路由活了
上傳頁 create mode:framework + version Dropdown picker。update mode:直接 file upload。POST parse → 自動 redirect preview
預覽頁 5 sheet TabView(devices / info_systems / leveraged / parties / controls)+ badge(unmatched 紅 / fuzzy 橘)
Sheet DataTable devices / info_systems 全功能(matched / fuzzy / unmatched 標示 + 操作 menu);controls row expansion 顯示 objectives;parties union org+person;leveraged status-only(無 inline action)
Unmatched 三路徑 RowActionMenu popup:選現有 (EntityPickerDialog) / 新建 (InlineCreateDialog 4 entity form) / 純文字保留 / 重置
編輯持久 localStorage ssp-excel-import:<parse_uid> 暫存 decisions + inlineCreates + contentOverrides;TTL 7 天對齊 BE parse job;reload 自動恢復
Confirm Dialog 顯示 decisionSummary 4 計數(自動配對 / 已改選 / 新建 / 純文字保留)+ inlineCreatesCount hint;點確定 → POST confirm → 成功 redirect MF 詳細頁 + clear localStorage
i18n zh-tw + en 補 80+ 個 key;切語言所有 label / Dialog / Tag 都翻譯
BE schema 結構化 decisions = List[Nested(DecisionSchema)] + inline_creates = List[Nested(InlineCreateSchema)] + content_overrides = Dict;舊 caller 傳 {} / {"decisions": [], "overrides": {}} 仍合法(defensive .get(...) 模式)
Inline create 4 entity confirm @transaction 內依序套:content_overrides → inline_creates(device / info_system / org_unit / user)→ decisions → A4 8-step write;失敗整段 rollback
import_summary A4 既有 + 加 inline_created_devices / _info_systems / _org_units / _users / decision_applied_count / skipped_as_text_count

5. 規範文件清單

BE repo

文件 路徑
Design + Plan docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A5.md (含 §10.1-10.4 共 12 條偏差) + implementation-plan-A5.md
Changelog docs/changelog/2026-05-21-feat-ssp-excel-import-phase2-a5-be.md (type=feat)
Smoke checklist docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-21-a5-smoke-checklist.md (8 段 user 自跑 checklist)
本 SUMMARY docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-21-a5-SUMMARY.md
對話歷史 待 user 匯出原始對話 dump 到 docs/conversation-history/2026-05-21/ssp-import-export-phase2-A5/ (兩層目錄,原始 dump only)
Tracker README docs/features/FR-011.2-2605-ssp-import-export-phase2/README.md A5 row 改 BE+FE shipped ✅

FE repo

文件 路徑
Changelog docs/changelog/2026-05-21-feat-ssp-excel-import-phase2-a5-fe.md

6. 15 條偏差紀錄(design-A5 §10.1-10.3 詳細)

§10.1 T0 pre-flight verify 偏差 (6 條,Session B 開工前)

  1. 10.1.1 — Domain service .add() 方法名 3/4 不一致(device → add_device / info_sys → add ✓ / org_unit → add_org_unit / user → add_user)→ _apply_inline_creates 用 entity_type → method-name dispatch
  2. 10.1.2UserDomainService.add_usersend_invite 機制 → 不發邀請信,user 帳號由 admin 後續手動處理
  3. 10.1.3 — DELETE endpoint + discard_parse 已 ship (A2 階段) → T5 縮 scope ~3 個 pytest 併入 T7
  4. 10.1.4 — content_overrides 命名沿 docx pattern(implementation + objectives[<key>]
  5. 10.1.5 — Error code 起始序號 400=071 / 409=031 / 412=027
  6. 10.1.6 — Tests 跳過 schema 驗證 → app service 用 defensive .get(...) or []

§10.2 BE 實作偏差 (1 條)

  1. 10.2.1 — Decisions 對 write-time FK 不直接 propagate(known limitation):A5 _apply_decisions 蓋 parsed_result 的 matched_*_id,但 _write_all_data Step 7 by-key 對齊時被 orchestrator 結果覆寫。Inline creates 跟 stats 正確,但 user 改 ID 不一定反映 DB。Follow-up F-A5-decision-write-propagation — 需動 A4 base.py reconciler 加 _already_resolved_by_decision() hook,跨 §2.3 邊界,待 Session C smoke 後評估 priority

§10.3 FE 實作偏差 (8 條,Session C)

  1. 10.3.1 — FE 檔案結構照 FE 慣例(service 平鋪 / stores 複數 / config/router/index.js / i18n JSON)— design §3.2 路徑寫得太早未驗 FE repo
  2. 10.3.2 — 5 sheet 而非 9 sheet(BE DecisionSchema OneOf 限制;其他 4 sheet 走 content_overrides 留 T14 polish)
  3. 10.3.3 — Upload + Preview 拆 2 個 route(跟 docx pattern 不同;換 reload 恢復 + share link)
  4. 10.3.4 — RowActionMenu(menu) + InlineCreateDialog + EntityPickerDialog 三檔代替原 plan UnmatchedRow + FuzzyBadge;MatchStatusCell 已含 fuzzy 顯示
  5. 10.3.5 — Leveraged sheet RowActionMenu 不接(BE InlineCreateSchema OneOf 不含 leveraged + 無 party menu API)
  6. 10.3.6 — localStorage shape 跟 §4.3 example 不一致(store 用 nested dict + Map 而非 flat array;trade-off:避免 splice shift;buildConfirmPayload 才 enumerate 成 BE schema array)
  7. 10.3.7 — T14 manual smoke 拋給 user 跑(agent 無 browser interactive;agent 完成的是 build:DEV verify;checklist 在 handoff/2026-05-21-a5-smoke-checklist.md)
  8. 10.3.8 — T11 從 7 個獨立 sheet preview 變 5 sheet + MatchStatusCell 共用元件(實際 9 個 .vue 檔:5 sheet preview + 3 共用元件 + 1 cell;比 plan 7 個多但拆共用元件好維護)

7. 已知 follow-up

ID 描述 Priority 觸發條件
F-A5-decision-write-propagation A5 decisions 設的 matched_*_id 在 write-time 被 orchestrator 覆寫 medium-high Session C smoke 後評估 user 是否真的踩到
F-A5-leveraged-action Leveraged sheet action column 為 (無 party menu API + BE 不支援 leveraged inline) medium 後續評估
F-A5-content-overrides-ui SheetPreviewBasic (01_基本資料) + SheetPreviewRefDocs (08_程序書) 未實作 medium T14 polish 或下個 phase
F-A5-cucumber cucumber regression 沿 F-A4-cucumber pattern low env 配齊那天一次性補 A1-A5 共 5 phase
F-A5-user-invite-on-inline-create inline-create user 不發邀請信(add_user 無 send_invite) low 若客戶有需求再加

8. 部署 Handover

8.1 部署 dependency

  • jedi- 套件*:不動(沒 bump version;feature 全完工才一次性 bump)
  • DB migration:A5 無 schema 異動,無 SQL migration 需執行
  • Config:無新環境變數

8.2 部署順序

  1. BE deployfeature/ssp-import-export-phase2 → merge → main)
  2. FE deployfeature/ssp-import-export-phase2 → merge → main + npm run build:DEV/STG/PRD
  3. Smoke test:照 docs/features/FR-011.2-2605-ssp-import-export-phase2/handoff/2026-05-21-a5-smoke-checklist.md 8 段
  4. 若踩到 Follow-up 7.1 (F-A5-decision-write-propagation) → 視 user 重要度補 hotfix;否則暫留 follow-up

8.3 Manual smoke 重點

  • ✅ Build verified(npm run build:DEV 通;ImportExcelPreviewPage 30 kB 進 dist)
  • ✅ BE pytest 273 全綠(0 regression)
  • ⏳ 待 user 跑 8 段 smoke:路由 / 預覽 / RowActionMenu / localStorage / Confirm / Discard / i18n / 已知限制觀察

9. 下一步建議

A5 ship 後 Track A Excel 匯入完整可用。Phase 2 後續:

  • Track A Excel 匯入 ✅ 完工(A1 樣板 + A2 parser + A3 matcher + A4 寫入 + A5 預覽 confirm)
  • Track B SSP 匯出 (B1-B6 6 phase 待開)— 預估 1-2 週

短期 follow-up 優先序:

  1. F-A5-decision-write-propagation — 跑 manual smoke 後評估,若 user 真踩到就 hotfix
  2. F-A5-content-overrides-ui — SheetPreviewBasic + SheetPreviewRefDocs;user 可在預覽頁編輯 metadata + 程序書連結文字
  3. Track B 開工 — 評估與 A5 ship 後資料模型是否一致

10. 致謝

A5 task arc 跨 3 session、2 repo、6 commits BE + 5 commits FE。Session A 拍板 3 個關鍵決策(confirm 階段 inline create / fuzzy auto-accept / FE 獨立路由)。Session B 把 BE schema 結構化並寫齊 54 個 pytest。Session C FE 用既有 docx import pattern 1:1 mirror,避免重造輪子。

12 條偏差紀錄全寫進 design-A5 §10.1-10.4 — 給未來讀者一個完整的「為什麼這樣做、不那樣做」回顧。

— End of A5 Final SUMMARY —