chore: graf db
feat: workout plans (volný, fixní, plovoucí)
This commit is contained in:
1 parent
865c2c3b22
commit
7641e26c9f
43 files changed
+3459
-599
No files matched your search
@@ -62,7 +62,8 @@ cd client && yarn build # tsc --noEmit + vite build → client/dist
|
||||
- **Domain:** `meals.ts` (jídlo a historie jídel), `mealGroups.ts` (seznam jídel —
|
||||
skupiny podle názvu a zdroje, doplnění a přejmenování), `mealPhotos.ts` (fotky
|
||||
jídel), `nutrients.ts` (živiny), `mealTemplates.ts` (recepty), `activities.ts` (pohyb), `workouts.ts` (šablony
|
||||
tréninků), `sleep.ts` (spánek), `weights.ts` (vážení po dnech), `profile.ts`
|
||||
tréninků a plány), `workoutSchedule.ts` (co plán navrhuje na den, náhrady
|
||||
vynechaných cviků), `workoutPlans.ts` (záznamy použití šablon), `sleep.ts` (spánek), `weights.ts` (vážení po dnech), `profile.ts`
|
||||
(tělesné údaje a výpočet BMR), `bodyMetrics.ts` (BMI, podíl tuku, cíle),
|
||||
`dayOverview.ts` (spojení dne a bilance), `statsService.ts` (agregace),
|
||||
`luncherImport.ts` (parsování exportů z Luncheru), `settings.ts`, `calories.ts`
|
||||
@@ -76,11 +77,13 @@ cd client && yarn build # tsc --noEmit + vite build → client/dist
|
||||
- **Pages:** `pages/` — `DayPage` (přehled dne se záložkami Příjem/Výdej),
|
||||
`MealGroupsPage` (`/jidla` — seznam jídel podle názvu a zdroje s filtrem zdroje,
|
||||
hromadným doplněním údajů a přejmenováním),
|
||||
`WorkoutsPage` (`/treninky` — šablony tréninků), `ProfilePage` (Profil — ukazatele,
|
||||
`WorkoutsPage` (`/treninky` — plány a šablony tréninků), `ProfilePage` (Profil — ukazatele,
|
||||
vývoj hmotnosti, tělesné údaje, cíle a klidový výdej),
|
||||
`StatsPage` (statistiky se záložkami Příjem / Výdej / Útrata a import; panely
|
||||
`IntakeStatsPanel`, `ActivityStatsPanel`, `SpendingStatsPanel`)
|
||||
- **Components:** `components/` (Header, CalorieLookup, MealSuggestions, NutrientsFieldset)
|
||||
- **Components:** `components/` (Header, CalorieLookup, MealSuggestions, NutrientsFieldset,
|
||||
PlannedWorkoutCard a PendingReplacementsPanel — návrh tréninku a náhrady v přehledu dne,
|
||||
WorkoutTemplateForm/WorkoutTemplateCard — šablony a plány)
|
||||
a `components/modals/` (MealModal, ActivityModal, ApplyWorkoutModal, ApplyMealModal —
|
||||
výběr z historie a receptů, SettingsModal, ImportModal, SpinWheelModal — kolo štěstí)
|
||||
- **Klientské enumy** patří do `enums.ts` jako TypeScript `enum` s mapou popisků,
|
||||
@@ -186,7 +189,7 @@ trénink než 120 v kuse, i když spálené kalorie vyjdou stejně. Jedna série
|
||||
výchozí stav a neukládá se.
|
||||
|
||||
Opačný směr k použití šablony je `createWorkoutTemplateFromActivities` —
|
||||
z aktivit odcvičeného dne (všech, nebo vybraných) vznikne šablona. Záznamy ve dni
|
||||
z aktivit odcvičeného dne (všech, nebo vybraných) vznikne volná šablona. Záznamy ve dni
|
||||
zůstanou beze změny. U jídla nic takového není, opakovaně jedená jídla se nabízejí
|
||||
z historie (viz Historie jídel a recepty).
|
||||
|
||||
@@ -195,17 +198,49 @@ je jen informace o tréninku, kalorie **nemění** — žádný jednoduchý vzor
|
||||
spotřebu podle zátěže nedává, takže by šlo o vymyšlené číslo. Kdo chce, promítne
|
||||
ji do sazby na 100 jednotek.
|
||||
|
||||
`WorkoutTemplate` (`workouts.ts`) je pojmenovaný seznam položek. Položka je buď
|
||||
cvik (`kind: CVIK`), nebo odkaz na jinou šablonu (`kind: SABLONA`), jejíž cviky se
|
||||
při použití rozbalí. Použitím vzniknou běžné aktivity s vazbou `templateId` — jsou
|
||||
samostatné, takže úprava založené položky šablonu nemění.
|
||||
`WorkoutTemplate` (`workouts.ts`) má typ (`WorkoutTemplateType`):
|
||||
|
||||
**Zanoření je povolené jen na jednu úroveň** a `checkNesting` to hlídá z obou stran:
|
||||
šablona nesmí odkazovat na takovou, která sama něco skládá, a zároveň nesmí začít
|
||||
skládat, pokud ji už někdo používá. Bez druhé kontroly by druhá úroveň vznikla
|
||||
oklikou přes úpravu. Smazat nelze šablonu, kterou skládá jiná — zůstal by odkaz
|
||||
do prázdna. Šablony uložené dřív, než skládání přibylo, nemají `kind`; `withKind`
|
||||
jim ho při načtení doplní na `CVIK`.
|
||||
- **VOLNY** — pojmenovaný seznam položek, do dne se zakládá ručně. Výchozí typ,
|
||||
nezapisuje se; šablony uložené dřív, než typy přibyly, jsou volné.
|
||||
- **FIXNI** — plán s dny (`days`) navázanými na den v týdnu (`weekday` 1–7).
|
||||
- **PLOVOUCI** — plán jako sekvence dnů zakončená dnem volna (volno se jako den
|
||||
nezapisuje, plyne z typu).
|
||||
|
||||
Položka je buď cvik (`kind: CVIK`), nebo odkaz na volnou šablonu (`kind: SABLONA`),
|
||||
jejíž cviky se při použití rozbalí (`expandExercises`). Použitím vzniknou běžné
|
||||
aktivity s vazbou `templateId` (u plánu i `planDayId`) — jsou samostatné, takže
|
||||
úprava založené položky šablonu nemění. Plán má navíc `replaceWithinDays`
|
||||
(lhůta pro náhradu vynechaných cviků) a `startDate`. Dny plánu mají stálé `id`,
|
||||
podle kterého se v historii pozná, který den se kdy cvičil, i po úpravě plánu.
|
||||
|
||||
**Zanoření volných šablon je povolené jen na jednu úroveň** a `checkReferences`
|
||||
to hlídá z obou stran: šablona nesmí odkazovat na takovou, která sama něco skládá,
|
||||
a zároveň nesmí začít skládat, pokud ji už jiná volná šablona používá. Bez druhé
|
||||
kontroly by druhá úroveň vznikla oklikou přes úpravu. Den plánu úroveň nepřidává,
|
||||
smí odkázat na libovolnou volnou šablonu; plán sám do ničeho vnořit nejde a volná
|
||||
šablona, kterou něco používá, se nemůže stát plánem. Smazat nelze šablonu, kterou
|
||||
skládá jiná nebo kterou má plán v některém dni — zůstal by odkaz do prázdna.
|
||||
Šablony uložené dřív, než skládání přibylo, nemají `kind`; `withKind` jim ho při
|
||||
načtení doplní na `CVIK`.
|
||||
|
||||
**Návrh tréninku** (`getPlannedWorkouts` ve `workoutSchedule.ts`, v přehledu dne
|
||||
`DayOverview.plannedWorkouts`): fixní plán navrhne den podle dne v týdnu.
|
||||
Plovoucí prochází záznamy použití od `startDate` jako stavový automat
|
||||
(`advanceDone`, `advanceGap`): odcvičený den posune sekvenci, den bez tréninku je
|
||||
řádné volno (když je na řadě), **posunuté volno** (uprostřed rozběhnutého cyklu,
|
||||
jednou za cyklus — po posledním dni se pak pokračuje rovnou od začátku), jinak
|
||||
trénink jen odsune. Budoucí dny se počítají, jako by se navržený trénink splnil.
|
||||
Návrh se potvrdí přes `applyWorkoutTemplate` s `dayId` a `doneIndexes`
|
||||
(pořadí v rozbaleném seznamu cviků); odškrtnuté cviky se zapíšou do záznamu bez
|
||||
`entryId`, jako vynechané. Den jde potvrdit i celý jako vynechaný.
|
||||
|
||||
**Náhrady** (`getPendingReplacements`, `replaceSkippedExercise`,
|
||||
`POST /api/workouts/replace`): vynechaný cvik (bez aktivity a bez náhrady) se
|
||||
nabízí v přehledu dne po dobu `replaceWithinDays` ze záznamu (lhůta, jaká platila
|
||||
v den vynechání, nejvýš 14). Náhrada založí aktivitu s `replacesDate` a k cviku
|
||||
v záznamu původního dne zapíše `replacement` (datum a `entryId`). Smazání náhradní
|
||||
aktivity vazbu zruší, přesun jí změní datum (`updateReplacementLink`). Náhrada ani
|
||||
den volna plovoucí plán neposouvají — posouvá ho jen záznam dne plánu.
|
||||
|
||||
`buildEnergyBalance` v `dayOverview.ts` počítá:
|
||||
`bilance = příjem − (klidový výdej + pohyb)`. Záporná hodnota je deficit.
|
||||
@@ -251,8 +286,15 @@ jednotlivé cviky s `entryId` aktivity, která z nich vznikla; podle něj
|
||||
`analyzeDay` u každého dne pozná cvik **odebraný** (aktivita chybí) a **upravený**
|
||||
(jiné množství, série nebo násobek) — podle názvu by to nešlo, šablona může mít
|
||||
stejný cvik dvakrát. Smazání všech cviků šablony ve dni `dropOrphanedPlans`
|
||||
bere jako vrácené použití a plán zahodí. Aktivity ze šablony bez plánu (cvik
|
||||
bere jako vrácené použití a plán zahodí — kromě záznamu vynechaného celého dne
|
||||
plánu a záznamu, jehož cvik už má náhradu. Aktivity ze šablony bez plánu (cvik
|
||||
přesunutý z jiného dne) se počítají jako splněné přesně dle plánu.
|
||||
Plán se ve statistikách dělí po dnech (klíč `templateId:planDayId`). Nahrazený
|
||||
cvik je odchylka **NAHRAZENO** s `replacementDate` a počítá se jako provedený;
|
||||
náhrada sama je v `ActivityDayStats.replacements` dne, kdy se odcvičila, a její
|
||||
kalorie jdou do skutečnosti dne plánu, ze kterého pochází. Graf u takového dne
|
||||
místo „!" ukáže šipku na den náhrady. Dny volna ani necvičené dny plánu se do
|
||||
statistik nijak nepromítají.
|
||||
|
||||
**Statistiky příjmu** (`getIntakeStats`, `GET /api/stats/intake`) jsou protějšek
|
||||
výdeje: příjem po chodech a zdrojích, živiny a porovnání s výdejem. Výdej
|
||||
|
||||
Reference in new issue
Block a user