# FR-047 SSP 子頁 field-level 化 + 規劃頁深化 — 換 session 交接（2026-07-06）

## 🧭 原始需求（WHY，先懂再動）

user 要的是**給新人開發 / 追蹤用的「詳細規格書」**，不是概覽。核心原則（user 原話）：
> 「你都用 CRUD 帶過，但是要 CRUD 到哪裡、用哪些 API、畫面欄位是怎樣，都沒寫工程師怎麼開發？怎麼追蹤？這是一份詳細規格書，希望得到詳細的參考資訊，而不是敷衍帶過。」

所以每個功能要到 **field-level**：每個畫面欄位（label / 型別 / 必填 / 列舉值 / disabled 條件 / 存哪個 DB 欄或 props 鍵）、每支 API（method + path + 逐欄 request/response 表）、每個 error code、DB jsonb 內部結構。**「CRUD 帶過」「指向 GAI-SD-02」= 不合格**。

合格範本已寫好 → 讀 `docs/specs/v1.8.0/project-management/project-ssp-inventory.md`（資產頁，§5 逐欄表單 / §6 完整 request-response 欄位表 / §9 jsonb 結構 / §12 逐坑）。

## §0 冷接自檢 gate（動手前先答）

1. 為什麼 SSP 編輯器要拆 5 個子頁？→ 答：元件·授權·資產是同一 UI tab 但 3 個不同實體 / API，要詳細就各自一頁；單位+人員是同一 `/parties` API 只差 type 過濾，合一頁避免重複 drift。
2. schema 事實來源是哪個檔？→ 答：`scripts/deliverables/out/db_schema.json`（**不是** `docs/system-design/.../tbls/*.md`，那份會 drift，本 session 已踩到：元件 tbls 版寫 `ssp_id`/`component_type`/`leveraged_authorization_uid` 欄，db_schema.json 才是 `system_implementation_id`/`uuid`/`type`，且 leveraged_authorization_uid 在 props 不是欄位）。
3. 可以 commit / push 嗎？→ 答：**branch = main，本 session 全部未 commit，等 user 明示才 commit，push 永遠等 user**。build 出的 `html/` 依規則先不 commit。
4. 走哪個 skill？→ `writing-feature-specs`（13 節模板 + 事實來源紀律 + build 驗證）。

---

## Session 已完成（都在 working tree，未 commit，branch main）

本 session 是「FR-047 手冊可讀性/詳細化」大 arc，做了六大塊（詳見對應頁）：

1. **§6 API 格式一致化（30 頁）**：全站 §6 endpoint 清單改表格、request/response 改欄位表（不再擠散文）。
2. **UC 全展開（18 核心頁）**：每個有實質後端邏輯的功能補完整 UC + 流程圖，~22 個新 UC + 圖；忠實紀律（endpoint/error code 抄該頁、沒寫用中性字）。
3. **UC 缺口補圖（4 張）**：UC-PL-03（Drive 同步）、UC-CI-02（中斷連線）、UC-RA-02（對帳）、UC-PO-03（開始執行任務）。
4. **project-settings 退役 + 內容遷移**：`project-settings.md` 刪除（route 已孤兒，內容併入規劃頁）；基本資訊/參與人員 → 規劃頁 **UC-PP-09**（含 ⚠️ **PUT /grc/project 無角色守門**安全 finding 搬進 §12 坑 11）；`cloud-integrations.md` 5 處「專案設定頁」措辭修正。
5. **3 個新子頁**：`evidence/document-pool.md`（程序書池，Tab4）、`evidence/project-cloud-integration.md`（專案雲端 verify-repair，Tab5）、`project-management/project-ssp-edit.md`（SSP 編輯器 hub，Tab1）。
6. **NAV 調序**：`project-ap-list`（稽核輪次清單）移到 `project-overview` 前（照下鑽動線）；規劃頁 §5 加「六個 Tab 對照表」（每 Tab 指向真頁，0 死指標）。
7. **SSP 編輯器 5 子頁（進行中）**：pilot `project-ssp-inventory.md` 已寫完驗證；**其餘 4 頁待寫**（見待辦 A）。

驗證狀態：全部 build ✅（58 頁）、自查敏感資訊/「GRC 系統」= 0、新圖 error code 逐一比對防杜撰、斷圖 0。

---

## 待辦（下個 session 執行，按序）

### A. 完成 SSP 編輯器其餘 4 子頁（facts 已蒐集驗證，直接寫）

範本 = `project-ssp-inventory.md`（已寫好的第 5 頁）。放 `docs/specs/v1.8.0/project-management/`：

| 待寫頁 | 實體 / API | FE 元件 |
|--------|-----------|---------|
| project-ssp-basic.md | 系統特性 `/system-characteristic` | SspBasicSection.vue |
| project-ssp-parties.md | 參與方 `/parties`（單位+人員合一） | ModuleFramePartiesPanel.vue |
| project-ssp-components.md | 元件 `/components` | SspComponentsLeveragedInventoryTab.vue |
| project-ssp-leveraged.md | 利用授權 `/leveraged` | 同上 |

**已驗證 facts（本 session 5 隻 Explore agent 掃出 + 對 db_schema.json/routes.json/BE code 核過，直接用不必重跑）：**

**共用（4 頁都適用）**：
- 權限：`require_participant`（讀）/ `require_manager`（寫 = manager + AP=planning）。碼：`GRC_403051`（GRC_NOT_PROJECT_MANAGER）、`GRC_412028`（GRC_SSP_EDIT_AP_NOT_ACTIVE，AP 關閉/封存）。
- gate：`canEdit = apStatus==='planning' && role==='manager'`；launch-audit 後 living SSP 凍結唯讀。
- endpoint 全在 `/ssp/{ssp_uid}/...`（已驗 routes.json 存在）；表全在 `oscal` schema（已驗 db_schema.json）。
- pattern：FE `apiBase` 切 ssp vs module-frame；共用 `ModuleFrame*Service` mapper；props jsonb = `[{name,value}]` 非破壞性合併；無 socket；composable cache（`useSsp*`）。

**① project-ssp-basic（系統特性，1:1 upsert）**
- endpoint GET/PUT `/ssp/{uid}/system-characteristic`。
- FE 表單 8 欄（SspBasicSection.vue）：`name`(範圍名稱,InputText,必填→system_name) / `system_identifier`(範圍識別碼→system_ids[0].id jsonb) / `security_sensitivity_level`(安全分類等級,Dropdown low·moderate·high,預設 high) / `target_type`(範圍類型→props[target-type]) / `status`(運行狀態,Dropdown active·under-development·disposition·other——**FE 只 4 種，DB status_state 有 5 種缺 under-major-modification**) / `owner_uid`(範圍負責人,Dropdown searchable userMenu→props[owner-uid]) / `scope_description`(授權邊界描述,Textarea→authorization_boundary_description) / `description`(描述,Textarea)。
- serializer：`SspSystemCharacteristicUpdateSchema`（全欄 allow_none，route strip None）/ `SspSystemCharacteristicResponseSchema`。
- DB `oscal.ssp_system_characteristics`（ssp_id UNIQUE 1:1）：system_name/system_name_short/description/security_sensitivity_level/date_authorized/system_ids(jsonb)/status_state(varchar40)/status_remarks/authorization_boundary_description/authorization_boundary_props(jsonb)/props(jsonb: target-type + owner-uid)。
- props 非破壞性合併；FE 空值 → placeholder（fips 預設 high、status 預設 active）。
- 檔：route `api/oscal/routes/ssp/ssp_system_characteristic_route.py`、serializer `api/oscal/serializers/ssp/ssp_system_characteristic_inproject.py`、service `app/oscal/service/ssp_system_characteristic_app_service.py`、mapper `app/module_frame/service/module_frame_system_characteristic_service.py`。

**② project-ssp-parties（參與方，單位+人員合一頁）**
- endpoint GET/POST `/ssp/{uid}/parties`、PUT/DELETE `.../parties/{party_uuid}`；`party-type` prop = organization / person 過濾。
- DataTable：名稱/職稱、角色(Tag)、email、phone、address、鉤稽狀態、action。
- Dialog 欄位：`matched_user_id`/`matched_org_unit_id`(鉤稽,Dropdown person→userMenu·org→orgUnitMenu,選填) / `role`(Dropdown **9 OSCAL role**,必填,預設 person=system-owner·org=responsible-organization) / `name`(必填,**編輯時 disabled 自然鍵**) / `email_address`/`telephone_number`/`address`(選填)。
- **9 role（seed SQL `scripts/sql/2026-05-22-seed-oscal-ssp-roles.sql`）**：responsible-organization / system-owner / system-security-officer / authorizing-official / information-owner / information-provider / information-receiver / prepared-by / prepared-for。Menu：GET `/system/menu/ssp_party_role`。
- serializer `SspPartyUpsertSchema`（party_type OneOf person·organization / name / role / title / email_address / telephone_number / address / matched_user_id / matched_org_unit_id）；Response 多 enrich：matched_user_uid / matched_user_name / matched_org_unit_name。
- 映射：party_type→parties.type、name→parties.name、email_address→email_addresses[0](text[])、role·title·telephone·address·matched_*→props；**party 透過 metadata_id 掛 SSP，無 mapping 表**。
- DB `oscal.parties`：metadata_id / uuid / type / name / short_name / email_addresses(text[]) / telephone_numbers(jsonb) / addresses(jsonb) / props(jsonb: role+title+telephone+address+matched_*)。
- 碼：`GRC_400014`(INVALID_PARTY_TYPE) / `GRC_400015`(PARTY_NAME_REQUIRED) / `GRC_400016`(PARTY_ROLE_REQUIRED) / `GRC_404024`(PARTY_NOT_FOUND) / GRC_403051 / GRC_412028。
- 坑：party_uuid 被 `ap_task_participants` + `ssp_leveraged_authorizations` 軟參照（無 FK），**刪 party 無保護**（follow-up）。
- 檔：`api/oscal/routes/ssp/ssp_party_route.py`、`api/oscal/serializers/ssp/ssp_party.py`、`app/module_frame/service/module_frame_party_service.py`。

**③ project-ssp-components（元件）**
- endpoint GET/POST `/ssp/{uid}/components`、PUT/DELETE `.../{item_uid}`。
- DataTable：類型(Tag)/名稱/描述/狀態/利用授權(Chip)/協定/安全機制。
- Dialog：`title`(名稱,必填) / `component_type`(類型,Dropdown **15 項**,預設 system/BE 預設 software) / `description`(Textarea) / `purpose`(Textarea) / `status`(Dropdown 5:operational·under-development·under-major-modification·disposition·other) / `leveraged_authorization_uid`(Dropdown 來源 GET /leveraged) / `protocol`·`port_ranges`·`security_auth`(InputText→props)。
- **15 component_type**：this-system·system·service·interconnection·hardware·software·network·policy·physical·process-procedure·plan·guidance·standard·validation·other。
- **⚠️ DB 以 db_schema.json 為準**（tbls .md 有 drift，勿用）：`oscal.ssp_components` = system_implementation_id / uuid / type / title / description / purpose / status_state / status_remarks / responsible_roles(jsonb) / protocols(jsonb) / props(jsonb: protocol+port_ranges+security_auth+leveraged-authorization-uid) / links。**無** leveraged_authorization_uid 欄（在 props）、**無** tenant_id/is_active。
- 碼：`GRC_404034`(SSP_RESOURCE_NOT_FOUND) / GRC_403051。坑：component uuid 被 inventory implemented_components 軟參照。
- 檔：`api/oscal/routes/ssp/ssp_components_route.py`、`app/oscal/service/ssp_components_app_service.py`、mapper `app/module_frame/service/module_frame_components_service.py`。

**④ project-ssp-leveraged（利用授權）**
- endpoint GET/POST `/ssp/{uid}/leveraged`、PUT/DELETE `.../{item_uid}`；FE service 帶 `'ssp'` apiBase。
- DataTable：名稱/提供者/**FedRAMP Package ID(⚠️未實現)**/**影響等級(⚠️未實現)**/**資料類型(⚠️未實現)**/授權日期/關聯元件數。
- Dialog：`title`(授權名稱,必填) / `provider`(提供者) / `date_authorized`(Calendar,FE null→BE date.today()) / `description`(Textarea) / `purpose`(Textarea) / `category`(Dropdown 4:leveraged-authorization·external-service·interconnection·other,預設 leveraged-authorization) / `status`(Dropdown 5 同元件)。**⚠️ Dialog 無 party_uuid 欄**（硬置 null，註「日後 party picker UX」）。
- props 存 provider/description/purpose/status/category（DTO 攤平到頂層）。
- DB `oscal.ssp_leveraged_authorizations`：system_implementation_id / uuid / title / party_uuid(**NN，null 時存 NIL-UUID 哨兵 00000000-...**，軟參照 parties.uuid) / date_authorized / props / links / remarks。
- 碼：GRC_404034 / GRC_403051。
- **已知缺口（寫進 §12）**：fedramp_package_id / impact_level / data_types 清單顯示但 CRUD response 無回傳（只在 Excel/docx 路徑處理）；party_uuid picker 未實作；remarks 無 Dialog 欄。
- 檔：`api/oscal/routes/ssp/ssp_leveraged_route.py`、`app/oscal/service/ssp_leveraged_app_service.py`、mapper `app/module_frame/service/module_frame_leveraged_service.py`。

**寫完 4 頁後的收口**：
- 把 `project-ssp-edit.md` 從「完整頁」改成 **hub**：§1.1 各子區「詳述」欄改指這 5 個子頁；§6/§9 的詳細內容可精簡成「見各子頁」（保留概覽 + Excel 匯入那條跨子區的留 hub）。
- NAV_STRUCTURE（`scripts/deliverables/render_html.py`）：把 5 子頁**巢狀在 `project-ssp-edit.md` 下**（現在 project-ssp-edit 已巢狀在 project-planning 下，改成兩層：planning →[ssp-edit →[basic,parties,components,leveraged,inventory]]，或平掛 project-management 群，擇一）。
- build 驗證：57→62 頁全 ✅；每頁新圖 error code 逐一 grep 該頁 md 確認非杜撰；自查敏感/GRC系統=0。

### B. 規劃頁 §2 深化（user 拍板：**全部第②類 = 功能 1/4/13/15/16 補到 field-level**）

規劃頁 17 項裡「有真表單、卻只到 UC 流程圖級」的 5 項，要補逐欄 field-level。方法同 A（先 Explore 掃 FE 表單欄位 + BE serializer + db_schema，再親自寫）：

| 功能 | 現況 | 要補 | 主 FE 元件 / endpoint |
|------|------|------|----------------------|
| **4 任務檢視與編輯** ← 最大、最像「CRUD 帶過」 | UC-PP-02 流程 | 拆獨立子頁（建議 `project-task-edit.md`）：任務表單逐欄（名稱/描述/指南/類型 general·survey/指派人員/部門/設備/問卷+審核人）+ full-replace 語意 + 關聯四表 | ProjectPlanningView AO 面板 / 任務卡；PUT `/grc/project/{uid}/job/{jobId}` |
| 1 控制項/AO 現況編輯 | UC-PP-01 流程 | 補 field 表：implementation_status（5 種列舉）+ implementation_description + AO 備註 | PUT `/ssp/{uid}/control-implementation/{cid}`、`.../objective/{stmtId}` |
| 13 群組/控制項參與人員 | UC-PP-08 流程 | 補 field 表 + endpoint 逐欄 | POST/PUT/DELETE `/control-group-participant`、`/project-control-participant` |
| 15 專案基本資訊 | UC-PP-09 | 補 field 表（PUT /grc/project 欄位，可參 project-list.md §6.3 已有的 PUT 表） | PUT `/grc/project/{uid}` |
| 16 專案參與人員 | UC-PP-09 | 補 participants 全量覆寫 field 表（role 4 值 / owner 保護） | 同上 participants 欄 |

**第③類不動**（現有深度剛好）：3 樹導覽搜尋、7/8/9/10 Excel 匯出入（wizard 三步流程圖夠）、11 進度卡、12 階段推進、5/6 快速配置/啟動。

### C. commit（等 user 明示才做）

本 session 未 commit 量**極大**（35 md source + 39 新 dot + render_html.py），**強烈建議分主題 commit** 避免混在一起難 review：
1. §6 API 格式一致化（30 頁）
2. UC 全展開（18 頁）+ UC 缺口補圖（4 圖）
3. project-settings 退役 + UC-PP-09 遷移 + cloud-integrations 修正 + NAV 調序 + §5 tab 表
4. SSP 5 子頁 + document-pool + project-cloud + project-ssp-edit hub
5. 規劃頁深化（待辦 B 做完後）

commit 鐵則：**顯式 `git add <檔名>`、禁 `-am`/`add -A`**；避開別線 WIP（`docs/specs/v1.8.0/evidence/assets/img/` 截圖 session、FR-046 tracker、`docs/交付文件/*.docx`、`docs/features/ddd-layer-audit/`）。`html/` 依規則暫不 commit（等 source 收斂再連 source 一起）。push 永遠等 user 明示。

---

## 方法論 / 鐵則（本 session 驗證有效，沿用）

1. **事實蒐集用 Explore 唯讀 agent、主 session 自寫 md**（tracker 教訓 #6 已證；本 session 5 隻欄位級 Explore 產出優）。派 agent 的 prompt 要求：FE 表單每欄 label/型別/列舉/必填/disabled + BE serializer 逐欄 + db_schema jsonb 結構 + error code，標檔:行號，查無就說查無不編。
2. **schema 一律對 `db_schema.json`**（不信 agent 憑元件名猜、不信 tbls .md）；endpoint 對 `routes.json`；error code 開 `common/code/grc_error_code.py` 逐一 grep 確認真有（本 session 11 個碼全驗過）。
3. **防杜撰驗證**：新圖裡的 error code 逐一 grep 該頁 md 是否真有出處（本 session 靠這抓到縮寫式誤判 + 確認零杜撰）。
4. **每頁寫完必 build**：`python3 scripts/deliverables/render_html.py "docs/specs/v1.8.0"`（全 ✅）；.dot 先 `dot -Tsvg <檔> -o /dev/null` 驗編譯；自查 `grep -rEn '192\.168\.|password\s*=|Billows@' <檔>` = 0、`grep 'GRC 系統'` = 0。
5. **13 節模板 + 圖形化慣例**：見 `writing-feature-specs` skill 的 `references/page-spec-template.md`；配色海軍藍 #13294B / 判斷菱形 #FFF6E5 / 例外 #FDEBD3 / 錯誤 #F8DCDC / 成功 #D9E9DC。
6. **branch main 不切、未 commit 全留 working tree、push 等 user**。

---

## 座標

- 主 tracker：`docs/features/FR-047-2607-feature-spec-handbook/tracker.md`
- 合格範本（field-level 深度）：`docs/specs/v1.8.0/project-management/project-ssp-inventory.md`
- SSP 編輯器 hub：`docs/specs/v1.8.0/project-management/project-ssp-edit.md`
- 規劃頁（含 §5 六 Tab 表 + UC-PP-01~09）：`docs/specs/v1.8.0/project-management/project-planning.md`
- SOP：`writing-feature-specs` skill（13 節）、`closing-and-handoff` skill（本文件）
- 事實 dump：`scripts/deliverables/out/{db_schema,routes}.json`
- NAV_STRUCTURE：`scripts/deliverables/render_html.py`（約 line 268 專案管理群 / 297 證據管理群）
