Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- [docs] Add `docs/` folder with structured feature and shared infrastructure documentation for AI context (20 files: 1 template, 10 feature docs, 9 shared docs).
- [hitstar] Show current game mode (Classic / Range) as small grey label top-left, only visible during an active game (hidden in the main menu).

### Changed
Expand Down
37 changes: 37 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,43 @@ Feature modules follow NX library pattern with `@backend/` path aliases:
- `/lib/types/` - TypeScript definitions
- `/lib/util/` - Helper functions

## Feature Documentation

Structured docs live in `docs/`. Use these as context when working on or extending a feature.

**Template**: `docs/_template.md`

### Features

| Feature | Doc | Architecture Pattern | Has Backend |
|---------|-----|---------------------|-------------|
| Hitstar | [docs/features/hitstar.md](docs/features/hitstar.md) | Spotify API proxy, state machine, localStorage | Yes |
| Memorandum | [docs/features/memorandum.md](docs/features/memorandum.md) | Keystore-backed bookmarks, per-user identifier | Yes |
| Todo | [docs/features/todo.md](docs/features/todo.md) | 3-tier NX, shared lists, optimistic locking | Yes |
| Jokes | [docs/features/jokes.md](docs/features/jokes.md) | MongoDB CRUD, nightly cron, external API | Yes |
| Admin | [docs/features/admin.md](docs/features/admin.md) | Identity verify, 5 sub-routes, aggregator | Yes |
| Food Scan | [docs/features/food-scan.md](docs/features/food-scan.md) | Stateless OCR proxy, file upload | Yes |
| Settings | [docs/features/settings.md](docs/features/settings.md) | Frontend-only, localStorage stores | No |
| Uno Sort | [docs/features/uno-sort.md](docs/features/uno-sort.md) | Frontend-only card sorting | No |
| Catch-em-all | [docs/features/catch-em-all.md](docs/features/catch-em-all.md) | Stub/placeholder | No |
| About | [docs/features/about.md](docs/features/about.md) | Static page, i18n only | No |

### Shared Infrastructure

| Topic | Doc |
|-------|-----|
| NX library scaffold | [docs/shared/nx-library-scaffold.md](docs/shared/nx-library-scaffold.md) |
| Frontend route pattern | [docs/shared/route-page-pattern.md](docs/shared/route-page-pattern.md) |
| Toggle system | [docs/shared/toggle-system.md](docs/shared/toggle-system.md) |
| Auth guard (`@Public()`) | [docs/shared/auth-guard.md](docs/shared/auth-guard.md) |
| Keystore persistence | [docs/shared/keystore-persistence.md](docs/shared/keystore-persistence.md) |
| Identifiers | [docs/shared/identifiers.md](docs/shared/identifiers.md) |
| i18n system | [docs/shared/i18n.md](docs/shared/i18n.md) |
| Application routes | [docs/shared/application-routes.md](docs/shared/application-routes.md) |
| localStorage stores | [docs/shared/stores.md](docs/shared/stores.md) |

---

## Tech Stack

**Backend**: NestJS 11, Fastify, MongoDB/Mongoose, Socket.io, Swagger/OpenAPI, Pino logging, Prometheus metrics
Expand Down
122 changes: 122 additions & 0 deletions docs/_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Feature Name

> One-liner: What this feature does in one sentence.

## Architecture Pattern

2-3 sentences describing the data flow, persistence strategy, and any external APIs involved.

---

## Backend

**NX Library**: `backend/libs/<name>/`
**Path alias**: `@backend/<name>`

### Module Structure

| File | Purpose |
|------|---------|
| `src/lib/<name>.module.ts` | NestJS module definition |
| `src/lib/<name>.controller.ts` | HTTP endpoints |
| `src/lib/<name>.service.ts` | Business logic |
| `src/lib/<name>-mongodb.service.ts` | MongoDB layer (if applicable) |
| `src/lib/schema/<name>.schema.ts` | Mongoose schema |

### API Endpoints

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | `/v1/<resource>` | Public / Bearer | ... |
| POST | `/v1/<resource>` | Public / Bearer | ... |
| PUT | `/v1/<resource>/:id` | Public / Bearer | ... |
| DELETE | `/v1/<resource>/:id` | Bearer | ... |

### DTOs

- `InputDto` — ...
- `OutputDto` — ...

### Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `VAR_NAME` | Yes | Description |

### Cron Jobs

| Schedule | Timezone | Method | Description |
|----------|----------|--------|-------------|
| `0 3 * * *` | Europe/Berlin | `methodName` | What it does |

---

## Frontend

**Route**: `/feature-name`
**Route files**: `frontend/src/routes/feature-name/`

### Components

| Component | Path | Purpose |
|-----------|------|---------|
| `+page.svelte` | `routes/feature-name/` | Main page |
| `+page.ts` | `routes/feature-name/` | Prerender config + toggle gate |

### API Client

`frontend/src/lib/api/<name>.api.ts`

| Function | Description |
|----------|-------------|
| `getResource()` | ... |
| `createResource()` | ... |

### Types

`frontend/src/lib/types/<name>.dto.ts`

| Type/Interface | Description |
|----------------|-------------|
| `ResourceDto` | ... |

### Stores

`frontend/src/lib/util/stores/store-<name>.ts`

| Store | localStorage key | Description |
|-------|-----------------|-------------|
| `featureStore` | `feature.key` | ... |

### i18n Key Prefix

Keys live under `feature.<sub-key>` in `frontend/src/lib/config/en.json` and `de.json`.

---

## Toggle Configuration

| Property | Value |
|----------|-------|
| Toggle key | `TOGGLE_NAV_FEATURE_NAME` |
| Seed default | `'true'` |
| Frontend enum | `TogglesEnum.featureName` |
| Route config | `applicationRoutes.featureName` |

---

## Shared Infrastructure Dependencies

- [toggle-system.md](../shared/toggle-system.md) — toggle seed + frontend config
- [route-page-pattern.md](../shared/route-page-pattern.md) — `+page.ts` toggle gate
- [auth-guard.md](../shared/auth-guard.md) — `@Public()` decorator + `AdminGuard`
- [i18n.md](../shared/i18n.md) — translation system
- [stores.md](../shared/stores.md) — localStorage store pattern
- [application-routes.md](../shared/application-routes.md) — route registry

---

## Key Implementation Notes

- Note any gotchas, non-obvious design decisions, or patterns specific to this feature.
- Mention if this feature deviates from common patterns.
44 changes: 44 additions & 0 deletions docs/features/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# About

> Static "About me" page — frontend-only, no backend.

## Architecture Pattern

Static page with personal information. No backend API calls, no stores.

---

## Frontend

**Route**: `/about`
**Route files**: `frontend/src/routes/about/+page.svelte`, `+page.ts`

### i18n Key Prefix

Keys under `about.*` in translation files.

---

## Toggle Configuration

| Property | Value |
|----------|-------|
| Toggle key | `TOGGLE_NAV_ABOUT` |
| Seed default | `'true'` |
| Frontend enum | `TogglesEnum.about` |
| Route config | `applicationRoutes.about` |

---

## Shared Infrastructure Dependencies

- [toggle-system.md](../shared/toggle-system.md)
- [route-page-pattern.md](../shared/route-page-pattern.md)
- [i18n.md](../shared/i18n.md)

---

## Key Implementation Notes

- No backend library, no API client, no stores.
- Content is static and localized via i18n keys.
107 changes: 107 additions & 0 deletions docs/features/admin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Admin

> Admin dashboard with 5 sub-routes for managing identifiers, jokes, link presets, toggles, and activities.

## Architecture Pattern

The admin feature has a thin NestJS backend (single `POST /verify` endpoint) and a rich frontend with nested routes. The backend aggregates data from the `IdentifiersService`. Frontend admin pages call the respective resource APIs directly (identifiers, jokes, keystore).

---

## Backend

**NX Library**: `backend/libs/admin/`
**Path alias**: `@backend/admin`

### Module Structure

| File | Purpose |
|------|---------|
| `src/lib/admin.module.ts` | NestJS module |
| `src/lib/admin.controller.ts` | HTTP endpoints |
| `src/lib/admin.service.ts` | Verify admin/user identity |

### API Endpoints

| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/v1/admin/verify` | Public | Verify if ID is admin or registered user |

**Rate limit**: 300 requests per 5 minutes (stricter than default 500).

### `verifyAdmin` Logic

```ts
// type = 'admin' → compare against ADMIN_IDENTIFIER env var
// type = 'user' → check if identifier exists in MongoDB
{ id: string, type: 'admin' | 'user' } → { isVerified: boolean }
```

---

## Frontend

**Route**: `/admin` + sub-routes
**Route files**: `frontend/src/routes/admin/`

### Sub-Routes

| Sub-route | Path | Toggle | Description |
|-----------|------|--------|-------------|
| Activities | `/admin` | `TOGGLE_ADMIN_ACTIVITIES` | Main dashboard / activity log |
| Identifiers | `/admin/identifiers` | `TOGGLE_ADMIN_IDENTIFIERS` | Manage user identifiers |
| Jokes | `/admin/jokes` | `TOGGLE_ADMIN_JOKES` | Manage jokes CRUD |
| Presets | `/admin/presets` | `TOGGLE_ADMIN_LINK_PRESETS` | Manage memorandum link presets |
| Toggles | `/admin/toggles` | — | Manage feature toggles via Keystore |

### Navigation

Sub-routes defined in `adminSubRoutes` in `frontend/src/lib/config/applications.ts`. Note: there is a typo in the code — key is `idenfiers` (missing 't') but it's not user-facing.

### API Clients Used

- `frontend/src/lib/api/admin.api.ts` — verify admin identity
- `frontend/src/lib/api/identifiers.api.ts` — identifiers management
- `frontend/src/lib/api/jokes.api.ts` — jokes management
- `frontend/src/lib/api/keystore.api.ts` — toggle management

### Types

`frontend/src/lib/types/admin.dto.ts`

### i18n Key Prefix

Keys under `admin.*` in translation files.

---

## Toggle Configuration

Admin routes use their own toggles (not a single nav toggle):

| Toggle key | Enum | Controls |
|------------|------|---------|
| `TOGGLE_ADMIN_DASHBOARD` | `TogglesEnum.adminDashboard` | Admin area visibility |
| `TOGGLE_ADMIN_ACTIVITIES` | `TogglesEnum.adminActivities` | Activities tab |
| `TOGGLE_ADMIN_IDENTIFIERS` | `TogglesEnum.adminIdentifiers` | Identifiers tab |
| `TOGGLE_ADMIN_JOKES` | `TogglesEnum.adminJokes` | Jokes tab |
| `TOGGLE_ADMIN_LINK_PRESETS` | `TogglesEnum.adminLinkPreset` | Presets tab |

Admin is accessible via `utilityRoutes.admin` (always shown, no global toggle gate).

---

## Shared Infrastructure Dependencies

- [auth-guard.md](../shared/auth-guard.md) — admin verification + ADMIN_IDENTIFIER
- [identifiers.md](../shared/identifiers.md) — user identity management
- [keystore-persistence.md](../shared/keystore-persistence.md) — toggle management UI
- [toggle-system.md](../shared/toggle-system.md)
- [application-routes.md](../shared/application-routes.md) — adminSubRoutes

---

## Key Implementation Notes

- The admin area is not toggle-gated at the route level (no `+page.ts` toggle redirect). Auth is enforced by the verify flow in the frontend.
- `ADMIN_IDENTIFIER` is the same secret used by `AdminGuard` for Bearer token auth on protected endpoints.
39 changes: 39 additions & 0 deletions docs/features/catch-em-all.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Catch-em-all

> Stub / placeholder — feature not yet implemented.

## Status

This is a placeholder route. The navigation toggle and route entry exist, but the feature has no meaningful functionality.

---

## Frontend

**Route**: `/catch-em-all`
**Route files**: `frontend/src/routes/catch-em-all/+page.svelte`, `+page.ts`

---

## Toggle Configuration

| Property | Value |
|----------|-------|
| Toggle key | `TOGGLE_NAV_CATCH_EM_ALL` |
| Seed default | `'true'` |
| Frontend enum | `TogglesEnum.catchEmAll` |
| Route config | `applicationRoutes['catch-em-all']` |

---

## Backend

**NX Library**: `backend/libs/catch-em-all/` (exists in path aliases but may be minimal)
**Path alias**: `@backend/catch-em-all`

---

## Shared Infrastructure Dependencies

- [toggle-system.md](../shared/toggle-system.md)
- [route-page-pattern.md](../shared/route-page-pattern.md)
Loading
Loading