# farismnazri/learnmalay architecture

> Architecture diagram of the GitHub repository farismnazri/learnmalay, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/farismnazri/learnmalay
- Repository: https://github.com/farismnazri/learnmalay

## Overview

Learn Malay is a chapter-based Malaysian Malay learning game. Players choose or create a profile, progress through lessons on a chapter map, and unlock minigames; scores and progress are recorded through server APIs. The repository also documents admin user management, analytics, highscores, and privacy retention. The graph follows documented flows and relationships visible in indexed source references; unsampled implementation details are represented conservatively, and some optional or indirect connections are omitted.

Main entry points: [`app/map/page.tsx`](https://github.com/farismnazri/learnmalay/blob/main/app/map/page.tsx) (Chapter map), [`src/server/sessionAuth.ts`](https://github.com/farismnazri/learnmalay/blob/main/src/server/sessionAuth.ts) (Session authentication), [`app/api/highscores/route.ts`](https://github.com/farismnazri/learnmalay/blob/main/app/api/highscores/route.ts) (Highscore API), [`src/lib/userStore.ts`](https://github.com/farismnazri/learnmalay/blob/main/src/lib/userStore.ts) (Client user store)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["Player experience"]
  node_landing["Title screen<br/>[page.tsx]"]
end

subgraph group_learning["Lessons &amp; minigames"]
  node_map["Chapter map<br/>[page.tsx]"]
  node_progress_rules["Progress &amp; unlock rules<br/>[minigameUnlocks.ts]"]
  node_lesson["Chapter lesson renderer<br/>[page.tsx]"]
  node_chapter_content["Chapter content<br/>[index.ts]"]
  node_lesson_cards["Lesson activity cards<br/>[BoxDragCard.tsx]"]
  node_minigame_hub["Minigame hub<br/>[page.tsx]"]
  node_minigame_play["Minigame play pages"]
  node_highscores_ui["Highscore tables<br/>[page.tsx]"]
end

subgraph group_identity["Profiles &amp; progress"]
  node_profile_ui["Profile selection<br/>[page.tsx]"]
  node_client_store["Client user store<br/>[userStore.ts]"]
  node_user_api["User API routes"]
end

subgraph group_server["Server services"]
  node_session_auth["Session authentication<br/>[sessionAuth.ts]"]
  node_session_repo["Session repository<br/>[sessionRepo.ts]"]
  node_user_repo["User repository<br/>[userRepo.ts]"]
  node_database[("Storage adapter<br/>[db.ts]")]
  node_highscore_api["Highscore API<br/>[route.ts]"]
  node_highscore_repo["Highscore repository<br/>[highscoreRepo.ts]"]
  node_activity_api["Activity API<br/>[route.ts]"]
  node_activity_repo["Activity repository<br/>[activityRepo.ts]"]
end

subgraph group_admin["Administration"]
  node_admin_ui["Admin dashboard<br/>[page.tsx]"]
  node_admin_users["Admin user management"]
  node_admin_analytics["Analytics API<br/>[route.ts]"]
  node_retention["Privacy retention"]
end

node_player(("Player"))

node_player -->|"opens"| node_landing
node_landing -->|"routes to"| node_map
node_landing -->|"routes to"| node_profile_ui
node_player -->|"selects profile"| node_profile_ui
node_profile_ui -->|"uses"| node_client_store
node_client_store -->|"requests"| node_user_api
node_map -->|"checks unlocks"| node_progress_rules
node_map -->|"reads profile"| node_client_store
node_map -->|"opens chapter"| node_lesson
node_lesson -->|"loads lessons"| node_chapter_content
node_lesson -->|"renders activities"| node_lesson_cards
node_minigame_hub -->|"checks unlocks"| node_progress_rules
node_minigame_hub -->|"opens games"| node_minigame_play
node_minigame_play -->|"reads profile"| node_client_store
node_minigame_play -.->|"submits scores"| node_highscore_api
node_highscores_ui -.->|"loads scores"| node_highscore_api
node_user_api -->|"authenticates"| node_session_auth
node_session_auth -->|"reads and writes sessions"| node_session_repo
node_session_auth -->|"loads user"| node_user_repo
node_user_repo -->|"reads and writes users"| node_database
node_highscore_api -->|"handles scores"| node_highscore_repo
node_highscore_api -->|"checks session"| node_session_auth
node_highscore_repo -.->|"stores scores"| node_database
node_activity_api -->|"records events"| node_activity_repo
node_activity_repo -->|"stores activity"| node_database
node_admin_ui -.->|"loads analytics"| node_admin_analytics
node_admin_ui -->|"manages users"| node_admin_users
node_admin_users -.->|"uses user routes"| node_user_api
node_admin_analytics -.->|"reads user data"| node_user_repo
node_retention -.->|"prunes retained data"| node_database

click node_landing "https://github.com/farismnazri/learnmalay/blob/main/app/page.tsx"
click node_profile_ui "https://github.com/farismnazri/learnmalay/blob/main/app/user/page.tsx"
click node_client_store "https://github.com/farismnazri/learnmalay/blob/main/src/lib/userStore.ts"
click node_map "https://github.com/farismnazri/learnmalay/blob/main/app/map/page.tsx"
click node_progress_rules "https://github.com/farismnazri/learnmalay/blob/main/src/lib/minigameUnlocks.ts"
click node_lesson "https://github.com/farismnazri/learnmalay/blob/main/app/chapter/%5Bid%5D/page.tsx"
click node_chapter_content "https://github.com/farismnazri/learnmalay/blob/main/src/lib/chapters/index.ts"
click node_lesson_cards "https://github.com/farismnazri/learnmalay/blob/main/src/components/game/BoxDragCard.tsx"
click node_minigame_hub "https://github.com/farismnazri/learnmalay/blob/main/app/minigames/page.tsx"
click node_minigame_play "https://github.com/farismnazri/learnmalay/tree/main/app/minigames"
click node_highscores_ui "https://github.com/farismnazri/learnmalay/blob/main/app/minigames/highscores/page.tsx"
click node_user_api "https://github.com/farismnazri/learnmalay/tree/main/app/api/users"
click node_session_auth "https://github.com/farismnazri/learnmalay/blob/main/src/server/sessionAuth.ts"
click node_session_repo "https://github.com/farismnazri/learnmalay/blob/main/src/server/sessionRepo.ts"
click node_user_repo "https://github.com/farismnazri/learnmalay/blob/main/src/server/userRepo.ts"
click node_database "https://github.com/farismnazri/learnmalay/blob/main/src/server/db.ts"
click node_highscore_api "https://github.com/farismnazri/learnmalay/blob/main/app/api/highscores/route.ts"
click node_highscore_repo "https://github.com/farismnazri/learnmalay/blob/main/src/server/highscoreRepo.ts"
click node_activity_api "https://github.com/farismnazri/learnmalay/blob/main/app/api/activity/route.ts"
click node_activity_repo "https://github.com/farismnazri/learnmalay/blob/main/src/server/activityRepo.ts"
click node_admin_ui "https://github.com/farismnazri/learnmalay/blob/main/app/admin/page.tsx"
click node_admin_users "https://github.com/farismnazri/learnmalay/tree/main/app/admin/users"
click node_admin_analytics "https://github.com/farismnazri/learnmalay/blob/main/app/api/admin/analytics/route.ts"
click node_retention "https://github.com/farismnazri/learnmalay/blob/main/src/server/privacyRetention.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_landing toneBlue
class node_map,node_progress_rules,node_lesson,node_chapter_content,node_lesson_cards,node_minigame_hub,node_minigame_play,node_highscores_ui toneAmber
class node_profile_ui,node_client_store,node_user_api toneMint
class node_session_auth,node_session_repo,node_user_repo,node_database,node_highscore_api,node_highscore_repo,node_activity_api,node_activity_repo toneRose
class node_admin_ui,node_admin_users,node_admin_analytics,node_retention,node_player toneIndigo
```

## Components

### Player experience

- [Title screen](https://github.com/farismnazri/learnmalay/blob/main/app/page.tsx): `app/page.tsx`

### Lessons & minigames

- [Chapter map](https://github.com/farismnazri/learnmalay/blob/main/app/map/page.tsx): `app/map/page.tsx`
- [Progress & unlock rules](https://github.com/farismnazri/learnmalay/blob/main/src/lib/minigameUnlocks.ts): `src/lib/minigameUnlocks.ts`
- [Chapter lesson renderer](https://github.com/farismnazri/learnmalay/blob/main/app/chapter/%5Bid%5D/page.tsx): `app/chapter/[id]/page.tsx`
- [Chapter content](https://github.com/farismnazri/learnmalay/blob/main/src/lib/chapters/index.ts): `src/lib/chapters/index.ts`
- [Lesson activity cards](https://github.com/farismnazri/learnmalay/blob/main/src/components/game/BoxDragCard.tsx): `src/components/game/BoxDragCard.tsx`
- [Minigame hub](https://github.com/farismnazri/learnmalay/blob/main/app/minigames/page.tsx): `app/minigames/page.tsx`
- [Minigame play pages](https://github.com/farismnazri/learnmalay/tree/main/app/minigames): `app/minigames`
- [Highscore tables](https://github.com/farismnazri/learnmalay/blob/main/app/minigames/highscores/page.tsx): `app/minigames/highscores/page.tsx`

### Profiles & progress

- [Profile selection](https://github.com/farismnazri/learnmalay/blob/main/app/user/page.tsx): `app/user/page.tsx`
- [Client user store](https://github.com/farismnazri/learnmalay/blob/main/src/lib/userStore.ts): `src/lib/userStore.ts`
- [User API routes](https://github.com/farismnazri/learnmalay/tree/main/app/api/users): `app/api/users`

### Server services

- [Session authentication](https://github.com/farismnazri/learnmalay/blob/main/src/server/sessionAuth.ts): `src/server/sessionAuth.ts`
- [Session repository](https://github.com/farismnazri/learnmalay/blob/main/src/server/sessionRepo.ts): `src/server/sessionRepo.ts`
- [User repository](https://github.com/farismnazri/learnmalay/blob/main/src/server/userRepo.ts): `src/server/userRepo.ts`
- [Storage adapter](https://github.com/farismnazri/learnmalay/blob/main/src/server/db.ts): `src/server/db.ts`
- [Highscore API](https://github.com/farismnazri/learnmalay/blob/main/app/api/highscores/route.ts): `app/api/highscores/route.ts`
- [Highscore repository](https://github.com/farismnazri/learnmalay/blob/main/src/server/highscoreRepo.ts): `src/server/highscoreRepo.ts`
- [Activity API](https://github.com/farismnazri/learnmalay/blob/main/app/api/activity/route.ts): `app/api/activity/route.ts`
- [Activity repository](https://github.com/farismnazri/learnmalay/blob/main/src/server/activityRepo.ts): `src/server/activityRepo.ts`

### Administration

- [Admin dashboard](https://github.com/farismnazri/learnmalay/blob/main/app/admin/page.tsx): `app/admin/page.tsx`
- [Admin user management](https://github.com/farismnazri/learnmalay/tree/main/app/admin/users): `app/admin/users`
- [Analytics API](https://github.com/farismnazri/learnmalay/blob/main/app/api/admin/analytics/route.ts): `app/api/admin/analytics/route.ts`
- [Privacy retention](https://github.com/farismnazri/learnmalay/blob/main/src/server/privacyRetention.ts): `src/server/privacyRetention.ts`

### Other components

- **Player**

## Connections

- Player → Title screen: opens (evidence: `README.md`)
- Title screen → Chapter map: routes to (evidence: `README.md`)
- Title screen → Profile selection: routes to (evidence: `README.md`)
- Player → Profile selection: selects profile (evidence: `README.md`)
- Profile selection → Client user store: uses (evidence: `app/user/page.tsx`)
- Client user store → User API routes: requests (evidence: `src/lib/userStore.ts`)
- Chapter map → Progress & unlock rules: checks unlocks (evidence: `app/map/page.tsx`)
- Chapter map → Client user store: reads profile (evidence: `app/map/page.tsx`)
- Chapter map → Chapter lesson renderer: opens chapter (evidence: `README.md`)
- Chapter lesson renderer → Chapter content: loads lessons (evidence: `app/chapter/[id]/page.tsx`)
- Chapter lesson renderer → Lesson activity cards: renders activities (evidence: `app/chapter/[id]/page.tsx`)
- Minigame hub → Progress & unlock rules: checks unlocks (evidence: `app/minigames/page.tsx`)
- Minigame hub → Minigame play pages: opens games (evidence: `README.md`)
- Minigame play pages → Client user store: reads profile (evidence: `app/minigames/misi-membeli/play/page.tsx`)
- Minigame play pages → Highscore API: submits scores
- Highscore tables → Highscore API: loads scores
- User API routes → Session authentication: authenticates (evidence: `app/api/users/current/route.ts`)
- Session authentication → Session repository: reads and writes sessions (evidence: `src/server/sessionAuth.ts`)
- Session authentication → User repository: loads user (evidence: `src/server/sessionAuth.ts`)
- User repository → Storage adapter: reads and writes users (evidence: `src/server/userRepo.ts`)
- Highscore API → Highscore repository: handles scores (evidence: `app/api/highscores/route.ts`)
- Highscore API → Session authentication: checks session (evidence: `app/api/highscores/route.ts`)
- Highscore repository → Storage adapter: stores scores
- Activity API → Activity repository: records events (evidence: `app/api/activity/route.ts`)
- Activity repository → Storage adapter: stores activity (evidence: `src/server/activityRepo.ts`)
- Admin dashboard → Analytics API: loads analytics
- Admin dashboard → Admin user management: manages users (evidence: `README.md`)
- Admin user management → User API routes: uses user routes
- Analytics API → User repository: reads user data
- Privacy retention → Storage adapter: prunes retained data
