# EatMe — Docházka Evidence docházky pro bistro EatMe. Zaměstnanci se přihlašují Google účtem a logují příchod / odchod / start a konec pauzy; admin (majitel) spravuje seznam zaměstnanců (jen e-mail, žádná hesla) a vidí souhrnné i individuální statistiky s grafem a exportem do CSV. ``` backend/ Express + TypeScript API, SQLite (better-sqlite3) frontend/ React + TypeScript PWA (Vite), Google Sign-In, Zustand docs/ OKF (Open Knowledge Format) — architektura, datový model, provoz branding/ Logo a vygenerované favicony/PWA ikony z podkladu bistra deploy/ Šablony configů pro hosty mimo tento repo (nginx server block) Dockerfile Multi-stage build — jeden image pro API i frontend compose.yaml Produkční nasazení hotového image (viz Produkce níž) ``` Vzhled je podle `~/doc/concepts/ui/light-mono-tui.md` — světlý monochromní "TUI" styl (mono font, ostré hrany, žádné barvy, inverze pro aktivní stav). ## Požadavky - Node.js 22+ - Google Cloud projekt s nakonfigurovaným OAuth Client ID (Web application) — origins musí obsahovat `http://localhost:5174` pro vývoj a produkční doménu. Client ID se nastavuje do `GOOGLE_CLIENT_ID` (backend) a `VITE_GOOGLE_CLIENT_ID` (frontend) — musí být **stejné**. ## Vývoj ```bash # backend cd backend cp .env.example .env # doplň GOOGLE_CLIENT_ID, ADMIN_EMAILS, JWT_SECRET npm install npm run dev # http://localhost:4000 # frontend (v druhém terminálu) cd frontend cp .env.example .env # VITE_GOOGLE_CLIENT_ID stejné jako backend npm install npm run dev # http://localhost:5174 (port je pinnutý — musí sedět s Google origin) ``` Frontend v dev módu proxuje `/api/*` na backend (viz `frontend/vite.config.ts`). ### Typecheck / build ```bash cd backend && npm run typecheck && npm run build # -> dist/index.js (esbuild bundle) cd frontend && npm run build # -> dist/ (Vite, PWA) ``` ## Produkce (Docker) Jeden multi-stage `Dockerfile` v rootu postaví frontend i backend a spustí je jako jeden kontejner — backend servíruje API na `/api/*` a staticky sbalený frontend na všem ostatním. Image se buildí lokálně (pro platformu cílového serveru) a na server se posílá hotový, ne zdrojáky: ```bash # buildni pro platformu serveru (na Apple Silicon Macu proti x86_64 serveru # je --platform linux/amd64 povinné, jinak image tam vůbec nenaběhne) docker build --platform linux/amd64 \ --build-arg VITE_GOOGLE_CLIENT_ID= \ -t eatme:latest . # přenes hotový image přes ssh (žádný build na serveru) docker save eatme:latest | gzip | ssh "gunzip | docker load" # pošli jen compose.yaml + .env (viz .env.example) a nastartuj scp compose.yaml :~/eatme/compose.yaml ssh "cd ~/eatme && docker compose up -d" ``` `VITE_GOOGLE_CLIENT_ID` musí jít jako **build arg** (Vite ho zapéká při buildu, ne za běhu — v `.env` na serveru se proto řeší jen runtime proměnné). Pojmenovaný volume `eatme_data` (viz `compose.yaml`) drží SQLite databázi mimo kontejner, ať přežije redeploy. Před kontejner patří TLS-terminující reverse proxy (mimo tento repo) — šablona server blocku pro nginx je v `deploy/eatme.mipem.co`, proxuje na `http://:8092`. ## Datový model / provoz Zaměstnanci jsou whitelist e-mailů spravovaný adminem (`ADMIN_EMAILS` v env — samostatná role, není v tabulce zaměstnanců). Odebrání zaměstnance je pouze soft-delete (`active = 0`) — historie docházky zůstává, opětovným přidáním stejného e-mailu se účet reaktivuje. Statistiky se počítají po kalendářních měsících (`?month=YYYY-MM`), s možností listovat měsíci v adminově detailu zaměstnance (graf + export CSV). Víc v `docs/` (OKF bundle).