106 lines
3.9 KiB
Markdown
106 lines
3.9 KiB
Markdown
# Food Tracer
|
||
|
||
Aplikace pro evidenci snědených jídel a útraty za jídlo. Ke každému jídlu se dá
|
||
vedle názvu a zdroje uložit i cena a kalorie, takže jde zpětně zjistit, kolik
|
||
člověk za jídlo utratil za den, měsíc nebo rok.
|
||
|
||
Umí naimportovat měsíční přehled vyexportovaný ze stránky statistik
|
||
[Luncheru](../Luncher) — ve formátu XLSX, CSV i JSON.
|
||
|
||
## Struktura
|
||
|
||
```
|
||
types/ → Sdílené TypeScript typy generované z OpenAPI (zdroj pravdy: types/api.yml)
|
||
server/ → Express 5 backend (Node.js 22, ts-node)
|
||
client/ → React 19 frontend (Vite 7, React Bootstrap)
|
||
```
|
||
|
||
Package manager: **Yarn Classic**. Každá složka má vlastní `package.json`.
|
||
|
||
## Rozjetí
|
||
|
||
```bash
|
||
cd types && yarn install && yarn openapi-ts # typy je nutné vygenerovat první
|
||
cd ../server && yarn install
|
||
cd ../client && yarn install
|
||
```
|
||
|
||
Do `server/.env.development` patří `JWT_SECRET` o délce alespoň 32 znaků
|
||
(šablona je v `server/.env.template`).
|
||
|
||
## Vývoj
|
||
|
||
```bash
|
||
./run_dev.sh # vše naráz v tmuxu (Linux/macOS)
|
||
.\run_dev.ps1 # dvě PowerShell okna (Windows)
|
||
```
|
||
|
||
Nebo ručně ve dvou terminálech:
|
||
|
||
```bash
|
||
cd server && NODE_ENV=development yarn startReload # port 3001
|
||
cd client && yarn start # port 3000, proxy /api → 3001
|
||
```
|
||
|
||
## Testy a build
|
||
|
||
```bash
|
||
cd server && yarn test # Jest, in-memory úložiště
|
||
cd server && yarn build # tsc → server/dist
|
||
cd client && yarn build # tsc --noEmit + vite build → client/dist
|
||
```
|
||
|
||
## Nasazení
|
||
|
||
```bash
|
||
JWT_SECRET=... docker compose up --build
|
||
```
|
||
|
||
Produkčně běží aplikace nad Redisem, ve vývoji nad JSON souborem
|
||
(`server/data/db.json`). Viz `server/.env.template`.
|
||
|
||
## Den: příjem a výdej
|
||
|
||
Přehled dne má dvě záložky:
|
||
|
||
- **Příjem** — co jste snědli, s cenou, gramáží a kaloriemi.
|
||
- **Výdej** — pohyb. Kroky, minuty, kilometry nebo opakování; z množství a
|
||
spotřeby na 100 jednotek se dopočtou spálené kalorie (10 000 kroků ≈ 400 kcal).
|
||
|
||
Opakované tréninky se dají uložit jako **šablonu** — *Workout day 1* pak stačí
|
||
jedním kliknutím založit do dne celý, místo zadávání cviku po cviku. Založené
|
||
položky jsou samostatné, takže je jde doupravit, aniž by se změnila šablona.
|
||
|
||
Nahoře je **bilance dne**: `příjem − (klidový výdej + pohyb)`. Klidový výdej
|
||
(bazální metabolismus) se nastavuje v *Nastavení* — bez něj se porovnává jen
|
||
jídlo proti pohybu a nejde o skutečný deficit, na což aplikace upozorní.
|
||
|
||
## Kalorie a gramáž
|
||
|
||
Ke každému jídlu jde vyplnit **cenu za 100 g** a z ní se dopočítá **gramáž**
|
||
(u TechToweru typicky 44 Kč/100 g). Gramáž jde kdykoli přepsat ručně a každá
|
||
položka má vlastní sazbu — hlavní jídlo a salát s jiným cenováním se nepletou.
|
||
Sazby podniků se nastavují v *Nastavení* a při výběru zdroje se předvyplní.
|
||
|
||
Z gramáže a **energie na 100 g** se pak dopočítají kalorie. Hodnotu nabídne
|
||
tlačítko *Najít kalorie*:
|
||
|
||
- z **vlastní knihovny** — co jste jednou zadali, aplikace si pamatuje pod názvem
|
||
jídla a příště nabídne sama,
|
||
- z **Open Food Facts** (otevřená databáze, bez klíče),
|
||
- odkazem na **KalorickéTabulky.cz**, které veřejné API nemají — otevřou se
|
||
v novém panelu a název jídla se zkopíruje do schránky, hodnotu opíšete ručně.
|
||
|
||
Když je externí databáze nedostupná, hledání nespadne — zůstane vlastní knihovna.
|
||
|
||
## Import z Luncheru
|
||
|
||
Na stránce **Statistiky** je tlačítko *Import z Luncheru*. Stačí nahrát soubor
|
||
stažený ze statistik Luncheru:
|
||
|
||
- Záznamy se rozdělí do dnů, ke kterým patří (export je typicky za celý měsíc).
|
||
- Zakládají se jako **oběd**, protože Luncher řeší výběr obědů. Chod jde při
|
||
importu změnit a jednotlivá jídla pak upravit v přehledu dne.
|
||
- Před uložením se ukáže náhled toho, co se založí.
|
||
- Opakovaný import stejného měsíce data nezduplikuje.
|