# Session 4 交接 Prompt — C3 PR1 + C4 + C5 完工，接續 C6 / C3 PR2 觀察 / follow-ups

> 2026-05-23 Session 3 完成後建立。貼以下 ``` 框內容開啟 Session 4。

---

```
你正在接手 SSP 在專案內直接編輯 — Phase C Session 4。

## Session 3 完成狀況（已 ship）

### BE — C3 PR1 + C4 合併同 PR ship（受評範圍遷移到 SSP）

| Commit | 主題 |
|--------|------|
| `d2c3df2` | C3 PR1 + C4 主體 — service derive + 410 endpoint + DI cleanup + schema 拿欄位 + Step A/C 拿掉 + DTO + 2 個 error code |
| `ae6d7f1` | C3 PR1 backfill SQL |
| `02a2311` | C3 + C4 unit tests (15 cases 全綠) |
| `1253a92` | C3 PR1 + C4 changelog × 2 + analysis + tracker README |
| `74f4888` | tracker 補 commit hash |
| `f6d4f9d` | fix backfill SQL DISTINCT ON multi-characteristic |

**DB 已執行**：backfill 跑完 8 hardware items + 159 system items（A0 預先補
164 hardware device_id，C3 只補新增的 8 個）。沒任何 AP 的 118 個 project
按 C3-D3 決策 skip（多為 E2E 殘留）。

### FE — C5 SSP tab 完整 ship

| Commit | 主題 |
|--------|------|
| `57caca2` | C5 plumbing + 5 sections + SspTabPanel（16 files / 2185 insertions）|
| `dd28658` | C5 整合 SspTabPanel 進 TabView（方案 A — ProjectPlanningView 原內容包進「控制項實作」tab，新加「SSP」tab） |

**FE 新檔清單**：
- `src/composables/`：useSspContext.js / useSspParties.js / useSspResources.js / useSspSystemCharacteristic.js / useSspLeveraged.js
- `src/components/grc/ssp/`：SspTabPanel.vue / SspBasicSection.vue / SspScopeDevicesSection.vue / SspScopeInfoSystemsSection.vue / SspPartiesSection.vue / SspLeveragedSection.vue
- `src/service/SspService.js` 擴充 19 個 method
- `src/config/api/api.js` 加 13 個 endpoint constants
- i18n: tab_controls / tab_ssp / ssp_* / section.* keys (zh-tw + en)
- changelog: `docs/changelog/2026-05-23-feat-ssp-tab-panel-and-sections.md`

### Phase C 整體狀態（看 BE `docs/features/FR-011.3-2605-ssp-edit-in-project/README.md` tracker）

| Phase | 主題 | 狀態 |
|-------|------|------|
| C1 | OSCAL SSP 角色 master | ✅ shipped (`381d3ec`) |
| C2 | SSP-scoped endpoints (19) | ✅ shipped (C2.1 + C2.2) |
| **C3 PR1** | **受評範圍 derived from SSP + 410** | **✅ shipped (本期，合 C4)** |
| **C4** | **專案 CRUD 拿掉 audit_systems/devices** | **✅ shipped (本期，合 C3 PR1)** |
| **C5** | **FE SSP tab** | **✅ shipped (本期，方案 A TabView)** |
| C3 PR2 | DROP TABLE + 拆 stack | **觀察期中**（1-2 週後做）|
| C6 | 移除專案設定 UI 受評範圍 | spec-ready，FE polish |
| C7 | 06_外部利用服務 sheet | ✅ shipped |
| C8 | role label 清理 | ✅ shipped |

## Session 4 第一件事：驗收 + Push

user 早上要做的（**還沒做**）：

1. **BE restart**（無 hot reload）：
   ```
   # 在 BE repo 跑 (主目錄已是 .)
   # 找既有 process 殺掉再起；或：
   python main_socketio.py
   ```

2. **BE smoke**：
   - `GET /grc/project/<uid>` — 看 devices / audit_systems 來自 current SSP items (not from mapping 表)
   - `POST /project-device` — 應該回 410 + `error_code=GRC_410001`

3. **FE smoke**：
   ```
   cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe
   npm run dev   # port 5180
   ```
   - 進專案規劃頁 → 看到 2 個 tab：「控制項實作」(default) + 「SSP」
   - 切 SSP tab → AP selector + 5 個 accordion（基本資料預展開）
   - 編 / 刪 5 個 section CRUD
   - 切 AP 看 readonly hint
   - `?tab=ssp&section=parties` deep link 直接展開

4. **Push origin（兩 repo）**：
   ```
   # BE: 領先 origin 7 commits (a20959b ~ f6d4f9d)
   git push

   # FE: 領先 origin 2 commits (57caca2 + dd28658)
   cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe
   git push
   ```

## Session 4 候選方向

驗收完成後，user 決定下一個 phase。候選：

### 方向 A：C6 移除專案設定 UI 受評範圍（FE polish）

- 範圍：FE only，拿掉專案表單的 audit_systems / devices field
- C4 BE schema 已拿掉，FE 還有 form input — 不對齊
- 預估：半天
- 文件：`docs/features/FR-011.3-2605-ssp-edit-in-project/design-C6.md` + `implementation-plan-C6.md`

### 方向 B：C5 完成度補強

兩個延後項目：

1. **C1 system_menus 整合**
   - 目前 `SspPartiesSection.vue` 用 hardcode 9 個 OSCAL role
   - 應改吃 `GET /system/menu/ssp_party_role` (C1 已 ship)
   - 對應 i18n key `lang.oscal_role.ssp_party_role.<key>.label`

2. **design-C5 §3.1 沒做的 tab**
   - design 提到的「AP 列表 / 參與人員」其他 tab
   - 本期方案 A 只新加 SSP tab，避免動 ProjectPlanningView 太多
   - 評估是否要做（或者放棄這部分 design）

### 方向 C：清理 C2 延後 follow-up

兩個從 Session 2 / 3 跨過來的 follow-up：

1. **multi-round SSP `get_one` bug 修補**
   - 位置：`app/oscal/service/ssp_excel_import_app_service.py:_resolve_existing_ssp_shell()`
   - 問題：`get_one(SystemSecurityPlanQueryEntity(profile_id=...))` 在 SSP versioning 多輪場景撞 multiple match
   - 影響：MF-scoped excel update flow 在多輪 SSP 場景失準
   - SSP-scoped 路徑（C2.2 T8）已避開此 bug

2. **`PUT /ssp/<uid>/excel-import/<parse_uid>/decisions` partial-save endpoint**
   - design-C2.md §4.5 提的第 5 個 excel-import endpoint
   - 目前走「decisions 隨 confirm body 一次性傳入」已能滿足 day-1
   - 需要：app service 新 `save_decisions` method + parse_job 狀態擴充

### 方向 D：C3 PR2 — DROP TABLE + 拆 stack（觀察期未到，不可做）

**前提**：PR1 ship 後 1-2 週觀察期，監控 mapping 表無新 INSERT。本期才 ship，
**至少要等到 2026-06-06 後**才可以開始 PR2。

監控 SQL（PR1 後每天跑一次）：
```sql
SELECT 'pdm' AS tbl, COUNT(*) FROM compliance.project_device_mapping
WHERE created_at > '2026-05-23'
UNION ALL
SELECT 'pis', COUNT(*) FROM compliance.project_information_systems
WHERE created_at > '2026-05-23';
-- 預期：0 / 0
```

若非 0 表示有遺漏 caller，要先補修才能進 PR2。

### 方向 E：BDD e2e scenarios

切到 `~/Projects/Billows/Audit-Manager/compliance-manager-test/` repo 加：
- 專案啟動 → SSP tab 編輯 5 個 section 的 BDD scenario
- 410 endpoint regression
- C5 deep link 行為驗證

## 環境 / 規範速查

### Branch
**BE + FE 都同名**：`feature/ssp-import-export-phase3`（CLAUDE.md「禁止自行切換 branch」— user 自己切，Claude 不動）

### Working tree 狀態
- **BE 領先 origin 7 commits**（含 user 1 個 docs commit `a20959b`）
- **FE 領先 origin 2 commits**
- BE 剩 `pyproject.toml`（dev-only path dep）+ 2 個 zip（user 早前確認不動）
- FE working tree 乾淨

### DB 連線
```
PGPASSWORD='jedi@123!' psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev
```

### Dev 帳號
- manual：`blsadmin / Billows@123!`
- pytest：`blsit / Billows@123!`

### BE log
`log/app.log`（BE 專案根目錄）— 任何 BE 行為異常都先 tail / grep 這個

### 必讀文件
1. BE CLAUDE.md（會自動載入；含「禁止自行切換 branch」「階段性 commit 不用問」等規範）
2. `docs/features/FR-011.3-2605-ssp-edit-in-project/README.md`（tracker — 必看 C3 PR2 / C6 行）
3. `docs/changelog/2026-05-23-tweak-c3-scope-migrate-to-ssp-pr1.md`（C3 PR1 改動細節）
4. `docs/analysis/2026-05-23-c3-scope-migration-decisions.md`（為何偏離 design 的 7 個決策）
5. 走 C6 → FE CLAUDE.md + `docs/features/FR-011.3-2605-ssp-edit-in-project/design-C6.md` + `implementation-plan-C6.md`

## C3 PR1 + C4 + C5 留下可重用的基礎設施

接下來的 phase（C6 / C3 PR2 / 其他）可直接用：

### BE
- `domain/oscal/service/ssp_project_resolver.py`
  - `resolve(ssp_uid)` → `SspProjectContext(ssp, ap, project)` (raise NotFound)
  - `resolve_current_ssp(project_id)` → `SspProjectContext | None` (本期新加)
- `common/code/grc_error_code.py` 新加：
  - `GRC_PROJECT_DEVICE_DEPRECATED = GRC_410001`
  - `GRC_PROJECT_INFO_SYSTEM_DEPRECATED = GRC_410002`

### FE
- `src/composables/useSspContext.js` — projectUid → reactive SSP context
- `src/composables/useSsp{Parties,Resources,SystemCharacteristic,Leveraged}.js` — module-scope cache
- `src/components/grc/ssp/` — 6 個 .vue 元件
- `src/service/SspService.js` 擴充 19 個 method (對齊 C2 的 19 個 endpoint)

## 開工建議流程

1. **先問 user 走哪個方向**（A / B / C / E；D 觀察期未到不可選）
2. 跑 pre-flight（Session 4 開始時）：
   ```bash
   git log --oneline | head -10
   git status --short
   # 確認 BE 7 + FE 2 commits 已 push origin（user 早上會做）
   ```
3. 依方向開新任務清單（TaskCreate）

## 重要規範回顧（Session 3 期間落實）

CLAUDE.md memory `feedback_stage_commit_no_ask.md`：
> 階段性 commit 不用問 — 子 task / milestone / changelog / issue 完成後 commit 直接做，
> 不停下問 user；只有重大決策（架構衝突、需選 A/B/C 方案、breaking change）才停

Session 3 期間實踐：14 個 BE task → 5 commits；12 個 FE task → 2 commits，
中間只在 4 個重大決策點停下問（方向選擇 / 118 個 no-AP project / Step A 拿掉範圍 /
TabView 整合方案）。

## Session 3 期間關鍵決策（已寫進 `docs/analysis/2026-05-23-c3-scope-migration-decisions.md`）

1. `resolve_current_ssp` 用 **latest AP 不限 status**，對齊既有 `ProjectCurrentSspService._latest_ap`
2. **擴充 SspProjectResolver** 而非新建 `ssp_current_resolver.py`（重用 DI 注入）
3. **Step A 整段拿掉**（含 SystemCharacteristic auto-snapshot + PSCM）— design 沒提 PSCM 但邏輯上一起
4. **JobExecutionDevice 系列不動**（屬另一範疇）
5. C3 PR1 + C4 **合併同 PR**（plan 寫「搭配 C4」明示）
6. **118 個 no-AP project skip**（按 C3-D3 決策）
7. **schema class 保留**（OscalProjectStartRequest 內欄位拿掉但 AuditSystemInputSchema 等 class 留）

## Session 3 期間意外事件

**backfill SQL 第一次跑 bug**：
- INSERT 8 hardware + **210 system items**（>pis 165）
- 原因：SSP 251 有 4 個 characteristic，LEFT JOIN 撞 row 展開
- Rollback 218 row + 修 SQL 加 DISTINCT ON 重跑
- 第二次：8 hardware + 159 system items（正確）
- 已 commit `f6d4f9d` fix 進 SQL 檔，未來重跑就是修正版

教訓：SQL backfill 有 LEFT JOIN 時必須先確認多對一 / 一對多關係，加 DISTINCT。
```

---

## 補充：Session 3 期間調整的小事項

寫進 handoff 但 Session 4 可選擇性回顧：

1. **`isProjectManager` 模式重用**：FE TabView 整合時加 `myParticipantRole` computed，仿既有 `isProjectManager` pattern 從 `projectParticipants` + `userInfo.value.uid` 對應
2. **C5 偏離 design 部分**：design-C5 §3.1 提到「AP 列表 / 概覽 / 參與人員 / SSP」4 個 tab，本期方案 A 只在 ProjectPlanningView 加「控制項實作 + SSP」2 個 tab，避免 monolithic refactor 太大
3. **SSP `system_characteristic` 為 1:N**（同一個 SSP 可能有多個 characteristic，dev DB 中 SSP 251 有 4 個）— FE `useSspSystemCharacteristic` 假設 BE GET 回單筆（依 BE service.get(ssp_uid) 行為）；若未來 BE 改回 array 要重新評估
4. **CLAUDE.md memory 新增**：對話紀錄主動從 JSONL extract 規範（不憑記憶重建，用 `scripts/extract_claude_sessions.py`）— user 在 session 中間更新
5. **ProjectPlanningView 2125 → ~2145 行**：方案 A TabView 整合只加 ~20 行，原既有功能完全不動（左側 tree / 右側 control/AO 編輯 / 6 個 dialog / batch menu / FlowPhaseBanner / breadcrumb 等）
