FR-093 · 需求索引 · 本頁由 build 掃資料夾生成

FR-093 出貨升級鏈補齊(套件自帶的表、權限、選單,客戶升級時自動到位)

✅ 全案 Done,隨 v1.20.0 出版(2026-09-15)。母卡 CM-1752。十棒全完+端到端驗收(CM-1778:乾淨 docker 新裝與模擬舊機升級兩路比對,結構/權限/RLS/migration/能力點/種子檔全數零差異)。該輪抓到並修掉一處真缺陷——內建流程範本的適用範圍兩路不一致,新裝客戶看不到內建流程且畫面不報錯。

狀態:✅ 已完成 文件 6 份 handoff 1 份

FR-093 一頁看完

§1

🔴 先看哪一份

你想知道 看這份 這份的性質
為什麼要做、三個階段怎麼分、D1–D8 決定了什麼 設計 design.md 設計決策,已定案凍結
拍板之前怎麼吵的、哪些方案被排除 討論稿 discussion.md 討論歷史
哪一棒做了什麼、卡在哪、怎麼解的 交接日誌 handoff/fr093-LOG.md 歷史紀錄,append-only
盤點證據(fail-open 路由基線、24 支套件 SQL 冪等核對) inventory/ 一次性證據

這個案子還沒收口,所以沒有定版交付(FINAL-SPEC)。收口時補一份,寫「補齊後這條鏈長什麼樣」。

§2

結論

  1. 問題:套件會自己宣告「我需要哪些表」(自帶 SQL)與「我需要哪些權限」(能力點清單),但出貨線完全不讀這兩份宣告。結果是新版裝上去,功能在、表沒建、管理員點進去 403 而且沒有任何錯誤訊息說是缺資料。
  2. 活生生的例子:有人把資產的「系統狀態」選項從大寫改成小寫(CM-1678),只寫在套件裡,三個環境一個都沒套到。這個案子拿它當第一個驗收案。
  3. 做法分三段:① 出貨時把套件的 SQL 攤平進安裝包、升級時自動套;② 升級時自動把新權限寫進資料庫並補給管理員角色;③ 新頁面一定要綁權限(守衛擋),不綁就是靜默越權(沒綁權限的頁面預設全員可見)。
  4. 定下一條長期規則:往後套件疆界的表只在套件改,主專案的 scripts/sql/ 不再新增套件表的 migration。代價是既有的資料庫要一次性補登記。
  5. 刻意不做的:不擴充套件契約(不加 UI_ROUTES 宣告)——選單的位置、排序、圖示是前端版面知識,塞進套件等於把選單樹的一半搬進去。改用 SQL 現成寫法+守衛測試擋。
§3

📊 總進度

十棒完成八棒。母卡 CM-1752。

階段 棒 做什麼(白話) 卡號 狀態
.1 出貨線接套件 SQL .1a 寫腳本,build 時把套件裡的 SQL 撈出來攤平進安裝包 CM-1753 ✅ Done
.1b 升級程式加第二輪:套完主線再套套件的 CM-1754 ✅ Done
.1c 既有資料庫一次性補登記 23 支(留 1 支給下一棒當驗收案) CM-1755 ✅ Done
.1d 拿 CM-1678 當第一個驗收案,真的套一次看會不會好 CM-1756 ✅ Done(留缺口,見下)
.2 權限自動到位 .2a 出貨的權限資料改成用名稱查、不寫死編號 CM-1757 ✅ Done
.2b build 時把 21 支套件的權限宣告攤成一支 SQL CM-1758 ✅ Done
.2c 升級時自動寫入新權限,並補給管理員角色 CM-1759 ✅ Done
.3 選單守衛 .3a 守衛測試:有頁面就一定要綁權限,不綁測試紅字 CM-1760 ✅ Done
.3b 24 支套件 SQL 逐支核對能不能重複跑 CM-1761 ✅ Done(全數通過,未改一支)
.3c 套件補選單資料+發 jedi 1.1.0 CM-1762 ✅ Done

🔴 已知缺口(.1d 留下的)

症狀:全新安裝出來的資料庫,資產的「系統狀態」選項還是大寫(OPERATIONAL);既有資料庫升級上去才會變小寫。兩條路徑終態不一致。

為什麼:新裝走的是出貨基線檔 02-schema.sql,那份是從 188 那台的基線庫 dump 出來的,而基線庫本身還沒套過這支修正。安裝包卻已經把它標記成「已收斂進基線」,所以新裝時不會再套一次——那個標記目前是假的。

怎麼解:對 188 基線庫套一次 asset 002,再重新 dump 產生 02-schema.sql。這屬於動出貨基線,決策者 2026-09-14 裁示先不做,列為出貨前待辦,時間另定。在那之前這是已知缺口。

不採的兩個做法:把 002 從收斂清單排除讓新裝再套一次(純安裝路徑沒有升級步驟,仍會留大寫);手改 02-schema.sql(違反 D3,那份是 dump 產物不是手寫檔)。

§4

需求討論紀錄

  • 2026-09-13 D1–D8 拍板(全文見 design.md §3):靜態併入(build 期攤平,不讓安裝程式現場掃描)/檔名用 packages/<套件>/序號 當命名空間/套件疆界的表只在套件改/權限資料改名稱反查不寫死編號/升級時 upsert 權限/管理員角色用「參照角色法」回補而非認 is_admin 旗標/不擴套件契約/前兩階段不動套件源碼不綁發版。
  • 2026-09-14 決策者裁定(Q1):DEV 用 psql 手套 asset 002 並補登記;升級程式的基線守門不放寬。理由:實查發現 STG 與 POC 都是安裝程式建的庫、守門對它們是通的,舊制庫只有 DEV 與 188 基線庫兩顆,客戶端沒有這個問題。runner 原本判斷「升級鏈對舊制庫整個失靈」被首腦複驗修正。
  • 2026-09-14 決策者裁定(Q2):188 基線庫不動,一律只在本機操作。基線庫套 002 + 重產 02-schema.sql 列為出貨前待辦。
  • .1d 的教訓(已入 LOG):拆卡時假設「.1c 補登 23 支、獨留 002 給 .1d 驗收」,卡在更前面一關——DEV 根本不是升級程式認得的目標庫。開卡前對「這條路走不走得通」的假設要親手跑一次 dry-run,不能只看清單差集算出來的數字。
  • .3b 的結果值得記一筆:24 支套件 SQL 對 DEV 逐支核對,全數通過、一支都沒改。原本預期會撈到一批(design 甚至點名 detection 缺 7 個外鍵),實際沒有。
§5

這個案子從哪來、往哪去

從哪來:FR-089(套件結構統一)做的時候查出「出貨 image 只讀主專案的建表腳本,套件自帶的客戶端永遠套不到」,獨立成本案。上游還有 FR-080(25 支合併成 21 支)與 FR-091(21 支套用標準形狀)。

往哪去:.3c 要動套件源碼並發 jedi 1.1.0,發版等令。全案收口的驗收是「一台乾淨機器裝新版 + 一顆舊資料庫升級上去」兩條路徑都對。

同期的姊妹案:FR-094 租戶隔離修正(13 張表沒開「每個客戶只看自己資料」的鎖)——跟本案同樣是 FR-089 連帶盤出來的,但兩案獨立,沒有相依。

§6

文件

以下全部由 build 掃資料夾產生,新增檔案重 build 即自動出現。標題連結指向渲染後的 HTML,md 連向源檔。

需求與討論

文件 類型 標題 最後更新
discussion / md 需求討論稿 讓「套件裡的東西」真的跟著版本出貨到客戶那裡 2026-09-13

設計

文件 類型 標題 最後更新
design / md 設計 套件宣告的表、權限、選單,在客戶升級時自動到位 2026-09-13

inventory/(4 份)

證據與盤點

文件 類型 標題 最後更新
e2e-install-upgrade-acceptance / md 操作手冊 出貨升級鏈端到端驗收:乾淨新裝 vs 舊機升級(CM-1778,2026-09-14) 2026-09-14
fail-open-routes-baseline / md 盤點證據 DEV fail-open 路由基線白名單(CM-1760,2026-09-13 盤點) 2026-09-14
package-sql-idempotency / md 文件 套件隨包 migration:冪等與基線一致性對照表 2026-09-14
package-ui-routes / md 文件 套件 ↔︎ 頁面 ↔︎ group ↔︎ 能力點 對照表(CM-1762,2026-09-14 盤點) 2026-09-14

交接與收口時間軸(handoff/,1 份)

由新到舊。每份是某一棒次交接當下的完整現況快照,看某個時間點「當時知道什麼」請從這裡進。

日期 文件 標題
2026-09-14 fr093-LOG / md FR-093 套件 migration 與能力點種子 — LOG(append-only)
§7

Notion 卡

卡片內容(決策紀錄、驗收條件)以 Notion 為準,本頁只記座標。

關係 卡號 標題 狀態
母案 CM-1752 FR-093 出貨升級鏈補齊(母卡,十棒) —
子卡 CM-1753 .1a 套件 migration 攤平腳本+子清單 Done
子卡 CM-1754 .1b migrate.sh 第二輪+Dockerfile 斷言+stamp gate Done
子卡 CM-1755 .1c 既有庫補登 23 支套件 migration 檔名 Done
子卡 CM-1756 .1d CM-1678 驗收案:DEV 真套 asset 002+新裝路徑確認 Done(留 Q2 缺口)
子卡 CM-1757 .2a 出貨 seed 權限四表改 name-based 反查 Done
子卡 CM-1758 .2b 能力點宣告攤平+角色回補 SQL 模板 Done
子卡 CM-1759 .2c migrate 第三輪+角色回補+DEV 六項驗收 Done
子卡 CM-1760 .3a 選單路由必綁權限守衛+fail-open 盤點 Done
子卡 CM-1761 .3b 24 支套件 SQL 冪等核對 Done(全數通過未改一支)
子卡 CM-1762 .3c 套件補 ui_routes/route_capabilities+發 1.1.0 待派