# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Luncher is a lunch management app for teams — daily restaurant menus, food ordering, pizza day events, and payment QR codes. Czech-language UI. Full-stack TypeScript monorepo.

## Monorepo Structure

```
types/    → Shared OpenAPI-generated TypeScript types (source of truth: types/api.yml)
server/   → Express 5 backend (Node.js 22, ts-node)
client/   → React 19 frontend (Vite 7, React Bootstrap)
e2e/      → Playwright E2E tests (separate package)
```

Each of the four directories has its own `package.json`. Package manager: **Yarn Classic**.

Deployment files at repo root: `Dockerfile` (multi-stage, dva runner targety: výchozí `runner` pro lokální build, `runner-prebuilt` pro CI s předem sestavenými artefakty), `compose.yml`, `compose-traefik.yml`.

## Development Commands

### Initial setup
```bash
cd types && yarn install && yarn openapi-ts   # Generate API types first
cd ../server && yarn install
cd ../client && yarn install
cd ../e2e && yarn install
```

### Running dev environment
```bash
# All-in-one (tmux):
./run_dev.sh

# Or manually in separate terminals:
cd server && NODE_ENV=development yarn startReload   # Port 3001, nodemon watch
cd client && yarn start                               # Port 3000, proxies /api → 3001
```

### Building
```bash
cd types && yarn openapi-ts      # Regenerate types from api.yml
cd server && yarn build          # tsc → server/dist
cd client && yarn build          # tsc --noEmit + vite build → client/dist
```

### Tests
```bash
# Server unit tests (Jest)
cd server && yarn test                  # All tests in server/src/tests/
cd server && yarn test dates            # Run one file by name
cd server && yarn test -t "name"        # Run by test name pattern

# E2E (Playwright) — requires prebuilt server
cd server && yarn build
cd e2e && yarn test                     # chromium + firefox, baseURL 127.0.0.1:3001
cd e2e && yarn test:ui                  # interactive UI mode
cd e2e && yarn report                   # open last HTML report
```

Jest setup (`server/src/tests/setupEnv.ts`) forces `STORAGE=memory`, deletes `MOCK_DATA`, and sets a fixed `JWT_SECRET`. Playwright auto-starts the prebuilt server and authenticates via the `remote-user: e2e-user` trusted-header path; locally uses `STORAGE=json` + `MOCK_DATA=true`, CI uses `STORAGE=redis`.

### CI pipeline
Gitea Actions — `.gitea/workflows/ci.yaml` (no `.github/` equivalent):

1. `generate-types` — runs `yarn openapi-ts`, uploads artifact
2. `server-test` — Jest
3. `server-build` + `client-build` — parallel tsc/vite builds
4. `e2e` — Playwright in `mcr.microsoft.com/playwright:v1.59.1-jammy` with a Redis service container; only Firefox installed in CI
5. `docker-build` — master branch only, uses `Dockerfile` with `--target runner-prebuilt` (skládá image z artefaktů `server-build` + `client-build`)
6. `notify` — Discord + ntfy webhooks

### Formatting
Prettier is installed in `client/` (devDependency only, no script or config) — invoke via `yarn prettier <path>` with defaults.

## Architecture

### API Types (types/)
- OpenAPI 3.0 spec in `types/api.yml` — all API endpoints and DTOs defined here
- `api.yml` is a thin aggregator — actual endpoint specs live in `types/paths/<domain>/*.yml`, shared schemas in `types/schemas/_index.yml`
- `yarn openapi-ts` generates `types/gen/` (client.gen.ts, sdk.gen.ts, types.gen.ts)
- Both server and client import from these generated types
- **When changing API contracts: update api.yml first, then regenerate**

### Server (server/src/)
- **Entry:** `index.ts` — Express app + Socket.io setup
- **Routes:** `routes/` — 9 modular Express route handlers (food, pizzaDay, voting, notifications, qr, stats, easterEgg, dev, changelog)
- **Services:** domain logic files at root level (`service.ts`, `pizza.ts`, `restaurants.ts`, `chefie.ts`, `voting.ts`, `stats.ts`, `qr.ts`, `notifikace.ts`)
- **Helpers:** `mock.ts` (fake menu data for `MOCK_DATA=true`), `pushReminder.ts` (push notification reminders), `utils.ts` (shared utilities)
- **Auth:** `auth.ts` — JWT + optional trusted-header authentication
- **Storage:** `storage/index.ts` factory selects implementation; backends: `json.ts` (file-based, dev), `redis.ts` (production), `memory.ts` (tests). Data keyed by date (YYYY-MM-DD).
- **Restaurant scrapers:** Cheerio-based HTML parsing for daily menus from multiple restaurants
- **Pizza Chefie integration:** `chefie.ts` scrapes pizzachefie.cz for Pizza day menus and salads (only active when a Pizza day is open)
- **WebSocket:** `websocket.ts` — Socket.io for real-time client updates
- **Mock mode:** `MOCK_DATA=true` env var returns fake menus (useful for weekend/holiday dev)
- **Config:** `.env.development` / `.env.production` (see `.env.template` for all options)

### Client (client/src/)
- **Entry:** `index.tsx` → `App.tsx` → `AppRoutes.tsx`; `Login.tsx` is the auth screen; `FallingLeaves.tsx` is a seasonal visual effect
- **Pages:** `pages/` (StatsPage)
- **Components:** `components/` (Header, Footer, Loader, PizzaOrderList, PizzaOrderRow, and modals in `components/modals/`)
- **Context providers:** `context/` — `auth.tsx`, `settings.tsx`, `socket.js`, `eggs.tsx` (note: `socket.js` is the only non-TSX context file)
- **Hooks:** `hooks/` (`usePushReminder.ts`)
- **Utils:** `utils/` (`parsePrice.ts`)
- **Styling:** Bootstrap 5 + React Bootstrap + custom SCSS files (co-located with components)
- **API calls:** use OpenAPI-generated SDK from `types/gen/`
- **Routing:** React Router DOM v7

### Data Flow
1. Client calls API via generated SDK → Express routes
2. Server scrapes restaurant websites or returns cached data
3. Storage: Redis (production) or JSON file (development)
4. Socket.io broadcasts changes to all connected clients

## Environment

- **Server env files:** `server/.env.development`, `server/.env.production` (see `server/.env.template`)
- Key vars: `JWT_SECRET`, `STORAGE` (json/redis/memory), `MOCK_DATA`, `REDIS_HOST`, `REDIS_PORT`
- **Docker:** multi-stage Dockerfile, `compose.yml` for app + Redis. Timezone: Europe/Prague.

## Conventions

- Czech naming for domain variables and UI strings; English for infrastructure code
- TypeScript strict mode in both client and server
- Server module resolution: Node16; Client: ESNext/bundler
- `TODO.md` tracks open bugs and roadmap items — worth scanning before starting non-trivial work
