交接 Prompt — A1 收尾(T6 FE + T7 完整 E2E)

使用方式:把下方「交接 prompt 本體」整段貼到新 session 即可接手。 前置狀態:A1 BE 端 partial shipped,剩 FE 下載按鈕 + 完整 E2E。


§1

交接 prompt 本體(從此貼到新 session)

我要接手 SSP 匯入匯出 Phase 2 A1(Excel 樣板下載)的收尾工作,BE 端
已完整 ship(partial T7 BE 部分含 changelog + tracker 都完成),剩 T6 FE
下載按鈕 + T7 完整 E2E。

前置狀態
========

- branch: feature/ssp-import-export-phase2(BE repo,沿用,不另開)
- A1 已 ship 8 commits 未 push(涵蓋 T0~T5 + partial T7 BE 部分)
- 71 個 unit test 全綠(T2 22 + T3 16 + T3/T4/T5 app service 24 +
  T4/T5 generator filled 7)
- blank / filled 兩模式 code 層級完整可用
- BE smoke 撞 A0.1 follow-up #7 jedi-issue GitLab env,user 端配齊環境後可跑完整 boot
- jedi-oscal 仍 path-dep(A0.1 既有,本 phase 不動套件層)

開工 SOP
========

第一步:必讀文件(順序)

1. docs/conversation-history/2026-05-19/ssp-import-export-phase2-A1/SUMMARY-be-partial-ship.md
   ← 本 session(T4 + T5 + partial T7)完整收口 + A1 全 commit 鏈 + 設計 anchor + 剩餘工作
2. docs/conversation-history/2026-05-19/ssp-import-export-phase2-A1/SUMMARY.md
   ← 上 session(T0-T3)partial summary
3. docs/changelog/2026-05-19-feat-mf-ssp-import-template-download.md
   ← 完整 changelog 含 API spec、行為差異、父子 row contract、TEMPLATE_VERSION
4. docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A1.md
   ← A1 完整設計(含 §14 SemVer SOP)
5. docs/features/FR-011.2-2605-ssp-import-export-phase2/implementation-plan-A1.md
   ← 7 個 task 詳細 plan;T6 / T7 詳細範圍在 line 533-577 / 580-660

讀完後給「我看完了,A1 BE 完成範圍是 T0-T5 + partial T7,下一步建議做 X」的
簡短確認。

第二步:決定下一階段
====================

兩個方向:

選項 A — T6(FE 下載按鈕)
- 中型,0.5d
- 跨到 ~/Projects/Billows/Audit-Manager/compliance-manager-fe/
- 範圍:MF 詳細頁工具列加 SplitButton(blank / filled 下拉)+ axios blob
  download + i18n(zh_Hant_TW + en)+ API endpoint constant
- 跟 T7 cucumber 平行可做(T6 先做能讓人手動測,T7 才寫自動化 e2e)

選項 B — T7 完整 E2E(cucumber + 完整 BE smoke)
- 中型,0.5d
- 跨到 ~/Projects/Billows/Audit-Manager/compliance-manager-test/
- 範圍:cucumber feature `mf_excel_template_download.feature` 兩 scenario
  (blank + filled)+ Playwright step + page object;user 端配齊 GitLab env
  後跑完整 BE boot smoke
- 嚴格說 T7 cucumber 需 T6 FE 按鈕已實作(FE 才能點下載)

建議順序:T6 → T7(依賴關係 + 可手動測過 T6 再寫自動化)

選項 C — 暫停 A1 收尾,切到其他 phase
- 例如 B1 Docx 樣板 + generator 骨架(中型,依賴 A0.1,可平行 A1 未完項)
- 或 A2 Excel Parser + 解析 API(中型,依賴 A1 BE 已 ship,可開始)

問我選哪個,等我說 GO 才開工。

第三步:依選擇走對應 SOP
========================

T6 (FE) SOP:
- 主要 repo 切到 compliance-manager-fe
- 不必新開 phase docs(implementation-plan-A1.md Task 6 已涵蓋)
- 完成後寫 changelog(type=feat,modules=[module-frame, ssp-import-template, frontend])
- BE repo 改 docs/changelog 標 T6 完成 + tracker README 更新「FE shipped」

T7 (E2E + 完整 BE smoke) SOP:
- 主要 repo 切到 compliance-manager-test
- BE repo user 端 配齊 GitLab env 後做完整 smoke(curl 兩個 mode + openpyxl 驗)
- 完成後 update docs/changelog 標 T7 完成 + tracker README 改 "A1 fully shipped"

Pre-flight verify 該做的事(動工前必驗):

T6 verify:
- MF 詳細頁 .vue 檔路徑(compliance-manager-fe src/views/ 下;user 確認過去)
- 既有 SplitButton 元件用法(看 PrimeVue Splitter / Button 用法)
- axios blob download pattern(既有 export 功能可能已有)
- API 端點 constant 加哪裡(compliance-manager-fe/src/config/api/api.js)
- BaseService 用法(compliance-manager-fe/src/service/BaseService.js)

T7 verify:
- 既有 cucumber feature 結構(compliance-manager-test/features/)
- Playwright page object pattern
- 既有 download / file 驗證 step(之前 framework PDF / SSP 匯入應有類似)
- openpyxl 在 test repo 是否已裝(package.json)

每項在 implementation log 內列具體 grep / read 命令。

鐵律(沿用 A0.1 + A1 T0-T5 全部)
=================================

1. 顯式 git add <file>,禁 -am / -A — commit 前必 git status --short 確認 staged 區乾淨
2. jedi-oscal 維持 path-dep,不 bump 版本不推 Nexus(Phase 2 整體完工才一次性 bump)
3. pyproject.toml dev-path 改動不該 commit(仍 working tree M 是對的)
4. BE 重啟必 lsof -ti:8000 | xargs kill -9(nohup orphan PID 已知陷阱)
5. 改 BE service code 後必提醒 user 重啟 — BE 沒 hot reload(FE 有 hot reload, 但 routes 改要重 build)
6. DDD 嚴格分層 — Route 不碰 DB,App Service 用 @transaction,Generator 純函式不依賴 DI
7. 不寫 docstring / 註解除非真有 non-obvious 的 why 要記
8. Test 用 mock 包 logger 避開 jedi DBLogHandler 撞 SessionLocal=None
9. T0 verify 結果不符 design 假設時主動修 design.md(不照舊硬幹)
10. 跨 repo 切換時提醒 user:FE / test repo 跟 BE 是不同 git repo,commit / branch 分開

T6 specific:
- compliance-manager-fe 自己的 CLAUDE.md(646 行)為 FE 規範主導;BE CLAUDE.md
  的 BE 視角文件 `docs/claude/frontend-overview.md` 提供 BE 開發者 cheatsheet
- 加按鈕走 i18n(不寫死中文)
- response handling 注意 BaseService 的返回值規則
- PrimeVue 3.53 quirks:SplitButton / Dropdown null-value bug 看 BE CLAUDE.md
  「PrimeVue 3.53 已知 quirks」段

T7 specific:
- E2E 一律在 compliance-manager-test repo,不在主 BE 加 test
- BDD 三層分離:requirements → specs → features/steps/pages
- 完整 BE smoke 需 user 端配齊 GitHub / GitLab env

已知 contracts(接 T6 / T7 必看)
=================================

API endpoint
~~~~~~~~~~~~

GET /api/1.0/module-frame/<uid>/ssp-import-template?mode=blank|filled&locale=zh_Hant_TW

回 xlsx binary + Content-Disposition: attachment; filename=ssp_template_<mf_short_name>_<mode>_<yyyymmdd>.xlsx

錯誤:
  - 404 GRC_MODULE_FRAME_NOT_FOUND
  - 400 mode 不在 blank/filled
  - 401 無 JWT

樣板版本 TEMPLATE_VERSION
~~~~~~~~~~~~~~~~~~~~~~~~~

v1.0.0 — 寫在 00_說明 sheet R1 col B
A2 parser 讀此版本做相容性判斷(design.md §14 SemVer SOP)

控制項 sheet B 模式(07_控制項與AO)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- 父 row:statement_id 空 + control_id 填 + control_name 填 + 灰底 F2F2F2 覆蓋整 row
- 子 row:statement_id=AO uid 字串 + control_id 同父 + objective_id (e.g. "AC-1_smt.a") + 白底
- A2 parser 用 statement_id 是否為空判斷父子;control_id 連續判斷階層歸屬

DI wiring(T6/T7 不必動,但理解有幫助)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

module_frame_container 加 3 個 DependenciesContainer slot(device / oscal /
information_system);main containers.py device 直接傳、oscal/info_system 用
override pattern(mirror line 175)。

已知限制
========

- 主 BE 完整 boot 撞 jedi-issue 缺 GITHUB_PRIVATE_TOKEN / GITLAB_* env vars
  (A0.1 follow-up #7,非 A1 引入),單元測試與 partial smoke 可跑,完整 boot
  smoke 需 user 環境
- pre-existing test_module_frame_write_strategy_v2_parties::test_write_parties_refreshes_existing_party_in_place
  失敗(非 A1 引入,T4 c3de9fa 也 fail)— low severity,OSCAL Party 模型相關 stale test

工具預期
========

- T6 用既有 PrimeVue 元件 + BaseService pattern,不需新建 helper
- T7 用既有 cucumber + Playwright + openpyxl pattern
- 對 BE 端只需把 changelog + tracker README 標 T6/T7 完成

謝謝。

§2

收口清單(A1 全 ship 後做)

T6 + T7 完整 ship 後:

  1. docs/changelog/ 加 T6 (FE) + T7 (E2E + 完整 smoke) 對應 changelog
  2. docs/features/FR-011.2-2605-ssp-import-export-phase2/README.md A1 row 改 fully shipped
  3. docs/features/FR-011.2-2605-ssp-import-export-phase2/design-A1.md 加 §11 Reconciliation 段(記錄 16+ 條實作偏離原始 design 的條目)
  4. docs/conversation-history/2026-05-19/ssp-import-export-phase2-A1/ 加最終 SUMMARY-full-ship.md(涵蓋 T0-T7 全部)
  5. 跨 repo commits 各自 push + open PR
  6. changelog frontmatter commit hash 全部回填(push 後最終 hash 才確定)

§3

速查:A1 全 commit 鏈

Commit 主題
b18db55 docs A1 phase docs — design + implementation plan
f59c4ff docs T0 verify 結果回填 design.md (4 處)
d9d54c2 feat T1 skeleton — route + app service + DI 接通
f68525f feat T2 generator base — sheet defs + styles + lookup + DV helpers
ffd5d63 feat T3 blank mode — generator 主邏輯 + lookup wiring + 30 tests
f14a942 docs T0-T3 partial summary
c3de9fa feat T4 filled mode 非控制項 sheet — 6 領域預填 + DI + 12 tests
419907d feat T5 07 控制項與AO sheet — 父子 row + MF defaults 預填 + 6 tests
46b8999 docs T7 partial — BE smoke + changelog + tracker

8 commits 未 push