# AWOOOI i18n 字典檔結構規範 > **版本**: v1.0 > **建立日期**: 2026-03-20 > **負責人**: CPO > **框架**: next-intl --- ## 概述 > 🎯 **顧問深度討論 #4**: 語意化 Key 命名學 此文件定義 AWOOOI 國際化字典檔的結構規範,採用語意化樹狀命名, 確保 500+ 個翻譯項目在工程師與翻譯員之間有明確的上下文。 --- ## 命名規範 ### Key 命名格式 ``` [頁面].[組件].[元素]_[動作/狀態] ``` ### 正確與錯誤範例 ```json // ❌ 錯誤: 無上下文,容易混淆 { "approve": "批准", "cancel": "取消", "error": "發生錯誤", "warning": "警告" } // ✅ 正確: 語意化命名,清楚上下文 { "dashboard": { "approval_card": { "btn_approve": "批准執行", "btn_reject": "拒絕", "btn_request_info": "詢問更多", "label_blast_radius": "爆炸半徑", "status_pending": "等待簽核", "status_approved": "已批准" } } } ``` --- ## 字典檔結構 ### 目錄結構 ``` apps/web/messages/ ├── zh-TW.json # 繁體中文 (主要) └── en.json # English ``` ### 頂層分類 ```json { "common": {}, // 共用元素 (按鈕、狀態、錯誤) "layout": {}, // 佈局元素 (導航、側邊欄、頁尾) "dashboard": {}, // 戰情室頁面 "monitor": {}, // 監控模組 "security": {}, // 安全模組 "deploy": {}, // 部署模組 "tickets": {}, // 工單模組 "billing": {}, // 帳單模組 "settings": {}, // 設定模組 "ai_copilot": {}, // AI 助手 "errors": {}, // 錯誤訊息 "validation": {} // 表單驗證 } ``` --- ## 完整字典檔範本 ### zh-TW.json ```json { "common": { "btn": { "save": "儲存", "cancel": "取消", "confirm": "確認", "delete": "刪除", "edit": "編輯", "view": "查看", "back": "返回", "next": "下一步", "previous": "上一步", "submit": "送出", "reset": "重設", "search": "搜尋", "filter": "篩選", "export": "匯出", "import": "匯入", "refresh": "重新整理" }, "status": { "loading": "載入中...", "success": "成功", "error": "失敗", "pending": "處理中", "active": "啟用", "inactive": "停用", "healthy": "健康", "warning": "警告", "critical": "嚴重", "unknown": "未知" }, "time": { "just_now": "剛剛", "minutes_ago": "{count} 分鐘前", "hours_ago": "{count} 小時前", "days_ago": "{count} 天前", "today": "今天", "yesterday": "昨天" }, "pagination": { "page": "第 {current} 頁,共 {total} 頁", "showing": "顯示 {from}-{to},共 {total} 筆", "per_page": "每頁顯示" } }, "layout": { "nav": { "dashboard": "戰情室", "monitor": "監控", "security": "安全", "deploy": "部署", "tickets": "工單", "billing": "帳單", "settings": "設定" }, "sidebar": { "collapse": "收合側邊欄", "expand": "展開側邊欄" }, "header": { "search_placeholder": "搜尋... (⌘K)", "notifications": "通知", "profile": "個人檔案", "logout": "登出" }, "footer": { "copyright": "© {year} 岑洋國際行銷有限公司", "version": "版本 {version}" } }, "dashboard": { "page_title": "戰情室", "page_description": "系統健康狀態總覽", "host_card": { "title": "主機狀態", "label_ip": "IP 位址", "label_role": "角色", "label_cpu": "CPU", "label_memory": "記憶體", "label_disk": "磁碟", "label_last_seen": "最後更新", "status_online": "上線", "status_offline": "離線" }, "alert_panel": { "title": "即時告警", "btn_acknowledge": "確認", "btn_view_all": "查看全部", "empty_state": "目前沒有告警", "severity_info": "資訊", "severity_warning": "警告", "severity_critical": "嚴重" }, "approval_card": { "title": "待簽核項目", "btn_approve": "批准執行", "btn_reject": "拒絕", "btn_request_info": "詢問更多", "label_requester": "申請人", "label_blast_radius": "爆炸半徑", "label_signatures": "簽核進度", "label_expires_in": "剩餘時間", "label_ai_summary": "AI 摘要", "label_confidence": "信心度", "status_pending": "等待簽核", "status_approved": "已批准", "status_rejected": "已拒絕", "status_expired": "已過期", "blast_low": "低", "blast_medium": "中", "blast_high": "高", "blast_critical": "嚴重" }, "metrics": { "total_hosts": "主機總數", "active_alerts": "活躍告警", "pending_approvals": "待簽核", "deployments_today": "今日部署" } }, "ai_copilot": { "title": "AI 助手", "placeholder": "輸入問題或指令...", "btn_send": "送出", "btn_stop": "停止", "btn_clear": "清除對話", "thinking": "AI 思考中...", "error_offline": "AI 服務暫時不可用", "error_timeout": "回應超時,請重試", "suggestion_prefix": "建議", "action_prefix": "建議執行", "warning_destructive": "此操作具有破壞性,請謹慎執行" }, "command_palette": { "placeholder": "輸入指令...", "category_navigation": "導航", "category_action": "操作", "category_ai": "AI 功能", "category_settings": "設定", "no_results": "沒有符合的結果", "hint_shortcut": "快捷鍵" }, "errors": { "generic": "發生錯誤,請稍後再試", "network": "網路連線失敗", "unauthorized": "您沒有權限執行此操作", "not_found": "找不到請求的資源", "validation": "輸入資料驗證失敗", "server": "伺服器錯誤", "timeout": "請求超時", "rate_limited": "請求過於頻繁,請稍後再試" }, "validation": { "required": "此欄位為必填", "email": "請輸入有效的電子郵件", "min_length": "至少需要 {min} 個字元", "max_length": "最多 {max} 個字元", "pattern": "格式不正確" } } ``` ### en.json ```json { "common": { "btn": { "save": "Save", "cancel": "Cancel", "confirm": "Confirm", "delete": "Delete", "edit": "Edit", "view": "View", "back": "Back", "next": "Next", "previous": "Previous", "submit": "Submit", "reset": "Reset", "search": "Search", "filter": "Filter", "export": "Export", "import": "Import", "refresh": "Refresh" }, "status": { "loading": "Loading...", "success": "Success", "error": "Failed", "pending": "Processing", "active": "Active", "inactive": "Inactive", "healthy": "Healthy", "warning": "Warning", "critical": "Critical", "unknown": "Unknown" } }, "dashboard": { "page_title": "War Room", "page_description": "System Health Overview", "approval_card": { "title": "Pending Approvals", "btn_approve": "Approve", "btn_reject": "Reject", "btn_request_info": "Request Info", "label_blast_radius": "Blast Radius", "label_signatures": "Signatures", "status_pending": "Pending" } }, "ai_copilot": { "title": "AI Assistant", "placeholder": "Enter a question or command...", "thinking": "AI is thinking..." }, "errors": { "generic": "An error occurred. Please try again later.", "network": "Network connection failed", "unauthorized": "You don't have permission to perform this action" } } ``` --- ## 使用方式 ### 組件中使用 ```tsx // apps/web/src/components/ApprovalCard.tsx import { useTranslations } from 'next-intl'; export function ApprovalCard({ approval }: Props) { const t = useTranslations('dashboard.approval_card'); return (

{t('title')}

{t('label_blast_radius')}: {t(`blast_${approval.blastRadius}`)}

); } ``` ### 動態參數 ```tsx // 使用變數 const t = useTranslations('common.time'); t('minutes_ago', { count: 5 }); // "5 分鐘前" const t = useTranslations('common.pagination'); t('showing', { from: 1, to: 20, total: 100 }); // "顯示 1-20,共 100 筆" ``` --- ## CI 檢查規則 ### 翻譯完整性檢查 ```typescript // scripts/check-i18n.ts import zhTW from '../messages/zh-TW.json'; import en from '../messages/en.json'; function getAllKeys(obj: object, prefix = ''): string[] { return Object.entries(obj).flatMap(([key, value]) => { const fullKey = prefix ? `${prefix}.${key}` : key; return typeof value === 'object' ? getAllKeys(value, fullKey) : [fullKey]; }); } const zhKeys = new Set(getAllKeys(zhTW)); const enKeys = new Set(getAllKeys(en)); const missingInEn = [...zhKeys].filter(k => !enKeys.has(k)); const missingInZh = [...enKeys].filter(k => !zhKeys.has(k)); if (missingInEn.length > 0) { console.error('❌ Missing in en.json:', missingInEn); process.exit(1); } if (missingInZh.length > 0) { console.error('❌ Missing in zh-TW.json:', missingInZh); process.exit(1); } console.log('✅ All translations are complete'); ``` ### PR Checklist ```markdown ## i18n Checklist - [ ] 新增的 UI 文字已加入 zh-TW.json - [ ] 新增的 UI 文字已加入 en.json - [ ] Key 命名遵循 `[頁面].[組件].[元素]` 格式 - [ ] CI i18n 檢查通過 ``` --- ## 變更記錄 | 日期 | 版本 | 變更 | 作者 | |------|------|------|------| | 2026-03-20 | v1.0 | 初版建立 | CPO | --- *此文件由 CPO 維護,前端開發者新增 UI 文字時必須遵守。*