# abdalla-eldoumani/dust architecture

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

- Interactive diagram: https://gitdiagram.com/abdalla-eldoumani/dust
- Repository: https://github.com/abdalla-eldoumani/dust

## Overview

1. **Product shape**
   - DUST is a monorepo for a single game experience: a Next.js frontend, a Convex realtime backend, and a Python ingestion pipeline that feeds content into the game.

2. **Frontend application shell**
   - `apps/web` is the main user-facing app, built with the Next.js App Router.
   - Key routes are split by concern: landing (`/`), tutorial/about, solo play (`/play`), multiplayer (`/multiplayer` and `/multiplayer/[code]`), leaderboard, and Clerk sign-in/up pages.
   - `src/app/layout.tsx`, `middleware.ts`, `providers.tsx`, and the auth pages define the app shell, route protection, and client providers.

3. **Game loop boundary**
   - The core game loop lives in `src/components/game` and `src/lib`.
   - Visual degradation is handled by the decay subsystem (`decay-engine`, text/layout/color/image decay modules), while gameplay UI is split into fake page renderers, tools, scoring screens, archive controls, and timers.
   - `src/store/game-store.ts` and `src/store/multiplayer-store.ts` hold session state on the client.

4. **Content pipeline for rounds**
   - Gameplay content is not just static pages; it is selected/generated from a content layer in `src/lib/content`.
   - This layer includes caching, difficulty selection, a Convex adapter, and demo content, which suggests the app can switch between local/demo content and backend-provided content.
   - The `/api/generate-content` route is the server-side entry point for AI-assisted content generation using Anthropic Claude.

5. **Real-time backend and data ownership**
   - `packages/backend/convex` is the persistent system of record.
   - The Convex modules model the domain around `users`, `pages`, `pageVariants`, `cachedContent`, `archives`, `gameSessions`, `levels`, `leaderboard`, and `multiplayer`.
   - This is where score, session state, archived selections, and multiplayer room state are stored and synchronized.

6. **Solo mode architecture**
   - Solo play is primarily frontend-driven but backed by Convex for persistence and ranking.
   - The client evaluates page content locally, applies decay locally, and records outcomes/archives to backend tables so progress and leaderboard data can survive across sessions.

7. **Multiplayer architecture**
   - Multiplayer is a separate gameplay path with room creation, waiting/lobby, in-match status, round results, and match results components.
   - Convex provides the shared realtime state and synchronization channel for multiplayer rooms, while the client handles the live UX around joining, waiting, playing, and scoring.
   - The `docs/specs/multiplayer-pre-game-leave-spec.md` indicates explicit room lifecycle rules around pre-game leaving.

8. **Leaderboard and progression**
   - The leaderboard is a backend-backed aggregate exposed to the frontend via realtime queries.
   - `leaderboard` components render the ranked view, while Convex is responsible for authoritative score storage and any scoping rules documented in `docs/specs/leaderboard-scope-spec.md`.

9. **Authentication and identity**
   - Clerk handles sign-in/sign-up and user identity on the frontend.
   - Convex is configured for Clerk JWT auth, so authenticated user identity flows from Clerk into backend queries/mutations and then into gameplay persistence and ranking.

10. **Offline ingestion and curation pipeline**
   - `dust_ingest/` is a separate Python toolchain for sourcing and preparing web content.
   - It includes scraping, HTML sanitization, normalization, variant validation, leveling/difficulty assignment, LLM-based alteration, and upload to Convex.
   - This pipeline feeds the game’s page corpus rather than serving end-user traffic directly.

11. **Shared workspace boundaries**
   - `packages/config` provides shared TypeScript config, and `packages/env` centralizes environment validation.
   - `apps/web` depends on these shared packages, keeping runtime configuration and type settings consistent across the frontend and backend packages.

12. **External services that materially shape the architecture**
   - Next.js is the runtime for the UI and API route.
   - Convex is the realtime database and serverless backend.
   - Clerk is the auth boundary.
   - Anthropic Claude is used for content generation.
   - Vercel deployment config and Turborepo orchestration indicate the repo is structured for multi-package builds and deployment.

Main entry points: [`apps/web/src/app/layout.tsx`](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/layout.tsx) (App shell), [`packages/backend/convex/schema.ts`](https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/schema.ts) (Convex backend), [`apps/web/src/components/game/decaying-page.tsx`](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/components/game/decaying-page.tsx) (Game UI), [`apps/web/src/app/api/generate-content/route.ts`](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/api/generate-content/route.ts) (Generate API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Frontend app"]
  node_web_shell["App shell<br/>nextjs app<br/>[layout.tsx]"]
  node_landing_route["Landing<br/>route<br/>[page.tsx]"]
  node_tutorial_route["How to play<br/>route<br/>[page.tsx]"]
  node_solo_route["Solo play<br/>route<br/>[page.tsx]"]
  node_multiplayer_route["Multiplayer<br/>route<br/>[page.tsx]"]
  node_auth_routes["Auth pages<br/>route group<br/>[page.tsx]"]
  node_leaderboard_route["Leaderboard<br/>route<br/>[page.tsx]"]
  node_content_api["Generate API<br/>next api<br/>[route.ts]"]
  node_game_shell["Game UI<br/>client game shell<br/>[decaying-page.tsx]"]
  node_decay_core{{"Decay engine<br/>decay subsystem<br/>[decay-engine.ts]"}}
  node_game_store(("Game store<br/>client state<br/>[game-store.ts]"))
  node_multi_store(("Multiplayer store<br/>client state"))
  node_content_layer["Content layer<br/>content selection<br/>[content-cache.ts]"]
  node_leaderboard_ui["Leaderboard UI<br/>ui components"]
  node_multiplayer_ui["Match UI<br/>multiplayer ui<br/>[room-lobby.tsx]"]
end

subgraph group_backend["Backend system"]
  node_backend_core[("Convex backend<br/>realtime backend<br/>[schema.ts]")]
  node_backend_auth["Auth config<br/>clerk auth<br/>[auth.config.ts]"]
  node_game_data[("Game data<br/>domain modules<br/>[pages.ts]")]
  node_multiplayer_data[("Multiplayer state<br/>room state<br/>[multiplayer.ts]")]
  node_leaderboard_data[("Leaderboard data<br/>ranking store<br/>[leaderboard.ts]")]
end

subgraph group_ingest["Ingestion pipeline"]
  node_ingest_pipeline["Ingest pipeline<br/>python pipeline<br/>[cli.py]"]
end

subgraph group_shared["Shared packages"]
  node_shared_config["TS config<br/>workspace config<br/>[tsconfig.base.json]"]
  node_shared_env["Env config<br/>env validation<br/>[web.ts]"]
end

node_nextjs_runtime{{"Next.js<br/>runtime"}}
node_anthropic{{"Anthropic Claude<br/>external ai"}}
node_clerk{{"Clerk<br/>external auth"}}
node_convex_service[("Convex<br/>external backend")]

node_nextjs_runtime -->|"hosts"| node_web_shell
node_nextjs_runtime -->|"executes"| node_content_api
node_web_shell -->|"renders"| node_landing_route
node_web_shell -->|"renders"| node_tutorial_route
node_web_shell -->|"renders"| node_solo_route
node_web_shell -->|"renders"| node_multiplayer_route
node_web_shell -->|"renders"| node_leaderboard_route
node_web_shell -->|"protects"| node_auth_routes
node_solo_route -->|"uses"| node_game_shell
node_multiplayer_route -->|"uses"| node_multiplayer_ui
node_game_shell -->|"applies"| node_decay_core
node_game_shell -->|"reads/writes"| node_game_store
node_multiplayer_ui -->|"reads/writes"| node_multi_store
node_game_shell -->|"loads"| node_content_layer
node_content_layer -->|"queries"| node_backend_core
node_content_layer -->|"syncs"| node_convex_service
node_content_api -->|"calls"| node_anthropic
node_content_api -->|"writes"| node_backend_core
node_backend_core -->|"authenticates"| node_backend_auth
node_backend_core -->|"stores"| node_game_data
node_backend_core -->|"syncs"| node_multiplayer_data
node_backend_core -->|"aggregates"| node_leaderboard_data
node_leaderboard_route -->|"renders"| node_leaderboard_ui
node_leaderboard_ui -->|"queries"| node_backend_core
node_multiplayer_ui -->|"syncs"| node_backend_core
node_ingest_pipeline -->|"uses"| node_anthropic
node_ingest_pipeline -->|"uploads"| node_backend_core
node_shared_config -->|"supports"| node_web_shell
node_shared_env -->|"validates"| node_web_shell

click node_web_shell "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/layout.tsx"
click node_landing_route "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/page.tsx"
click node_tutorial_route "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/how-to-play/page.tsx"
click node_solo_route "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/play/page.tsx"
click node_multiplayer_route "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/multiplayer/page.tsx"
click node_auth_routes "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/sign-in/[[...sign-in]]/page.tsx"
click node_leaderboard_route "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/leaderboard/page.tsx"
click node_content_api "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/api/generate-content/route.ts"
click node_game_shell "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/components/game/decaying-page.tsx"
click node_decay_core "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/lib/decay/decay-engine.ts"
click node_game_store "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/store/game-store.ts"
click node_multi_store "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/store/multiplayer-store.ts"
click node_content_layer "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/lib/content/content-cache.ts"
click node_leaderboard_ui "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/components/leaderboard/leaderboard-table.tsx"
click node_multiplayer_ui "https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/components/game/multiplayer/room-lobby.tsx"
click node_backend_core "https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/schema.ts"
click node_backend_auth "https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/auth.config.ts"
click node_game_data "https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/pages.ts"
click node_multiplayer_data "https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/multiplayer.ts"
click node_leaderboard_data "https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/leaderboard.ts"
click node_ingest_pipeline "https://github.com/abdalla-eldoumani/dust/blob/main/dust_ingest/cli.py"
click node_shared_config "https://github.com/abdalla-eldoumani/dust/blob/main/packages/config/tsconfig.base.json"
click node_shared_env "https://github.com/abdalla-eldoumani/dust/blob/main/packages/env/src/web.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_web_shell,node_landing_route,node_tutorial_route,node_solo_route,node_multiplayer_route,node_auth_routes,node_leaderboard_route,node_content_api,node_game_shell,node_decay_core,node_game_store,node_multi_store,node_content_layer,node_leaderboard_ui,node_multiplayer_ui toneBlue
class node_backend_core,node_backend_auth,node_game_data,node_multiplayer_data,node_leaderboard_data toneAmber
class node_ingest_pipeline toneMint
class node_shared_config,node_shared_env toneRose
class node_nextjs_runtime,node_anthropic,node_clerk,node_convex_service toneNeutral
```

## Components

### Frontend app

Next.js user-facing experience and client-side game loop

- [App shell](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/layout.tsx): nextjs app · Top-level Next.js layout, middleware, and providers for the UI shell · `apps/web/src/app/layout.tsx`
- [Landing](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/page.tsx): route · Public entry page for the game · `apps/web/src/app/page.tsx`
- [How to play](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/how-to-play/page.tsx): route · Tutorial and onboarding content · `apps/web/src/app/how-to-play/page.tsx`
- [Solo play](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/play/page.tsx): route · Single-player game entry and play surface · `apps/web/src/app/play/page.tsx`
- [Multiplayer](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/multiplayer/page.tsx): route · Multiplayer lobby and room entry routes · `apps/web/src/app/multiplayer/page.tsx`
- [Auth pages](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/sign-in/[[...sign-in]]/page.tsx): route group · Clerk sign-in and sign-up routes · `apps/web/src/app/sign-in/[[...sign-in]]/page.tsx`
- [Leaderboard](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/leaderboard/page.tsx): route · Ranked results view for players and sessions · `apps/web/src/app/leaderboard/page.tsx`
- [Generate API](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/app/api/generate-content/route.ts): next api · Server route for AI-assisted content generation · `apps/web/src/app/api/generate-content/route.ts`
- [Game UI](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/components/game/decaying-page.tsx): client game shell · Core game loop UI, decay presentation, scoring, and tools · `apps/web/src/components/game/decaying-page.tsx`
- [Decay engine](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/lib/decay/decay-engine.ts): decay subsystem · Orchestrates text, layout, color, and image degradation · `apps/web/src/lib/decay/decay-engine.ts`
- [Game store](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/store/game-store.ts): client state · Client session state for solo gameplay · `apps/web/src/store/game-store.ts`
- [Multiplayer store](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/store/multiplayer-store.ts): client state · Client room and match state for multiplayer UX · `apps/web/src/store/multiplayer-store.ts`
- [Content layer](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/lib/content/content-cache.ts): content selection · Caching, difficulty, demo content, and Convex-backed content selection · `apps/web/src/lib/content/content-cache.ts`
- [Leaderboard UI](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/components/leaderboard/leaderboard-table.tsx): ui components · Ranked table and user rank presentation · `apps/web/src/components/leaderboard/leaderboard-table.tsx`
- [Match UI](https://github.com/abdalla-eldoumani/dust/blob/main/apps/web/src/components/game/multiplayer/room-lobby.tsx): multiplayer ui · Lobby, waiting, round results, and match results screens · `apps/web/src/components/game/multiplayer/room-lobby.tsx`

### Backend system

Convex persistent data model, realtime state, and auth-bound operations

- [Convex backend](https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/schema.ts): realtime backend · Persistent system of record for users, content, sessions, and multiplayer · `packages/backend/convex/schema.ts`
- [Auth config](https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/auth.config.ts): clerk auth · Convex authentication boundary configured for Clerk JWTs · `packages/backend/convex/auth.config.ts`
- [Game data](https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/pages.ts): domain modules · Pages, variants, cached content, levels, archives, sessions, and leaderboard tables · `packages/backend/convex/pages.ts`
- [Multiplayer state](https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/multiplayer.ts): room state · Realtime room lifecycle and match synchronization · `packages/backend/convex/multiplayer.ts`
- [Leaderboard data](https://github.com/abdalla-eldoumani/dust/blob/main/packages/backend/convex/leaderboard.ts): ranking store · Authoritative score storage and leaderboard queries · `packages/backend/convex/leaderboard.ts`

### Ingestion pipeline

Python content sourcing and preparation flow

- [Ingest pipeline](https://github.com/abdalla-eldoumani/dust/blob/main/dust_ingest/cli.py): python pipeline · Scrape, sanitize, normalize, level, alter, and upload content · `dust_ingest/cli.py`

### Shared packages

Workspace-wide config and environment validation

- [TS config](https://github.com/abdalla-eldoumani/dust/blob/main/packages/config/tsconfig.base.json): workspace config · Shared TypeScript configuration for packages and apps · `packages/config/tsconfig.base.json`
- [Env config](https://github.com/abdalla-eldoumani/dust/blob/main/packages/env/src/web.ts): env validation · Centralized runtime environment validation · `packages/env/src/web.ts`

### Other components

- **Next.js**: runtime · Frontend runtime and API execution environment
- **Anthropic Claude**: external ai · Model provider used for content generation and alteration
- **Clerk**: external auth · Identity provider for sign-in, sign-up, and user sessions
- **Convex**: external backend · Realtime database and serverless backend platform

## Connections

- Next.js → App shell: hosts · Next.js serves the app shell and routes
- Next.js → Generate API: executes · API route runs in the Next.js runtime
- App shell → Landing: renders · Shell composes public landing experience
- App shell → How to play: renders · Shell composes tutorial route
- App shell → Solo play: renders · Shell composes solo play route
- App shell → Multiplayer: renders · Shell composes multiplayer routes
- App shell → Leaderboard: renders · Shell composes leaderboard route
- App shell → Auth pages: protects · Middleware and providers support auth pages
- Solo play → Game UI: uses · Solo play mounts the core game UI
- Multiplayer → Match UI: uses · Multiplayer routes mount match and lobby UI
- Game UI → Decay engine: applies · Core gameplay uses degradation engine
- Game UI → Game store: reads/writes · Solo game state lives in client store
- Match UI → Multiplayer store: reads/writes · Multiplayer UX is driven by client room state
- Game UI → Content layer: loads · Game loop selects round content from content layer
- Content layer → Convex backend: queries · Content can come from Convex-backed sources
- Content layer → Convex: syncs · Backend adapter connects content selection to Convex
- Generate API → Anthropic Claude: calls · Server route invokes Claude for generation
- Generate API → Convex backend: writes · Generated content is persisted through backend
- Convex backend → Auth config: authenticates · Convex uses Clerk identity for access control
- Convex backend → Game data: stores · Domain modules persist pages, variants, archives, and sessions
- Convex backend → Multiplayer state: syncs · Realtime room state is owned by Convex
- Convex backend → Leaderboard data: aggregates · Ranking data is computed from backend scores
- Leaderboard → Leaderboard UI: renders · Leaderboard page uses ranked table components
- Leaderboard UI → Convex backend: queries · Leaderboard view reads realtime backend data
- Match UI → Convex backend: syncs · Lobby and match flow use Convex realtime state
- Ingest pipeline → Anthropic Claude: uses · Pipeline can alter or generate content with LLMs
- Ingest pipeline → Convex backend: uploads · Prepared content is uploaded into Convex
- TS config → App shell: supports · Shared TS settings keep frontend packages aligned
- Env config → App shell: validates · Frontend runtime env is centrally validated
