4.6 KiB
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)
Each directory has its own package.json and tsconfig.json. Package manager: Yarn Classic.
Development Commands
Initial setup
cd types && yarn install && yarn openapi-ts # Generate API types first
cd ../server && yarn install
cd ../client && yarn install
Running dev environment
# 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
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
cd server && yarn test # Jest (tests in server/src/tests/)
Formatting
# Prettier available in client (no config file — uses defaults)
Architecture
API Types (types/)
- OpenAPI 3.0 spec in
types/api.yml— all API endpoints and DTOs defined here yarn openapi-tsgeneratestypes/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/— modular Express route handlers (food, pizzaDay, voting, notifications, qr, stats, easterEgg, dev) - Services: domain logic files at root level (
service.ts,pizza.ts,restaurants.ts,chefie.ts,voting.ts,stats.ts,qr.ts,notifikace.ts) - Auth:
auth.ts— JWT + optional trusted-header authentication - Storage:
storage/StorageInterface.tsdefines the interface; implementations instorage/json.ts(file-based, dev) andstorage/redis.ts(production). Data keyed by date (YYYY-MM-DD). - Restaurant scrapers: Cheerio-based HTML parsing for daily menus from multiple restaurants
- WebSocket:
websocket.ts— Socket.io for real-time client updates - Mock mode:
MOCK_DATA=trueenv var returns fake menus (useful for weekend/holiday dev) - Config:
.env.development/.env.production(see.env.templatefor all options)
Client (client/src/)
- Entry:
index.tsx→App.tsx→AppRoutes.tsx - Pages:
pages/(StatsPage) - Components:
components/(Header, Footer, Loader, modals/, PizzaOrderList, PizzaOrderRow) - Context providers:
context/— AuthContext, SettingsContext, SocketContext, EasterEggContext - 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
- Client calls API via generated SDK → Express routes
- Server scrapes restaurant websites or returns cached data
- Storage: Redis (production) or JSON file (development)
- Socket.io broadcasts changes to all connected clients
Environment
- Server env files:
server/.env.development,server/.env.production(seeserver/.env.template) - Key vars:
JWT_SECRET,STORAGE(json/redis),MOCK_DATA,REDIS_HOST,REDIS_PORT - Docker: multi-stage Dockerfile,
compose.ymlfor 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
Code Search Strategy
When searching through the project for information, use the Task tool to spawn subagents. Each subagent should read the relevant files and return a brief summary of what it found (not the full file contents). This keeps the main context window small and saves tokens. Only pull in full file contents once you've identified the specific files that matter. When using subagents to search, each subagent should return:
- File path
- Whether it's relevant (yes/no)
- 1-3 sentence summary of what's in the file Do NOT return full file contents in subagent responses.