Requirement #363 » N4_i18n_批次外譯_DOM驗證_20261018.md
N4 i18n 內文外譯完成與真實渲染驗證(#A-323,2026-10-18)
目的:以真實瀏覽器渲染(非僅「能編譯」)證明
en-US模式下頁面無中文殘留,
並如實列出量測看不到的缺口與其處置。對應 NFR「支援多國語系」(B.2)。
1. 範圍與結果(單一真實來源:tools/i18n_pending.py)
| 項目 | 起始(#A-322 收尾) |
本批完成後 |
|---|---|---|
| 待遷移檔案 | 26 檔(18 頁 + 8 個 .ts) |
0 檔 |
| 待遷移行數 | 761 行 | 0 行 |
| 語系鍵(leaf) | 659 | 1297(zh-TW 與 en-US 皆同) |
| 語系區塊 | 17 | 34 |
量測指令(與 verify_nfr_ext.py::check_fe_i18n 同一邏輯):
cd cardcore && python3 tools/i18n_pending.py # 全量
python3 tools/i18n_pending.py frontend/src/pages/X.tsx # 單檔(逐頁驗收用)
輸出:---- 檔案 0/行 0。
2. 真實渲染驗證(vite preview + headless Chrome --dump-dom)
- 建置:
VITE_AUTH_ENABLED=false npm run build(dist/已 gitignore) - 英文觸發:注入
localStorage.setItem('cardcore.lang','en-US')進dist/index.html
(★ Chrome--lang不會改變navigator.language,只設旗標驗不到英文路徑) - 逐頁
--dump-dom(--virtual-time-budget=6000),移除<script>與標籤後,
比對渲染後文字中的中日韓字元
| # | 路由 | 中文殘留(排除語系自稱) | 分頁標題(document.title) |
|---|---|---|---|
| 1 | /card/token |
0 | BEAM Card Core — Virtual Card & Token Management |
| 2 | /limit-adjustments |
0 | BEAM Card Core — Limit Adjustment Request |
| 3 | /system/reports |
0 | BEAM Card Core — Reports |
| 4 | /switch/auth/reversal |
0 | BEAM Card Core — Reversal Mechanism |
| 5 | /system/audit |
0 | BEAM Card Core — Audit Trail Query |
| 6 | /auth/clearing |
0 | BEAM Card Core — Clearing & Settlement |
| 7 | /auth/dispute |
0 | BEAM Card Core — Dispute Handling |
| 8 | /system/migration |
0 | BEAM Card Core — Data Migration |
| 9 | /payments |
0 | BEAM Card Core — Payment Console |
| 10 | /system/endpoints |
0 | BEAM Card Core — Endpoint & Connection Management |
| 11 | /authorizations |
0 | BEAM Card Core — Authorization Console |
| 12 | /merchant/settlements |
0 | BEAM Card Core — Merchant & Settlement |
| 13 | /system/split-ratio |
0 | BEAM Card Core — Traffic Split Ratio |
| 14 | /parties |
0 | BEAM Card Core — Cardholder / Account Lookup |
| 15 | /switch/auth/state |
0 | BEAM Card Core — Transaction State Machine View |
| 16 | /postings |
0 | BEAM Card Core — Posting Console |
| 17 | /statements |
0 | BEAM Card Core — Statement Console |
| 18 | /card-applications |
0 | BEAM Card Core — Card Application Console |
唯一允許的中文:語言切換器的「繁體中文」——選項以各語系自稱呈現,
否則切到英文後使用者無從辨識哪個是中文(#A-307 既定決策,非殘留)。
繁中模式抽查(全新 Chrome profile,避免沿用已存的 localStorage):
/card/token 標題為 BEAM 信用卡核心 — 虛擬卡與 Token 管理。
★ 驗證陷阱(本批實測):--user-data-dir 會保留 localStorage,
以同一 profile 重跑會一直得到英文——要驗繁中必須換新 profile 或清除。
3. 本批併修的三個真缺陷(非「順手美化」)
| # | 缺陷 | 影響 | 處置 |
|---|---|---|---|
| 1 |
useApiErrorMessage 每次 render 回傳新函式,而多頁把它放進 useCallback([apiErr]) 依賴 |
useEffect 每輪重跑 → 無限重新查詢(畫面看似正常,實則持續打後端) |
改 useCallback([t]) 固定身分 |
| 2 |
bff.ts/gateway.ts 以中文字串當語系鍵(getJson(..., '查詢健康狀態失敗')) |
英文模式顯示中文;且 t() 查無此鍵 → 原樣回傳中文 |
改為 errors.action.* 鍵(6 個) |
| 3 |
index.html 的 <title> 為靜態中文,且 i18n 掃描只掃 .ts/.tsx
|
英文模式分頁標題仍為中文,量測看不到 |
App.tsx 以 document.title = brand — nav.<path>.title 動態設定,隨語系切換 |
4. 如實揭露(未完成/不在本批範圍)
-
CR-060 P3:後端錯誤訊息在地化——未開始(需另立 CR)。
ApiError.serverMessage優先顯示後端原文且不翻譯,故後端回中文時畫面仍為中文。
本批已把前端 fallback 全部語系化,但後端訊息這一層未動。 -
開發診斷訊息固定英文(
authClient/pkce/main.tsx之throw/console.error):
僅進 console/日誌、不顯示於介面,故不進 i18n(已於程式內註明)。 -
行尾註解仍會被量測計入(
code(); // 中文):本批把 2 處此類註解移至獨立行。
tools/i18n_pending.py已載明此保守限制;不建議為此放寬規則(寧可多報)。 -
數字/日期格式仍以
toLocaleString('zh-TW')固定地區(千分位與日期格式在
en-US 下差異有限,但不是真正的 locale-aware 格式)——屬另一層缺口,未在本批處理。