Advanced Problem

Multilingual learning apps become brittle when content storage, script rendering, and progression logic are tightly coupled. This is where many products start shipping incorrect prompts or broken character previews.

Step 1: Build a script-agnostic domain model

type Lexeme = {
  id: string;
  language: 'ja' | 'zh' | 'en';
  surface: string;
  reading?: string;
  meanings: string[];
};

Step 2: Attach script-specific render strategies

interface Renderer {
  renderInputGuide(term: Lexeme): string;
}

class JapaneseRenderer implements Renderer {
  renderInputGuide(term: Lexeme) {
    return `${term.surface} (${term.reading ?? 'reading-n/a'})`;
  }
}

Step 3: Keep progression logic independent from locale formatting

function scoreReview(correct: boolean, streak: number) {
  return correct ? Math.min(streak + 1, 30) : 0;
}

Step 4: Add content-manifest validation

Before publishing packs, verify required fields per language and ensure no malformed entries ship.

Preview: first 50% is visible. Unlock to read the full article.
To view this content, you must be a member of CodeWithWilliamJiamin's Patreon at $1 or more
Already a qualifying Patreon member? Refresh to access this content.