# FR-089 arc 收尾 SUMMARY — 套件體系收整、出貨升級鏈、租戶隔離（隨 v1.20.0 出版）

> 收尾日期 2026-09-15。涵蓋五個需求（FR-089／090／091／093／094）＋ 出版後修正（FR-096），
> 歷時 2026-09-12～09-15、十三任首腦接力。**素材來自 `FR-089-LOG.md` 十五個時間 block，非憑記憶重建。**

## 這個 arc 解決了什麼

FR-069／FR-080 把功能抽成 21 支套件之後，留下三個問題：

1. **每支套件長得不一樣**——接手的人要翻四五處，且每支翻的地方不同。
2. **套件的表與權限進不了客戶手上**——安裝包不讀套件的宣告，新版裝上去功能在、表沒建，管理員點進去 403 且畫面不報錯。
3. **租戶隔離實際上是關的**——決策者親測，切到子租戶仍看得到別家的待辦 39 筆、專案 213 筆。

## 五個需求的成果

| 需求 | 母卡 | 成果 |
|---|---|---|
| **FR-089** 套件結構統一 | CM-1688 | 以 jedi-asset 定形；`plugin/` 五檔＋`api/` 四件；主專案接一支套件收斂成三步 |
| **FR-090** 主專案側收斂 | CM-1682 | 接線收成 `core/plugins/<pkg>.py` 一支一檔；DI 瘦身改從套件取用口拿 service |
| **FR-091** 21 支套用 | CM-1690 | 28 卡全落地；整理過程查出五個既有真缺陷 |
| **FR-093** 出貨升級鏈 | CM-1752 | 套件 SQL／能力點／選單升級時自動到位；兩路端到端驗收零差異 |
| **FR-094** 租戶隔離 | CM-1766 | 30+ 張表開啟隔離；排程改用具名系統身分；「分享給子租戶」開關 |

## 出版

**主專案 v1.20.0**（2026-09-15），21 支套件統一 1.1.0（八支後續進 1.1.2、兩支 1.1.1，jedi-oscal-v2 走自身序列 2.4.0）。

- release note `docs/release_notes/v1.20.0.md`
- spec 凍結快照 `docs/spec-site/v1.20.0/`
- 三個 repo 都已 merge main 並推送；BE／FE 打上 `v1.20.0` tag 並推送
- **190 e2e 測試機**：beta.1／beta.2 先後部署，決策者逐項手測通過

## 這個 arc 查出的真缺陷（不是重構造成的）

整理與驗收的附加價值——逐檔看過、兩路比對才發現的：

| 缺陷 | 症狀 | 狀態 |
|---|---|---|
| 內建流程範本適用範圍兩路不一致 | **新裝客戶看不到內建流程**，被存取規則靜默濾掉、畫面不報錯 | ✅ 已修 |
| 13 張表沒有租戶隔離 | 看得到別租戶的資料 | ✅ 已修 |
| 問卷資料夾三端點全 500 | 套件事件碼表只抄了 1 個、漏 3 個；**刪除那支是資料已軟刪之後才炸** | ✅ 已修 |
| flow-engine 某個碼從沒定義過 | 不是抄漏，是根本沒有 | ✅ 已修 |
| 權限勾選存檔 409 | 同功能四個動作被切在兩層，前端分組勾選時自己補齊整組 | ✅ 已修（FR-096） |
| 出貨腳本寫死舊套件名 | 套件改名後路徑失效，build 中止 | ✅ 已修 |
| jedi-iam `get_tenant_by_uid` 回 500 | 應回 404 | ✅ 已修 |
| `project_audit_rounds` 17 筆孤兒 | 父專案已刪的殘留列 | ✅ 已刪 |
| file-upload 兩支方法有死分支 | 永遠執行不到 | ⬜ 記母卡待裁 |
| system-core `get_system_menu_by_id` | 從來不能用 | ⬜ 記母卡待裁 |
| survey 資料夾暱稱顯示 null | — | ⬜ 記母卡待裁 |
| `GET /feedback` 回 500 | 既有問題，非本 arc 引入 | ⬜ 待辦 |

## 最有價值的部分：被推翻的判斷

**首腦的判斷被實查推翻了十幾次。** 這些比成功的部分更值得記住：

- 「守衛要整支刪掉重寫」→ 實查後改判保留原地瘦身。
- 「iam 某物件零引用可整支刪」→ 實查主專案有 34 處引用。
- 「補暱稱有七處要改」→ 實際是三套並存的寫法，且漏列第四份複本。
- 「落地版客戶用不到跨租戶隔離」→ 決策者指出集團／子公司的實際需求。
- 「191 筆無主流程範本是公版」→ 查證後是測試孤兒資料。
- 「升級鏈對所有既有資料庫都失靈」→ 只有本地舊制資料庫有問題。
- 「FE image 兩種版號標籤並存沒問題」→ 封包腳本按 BE 版號找，找不到就停。
- 「授權簽發鑰壞掉」→ 查證後是**根本還沒建立**。
- 權限 409 連續三個假設（後端沒過濾／預設資料錯／重構造成）**全錯**，真因是四個動作被切兩層。
- 「某套件既有 320 支測試全綠」→ 實況 48 失敗 42 報錯，**沒先跑基準測試就寫數字**。
- 首腦盤點的數字多次被推翻——此後開卡數字一律標「估計」。

## 教訓（濃縮）

**關於驗證**
- **驗證要走真實路徑**：虛擬環境裝的可能是舊版套件包，不指定路徑會驗到假的通過——這個陷阱影響了第一批全部驗收。
- **驗收要看該卡 commit 的工作樹**，不能只看主線目前的顏色。
- **「跟基線一樣」「測試都過」要附真實比對輸出**，不能只憑口頭保證。
- **突變測試前要先確認自己真的改到了檔案**——曾因替換寫法有誤，變異沒生效卻誤判測試沒用。
- **驗收要批次**：整批跑完再一起修，不要一項一項來回。

**關於缺陷的形狀**
- **順序相依就是缺陷**：靠 A 不寫值、指望 B 回填，順序一變就破。正確做法是插入當下就寫對。
- **靜默過濾最難抓**：資料被規則擋掉但畫面不報錯，只有兩條路比對才看得到。
- **「只抄一半」要用語法樹掃描**：靠列舉清單的守衛天生看不到沒列出來的東西。
- **殘留檔案會遮住本來就在的缺口**——凡是「這次清了環境就壞了」的，多半是本來就壞、只是看不見。

**關於協作**
- **並行改同一個 monorepo**：`git commit` 要明確指定路徑，否則會吞掉別人未提交的改動（實際發生四次）。
- **改名／合併套件要搜出貨腳本裡的字串路徑**，不只搜程式碼裡的 import（那些有測試守著）。
- **跨租戶錯誤碼要一致**：「找不到」跟「沒權限」回不同訊息，等於送別人一個枚舉工具。
- **腳本刻意設計的限制不要繞過**（如拒絕在非互動環境執行），請人在正確環境操作。

## 已知 follow-up（不擋出版，已寫入 release note 第 6 節）

- `GET /feedback` 回 500（既有問題）。
- 四支 audit-round 端點前端零呼叫，待裁決後退役。
- 資安掃描總表 12 項待裁（修正另開 arc，不進 1.20.0）。
- jedi-flow-engine 未宣告 jedi-common 相依（實查屬實，靠主專案間接帶入）。
- **前端簡體中文錯誤訊息翻譯僅 92 條**（繁中英文各 638 條），簡體使用者碰到多數錯誤會看到原始碼字串。
- 錯誤碼正名後 `docs/api/uploadfile/api-spec.md` 與 spec-site 三頁待同步。
- FR-094 B 案排在 1.20.0 之後的五張子卡。
- 主專案自有 36 筆能力點待申報（FR-090 範圍外，另開卡）。
- 「migrate 自動補能力點」是獨立大 arc，另開 FR。

## 交付包注意

🔴 **目前出貨包缺正式環境授權簽發公鑰**（尚未建立，非故障——套件內只有 dev／stg／poc 三把）。要出**可交付客戶**的包需另行四步：授權中心產正式簽發鑰 → 加進公鑰表 → 發版 → 重新 build。在此之前產出的包僅供內部環境使用。

## 部署 handover

1. **STG（188）** `install.sh --upgrade` → 觀察六服務健康、登入、切租戶、我的任務。
2. 確認無誤後 **POC（189）** 同步驟。**POC 等同 production**，務必先在 STG 驗過。
3. 升級腳本會自動備份資料庫並印出還原指令。

## 過程中處理的環境問題

- **188 build 機磁碟滿**（剩 1.8G，封包失敗）：清掉 52GB build cache ＋ 舊的解開目錄，回收至 58G。**10 個歷史交付包全數保留**（決策者裁只留 tar.gz）。建議往後固定清理或設上限。
- **jedi monorepo 262 顆 commit 未推**：遠端停在 2026-09-02，十三天的工作全積本地。功能上無影響（套件走 Nexus 供貨），但原始碼在遠端看不到。收尾時已推。
