# FR-145 交接現況（STATE）

> **這份是 living 檔**：每棒就地 Edit，只描述「此刻」。歷史脈絡看同資料夾的 `FR-145-LOG.md`。

| 項目 | 值 |
|------|-----|
| 最後更新 | 2026-10-17 21:10（第 2 棒首腦交棒給總驗收首腦；開發告一段落） |
| branch | BE／FE／jedi-python-package 都在 `feature/FR-139`。**BE、FE 已 push**（2026-10-17 21:20，BE `cea99dc0e`、FE `a424b9c1`，含本案全部）；jedi 2 筆未 push（FR-143／147 的，非本案） |
| 母案卡 | CM-2854 https://app.notion.com/p/FR-145-3fc346da4cd081a89e29ecd3e0140c90 |
| 本棒角色 | 首腦第 2 棒（驗收卡 3～5、8；收口 SPEC／手冊）。**下一棒仍是本案首腦（第 3 棒）**：上層有一個跨 FR-139～147 的總驗收首腦在跑全專案總測試，測出本案問題會派修單過來，第 3 棒負責分析根因、開卡、派 runner、驗收；總收尾（進版等）由上層統一做 |
| 卡片狀態 | **八張全 Done**（2855／2856／2857／2858／2859／2860／2863／2873）；母卡 CM-2854 待收口 |
| Notion 回寫規範 | `docs/claude/notion-issue-tracker.md` |
| 接手前必讀 | §0 讀序 |

## 🧭 原始需求 / WHY

決策者 2026-10-17 原話：
> 1. 要可以下載結案報告一大包：調查結果 PDF（顧問）、控制項 Excel mapping 表、證據包（依照控制項結構分類）、稽核結果、稽核計畫
> 2. 要可以匯出稽核報告（內外都要）：內容是每個控制項的結果，以及改善計劃內容
> 我在模擬真實 PM 或顧問什麼時間點會被客戶要報告，那我們可能就在出該階段的報告。

**需求的演變（一天內三輪雛形審查定下來的）**：
- 稽核報告（Word／PDF／Excel）掛在**每個稽核次**後面，結案就能下載；Excel 只給最後一份（有改善計畫給改善計畫工作表，沒有給稽核結果工作表），一律列全部評估目標。
- 結案報告分**兩層**：階段結案報告一輪一份（只在輪次結案仍有不符合、後面接覆核輪時才建），專案總報告一專案一份（專案完成才建）；一次通過的專案只有總報告。
- 報告**由系統自動建立**，不設建立鈕；六章文件版面只有「總結與建議」由人寫（不標撰寫者），其餘從 AP／AR／POA&M 即時算。
- 三顆按鈕：**存檔／定稿／下載**（下拉：Word、PDF、報告包 zip、報告包內容）。「發出」「定版」都被退，最後定「定稿」。Word 與 PDF 都給顧問自己改，系統不介入、只記下載日誌。
- 報告包：Word＋PDF＋證據對照表＋各稽核次報告與工作表＋依族群／控制項／評估目標分資料夾的**凍結證據**，問卷填答轉 PDF、連結只進對照表。

**目標模型**：`project_summary_reports` 加 `report_type(stage|final|legacy)`／`audit_round_id`／`status(draft|issued)`／`issued_version`；歷史表加 `version_no`／`issued`／`bundle_ref`。「專案調查結果」選單改名「結案報告」，舊資料標 legacy 唯讀。

**本棒在大圖**：首腦第 2 棒，驗收卡 3、4、5、8，收口 SPEC 與手冊。**開發告一段落**：八張卡全 Done、SPEC／手冊已更新、已 push。第 3 棒的工作是**接上層總驗收派來的修單**：分析→開卡→派 runner→驗收→回報上層；剩的 e2e、出貨基線、還原 pin、進版、母卡收 Done 由上層總收尾統一做。

## §0 接手讀序（本案首腦第 3 棒）

### 0.1 🔒 先懂這個功能在做什麼（全讀）
1. 本檔 🧭 WHY 節＋§2 已定裁示
2. 使用手冊 `docs/user-manual/closing-report-guide.md`——白話版的操作全貌；上層總測試照這份走，修單來時先對這份看「設計如此」還是「壞了」
3. SPEC 子頁 `docs/spec-site/current/reporting/closing-report-page.md`——§6 讀模型欄位與算法、§8 檔案地圖（修單定位用）、§12 已知坑（11 條「不是 bug」）

### 0.2 現況與待辦
4. 本檔 §1（git／DB／測試資料）、§3（上層會驗什麼、修單來了怎麼接、發版前欠什麼）
5. `FR-145-LOG.md` 最後 2 個 block（卡 8 驗收、收口）

### 0.3 需要細節才開
- `design.md` D1～D16 與「坑與陷阱」；Notion 八張卡尾各有「✅ 首腦復核」段（實打了什麼、打折處）
- 討論稿 `discussion.md`（為什麼這樣定、被排除方案）

### 0.4 ✅ 冷接自檢
1. 什麼情況一個專案只有「專案總報告」、沒有階段報告？
2. 「定稿」做三件什麼事？為什麼已定稿不能從版本紀錄還原？
3. 報告包的證據為什麼取凍結版本？DEV 既有資料為什麼打不到這條路？
4. 修單來了，先查哪三處判斷是「設計如此」還是真壞？（手冊、SPEC §12、Notion 卡尾首腦復核段的打折處）

## §1 當前狀態（2026-10-17 21:10 實查）

**git**
- BE `feature/FR-139` HEAD `cea99dc0e`，已 push。工作樹：`pyproject.toml`／`poetry.lock` 未 commit——**四支套件（task-platform、compliance-audit、flow-engine、oscal-v2）開在 path dependency**，是 FR-139／143 開發期留的、不是本案開的，**進版前要還原 pin**（屬總收尾）；另有平行 FR-144／147 的未追蹤檔，不碰。
- FE `feature/FR-139` HEAD `a424b9c1`（含平行 FR-147 後續），已 push；本案最後一筆 `8c1c30e7`。工作樹有平行 FR-147 module_frame 改動，不碰。
- jedi-python-package 未 push 2 筆（FR-143.1、FR-147.4b），非本案。平行有別案 commit（批次刪除 3d66f646／c7a91f45）插在卡 3、4 之間。
- jedi-python-package 乾淨。

**本案 commits**（BE／FE 全部已 push）
| 卡 | BE | FE |
|---|---|---|
| 1 CM-2855 | `b95c6eb6a` | `0378b001` |
| 2 CM-2856 | `1f84d3bc6`（撞進 FR-142 的 doc commit，內容完整）＋首腦修正 `6ea7e136a` | `fee81522`＋首腦修正 `a4fe5065` |
| 6 CM-2860 | `30650bdd0` | `249ea078` |
| 7 CM-2863 | — | `88ca7ca8`（退回）→ `67e9e11c` |
| 3 CM-2857 | `824bffc80`＋截圖 `85e2f6ee8` | `6ea3ecc1` |
| 4 CM-2858 | `8fe83c3df` | `17c51806` |
| 5 CM-2859 | `2da62a70a` | `8c1c30e7` |
| 8 CM-2873 | `0e95b7166` | — |
| 首腦版面修正 | — | `04f58f2f`（撐滿、dark-card、下載紀錄對話框）`7a836ec4`（表格字級） |
| 文件 | `be8e18fe4`（討論稿）`35188c16f`（design＋開卡）…`f1aea52ea`（第 1 棒交接）`a43c5736a`（SPEC 重寫）＋本棒 | — |

**DEV DB**（localhost:5432 `guidant_ai_dev`，密碼看 `.env` `DB_PASSWORD`）：migration `2026-10-17-fr145-closing-report-columns.sql` 已套，六欄＋兩個部分唯一索引＋歷史表三欄到位，既有 2 列 `legacy／issued`。**出貨基線 `scripts/init/02-schema.sql` 待重產**（CM-2856 的主線 migration），首腦排、不是 runner 動。STG／POC 未套。

**服務**：BE 8000 於 20:01 由首腦重啟（在 `0e95b7166` 之後，已含全部本案程式）；FE 5180 是決策者自己起的。

**DEV 資料缺口**（影響驗收）：沒有任何已送出的改善計畫。卡 1「Word 五欄改善計畫表」、卡 6「符合列灰底」、卡 3「第 4 章任務表」三條「有改善計畫」路徑都只有單測，**決策者全流程測試時造一份真送出的改善計畫一次驗**（首腦驗卡 3 時仍沒造，欠著）。另外 DEV 輪次 1199 的 observation／risk 都是空的，第 3 章「稽核發現／稽核建議」只驗到欄位接上。卡 3 的測試報告 `4081bb5d…`（id 111）目前 draft、版號 9、第 5 章空；v5～v9 歷史筆有定稿版 zip。**卡 5 runner 手插兩筆 final 測試列 id 112（專案 1321）／113（專案 1548）**給複測用，複測完 `UPDATE compliance.project_summary_reports SET is_delete=1 WHERE id IN (112,113)` 收掉。**DEV 全庫沒有帶 `content-hash` 的凍結紀錄**（凍結機制上線前結案），卡 4「依凍結雜湊取舊版」只有單測＋runner 暫插資料驗過，全流程測試要開一輪新結案、結案後換證據檔再下載驗。

**Notion**：母卡 CM-2854 尾段有子卡清單表＋八張復核紀錄；每張 Done 卡尾有「✅ 首腦復核」段。

## §2 已定裁示（不要重新討論）

全部 2026-10-17 決策者拍板，細節在 design.md D1～D16：
- 兩層報告、自動建立、無缺失不建階段報告、覆核又沒過照建（D3～D5）
- 狀態只有 draft／issued；清單分段鈕只剩「待撰寫／已完成」，**沒有報告的專案不列**，專案狀態要篩另開篩選（D6；決策者驗收卡 2 時再改一次）
- 清單一專案一列展開子列、總報告固定最後、欄頭可排序、**分頁一律 DataTable 內建**（`lazy`＋`totalRecords`＝專案數），不要再抽外掛分頁元件（卡 7 教訓）
- 存檔／定稿／下載三分開；「定稿」這個詞定了，不要再換
- Word 與 PDF 都給、顧問自行修改交付、系統只記下載日誌、定稿照舊提供
- 第 2 章定論取該輪最後一次稽核；總報告不擋各輪未定稿；矯正中可下載；報告 Word 套 FR-141／142 同一份 docx 範本；TipTap 沿用不換
- 不做：差距分析報告、總報告至今版、改善計畫 Word、舊資料遷移

## §3 下一步（第 3 棒：接修單、驗收、回報上層）

### 3.1 本案進度一句話
八張卡全 Done（功能、FE、Word 排版）、SPEC 與使用手冊已更新、DEV migration 已套、BE／FE 已 push。**開發結束，未進版。**

### 3.2 上層總測試會驗的（本案這四條 DEV 既有資料打不到，修單最可能從這裡來）

上層總測試會從 FR-140 開新專案走完整流程；下面四條是本案在 DEV 既有資料（1199／1548）上**沒驗過真實路徑、只有單測**的，修單來時優先懷疑這裡：

| # | 要造的情境 | 要看到什麼 | 對應卡 |
|---|---|---|---|
| A | 最終稽核有不符合 → **送出改善計畫** | 稽核作業「下載報告」Word 最後一節有五欄改善計畫表、Excel 是改善計畫工作表且符合列灰底；階段報告第 4 章列任務；總報告第 4 章任務欄有值 | 1、3、5、6 |
| B | 結案後**重新上傳同名證據檔**，再下載報告包 | 包內仍是結案時那版，對照表備註「原檔已被換掉，收錄結案時的版本」、雜湊相符 | 4 |
| C | 某評估目標的佐證是**本專案的問卷** | 報告包 `證據/…/問卷填答_<名>.pdf` 開得了、題目答案齊 | 4 |
| D | 第 1 輪有不符合 → 開**覆核輪全過 → 專案完成** | 清單出現「專案總報告」；第 2 章跨多次未改善列「最終通過」的稽核次；第 3 章全符合；一次全過的另一個專案只有總報告 | 2、5 |

其餘照手冊：清單展開／分段／排序／分頁、報告頁六章與附件一數字對稽核結果頁（記得是逐評估目標計）、存檔→定稿 v1→修訂→定稿 v2→版本紀錄還原 v1、draft PDF 浮水印與檔名、報告包 zip 解開對照表路徑逐一存在、auditor 看不到存檔／定稿、viewer 進不去、舊版「專案調查結果」只能看。**Word／PDF 要實際開檔看排版**（卡 8），不要只看有沒有下載成功。

DEV 已有的測試資料可先用：階段報告 uid `4081bb5d-1edd-4a0f-8015-8ff8b6331f2e`（輪次 1199，draft，版號 9），手插的總報告 id 112／113（uid `fr1455-test-final-0000000000000000001`／`…002`）。**測完要清**：`UPDATE compliance.project_summary_reports SET is_delete=1 WHERE id IN (112,113);`。

### 3.3 修單怎麼接

1. 先對 §3.4、SPEC §12、對應 Notion 卡尾「✅ 首腦復核」段的打折處——很多「怪」是設計如此或已知打折，回上層說明即可。
2. 真壞：自己 grep／開檔／查 DEV 找根因（首腦不開 subagent），寫進 Notion 新子卡（母卡 CM-2854 下，格式照 `docs/claude/notion-card-templates.md` 修正類），印薄 prompt 等決策者派。卡號接 CM-2874 之後，**建完再回填**。
3. runner 回寫後首腦實打驗收（重啟 BE、開檔、查 DB、Word 轉圖看），通過收 Done、回上層。
4. 改到 `app/closing_report/` 的 Word 產生器要同時顧 stage 與 final 兩支；改 FE `ClosingReportView.vue` 要保住版面修正（`04f58f2f`／`7a836ec4`，不自訂字級／紙面）。

### 3.4 發版前本案還欠的（上層總收尾做，本案首腦不動，知道即可）

| # | 事 | 怎麼做 | 誰 |
|---|---|---|---|
| ③ | e2e | test repo 另開一棒：舊「專案調查結果」頁四個檔（`site-regression/features/modules/reporting/project-summary-report.*`、`steps/`、`pages/`、`docs/test-cases/`）已失效，要照新清單＋報告頁重寫；稽核作業頁「下載報告」下拉也要補案 | 另開 session |
| ④ | 出貨基線重產 | 本案有 1 支主線 migration `scripts/sql/2026-10-17-fr145-closing-report-columns.sql`（已套 DEV、登記 `schema_migrations`），`scripts/init/02-schema.sql` 要重產；步驟見 `sql-migration` skill「出貨基線同步」段。**STG／POC 未套**，走 init image migrate 模式 | 決策者裁、首腦排 |
| ⑤ | 還原 pin | `pyproject.toml` 四支 path dependency 還原成 Nexus pin（任何一支套件有改動要先發版）；`poetry update <套件名>` 後重打本案端點一次（`feedback_verify_at_final_pin_not_path_dependency`） | 總收尾 |
| ⑥ | 新 env 鍵 | `CLOSING_REPORT_BUNDLE_MAX_BYTES`（選填，預設 1 GB）已進 `.env.sample` 與 `deployment-env.md`；部署時不填也行 | 無動作，知道即可 |
| ⑦ | 進版 | `version-bump` skill：release note 要寫結案報告整組（稽核作業下載報告、結案報告清單與報告頁、報告包、總報告）、FE 對齊版號、spec-site 切快照 | 總收尾 |
| ⑧ | 母卡 CM-2854 收 Done | 五段從 LOG 彙整；八張子卡已 Done | 總收尾 |
| ⑨ | push | BE／FE 已推（2026-10-17）；jedi 2 筆非本案 | — |

### 3.5 上層可能派來、但不是 bug 的（先看 SPEC 子頁 §12）
- 報告數字跟稽核結果頁上方六格不同：報告逐評估目標、那六格逐控制項。
- 封面沒有「受稽單位」：系統沒這欄位，用稽核計畫概要的「稽核單位」。要加屬 FR-141。
- 版本紀錄早期定稿版沒「下載報告包」鈕：卡 4 之前定稿的沒存包。
- 本機 PDF 兩份報告字型不同（楷體／明體）：三份 docx 範本（含 FR-142）東亞字型都沒指定繁中，LibreOffice 替代不穩；伺服器端裝 Noto CJK 一致。要徹底解在三份範本指定字型，屬 FR-142。
- 定稿要等幾秒：同步打包；證據很多會更久，背景產檔列後續。

> ⚠️ 這節是建議清單，不是執行授權。接手方讀完盤點完即停，等決策者發令。

## §4 待辦與風險

- **SPEC 落點**（2026-10-17 全部完成）：清單 hub `docs/spec-site/current/reporting/project-summary-report.md`＋子頁 `closing-report-page.md`（報告頁、報告包、總報告）；nav 兩層。§5 截圖欠（tracker 標）。**稽核作業頁 `audit-execution/my-audits.md` 與改善計畫頁 `audit-execution/poam.md` 不由本案改**——兩頁整頁還在描述 FR-142／143 改版前的舊畫面，已列在 FR-142／143 自己的收口待辦。已在兩條線的 STATE 留言：重寫時要帶上本案的「稽核報告欄（下載報告下拉）」與「Excel 列全部評估目標勾選」。
- **design.md 不回頭改**：定稿凍結，實作後的改判（選單 name 不改、待覆核算輪次結束、顧問取稽核人員、手動新增 409、分段鈕只剩兩態、清單只列有報告的專案、內建分頁）寫在 SPEC 頁與 LOG。

- **三份 docx 範本（stage／final／FR-142 ar）東亞字型都沒指定繁中**（走 theme 字型，本機 LibreOffice 替代不穩，一份楷體一份明體）：伺服器端裝 Noto CJK 無此問題；要徹底解得在三份範本統一指定 `Noto Sans CJK TC`，屬 FR-142 範圍另議。
- **封面沒有「受稽單位」**：系統沒這個欄位，卡 3 用稽核計畫概要的「稽核單位」（顧問公司）。要受稽單位得在稽核計畫概要加欄位，屬 FR-141 範圍，等決策者裁。
- 卡 3 的改判（統計單位＝評估目標、路由不新增改入口分流、已定稿不可從歷史頁還原要先修訂）寫在 CM-2857 卡尾與 LOG，design.md 不回頭改。
- `pass_report_export_service` 呼叫 `poam_workbook_export(all_objectives=True)`——卡 6 已落地，卡 3 讀模型第 4 章也要走同一個 POA&M 讀端點（CM-2842）。
- 清單「顧問」欄取最近一次 AP 的稽核人員（系統無顧問角色），卡 3 封面同一來源，別另造。
- **e2e 現況**：test repo 沒有 ar/export 的 e2e；舊「專案調查結果」頁四個檔會壞（§3.3 ③）。

## §5 Pre-flight（必跑，唯讀）

```bash
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be && git branch --show-current && git log --oneline -3 && git status --short | grep -v '^??'
cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe && git branch --show-current && git log --oneline -3 && git status --short
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
for c in CM-2854 CM-2857 CM-2858 CM-2859 CM-2873; do python scripts/notion_case.py query --case $c | head -1 | cut -f1,3; done   # 子卡應全 Done、母卡 Not started
lsof -ti:8000 >/dev/null && echo "BE up" || echo "BE down"
# DEV（密碼看 .env DB_PASSWORD；cm_app 受 RLS，查系統表用 cmmgr）
PGPASSWORD=$(grep '^DB_PASSWORD=' .env | cut -d= -f2-) psql -h localhost -p 5432 -U cm_app -d guidant_ai_dev -Atc "\d compliance.project_summary_reports" | grep -c "report_type\|audit_round_id\|issued_version"   # 應為 3
PGPASSWORD=$(grep '^DB_PASSWORD=' .env | cut -d= -f2-) psql -h localhost -p 5432 -U cmmgr -d guidant_ai_dev -Atc "select id, report_type, status, issued_version from compliance.project_summary_reports where report_type in ('stage','final') and is_delete=0;"   # 111 stage draft v9、112／113 final 測試列
git log --oneline origin/feature/FR-139..HEAD | grep -c FR-145   # 0，已 push
```

## §6 環境座標

- DEV DB：本機 `localhost:5432` `guidant_ai_dev`，帳號看 `.env`（`DB_USER`／`DB_PASSWORD`）；`cm_app` 受 RLS，查 `project_summary_reports` 全表要用 `cmmgr`
- BE：`python main.py` 8000，log `log/app.log`；重啟 `kill -9 $(lsof -ti:8000)` 再起
- FE：決策者自己起 5180；**不要起 5173**（本棒曾為 TipTap 截圖起過，已關）
- 登入打端點：`POST /api/1.0/login` body `{"username":"blsadmin","password":<test repo .env.e2e 的 TEST_PASSWORD>}`，取 `data.access_token`
- 文件站：`cd docs/features && python3 -m http.server 8124` → `/FR-145-2610-closing-report-bundle/`
- 雛形：同站 `/FR-145-2610-closing-report-bundle/prototype/index.html`
- Notion CLI：`scripts/notion_case.py get|status|append|query`、建卡 `scripts/notion_create_case.py <spec.json>`

## §7 行為規範提醒（本 arc 會踩的）

- 首腦自己做分析、雛形、design、開卡、驗收；**不開 subagent**（決策者 2026-10-16）
- **派 FE 卡固定帶一句**「版面與字級一律套全站規範（dark-card、全站字級），雛形只取結構不抄視覺樣式」；驗收 FE 頁面 `grep -n "max-width\|font-size\|font-family"` 頁面自己整組字級定義就退回（memory `feedback_fe_page_no_custom_typography_or_paper_layout`）
- 派工前 **fetch 卡看狀態與卡尾**，別把同一張 prompt 貼兩次；開卡前 **`git log` 同區域看有沒有平行棒剛動過**（卡 7 教訓）
- 卡號**建完再回填**，不預估（本棒 design.md 預估 CM-2853 起，實際 2854 起，改了三處）
- 驗收**實打端點**、查 DEV、開檔，不信 runner 自報；runner 列的打折處逐條確認
- 不切 branch、不 push、只動 DEV；STG／POC 等放行
- 決策者在驗收畫面提的 UI 修正，小的首腦直接修 commit（本棒三次），大的開卡

## §8 不在本期 scope

- 差距分析報告（規劃期交付物）
- 清單「專案狀態」篩選（決策者說要另開，還沒開）
- 全站清單頁抽共用篩選元件（memory `feedback_list_page_filter_baseline_my_tasks` 提到的盤點）
- 報告包背景產檔（超過大小門檻先回 413）

## §9 給 fresh session 的短 prompt

```
你是 FR-145「結案報告與一包下載」的首腦第 3 棒。上層有一個跨 FR-139～147 的總驗收首腦在跑全專案總測試，測出本案問題會派修單給你；你負責分析根因、開 Notion 卡、派 runner、驗收、回報上層，總收尾（進版等）不歸你。
先讀 docs/features/FR-145-2610-closing-report-bundle/handoff/FR-145-STATE.md 的 🧭 WHY 與 §0 讀序（含使用手冊 closing-report-guide.md、SPEC 子頁 closing-report-page.md），答完 §0.4 四題自檢，再跑 §5 pre-flight 唯讀盤點。
讀取與盤點完成後不做任何事——不派工、不跑測試、不改檔、不 commit——回報「①自檢答案 ②現況盤點（含與 STATE 不符處）③待接修單已就緒」後等我下指令。
```
