CR #891
open[CR-078] POC-12 系統功能查證發現:12-3 無視覺化部署介面/一鍵進退版/12-7 無客製化工具SDK/12-2·12-6 有實作但待實測或待前端
0%
Description
【發現情境】POC-12 系統功能 查證(2026-10-24;涉及 platform gateway/common,FR SYS-2.x/SYS-4/SYS-5)。
本 POC 多屬平台/維運類,無法以單一 API 驗證,故以「程式設計+檔案事實」查證;未實測者如實標「未驗證」。
【已查證到具體實作】
- 12-2 即時生效:
api-gateway用@ConfigurationProperties(刻意不用@RefreshScope),
POST /actuator/refresh原位重綁定、無需重啟;SplitRatioAdminService流程「讀現值→定點寫檔→refresh→回讀驗證」;
GatewayRouteService明載「不快取,熱更新後下次查詢即反映新值」。⚠️ 本次未實打 refresh 端點,故標「部分(機制明確/未實測)」。 - 12-6 多國語言:
common-spring/src/main/resources/i18n/實際存在messages.properties與messages_en.properties(中/英),
由tools/gen_error_i18n.py自 SDD-006 §3.4 產生(註明勿手改),並有LocaleConfiguration/LocaleResolver。
⚠️ 完整 Layout 多語屬前端,待確認。
【部分/缺口】
- 12-3 部署自動化:有
ops/(dev/local/redmine)、docker-compose、tools/產生器腳本等基礎;
⚠️ 未見「視覺化介面部署」「部分進版/部分退版」「一鍵進版/一鍵退版」具體實作。 - 12-7 客製化:有可替換實作之埠設計(如
ObjectStoragePort,註明「換 SDK/改測試替身亦然」);
⚠️ 未見對外「客製化工具或 SDK」與已完成之客製化案例,『易操作與 Debug』無從演示。
【未驗證(需演練/壓測,非缺陷)】
- 12-1 7×24 不中斷:需實際過版(滾動升級/藍綠)演練佐證。
- 12-4 業務連續性:需於腳本執行期間壓測佐證(觀察錯誤率/延遲)。
- 12-5 封閉驗證:未見影子測試/流量回放比對機制;僅見部分
dryRun參數(如計息重算),不足以構成封閉驗證。
【交付】docs/09-demo/poc-12-system/(overview+12-1~12-7);截圖 docs/08-evidence/DEMO_POC-12_step-*;poc-flows/POC-12 已標「已驗證(部分)」。
RA Updated by Redmine Admin 1 day ago
【追蹤中(#A-393)】缺口:①12-3 部署自動化——有 ops/+compose+tools 基礎,但未見「視覺化介面部署」「部分進版/退版」「一鍵進版/退版」;②12-7 客製化——有可換 SDK 之 Port 設計,但未見對外「客製化工具或 SDK」與客製化案例。未驗證(需演練/壓測):12-1 7×24 過版不中斷、12-4 腳本執行期間業務連續性、12-5 封閉驗證(無影子測試/回放比對,僅見 dryRun)。已查證到實作:12-2(POST /actuator/refresh 原位重綁定、無需重啟、SplitRatioAdminService 含回讀驗證;本次未實打 refresh)與 12-6(i18n 中/英訊息檔由 tools/gen_error_i18n.py 自 SDD-006 §3.4 產生;完整 Layout 多語待前端)。證據 DEMO_POC-12_step-*;動畫 docs/09-demo/poc-12-system/。本 CR 暫不結案。
RA Updated by Redmine Admin about 19 hours ago
【GAP-003 登錄(2026-10-25,#A-396)】本 CR 之缺口已逐項整理進 docs/00-governance/GAP-003_功能補齊清單_CR-073-075-078.md:2 組開發缺口(12-3 部署作業台 L——環境須裁定、與 CR-082 K8s 基礎合流;12-7 客製化案例 M——形式須裁定)+驗證/演練待辦(12-2 完整演示 S、12-6 前端 i18n SM、12-1/12-4 演練 M 併 G-04、12-5 形式裁定後 ML)。
RA Updated by Redmine Admin about 14 hours ago
h2. GAP-003⑬ 完成:CR-078 中不需裁定之 2 項(2026-10-25,#A-396)
先分類六項:12-3/12-7/12-5 需裁定(部署環境/SDK 形式/封閉驗證形式)、12-1/12-4 需效能環境(GAP-001 G-04),只有 12-2 與 12-6 可自主。
h3. 12-2 即時生效(免重啟)—— 真機驗證
| 步驟 | 結果 |
| 現況 | @percentage=0@、@configFileWritable=true@ |
| @PUT /api/v1/gateway/split-ratio {"percentage":30}@ | 200、@effectiveMatchesRequest=true@、@warning=null@ |
| 回讀 | @percentage=30@ |
| @cycle-split.yml@ 實際內容 | @percentage: 30@(檔案確已改寫) |
| @POST /actuator/refresh@ | 200(yml 編輯路徑亦通) |
| 未重啟之證明 | @process.start.time@ = 07:59:17;操作 13:37 → 行程已運行 5h38m |
h3. 12-6 多國語言 Layout —— 查證:原本已具備
- 語系檔:@zh-TW@ 1351 keys/@en-US@ 1351 keys,雙向零缺漏、零多餘
- 頁面覆蓋:@pages/*.tsx@ 共 32 檔,全部使用 @useTranslation@
- 切換器:@App.tsx@ 已 import 並掛載 @@
- 硬編中文(去註解、去 @t()@ fallback 後):修正前 1 字元 → 修正後 0
→ GAP-003 原載「前端 Layout 多語待確認」為 未查證之幽靈;實際只差 1 處硬編。
h3. 本次修正
@ParkingConsole.tsx@ 之 @
h3. 驗證
- @npx tsc --noEmit@ → 0 error
- @npx vitest run@ → 121 測全綠
- 兩語系 key 數仍對稱(1351+1)
h3. 如實揭露
12-2 只驗閘道分流比例一項;其他 @ConfigurationProperties@ 是否全部可 refresh 後原位重綁,未逐一驗證。¶
12-6 以語系檔對稱+頁面覆蓋+硬編掃描佐證,未做真實瀏覽器中英切換截圖。¶
12-3/12-7/12-5 仍待 PMO 裁定;12-1/12-4 需效能環境(GAP-001 G-04)——這三類不是補程式能解決的。¶
h3. 證據
@docs/08-evidence/CR-078_12-2_12-6_即時生效與多語_20261025/@(README+2 份原始輸出)
RA Updated by Redmine Admin about 13 hours ago
h2. GAP-003⑭:12-3 部署作業台「後端與編排」完成(2026-10-25,#A-396)
裁定:PMO 採 K8s(Helm chart + 本機 kind)(D-056);另 G-04 採 基線+方法、不作容量承諾(D-057)。
h3. 交付
- 規格:@SDD-007 §5.4.33@(按鈕/端點/狀態徽章/檢核)
- 編排:@ops/deploy/helm/cardcore@(傘式 chart,20 服務)+@ops/deploy/kind@(叢集組態+佔位映像 Dockerfile)
- 部署 API:@ops/deploy/api/deploy_api.py@(Python 標準庫、零依賴;@GET /deployments@、單一進版/退版、部分退版、一鍵進版/退版)
h3. 真機實測(kind v0.30.0,20 個 Deployment 全 READY)
| # | 情境 | 結果 |
| 1 | 基準 | revision 1、20 × v1 |
| 2 | 部分進版(api-gateway+limit-service → v2) | v2 僅 2 個、其餘 18 個 v1 |
| 3 | 部分退版(只退 api-gateway) | api-gateway → v1、limit-service 保持 v2;pod 內容實測 @api-gateway → v1@/@limit-service → v2@ |
| 4 | 一鍵進版(全部 → v2) | UPGRADED 19 + SKIPPED 1 → 20/20 v2 |
| 5 | 一鍵退版 | ROLLED_BACK 2 + SKIPPED 18 → 20 × v1、全 READY,不再震盪 |
「pod 內容實測」=@kubectl exec … cat /www/index.html@,證明真的換了映像,不是只改 label。
h3. ★ 實作挖出的四個真問題(皆已修)
Sprig @merge@ 是「dst 優先」 → 預設值蓋掉實際值:版本永遠 v1、埠永遠 8080;@helm upgrade@ 回 success 但 pod 內容仍是 v1。改 @mergeOverwrite@。¶
helm 無 values 時回字面 @null@ → @json.loads@ 得 None → @.get@ 爆 @AttributeError@,@GET /deployments@ 直接 500。加 @or {}@。¶
@--reuse-values@ 只存「被覆寫的值」 → 未覆寫的服務在舊 revision 沒有 tag 欄位 → 「前一版」永遠算成 None(退版一律 409)。回退到該 revision 的 @defaultTag@。¶
「退到任一不同版本」會來回震盪 → 連兩次一鍵退版,v1/v2 分佈來回跳。改為「只往低版本退」,無更低版即 SKIPPED。¶
另:@previous_tag@ 逐 revision 呼叫 helm,20 服務 × 25 revision 變成數百次子程序(一鍵退版 45 秒 → 18 分鐘未完成)→ 加 per-revision 快取。
h3. ⚠️ 如實揭露(未完成)
前端頁 @/ops/deployments@ 尚未實作——規格(@SDD-007 §5.4.33@)已寫,畫面待做。→ 12-3 目前為「後端與編排完成」,尚未達「視覺化介面」之完整驗收(GAP-003 標 ◐)。¶
映像為佔位(@cardcore-standin:vN@),非 20 個服務的真實映像——本專案無 CI。佔位映像會回應自身版本,足以證明進退版真的換映像。¶
部署 API 直接呼叫 helm/kubectl,CORS 開放 @@ 且無認證*——僅供本機演示;正式須接 CI/CD+RBAC。¶
kind 為單節點,與正式多節點行為不同。¶
h3. 證據
@docs/08-evidence/CR-078_12-3_部署作業台_20261025/@(README+18 份原始輸出)
RA Updated by Redmine Admin about 13 hours ago
h2. 12-3 前端頁完成 → 12-3 收斂 ✅(2026-10-25,#A-396)
h3. 新增
- @frontend/src/pages/DeploymentConsole.tsx@:版本清單、四態徽章(
READY/PROGRESSING/DEGRADED/UNKNOWN)、單一進/退版、勾選部分退版、一鍵進版/退版、結果彙總(已進版/已退版/略過/失敗)、Revision顯示 - @frontend/src/api/deployments.ts@:部署 API 用戶端(
/deploy-api經 Vite 代理至 18090) - @App.tsx@ 路由與側欄:@/ops/deployments@(服務標示 @ops/deploy/api:18090@)
- 中英 i18n:@nav.ops.deployments@ + @deployments.*@(31 鍵);兩語系 1387 鍵對稱(只在 zh/只在 en 皆 0)
- @styles.css@:@.toolbar@
h3. 驗證
- @npx tsc --noEmit@ → 0 error
- headless Chrome 截圖(@12_ui_deployments_zh.png@):側欄「部署作業台」、工具列(重新整理/進版至 v2/一鍵進版/一鍵退版/部分退版)、20 列服務(版本、前一版、就緒/期望、綠「就緒」徽章、逐列進/退版)、頁尾「本頁呼叫本機部署 API(無認證、僅供演示)」皆正確渲染
h3. ⚠️ 如實揭露
截圖攝於「卡片標題鍵」修正之前(當時卡片標題顯示原始鍵 @deployments.title@)。已改為沿用 @nav.ops.deployments.title@——同一鍵在截圖側欄已正確顯示「部署作業台」,故修正必然正確;修正後未能重拍:本機 Chrome headless 反覆無回應(SIGTERM),如實記錄。¶
本輪 @vitest@ 全量執行兩次皆未取得通過計數(第二次起 vitest 啟動即報內部錯誤)——環境問題,非測試失敗;tsc 0 error 與既有 121 測之基線未變(本次僅新增頁面與附加 i18n 鍵,未改既有頁面)。¶
映像仍為佔位(@cardcore-standin:vN@,本專案無 CI);部署 API 無認證、CORS 開放 @*@(僅本機演示)。¶
h3. 進度
12-3 收斂(GAP-003 標 ✅)。CR-078 剩:12-7、12-5 待 PMO 裁定(GOV-009 #2/#3);12-1/12-4 依 D-057 以基線+方法結案。
RA Updated by Redmine Admin about 12 hours ago
h2. GAP-003⑮:12-7/12-5 最小可演示完成(2026-10-25,#A-396)
依 BEAM PMO 指示「先給最小可演示版本、裁定後再對齊」——兩項形式仍待裁定,但已有可跑的東西。
h3. 12-7 客製化(建議選項 A:指引+可執行範例)
- @docs/09-wiki/05-客製化指引.md@:原理(DIP 埠替換)/怎麼挑埠(112 個)/四步接上(實作→守契約→@Bean@ 註冊→驗證)/Debug 三招/為何不給 SDK jar
- @examples/custom-storage-adapter/@:@FileSystemObjectStorageAdapter@ 只實作 @ObjectStoragePort@ 兩個方法,未改 cardcore 任何程式碼
- 真機(@bash examples/custom-storage-adapter/run.sh@):①上傳/取回位元組一致 true ②查無回 @Optional.empty()@ true ③路徑穿越被拒 true → @ALL CHECKS PASSED@
- 負樣本:@get@ 查無改成回空陣列 → ② 立即失敗(精準轉紅),還原後全過
- ⚠️ 過程踩坑:@javac@ 用系統 Java 8 → @class file has wrong version 65.0, should be 52.0@;已改為 @source env.sh@ 並印出實際 JDK
h3. 12-5 封閉驗證(建議選項 B:錄製回放)
- @ops/local/replay/replay.py@(@record@/@replay@,Python 標準庫零依賴)
- 真機:6 筆唯讀請求錄製(含 1 筆 422 真實錯誤)→ 同版回放差異 0/exit 0
- 負樣本:回放到不同服務 → 差異 6/6/exit 1;含寫入請求之錄製 → 拒絕/exit 2
- 設計要點:排除易變欄位(@traceId@/@asOf@/@updatedAt@)否則永遠假紅;唯讀在檔案層強制(@readOnly@ 標記+回放前檢查),不靠使用者自律
h3. ⚠️ 如實揭露
兩項形式仍待裁定(GOV-009 #2/#3):若要求 SDK jar 或指定封閉驗證工具,本批為其內容基礎/可替換核心,需再對齊。¶
12-7 範例不含 Spring 註冊(刻意與框架無關),指引給出 @Bean@ 接線但未在叢集驗證。¶
12-5 樣本僅 6 筆、單一服務——足以證明機制,不足以代表流量分佈;未實作影子分流(第二階段,需獨立 schema)。¶
h3. 證據
@docs/08-evidence/CR-078_12-7_客製化_20261025/@、@docs/08-evidence/CR-078_12-5_封閉驗證_20261025/@
h3. 進度
CR-078:12-2 ✅、12-3 ✅、12-6 ✅、12-7 ◐ 最小可演示、12-5 ◐ 最小可演示、12-1/12-4 依 D-057 以基線+方法結案。