# vivaanhooda/digital-treasure-hunt architecture

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

- Interactive diagram: https://gitdiagram.com/vivaanhooda/digital-treasure-hunt
- Repository: https://github.com/vivaanhooda/digital-treasure-hunt

## Overview

Digital Treasure Hunt is a server-authoritative campus game: teams register, receive a frozen randomized challenge order, visit locations, and submit GPS for server verification and scoring before seeing live standings. Admins configure datasets and game operations, while teams receive game state, notifications, and leaderboard updates through APIs and SSE. The README documents the major capabilities; sampled route handlers confirm registration, leaderboard, streaming, notifications, and upload flows. Other admin branches are represented by their exact enclosing route directories because their implementations were not sampled.

Main entry points: [`src/app/api/game`](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/game) (Game endpoints), [`src/app/api/leaderboard`](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/leaderboard) (Leaderboard endpoints), [`src/lib/session.ts`](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/session.ts) (Request authorization), [`src/app/api/register/route.ts`](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/register/route.ts) (Team registration)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_play["Team gameplay"]
  node_register_ui["Registration UI<br/>[page.tsx]"]
  node_register_api["Team registration<br/>[route.ts]"]
  node_game_ui["Game screen<br/>[page.tsx]"]
  node_game_hook["Game client hook<br/>[useGame.ts]"]
  node_game_api["Game endpoints"]
  node_leaderboard_ui["Leaderboard screen<br/>[page.tsx]"]
  node_leaderboard_api["Leaderboard endpoints"]
end

subgraph group_identity["Identity and live updates"]
  node_auth_ui["Login UI<br/>[page.tsx]"]
  node_auth_api["Auth endpoints"]
  node_stream_api["SSE stream<br/>[route.ts]"]
  node_stream_client["Event stream client<br/>[useEventStream.ts]"]
  node_notification_api["Notification endpoints"]
end

subgraph group_operations["Admin operations"]
  node_admin_ui["Admin console"]
  node_dataset_ui["Dataset manager"]
  node_dataset_api["Dataset endpoints"]
  node_admin_api["Game and archive admin"]
  node_upload_api["Image upload<br/>[route.ts]"]
  node_upload_serve["Uploaded image serving<br/>[route.ts]"]
end

subgraph group_core["Server services"]
  node_game_logic["Game rules<br/>[game.ts]"]
  node_geo["GPS distance<br/>[geo.ts]"]
  node_leaderboard_logic["Standings<br/>[leaderboard.ts]"]
  node_auth_logic["Auth and sessions<br/>[auth.ts]"]
  node_session["Request authorization<br/>[session.ts]"]
  node_notification_logic["Notifications<br/>[notifications.ts]"]
  node_upload_store["Upload handling<br/>[uploads.ts]"]
  node_datasets["Dataset services<br/>[datasets.ts]"]
end

subgraph group_infra["External infrastructure"]
  node_db[("PostgreSQL")]
  node_redis[("Redis")]
end

node_team(("Team"))
node_browser(("Team browser"))
node_admin(("Administrator"))

node_team -->|"registers"| node_register_ui
node_register_ui -->|"submits"| node_register_api
node_register_api -->|"creates team and game state"| node_db
node_register_api -->|"shuffles challenges"| node_game_logic
node_team -->|"plays"| node_game_ui
node_game_ui -->|"uses"| node_game_hook
node_game_hook -->|"fetches and submits"| node_game_api
node_game_api -->|"authorizes"| node_session
node_game_api -->|"applies rules"| node_game_logic
node_game_api -->|"checks location"| node_geo
node_game_api -->|"reads and updates progress"| node_db
node_game_api -->|"rate limits and publishes"| node_redis
node_team -->|"views standings"| node_leaderboard_ui
node_leaderboard_ui -->|"requests"| node_leaderboard_api
node_leaderboard_api -->|"authorizes"| node_session
node_leaderboard_api -->|"gets standings"| node_leaderboard_logic
node_leaderboard_api -->|"reads own game state"| node_db
node_leaderboard_api -->|"caches standings"| node_redis
node_leaderboard_logic -->|"reads scores"| node_db
node_team -->|"signs in"| node_auth_ui
node_auth_ui -->|"authenticates"| node_auth_api
node_auth_api -->|"delegates sign-in"| node_auth_logic
node_auth_logic -->|"checks accounts"| node_db
node_auth_logic -->|"tracks sessions"| node_redis
node_game_ui -->|"subscribes"| node_stream_client
node_stream_client -->|"opens SSE"| node_stream_api
node_stream_api -->|"requires user"| node_session
node_stream_api -->|"subscribes channels"| node_redis
node_team -->|"views notifications"| node_notification_api
node_notification_api -->|"authorizes"| node_session
node_notification_api -->|"loads notifications"| node_notification_logic
node_notification_logic -->|"reads notifications"| node_db
node_admin -->|"manages game"| node_admin_ui
node_admin_ui -->|"manages datasets"| node_dataset_ui
node_dataset_ui -->|"requests changes"| node_dataset_api
node_dataset_api -->|"delegates dataset work"| node_datasets
node_datasets -->|"reads and writes datasets"| node_db
node_admin_ui -->|"configures operations"| node_admin_api
node_admin_api -->|"manages game and archive data"| node_db
node_admin_api -->|"publishes updates"| node_redis
node_dataset_ui -->|"uploads images"| node_upload_api
node_upload_api -->|"checks dataset lock"| node_datasets
node_upload_api -->|"saves file"| node_upload_store
node_upload_store -.->|"serves stored images"| node_upload_serve
node_upload_serve -->|"returns image"| node_browser

click node_register_ui "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/(auth)/register/page.tsx"
click node_register_api "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/register/route.ts"
click node_game_ui "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/game/page.tsx"
click node_game_hook "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/hooks/useGame.ts"
click node_game_api "https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/game"
click node_game_logic "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/game.ts"
click node_geo "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/geo.ts"
click node_leaderboard_ui "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/leaderboard/page.tsx"
click node_leaderboard_api "https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/leaderboard"
click node_leaderboard_logic "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/leaderboard.ts"
click node_auth_ui "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/(auth)/login/page.tsx"
click node_auth_api "https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/auth"
click node_auth_logic "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/auth.ts"
click node_session "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/session.ts"
click node_stream_api "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/stream/route.ts"
click node_stream_client "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/hooks/useEventStream.ts"
click node_notification_api "https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/notifications"
click node_notification_logic "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/notifications.ts"
click node_admin_ui "https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/admin"
click node_dataset_ui "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/components/admin/DatasetsManager.tsx"
click node_dataset_api "https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/admin/datasets"
click node_admin_api "https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/admin"
click node_upload_api "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/admin/upload/route.ts"
click node_upload_store "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/uploads.ts"
click node_upload_serve "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/uploads/%5B...path%5D/route.ts"
click node_datasets "https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/datasets.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_register_ui,node_register_api,node_game_ui,node_game_hook,node_game_api,node_leaderboard_ui,node_leaderboard_api,node_browser toneBlue
class node_auth_ui,node_auth_api,node_stream_api,node_stream_client,node_notification_api toneAmber
class node_admin_ui,node_dataset_ui,node_dataset_api,node_admin_api,node_upload_api,node_upload_serve toneMint
class node_game_logic,node_geo,node_leaderboard_logic,node_auth_logic,node_session,node_notification_logic,node_upload_store,node_datasets toneRose
class node_db,node_redis,node_team,node_admin toneIndigo
```

## Components

### Team gameplay

- [Registration UI](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/(auth)/register/page.tsx): `src/app/(auth)/register/page.tsx`
- [Team registration](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/register/route.ts): `src/app/api/register/route.ts`
- [Game screen](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/game/page.tsx): `src/app/game/page.tsx`
- [Game client hook](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/hooks/useGame.ts): `src/hooks/useGame.ts`
- [Game endpoints](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/game): `src/app/api/game`
- [Leaderboard screen](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/leaderboard/page.tsx): `src/app/leaderboard/page.tsx`
- [Leaderboard endpoints](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/leaderboard): `src/app/api/leaderboard`

### Identity and live updates

- [Login UI](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/(auth)/login/page.tsx): `src/app/(auth)/login/page.tsx`
- [Auth endpoints](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/auth): `src/app/api/auth`
- [SSE stream](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/stream/route.ts): `src/app/api/stream/route.ts`
- [Event stream client](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/hooks/useEventStream.ts): `src/hooks/useEventStream.ts`
- [Notification endpoints](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/notifications): `src/app/api/notifications`

### Admin operations

- [Admin console](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/admin): `src/app/admin`
- [Dataset manager](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/components/admin/DatasetsManager.tsx): `src/components/admin/DatasetsManager.tsx`
- [Dataset endpoints](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/admin/datasets): `src/app/api/admin/datasets`
- [Game and archive admin](https://github.com/vivaanhooda/digital-treasure-hunt/tree/main/src/app/api/admin): `src/app/api/admin`
- [Image upload](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/admin/upload/route.ts): `src/app/api/admin/upload/route.ts`
- [Uploaded image serving](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/app/api/uploads/%5B...path%5D/route.ts): `src/app/api/uploads/[...path]/route.ts`

### Server services

- [Game rules](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/game.ts): `src/lib/game.ts`
- [GPS distance](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/geo.ts): `src/lib/geo.ts`
- [Standings](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/leaderboard.ts): `src/lib/leaderboard.ts`
- [Auth and sessions](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/auth.ts): `src/auth.ts`
- [Request authorization](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/session.ts): `src/lib/session.ts`
- [Notifications](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/notifications.ts): `src/lib/notifications.ts`
- [Upload handling](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/uploads.ts): `src/lib/uploads.ts`
- [Dataset services](https://github.com/vivaanhooda/digital-treasure-hunt/blob/main/src/lib/datasets.ts): `src/lib/datasets.ts`

### External infrastructure

- **PostgreSQL**
- **Redis**

### Other components

- **Team**
- **Team browser**
- **Administrator**

## Connections

- Team → Registration UI: registers
- Registration UI → Team registration: submits
- Team registration → PostgreSQL: creates team and game state
- Team registration → Game rules: shuffles challenges
- Team → Game screen: plays
- Game screen → Game client hook: uses
- Game client hook → Game endpoints: fetches and submits
- Game endpoints → Request authorization: authorizes
- Game endpoints → Game rules: applies rules
- Game endpoints → GPS distance: checks location
- Game endpoints → PostgreSQL: reads and updates progress
- Game endpoints → Redis: rate limits and publishes
- Team → Leaderboard screen: views standings
- Leaderboard screen → Leaderboard endpoints: requests
- Leaderboard endpoints → Request authorization: authorizes
- Leaderboard endpoints → Standings: gets standings
- Leaderboard endpoints → PostgreSQL: reads own game state
- Leaderboard endpoints → Redis: caches standings
- Standings → PostgreSQL: reads scores
- Team → Login UI: signs in
- Login UI → Auth endpoints: authenticates
- Auth endpoints → Auth and sessions: delegates sign-in
- Auth and sessions → PostgreSQL: checks accounts
- Auth and sessions → Redis: tracks sessions
- Game screen → Event stream client: subscribes
- Event stream client → SSE stream: opens SSE
- SSE stream → Request authorization: requires user
- SSE stream → Redis: subscribes channels
- Team → Notification endpoints: views notifications
- Notification endpoints → Request authorization: authorizes
- Notification endpoints → Notifications: loads notifications
- Notifications → PostgreSQL: reads notifications
- Administrator → Admin console: manages game
- Admin console → Dataset manager: manages datasets
- Dataset manager → Dataset endpoints: requests changes
- Dataset endpoints → Dataset services: delegates dataset work
- Dataset services → PostgreSQL: reads and writes datasets
- Admin console → Game and archive admin: configures operations
- Game and archive admin → PostgreSQL: manages game and archive data
- Game and archive admin → Redis: publishes updates
- Dataset manager → Image upload: uploads images
- Image upload → Dataset services: checks dataset lock
- Image upload → Upload handling: saves file
- Upload handling → Uploaded image serving: serves stored images
- Uploaded image serving → Team browser: returns image
