chore: graf db

feat: workout plans (volný, fixní, plovoucí)
This commit is contained in:
Ondřej Anděl committed 2026-10-22 12:11:05 +02:00
1 parent 865c2c3b22
commit 7641e26c9f
43 files changed
+3459 -599

No files matched your search

+2
View File
@@ -84,6 +84,8 @@ paths:
$ref: "./paths/workouts/apply.yml"
/workouts/fromActivities:
$ref: "./paths/workouts/fromActivities.yml"
/workouts/replace:
$ref: "./paths/workouts/replace.yml"
# Recepty (/api/mealTemplates)
/mealTemplates:
+15 -1
View File
@@ -1,6 +1,9 @@
post:
operationId: applyWorkoutTemplate
summary: Založí do zvoleného dne všechny položky šablony tréninku.
summary: |
Založí do zvoleného dne cviky šablony tréninku. U plánu se zakládá jeden
jeho den a jde tak i potvrdit navržený trénink — cviky mimo doneIndexes
se zaznamenají jako vynechané a v okně replaceWithinDays je jde nahradit.
requestBody:
required: true
content:
@@ -16,6 +19,17 @@ post:
description: Den, do kterého se položky založí
type: string
format: date
dayId:
description: Den plánu. Povinný u šablony typu FIXNI a PLOVOUCI.
type: string
doneIndexes:
description: |
Pořadí odcvičených cviků v rozbaleném seznamu (jak ho vrací
PlannedWorkout.items). Bez něj se založí všechny; u dne plánu
může být prázdné — celý den se pak zaznamená jako vynechaný.
type: array
items:
type: integer
responses:
"200":
description: Aktualizovaný přehled dne
+40
View File
@@ -0,0 +1,40 @@
post:
operationId: replaceSkippedExercise
summary: |
Nahradí cvik vynechaný v předchozím dni plánu — založí ho jako aktivitu
do zvoleného dne a v záznamu původního dne ho označí jako nahrazený.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [date, sourceDate, planId, itemIndex]
properties:
date:
description: Den, do kterého se náhrada založí
type: string
format: date
sourceDate:
description: Den, ve kterém se cvik vynechal
type: string
format: date
planId:
description: Identifikátor záznamu o použití plánu (PendingReplacement.planId)
type: string
itemIndex:
description: Pořadí cviku v záznamu (PendingReplacement.itemIndex)
type: integer
responses:
"200":
description: Aktualizovaný přehled dne
content:
application/json:
schema:
$ref: "../../schemas/_index.yml#/DayOverview"
"400":
description: Cvik nejde nahradit (není vynechaný, už je nahrazený, nebo uplynula lhůta)
"401":
description: Neautentizovaný uživatel
"404":
description: Záznam o použití plánu neexistuje
+2 -13
View File
@@ -1,23 +1,12 @@
post:
operationId: saveWorkoutTemplate
summary: Založí novou šablonu tréninku, nebo upraví existující.
summary: Založí novou šablonu tréninku (volnou nebo plán), nebo upraví existující.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, items]
properties:
id:
description: Identifikátor upravované šablony. Bez něj se založí nová.
type: string
name:
type: string
items:
type: array
items:
$ref: "../../schemas/_index.yml#/WorkoutTemplateItem"
$ref: "../../schemas/_index.yml#/WorkoutTemplateInput"
responses:
"200":
description: Aktualizovaný seznam šablon
+315 -7
View File
@@ -884,6 +884,15 @@ ActivityEntry:
templateId:
description: Identifikátor šablony, ze které aktivita vznikla
type: string
planDayId:
description: Den plánu (šablony typu FIXNI nebo PLOVOUCI), ze kterého aktivita vznikla
type: string
replacesDate:
description: |
Datum dne, ve kterém se cvik z plánu vynechal a tato aktivita ho nahrazuje.
Nastavuje jen server při náhradě.
type: string
format: date
createdAt:
description: Čas vzniku záznamu
type: string
@@ -992,10 +1001,22 @@ WorkoutTemplateItem:
description: Odhad kcal vnořené šablony. Doplňuje server, při ukládání se ignoruje.
type: integer
WorkoutTemplate:
WorkoutTemplateType:
description: |
Předpřipravený trénink. Použitím se jeho položky založí do zvoleného dne,
takže opakovaný trénink není potřeba zadávat cvik po cviku znovu.
Typ šablony tréninku.
VOLNY — cviky, které jde odcvičit kdykoli; do dne se zakládají ručně.
FIXNI — plán s pevnými dny v týdnu; dny bez tréninku jsou volno.
PLOVOUCI — plán jako sekvence dnů zakončená dnem volna. Na kalendář navázaný
není: další den sekvence přijde na řadu, až se splní předchozí, a volno jde
v rámci cyklu posunout dopředu.
type: string
enum:
- VOLNY
- FIXNI
- PLOVOUCI
WorkoutPlanDay:
description: Jeden tréninkový den plánu (šablony typu FIXNI nebo PLOVOUCI)
type: object
additionalProperties: false
required:
@@ -1003,20 +1024,95 @@ WorkoutTemplate:
- name
- items
- estimatedCalories
properties:
id:
description: |
Stálý identifikátor dne. Podle něj se v historii pozná, který den plánu
se kdy cvičil, i když se plán mezitím upraví.
type: string
name:
description: Název dne, např. "Workout Day 1"
type: string
weekday:
description: Den v týdnu u fixního plánu, 1 = pondělí až 7 = neděle
type: integer
items:
description: Cviky dne; odkazem lze zařadit i volnou šablonu
type: array
items:
$ref: "#/WorkoutTemplateItem"
estimatedCalories:
description: Odhad spálených kcal za den. Doplňuje server.
type: integer
WorkoutPlanDayInput:
description: Den plánu při ukládání šablony. Bez id se založí nový den.
type: object
additionalProperties: false
required:
- name
- items
properties:
id:
type: string
name:
type: string
weekday:
type: integer
items:
type: array
items:
$ref: "#/WorkoutTemplateItem"
WorkoutTemplate:
description: |
Předpřipravený trénink. Volná šablona je seznam cviků, který se použitím
založí do zvoleného dne. Plán (fixní nebo plovoucí) má tréninkové dny
a přehled dne z něj sám navrhne, co je ten den na řadě.
type: object
additionalProperties: false
required:
- id
- name
- type
- items
- estimatedCalories
- hasNested
- usedByCount
- usedInPlanCount
properties:
id:
type: string
name:
description: Název šablony, např. "Workout day 1"
type: string
type:
$ref: "#/WorkoutTemplateType"
items:
description: Položky volné šablony; u plánu je seznam prázdný a cviky jsou ve dnech
type: array
items:
$ref: "#/WorkoutTemplateItem"
days:
description: |
Tréninkové dny plánu. U plovoucího v pořadí, ve kterém se cvičí —
den volna za posledním se nezapisuje, plyne z typu.
type: array
items:
$ref: "#/WorkoutPlanDay"
replaceWithinDays:
description: |
Do kolika dní jde cvik vynechaný v plánu nahradit. Chybí-li, náhrady
se nenabízejí.
type: integer
startDate:
description: Od kterého dne plán platí a přehled dne z něj navrhuje trénink
type: string
format: date
estimatedCalories:
description: Odhad spálených kcal za celou šablonu včetně vnořených
description: |
Odhad spálených kcal za celou šablonu včetně vnořených, u plánu
za celý cyklus (týden)
type: integer
hasNested:
description: |
@@ -1024,8 +1120,155 @@ WorkoutTemplate:
už nelze vnořit do další — zanoření je povolené jen na jednu úroveň.
type: boolean
usedByCount:
description: Kolik jiných šablon tuto šablonu používá
description: Kolik jiných volných šablon tuto šablonu skládá
type: integer
usedInPlanCount:
description: V kolika plánech je šablona zařazená do některého dne
type: integer
WorkoutTemplateInput:
description: Data pro založení nebo úpravu šablony tréninku
type: object
additionalProperties: false
required:
- name
properties:
id:
description: Identifikátor upravované šablony. Bez něj se založí nová.
type: string
name:
type: string
type:
$ref: "#/WorkoutTemplateType"
items:
description: Položky volné šablony
type: array
items:
$ref: "#/WorkoutTemplateItem"
days:
description: Dny plánu (FIXNI, PLOVOUCI)
type: array
items:
$ref: "#/WorkoutPlanDayInput"
replaceWithinDays:
type: integer
startDate:
type: string
format: date
PlannedWorkoutStatus:
description: |
Stav plánu v konkrétní den.
NAVRH — den plánu je na řadě a čeká na potvrzení.
SPLNENO — den plánu se ten den už potvrdil.
VOLNO — podle plánu je den volna.
type: string
enum:
- NAVRH
- SPLNENO
- VOLNO
PlannedWorkoutItem:
description: Jeden cvik navrženého dne plánu, po rozbalení vnořených šablon
type: object
additionalProperties: false
required:
- name
- unit
- quantity
- calories
properties:
name:
type: string
unit:
$ref: "#/ActivityUnit"
quantity:
description: Množství na jednu sérii
type: integer
sets:
type: integer
caloriesPer100Units:
type: integer
extraWeightGrams:
$ref: "#/ExtraWeightGrams"
calories:
description: Spálené kcal za všechny série
type: integer
PlannedWorkout:
description: Co plán (fixní nebo plovoucí šablona) navrhuje na konkrétní den
type: object
additionalProperties: false
required:
- templateId
- templateName
- type
- status
- items
properties:
templateId:
type: string
templateName:
type: string
type:
$ref: "#/WorkoutTemplateType"
status:
$ref: "#/PlannedWorkoutStatus"
dayId:
description: Navržený den plánu; u stavu VOLNO chybí
type: string
dayName:
description: |
Název navrženého dne, u stavu SPLNENO dnů potvrzených v tento den
(při dvou potvrzeních jsou názvy spojené)
type: string
items:
description: Cviky navrženého dne; mimo stav NAVRH je seznam prázdný
type: array
items:
$ref: "#/PlannedWorkoutItem"
restAvailable:
description: |
Jen plovoucí plán: true, pokud v tomto cyklu ještě nebyl den volna,
takže když se dnes necvičí, bere se to jako posunuté volno a sekvence
pak pokračuje bez další mezery.
type: boolean
PendingReplacement:
description: Cvik vynechaný v některém z předchozích dnů, který jde ještě nahradit
type: object
additionalProperties: false
required:
- sourceDate
- planId
- itemIndex
- templateId
- templateName
- deadline
- item
properties:
sourceDate:
description: Den, ve kterém se cvik vynechal
type: string
format: date
planId:
description: Identifikátor záznamu o použití plánu v daném dni
type: string
itemIndex:
description: Pořadí cviku v záznamu o použití plánu
type: integer
templateId:
type: string
templateName:
type: string
dayName:
type: string
deadline:
description: Poslední den, kdy jde cvik ještě nahradit
type: string
format: date
item:
$ref: "#/PlannedWorkoutItem"
EnergyBalance:
description: Energetická bilance dne — kolik přišlo jídlem a kolik se vydalo
@@ -1078,6 +1321,8 @@ DayOverview:
- meals
- activities
- energy
- plannedWorkouts
- pendingReplacements
properties:
date:
type: string
@@ -1086,6 +1331,16 @@ DayOverview:
$ref: "#/DayRecord"
activities:
$ref: "#/ActivityDay"
plannedWorkouts:
description: Co na tento den navrhují plány tréninků, které už platí
type: array
items:
$ref: "#/PlannedWorkout"
pendingReplacements:
description: Cviky vynechané v předchozích dnech, které jde v tento den ještě nahradit
type: array
items:
$ref: "#/PendingReplacement"
energy:
$ref: "#/EnergyBalance"
sleepMinutes:
@@ -1389,6 +1644,12 @@ TemplateUsageTotal:
name:
description: Název šablony v době použití
type: string
planDayId:
description: Den plánu; plán se ve statistikách dělí po dnech
type: string
dayName:
description: Název dne plánu v době použití
type: string
dayCount:
description: Počet dní, ve kterých se šablona použila
type: integer
@@ -1402,7 +1663,9 @@ TemplateUsageTotal:
description: Kolik cviků šablona založila
type: integer
doneItemCount:
description: Kolik z nich ve dni zůstalo (smazané se berou jako neprovedené)
description: |
Kolik z nich se provedlo — ve dni zůstalo, nebo se později nahradilo
(smazané a nenahrazené se berou jako neprovedené)
type: integer
ActivityGroupTotal:
@@ -1513,6 +1776,7 @@ ActivityDayStats:
- date
- totalCalories
- templates
- replacements
- extraCalories
- extras
properties:
@@ -1527,6 +1791,11 @@ ActivityDayStats:
type: array
items:
$ref: "#/TemplateDayUsage"
replacements:
description: Náhrady cviků vynechaných v předchozích dnech, odcvičené v tento den
type: array
items:
$ref: "#/ReplacementUsage"
extraCalories:
description: Součet kcal aktivit mimo šablony
type: integer
@@ -1536,8 +1805,36 @@ ActivityDayStats:
items:
$ref: "#/ActivitySummaryItem"
ReplacementUsage:
description: Jedna náhrada vynechaného cviku z plánu
type: object
additionalProperties: false
required:
- templateId
- name
- sourceDate
- item
properties:
templateId:
type: string
name:
description: Název šablony (plánu)
type: string
planDayId:
description: Den plánu, ve kterém se cvik vynechal
type: string
dayName:
description: Název dne plánu, ve kterém se cvik vynechal
type: string
sourceDate:
description: Datum, kdy se cvik vynechal
type: string
format: date
item:
$ref: "#/ActivitySummaryItem"
TemplateDayUsage:
description: Použití jedné šablony v konkrétní den
description: Použití jedné šablony (u plánu jednoho jeho dne) v konkrétní den
type: object
additionalProperties: false
required:
@@ -1553,6 +1850,11 @@ TemplateDayUsage:
name:
description: Název šablony v době použití
type: string
planDayId:
type: string
dayName:
description: Název dne plánu v době použití
type: string
plannedCalories:
type: integer
actualCalories:
@@ -1572,10 +1874,12 @@ PlanDeviationKind:
description: |
ODEBRANO — cvik ze šablony ve dni chybí.
UPRAVENO — cvik je, ale s jiným množstvím, počtem sérií nebo násobkem.
NAHRAZENO — cvik ve dni chybí, ale později se nahradil (replacementDate).
type: string
enum:
- ODEBRANO
- UPRAVENO
- NAHRAZENO
PlanDeviation:
description: Odchylka jednoho cviku od plánu šablony
@@ -1593,6 +1897,10 @@ PlanDeviation:
description: Skutečné provedení; u odebraného cviku chybí
allOf:
- $ref: "#/ActivitySummaryItem"
replacementDate:
description: U nahrazeného cviku den, kdy se nahradil
type: string
format: date
ActivitySummaryItem:
description: Stručný popis jedné aktivity pro statistiky