# i18n Default Language Configuration Fix Design

> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development to implement this plan.

**Goal:** Add DEFAULT_LANGUAGE configuration in .env file, with English as the hardcoded fallback when not configured.

**Architecture:** Read DEFAULT_LANGUAGE from environment variables in constants.ts, default to 'en' if not set.

**Tech Stack:** NestJS (backend), React (frontend), TypeScript, dotenv

---

## Problem Statement

### Current Issues

1. **No .env Configuration** - Default language is hardcoded in constants.ts
   - Cannot be changed without code modification
   - Different environments cannot have different defaults

2. **Fallback Language Issue** (`server/src/i18n/i18n.service.ts:180`)
   - When an unsupported language is passed, system defaults to Japanese
   - This causes unexpected Japanese output for users with unsupported locale

3. **Japanese Comments** (`server/src/common/constants.ts:21`)
   - Comment `// デフォルト言語` should be English per project standards

4. **Hardcoded System Prompts** (`server/src/i18n/i18n.service.ts`)
   - `getPrompt()` method: Japanese fallback prompts hardcoded in else branch
   - `getDocumentTitlePrompt()` method: Japanese fallback hardcoded
   - `getChatTitlePrompt()` method: Japanese fallback hardcoded

### Current State

| Component | Default Language | Source |
|-----------|-----------------|--------|
| Backend constants | `'zh'` | Hardcoded |
| Backend i18n service | `'zh'` | From constants |
| Frontend context | `'en'` | Hardcoded |

---

## Fix Design

### Decision: Env-Based Configuration with English Default

**Configuration Flow:**
```
.env → DEFAULT_LANGUAGE → constants.ts → i18n.service.ts
         ↓ (if not set)
       'en' (hardcoded fallback)
```

**Rationale:**
- English is the most universally understood international language
- Safer default for international users
- Matches frontend default
- Environment-based config allows per-deployment customization

---

## Files to Modify

### 1. `server/.env.sample`

**Add:** Default language configuration option

```bash
# Default language for the system (zh, en, ja)
# If not set, defaults to 'en'
# DEFAULT_LANGUAGE=en
```

### 2. `server/src/common/constants.ts`

**Change:** Read from environment with English fallback

```typescript
// Supported languages
const SUPPORTED_LANGUAGES = ['zh', 'en', 'ja'] as const;

// Read DEFAULT_LANGUAGE from environment
function getDefaultLanguage(): typeof SUPPORTED_LANGUAGES[number] {
  const envValue = process.env.DEFAULT_LANGUAGE?.toLowerCase();
  
  // Validate: must be one of supported languages
  if (envValue && SUPPORTED_LANGUAGES.includes(envValue as typeof SUPPORTED_LANGUAGES[number])) {
    return envValue as typeof SUPPORTED_LANGUAGES[number];
  }
  
  // Fallback to English if not set or invalid
  return 'en';
}

// Default language - read from env, fallback to English
export const DEFAULT_LANGUAGE = getDefaultLanguage();
export const DEFAULT_LANGUAGE_FALLBACK = 'en';
```

### 3. `server/src/i18n/i18n.service.ts`

#### 3.1 Fix getPrompt() fallback (line ~180)

**Current:**
```typescript
} else { // 默认为日语，符合プロジェクト要求
  return type === 'withContext' ? `
  以下ナレッジベース...
```

**Proposed:**
```typescript
} else { // Fallback to English for unsupported languages
  return type === 'withContext' ? `
  Answer the user's question based on the following knowledge base content.
  ${hasKnowledgeGroup ? `
  **IMPORTANT**: The user has selected a specific knowledge group. Please answer strictly based on the knowledge base content below. If the relevant information is not found in the knowledge base, explicitly tell the user: "${noMatchMsg}", before providing an answer.
  ` : ''}
  Knowledge Base CONTENT:
  {context}

  Conversation history:
  {history}

  User question: {question}

  Please answer in English and strictly follow these Markdown formatting guidelines:

  1. **Paragraphs & Structure**:
     - Use clear paragraph breaks with blank lines between key points
     - Use headings (## or ###) to organize longer answers

  2. **Text Formatting**:
     - Use **bold** to emphasize important concepts and keywords
     - Use lists (- or 1.) to organize multiple points
     - Use \`code\` to mark technical terms, commands, file names

  3. **Code Display**:
     - Use code blocks with language specification:
       \`\`\`python
       def example():
           return "example"
       \`\`\`
     - Supported languages: python, javascript, typescript, java, bash, sql, etc.

  4. **Diagrams & Charts**:
     - Use Mermaid syntax for flowcharts, sequence diagrams, etc.:
       \`\`\`mermaid
       graph LR
           A[Start] --> B[Process]
           B --> C[End]
       \`\`\`
     - Use cases: process flows, architecture diagrams, state diagrams, sequence diagrams

  5. **Other Requirements**:
     - Keep answers concise and clear
     - Use numbered lists for multi-step processes
     - Use tables for comparison information (if applicable)
  ` : `
  As an intelligent assistant, please answer the user's question.

  Conversation history:
  {history}

  User question: {question}

  Please answer in English.
  `;
}
```

#### 3.2 Fix getDocumentTitlePrompt() fallback (line ~253)

**Current:**
```typescript
} else {
  return `あなたはドキュメントアナライザー...
```

**Proposed:**
```typescript
} else {
  return `You are a document analyzer. Read the following text (start of a document) and generate a concise, professional title (max 50 chars).
Return ONLY the title text. No preamble like "The title is...".
Language: English
Text:
${contentSample}`;
}
```

#### 3.3 Fix getChatTitlePrompt() fallback (line ~278)

**Current:**
```typescript
} else {
  return `以下の会話スニペットに基づい...
```

**Proposed:**
```typescript
} else {
  return `Based on the following conversation snippet, generate a short, descriptive title (max 50 chars) that summarizes the topic.
Return ONLY the title. No preamble.
Language: English
Snippet:
User: ${userMessage}
Assistant: ${aiResponse}`;
}
```

---

## Task Breakdown

### Task 1: Update .env.sample

**Files:**
- Modify: `server/.env.sample`

- [ ] **Step 1: Add DEFAULT_LANGUAGE configuration**

```bash
# Default language for the system (zh, en, ja)
# If not set, defaults to 'en' (English)
DEFAULT_LANGUAGE=en
```

### Task 2: Update constants.ts with env-based config

**Files:**
- Modify: `server/src/common/constants.ts`

- [ ] **Step 1: Replace hardcoded DEFAULT_LANGUAGE with env-based logic**

```typescript
// Supported languages
const SUPPORTED_LANGUAGES = ['zh', 'en', 'ja'] as const;

// Read DEFAULT_LANGUAGE from environment
function getDefaultLanguage(): typeof SUPPORTED_LANGUAGES[number] {
  const envValue = process.env.DEFAULT_LANGUAGE?.toLowerCase();
  
  // Validate: must be one of supported languages
  if (envValue && SUPPORTED_LANGUAGES.includes(envValue as typeof SUPPORTED_LANGUAGES[number])) {
    return envValue as typeof SUPPORTED_LANGUAGES[number];
  }
  
  // Fallback to English if not set or invalid
  return 'en';
}

// Default language - read from env, fallback to English
export const DEFAULT_LANGUAGE = getDefaultLanguage();
export const DEFAULT_LANGUAGE_FALLBACK = 'en';
```

**Note:** No new dependencies required - uses simple array validation.

### Task 3: Fix i18n.service.ts getPrompt() Fallback

**Files:**
- Modify: `server/src/i18n/i18n.service.ts:180-235`

- [ ] **Step 1: Replace Japanese fallback with English**

Replace the entire `else` block (lines ~180-235) with English fallback prompts.

### Task 4: Fix i18n.service.ts getDocumentTitlePrompt() Fallback

**Files:**
- Modify: `server/src/i18n/i18n.service.ts:253-259`

- [ ] **Step 1: Replace Japanese fallback with English**

Replace the `else` block with English prompt.

### Task 5: Fix i18n.service.ts getChatTitlePrompt() Fallback

**Files:**
- Modify: `server/src/i18n/i18n.service.ts:278-285`

- [ ] **Step 1: Replace Japanese fallback with English**

Replace the `else` block with English prompt.

### Task 6: Verification

- [ ] **Step 1: Run TypeScript check**

```bash
cd server && yarn build
```

Expected: Build succeeds without errors

- [ ] **Step 2: Test env configuration**

```bash
# Test with DEFAULT_LANGUAGE=zh
DEFAULT_LANGUAGE=zh yarn start:dev

# Test with DEFAULT_LANGUAGE=en
DEFAULT_LANGUAGE=en yarn start:dev

# Test with no DEFAULT_LANGUAGE (should default to 'en')
yarn start:dev
```

- [ ] **Step 3: Verify fallback behavior**

Test that unsupported language code returns English instead of Japanese.

---

## Expected Result

| Configuration | Before | After |
|---------------|--------|-------|
| DEFAULT_LANGUAGE source | Hardcoded `'zh'` | Read from `.env`, fallback to `'en'` |
| Fallback language | `'ja'` | `'en'` |
| constants.ts comment | 日本語 | English |
| getPrompt fallback | 日本語 | English |
| getDocumentTitlePrompt fallback | 日本語 | English |
| getChatTitlePrompt fallback | 日本語 | English |

### Configuration Examples

| .env Setting | Result |
|--------------|--------|
| `DEFAULT_LANGUAGE=zh` | 中文 |
| `DEFAULT_LANGUAGE=en` | English |
| `DEFAULT_LANGUAGE=ja` | 日本語 |
| (not set) | English (default) |
| `DEFAULT_LANGUAGE=invalid` | English (fallback) |

---

## Risk & Mitigation

**Low Risk:** Changes are configuration-based with safe defaults.

**Mitigation:**
- Hardcoded `'en'` fallback ensures safe behavior even if env is misconfigured
- Keep 'zh', 'en', 'ja' as supported languages
- Japanese ('ja') still fully supported when explicitly configured
