# FR-046 客戶交付文件套件 Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** 產出 6 份可交付外部顧問的正式 Word 文件（GAI-SD-01~06），採 Markdown 內容源 + 共用 python-docx renderer 管線。

**Architecture:** 三階段 — Phase 1 建管線（conventions + renderer + GAI-SD-06 pilot，user 驗收後才放量）；Phase 2 並行 fan-out（4 份文件各 1 agent + API 規格按模組拆 6 批）；Phase 3 收斂（程式化對帳 + 一致性 review + build 全部）。內容真相來源一律 code / DB 程式化產生（design §4）。

**Tech Stack:** python-docx（升級 `docs/claude/docx-generation-pattern.md` 既有 helper 工具組）、Graphviz、psycopg（information_schema dump）、importlib.metadata（license 收集）。

**Spec:** [design.md](design.md) — 所有內容規範以 design §5 + 本 plan Task 1 產出的 `conventions.md` 為準。

---

## 全域鐵則（每個 task、每個 subagent dispatch prompt 都要帶）

1. **敏感資訊**：內部 IP（`192.168.*`）、帳密、內部 Nexus URL、`.env` 內容一律不得寫入任何 md / docx / script 註解。環境值用佔位符（`<DB_HOST>`）。連 DB 的 script 從 `.env` 讀憑證，絕不 hardcode。
2. **語言**：繁體中文、技術名詞保留英文、動詞連接詞用中文（禁晶晶體）。產品名一律 **Guidant AI**，禁用「GRC 系統」。
3. **git**：顯式 `git add <檔名>`，**禁用 `-am` / `git add -A`**（working tree 有他人 WIP 與 staged cleanup）。不切 branch、不 push。
4. **真相來源**：DOC-02 掃 route/schema code、DOC-03 連 DEV DB、DOC-06 掃依賴 metadata；`docs/api/`、`docs/claude/database-schema.md` 只當敘述參考，**不當清單來源**。
5. **可解析標記**：GAI-SD-02 每個 endpoint、GAI-SD-03 每張表必須用 conventions.md 定義的固定 heading pattern（Task 1 §D），對帳 script 依 pattern 計數。

## 目錄結構（Task 1 建立）

```
docs/交付文件/v1.8.0/
├── conventions.md
├── src/
│   ├── doc-01-architecture/   # 每章一檔：NN-<slug>.md + meta.yaml
│   ├── doc-02-api-spec/
│   ├── doc-03-database/
│   ├── doc-04-security/
│   ├── doc-05-internal-packages/
│   ├── doc-06-licenses/
│   ├── glossary.md
│   └── assets/                # Graphviz .dot
└── GAI-SD-0N-<Name>-v1.8.0.docx   # build 產物（Phase 3 才 commit）
scripts/deliverables/
├── render_docx.py             # md → docx renderer
├── collect_licenses.py        # 依賴清單 → JSON + md 表格
├── collect_routes.py          # Flask route inventory → JSON
├── collect_db_schema.py       # information_schema dump → JSON
└── verify_deliverables.py     # 程式化對帳（design §7）
```

---

# Phase 1 — 管線與 pilot（序列執行）

### Task 1: 目錄骨架 + conventions.md + glossary.md

**Files:**
- Create: `docs/交付文件/v1.8.0/conventions.md`
- Create: `docs/交付文件/v1.8.0/src/glossary.md`
- Create: `docs/交付文件/v1.8.0/src/doc-0{1..6}-*/`（六個空資料夾，各放 `meta.yaml`）

- [ ] **Step 1: 建目錄骨架**（路徑含中文，shell 命令一律加引號：`mkdir -p "docs/交付文件/v1.8.0/src/doc-01-architecture"` …）
- [ ] **Step 2: 寫 conventions.md**，必含以下段落（agent 撰寫內容時的唯一格式依據）：
  - **§A 語言與用語**：全域鐵則 2 的完整版 + 避免用語表（GRC 系統→合規稽核平台、速贏→第一批 …）
  - **§B 敏感資訊**：全域鐵則 1 完整版 + 驗收 grep pattern 清單（`192\.168\.`、`password\s*=`、`Billows@`、`https?://[^\s]*nexus|nexus[^\s]*\.(jedicogy|internal)`（只抓 URL / host 形態，裸字 "Nexus" 是 DOC-05 合法內容）、`DB_SECRET`）
  - **§C md ↔ Word 對映**：`#`→章（Heading 1，自動編號 N.）、`##`→節（N.M）、`###`→小節（N.M.K）、GFM table→深藍表頭斑馬表格、fenced code→Consolas 灰底、`![caption](assets/xxx.dot)`→Graphviz 轉 PNG 嵌入、粗體/inline code 對映
  - **§D 可解析標記（對帳依據）**：
    - DOC-02 endpoint：`### [METHOD] /api/path` 一個 endpoint 一個 H3，內文固定小節順序：說明 / 權限 / Request / Response / Error codes
    - DOC-03 表：`### 表 <schema>.<table_name>` 一表一 H3，欄位表 GFM table 固定欄序：欄位 / 型別 / Nullable / 預設 / 說明
    - DOC-06 依賴：一列一依賴的 GFM table，欄序：套件 / 版本 / License / 用途
  - **§E meta.yaml schema**：`doc_id`（GAI-SD-0N）、`title`、`subtitle`、`version: v1.8.0`、`date`、`classification: 機密 Confidential`、`copyright: OOOO 版權所有`、`audience`、`chapters:`（檔名排序清單）、`toc_depth:`（預設 3；doc-02 設 2，否則 300+ 頁的 H3 endpoint 目錄會長達數十頁）
  - **§F 圖規範**：Graphviz 風格沿用 `docs/claude/docx-generation-pattern.md` §4.4（DDD 分層色系），.dot 進 `src/assets/`
- [ ] **Step 3: 寫 glossary.md 初版**：SSP / AP / AR / POA&M / OSCAL / Catalog / Profile / RLS / tenant / DDD / DI / envelope / JWT / mTLS 等（後續各 doc agent 只准引用與擴充，不准另建）
- [ ] **Step 4: Commit**
```bash
git add "docs/交付文件/v1.8.0/conventions.md" "docs/交付文件/v1.8.0/src/"
git commit -m "docs(FR-046): 交付文件管線 Phase1 — conventions + glossary + 目錄骨架"
```

### Task 2: 通用 renderer `scripts/deliverables/render_docx.py`

**Files:**
- Create: `scripts/deliverables/render_docx.py`
- Create: `test/test_deliverables_renderer.py`
- Reference: `docs/claude/docx-generation-pattern.md`（helper 工具組直接沿用：`T`/`H`/`P`/`code`/`render_dot`/`add_toc`/`set_shading`）

**介面：** `poetry run python scripts/deliverables/render_docx.py "docs/交付文件/v1.8.0/src/doc-06-licenses"` → 讀 `meta.yaml` + chapters md → 輸出 `docs/交付文件/v1.8.0/GAI-SD-06-<Name>-v1.8.0.docx`

**Renderer 職責（全部由 meta.yaml 驅動，內容 md 零排版指令）：**
1. 封面：title / subtitle / doc_id / version / date / audience / **密等（紅字置中）** / **「OOOO 版權所有」**（常數 `COPYRIGHT_HOLDER = "OOOO"`，公司名確定後改一處）/ 撰寫與審核欄（空白表格）
2. 版本紀錄表（`版本/日期/變更說明/作者`，初版一列 v1.8.0）
3. Word TOC field（層數由 meta.yaml `toc_depth` 驅動，預設 1–3 層）
4. 頁首：`{doc_id}｜機密 Confidential`；頁尾：頁碼（`w:fldChar PAGE`）
5. md 解析：conventions §C 的子集（heading / GFM table / fenced code / bullet / numbered / bold / inline code / `.dot` 圖引用），章自動編號、章末 page break
6. 不支援的 md 語法 → **報錯退出**（不靜默跳過，避免內容默默消失）
7. **文末自動 append `src/glossary.md` 為「附錄：術語表」章**（design §5.6 — 六份共用同一份；預設開啟，meta.yaml 可設 `appendix_glossary: false` 關閉）

- [ ] **Step 1: 寫失敗測試** `test/test_deliverables_renderer.py`：建 tmp doc 資料夾（meta.yaml + 一個含 H1/H2/table/code/bullet 的 md）→ 呼叫 renderer → 用 `docx.Document` 讀回，assert：封面含 doc_id 與「機密」與「OOOO 版權所有」、heading 數正確、表格存在、文末含「附錄：術語表」章、輸出檔名符合 `GAI-SD-*-v1.8.0.docx`
- [ ] **Step 2: 跑測試確認 FAIL**（`pytest test/test_deliverables_renderer.py -v` → module not found）
- [ ] **Step 3: 實作 renderer**（沿用 pattern doc helper；md 解析用手寫行狀態機即可，不引入新依賴）
- [ ] **Step 4: 跑測試 PASS**；補一個「不支援語法報錯」的測試 case
- [ ] **Step 5: Commit**（顯式 add `scripts/deliverables/render_docx.py` `test/test_deliverables_renderer.py`）

### Task 3: GAI-SD-06 pilot（走通全管線）

**Files:**
- Create: `scripts/deliverables/collect_licenses.py`
- Create: `docs/交付文件/v1.8.0/src/doc-06-licenses/{meta.yaml,01-overview.md,02-be-dependencies.md,03-fe-dependencies.md,04-internal-packages.md,05-license-summary.md}`

- [ ] **Step 1: 寫 collect_licenses.py**：
  - BE：在 venv 內用 `importlib.metadata.distributions()` 取名稱/版本/License（metadata 缺 License 時標 `UNKNOWN` 待人工補）；jedi-* 標記為「自有元件」
  - FE：讀 `~/Projects/Billows/Audit-Manager/compliance-manager-fe/package.json` dependencies + 各 `node_modules/<pkg>/package.json` 的 `license` 欄；**先確認 `node_modules/` 存在**，不存在就停下提示需 `npm install`，不准 silent 把整批標 UNKNOWN
  - 輸出：`scripts/deliverables/out/licenses.json` + 按 conventions §D 格式直接產 `02/03` 章的 GFM table md
- [ ] **Step 2: 執行並抽查**：跑 script、比對 `poetry show | wc -l` 與 json 筆數一致；抽 3 筆 license 對 PyPI 核實
- [ ] **Step 3: 手寫其餘章**：01 文件目的與範圍、04 jedi-* 自有元件清單（版本表，取自 pyproject pins）、05 license 類型彙總（MIT/BSD/Apache/LGPL… 統計 + 風險註記，copyleft 標紅）
- [ ] **Step 4: build docx** 並自查 checklist：封面/版本表/TOC/頁首頁尾/表格樣式/密等
- [ ] **Step 5: Commit**（md + script；docx 先不 commit）
- [ ] **Step 6: 🛑 USER GATE — pilot 驗收**：把 docx 給 user 開 Word 驗「專業感」。**未過不得進 Phase 2**；調整需求改 renderer 後重 build。

---

# Phase 2 — 內容 fan-out（Task 4/5 先行，6~9 與 10 可並行 dispatch）

### Task 4: route inventory `scripts/deliverables/collect_routes.py`

- [ ] **Step 1**: 用 app factory 建 app（不起 server）— **必須 `create_app(enable_socketio=False)`**（預設 True 會走 eventlet SocketIO init，script 情境沒 monkey-patch 會炸）；dump `app.url_map`：每筆含 method / rule / endpoint name / 所屬模組（由 blueprint / Resource module path 推得）。dump 完 **explicit shutdown APScheduler + `sys.exit(0)`**（`create_app` 尾端有 `init_scheduler()`，不收乾淨會留背景 job 打 DEV DB）。需要 env 時 `set -a; source .env; set +a` 後執行，**輸出 JSON 不得含任何 env 值**
- [ ] **Step 2**: 輸出 `scripts/deliverables/out/routes.json` + 按模組統計表（stdout）。人工抽查 3 個已知 endpoint 存在
- [ ] **Step 3**: 依統計把 33 個模組（`config/app_modules.py` REGISTERED_APPS 執行時實掃，加上任何 REGISTERED_APPS 之外的 blueprint）分成 **6 批、每批 endpoint 數量約略均等**，寫入 `scripts/deliverables/out/api_batches.json`
- [ ] **Step 4**: Commit script + 兩個 json

### Task 5: DB schema dump `scripts/deliverables/collect_db_schema.py`

- [ ] **Step 1**: 連 DEV DB（憑證讀 `.env` 的 `DB_SECRET` — **它是 JSON 字串**，`json.loads` 後取 `rds_master_username` / `rds_master_password`；host/port 讀 env；CLI 參數不接受密碼）dump：`compliance` / `oscal` / `public` 三 schema 的表、欄位（型別/nullable/default/COMMENT）、PK/FK、索引 → `scripts/deliverables/out/db_schema.json`
- [ ] **Step 2**: 對帳：json 表數 = `information_schema.tables` count；抽查 3 張表欄位與 psql `\d` 一致
- [ ] **Step 3**: Commit（json 檢查無憑證後才 add）

### Task 6~9: DOC-01 / 03 / 04 / 05 內容（4 個並行 subagent）

每個 subagent dispatch prompt 必含：**conventions.md 全文 + glossary.md + 全域鐵則 + 該文件章節骨架（design §2）+ 真相來源清單 + 顯式 git add 指示**。共同要求：每個技術描述寫入前對照當前 code 核實；圖一律 .dot 進 `src/assets/`；完成後跑 renderer build 自查一次能過。

| Task | 文件 | 真相來源（agent 必讀） | 章節骨架 |
|------|------|----------------------|---------|
| 6 | doc-01 系統架構 | `docs/claude/architecture-details.md`、`core/app_factory.py`、`di_containers/`、`config/`、FE repo `src/`（讀 FE CLAUDE.md 先）、`docs/claude/frontend-overview.md`、agent 拓撲（FR-039 design） | 系統總覽與拓撲圖 / 技術棧版本矩陣 / BE DDD 分層與 DI / BE 模組地圖（33 模組各一段職責）/ FE 架構 / 部署架構（premise、AWS）/ 外部整合（Drive、AI）|
| 7 | doc-03 資料庫 | `out/db_schema.json`（清單唯一來源）+ ORM model `comment=` + `docs/claude/sql-migration-conventions.md` | Schema 總覽 / ERD（按領域分張 .dot）/ 全表結構（§D pattern，一表一 H3）/ RLS 設計 / JSONB 欄位 / migration 機制 |
| 8 | doc-04 權限安全 | `docs/system-design/permission/` 說明書、jedi-auth 源碼、`session_scope` RLS 注入實作、mTLS（`build_cloud_mtls_context`） | RBAC 三層 / ui_routes 與 capabilities / RLS tenant 隔離機制 / JWT 生命週期 / secret 管理原則 / mTLS agent 通道 |
| 9 | doc-05 jedi-* 套件 | `~/Projects/Jedicogy/module/jedi-python-package/` 21 套件源碼 + `docs/claude/jedi-packages.md` + pyproject pins（19 個使用中） | 套件總覽與依賴圖 / 每套件一章：定位、模組結構、關鍵 class/service、公開介面、版本 / 發版機制（Nexus，URL 用佔位符）|

- [ ] Task 6 完成 + commit（每個 task 獨立 commit，訊息 `docs(FR-046): GAI-SD-0N <文件名> 內容`）
- [ ] Task 7 完成 + commit
- [ ] Task 8 完成 + commit
- [ ] Task 9 完成 + commit

### Task 10: DOC-02 API 規格（6 個並行 subagent，依 `api_batches.json`）

每 batch 一個 subagent：對 batch 內每個 endpoint，讀 route 檔 + marshmallow schema + error code 檔，按 conventions §D pattern 寫完整規格（說明 / 權限（角色與前置條件）/ Request schema 欄位表 / Response schema 欄位表 / Error codes 表）。`routes.json` 是 endpoint 清單唯一來源 — **不准漏、不准自創**。另有一個共同章（batch 0，隨第一個 agent）：API 設計規範總則（envelope / JWT / 分頁 / error code 體系 / i18n / 審計欄位慣例）。

- [ ] Batch 1~6 各自完成 + 各自 commit（`docs(FR-046): GAI-SD-02 API 規格 batch N — <模組列表>`）

---

# Phase 3 — 收斂

### Task 11: 對帳 script `scripts/deliverables/verify_deliverables.py`

- [ ] **Step 1**: 實作三項對帳（design §7）：doc-02 H3 endpoint 數 vs `routes.json`（列出缺漏清單，非只數字）、doc-03 H3 表數 vs `db_schema.json`、doc-06 表列數 vs `licenses.json`
- [ ] **Step 2**: 敏感資訊掃描：conventions §B 的 grep pattern 對 `src/` 全文，命中即 FAIL 並列出行號
- [ ] **Step 3**: 用語掃描：「GRC 系統」= 0
- [ ] **Step 4**: 跑到全綠（缺漏回派 agent 補），commit script
- [ ] **Step 5: 🛑 對帳結果貼給 user 看**（數字 + 掃描全綠證據）

### Task 12: 一致性 review（1 個 subagent）

- [ ] Dispatch consistency reviewer：跨六份查術語 vs glossary、交叉引用（互相提及的章節號正確）、數字一致（如模組數、套件數在不同文件說法一致）、抽 10 個技術描述回 code 核實、**抽查晶晶體與翻譯腔用語**（design §7 這條驗收的 owner 在此）。產出 issue 清單 → 修正 → 清零
- [ ] Commit 修正

### Task 13: build 全部 + 最終交付

- [ ] **Step 1**: 六份全部 build，檔名 `GAI-SD-0N-<Name>-v1.8.0.docx` 落 `docs/交付文件/v1.8.0/`
- [ ] **Step 2**: 逐份開檔抽查（封面/TOC/頁首頁尾/圖有進來/表格樣式一致）
- [ ] **Step 3**: 🛑 **USER GATE — 最終驗收**：user 人工審六份 docx
- [ ] **Step 4**: user 核可後 commit 六份 docx（顯式 add）
- [ ] **Step 5**: **停 — 收尾動作（changelog / SUMMARY / Notion）等 user 明確下令**（CLAUDE.md 收尾鐵則）

---

## 驗收總表（= design §7）

| 項目 | 驗證方式 | Task |
|------|---------|------|
| 六份樣式一致 | pilot 基準 + 逐份抽查 | 3 / 13 |
| endpoint 全量 | verify_deliverables.py 對 routes.json | 11 |
| 表全量 | verify_deliverables.py 對 db_schema.json | 11 |
| 依賴全量 | verify_deliverables.py 對 licenses.json | 11 |
| 無敏感資訊 / 無「GRC 系統」 | grep 掃描 = 0 | 11 |
| 術語一致 | consistency reviewer | 12 |
| 技術描述正確 | reviewer 抽 10 項回 code 核實 | 12 |
