# 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 (
    <div>
      <h3>{t('title')}</h3>
      <p>{t('label_blast_radius')}: {t(`blast_${approval.blastRadius}`)}</p>
      <button>{t('btn_approve')}</button>
      <button>{t('btn_reject')}</button>
    </div>
  );
}
```

### 動態參數

```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 文字時必須遵守。*
