feat: import jen některých dnů

feat: násobení jídel/cviků
feat: refaktor napojování šablon
This commit is contained in:
Ondřej Anděl committed 2026-09-30 19:10:54 +02:00
1 parent c3990d80f8
commit 8dac67bdd1
37 files changed
+2314 -481

No files matched your search

+4
View File
@@ -22,6 +22,8 @@ paths:
$ref: "./paths/meals/update.yml"
/meals/delete:
$ref: "./paths/meals/delete.yml"
/meals/multiplier:
$ref: "./paths/meals/multiplier.yml"
# Statistiky (/api/stats)
/stats/summary:
@@ -40,6 +42,8 @@ paths:
$ref: "./paths/activities/update.yml"
/activities/delete:
$ref: "./paths/activities/delete.yml"
/activities/multiplier:
$ref: "./paths/activities/multiplier.yml"
# Šablony tréninků (/api/workouts)
/workouts:
+35
View File
@@ -0,0 +1,35 @@
post:
operationId: setActivityMultiplier
summary: |
Nastaví násobek aktivity přímo z přehledu dne, bez úpravy ostatních údajů.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [id, date, multiplier]
properties:
id:
description: Identifikátor záznamu
type: string
date:
description: Datum záznamu (YYYY-MM-DD)
type: string
format: date
multiplier:
description: Násobek, kladné číslo (i necelé). Hodnota 1 násobek zruší.
type: number
responses:
"200":
description: Aktualizovaný přehled dne
content:
application/json:
schema:
$ref: "../../schemas/_index.yml#/DayOverview"
"400":
description: Neplatná data
"401":
description: Neautentizovaný uživatel
"404":
description: Záznam neexistuje
+3
View File
@@ -20,6 +20,9 @@ post:
description: Chod. Bez něj se použije chod ze šablony, jinak oběd.
allOf:
- $ref: "../../schemas/_index.yml#/MealType"
multiplier:
description: Násobek porce, třeba 2 za dvě stejné sušenky. Bez něj 1.
type: number
responses:
"200":
description: Aktualizovaný přehled dne
+35
View File
@@ -0,0 +1,35 @@
post:
operationId: setMealMultiplier
summary: |
Nastaví násobek porce jídla přímo z přehledu dne, bez úpravy ostatních údajů.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [id, date, multiplier]
properties:
id:
description: Identifikátor záznamu
type: string
date:
description: Datum záznamu (YYYY-MM-DD)
type: string
format: date
multiplier:
description: Násobek porce, kladné číslo (i necelé). Hodnota 1 násobek zruší.
type: number
responses:
"200":
description: Aktualizovaný přehled dne
content:
application/json:
schema:
$ref: "../../schemas/_index.yml#/DayOverview"
"400":
description: Neplatná data
"401":
description: Neautentizovaný uživatel
"404":
description: Záznam neexistuje
+140 -5
View File
@@ -59,6 +59,13 @@ MealEntry:
note:
description: Poznámka uživatele k jídlu
type: string
multiplier:
description: |
Násobek porce, třeba 2 za dvě sušenky nebo 0,5 za snědenou polovinu.
Násobí jen kalorie — cena zůstává, jak byla zadaná, protože za
nedojedené jídlo se platí celé. Chybí-li, platí 1. Uložené `calories`
jsou vždy za jednu porci, výsledné kcal jsou calories × multiplier.
type: number
importSource:
description: Odkud byl záznam naimportován (např. "luncher"). U ručně přidaných chybí.
type: string
@@ -123,6 +130,9 @@ MealInput:
description: Poznámka uživatele k jídlu
type: string
nullable: true
multiplier:
description: Násobek porce; nevyplněno znamená 1
type: number
DayRecord:
description: Přehled jídel jednoho dne včetně součtů
@@ -283,6 +293,17 @@ ImportRequest:
description: |
Pokud je true, import se pouze vyhodnotí a vrátí náhled, ale nic se neuloží.
type: boolean
mode:
description: Jak naložit s dřívějším importem týchž dnů. Výchozí je PRIDAT.
allOf:
- $ref: "#/ImportMode"
selectedKeys:
description: |
Klíče (`importKey`) řádků, které se mají založit. Klient je bere z náhledu,
kde si uživatel odškrtne, co nechce. Bez pole se založí všechny řádky.
type: array
items:
type: string
ImportResult:
description: Výsledek (nebo náhled) importu přehledu z Luncheru
@@ -298,10 +319,15 @@ ImportResult:
- totalPrice
- entries
- warnings
- mode
- replaced
- existing
properties:
dryRun:
description: True, pokud šlo pouze o náhled a data se neuložila
type: boolean
mode:
$ref: "#/ImportMode"
format:
description: Rozpoznaný formát vstupního souboru
type: string
@@ -313,8 +339,22 @@ ImportResult:
description: Počet záznamů, které import založil (u náhledu by založil)
type: integer
skipped:
description: Počet přeskočených řádků, protože už z dřívějšího importu existují
description: |
Počet přeskočených řádků — v režimu PRIDAT ty, které už z dřívějšího
importu existují, a v obou režimech ty, které uživatel odškrtl.
type: integer
replaced:
description: |
Počet dříve naimportovaných záznamů, které režim NAHRADIT odebere
(u náhledu by odebral). V režimu PRIDAT je vždy 0.
type: integer
existing:
description: |
Jídla, která už v dotčených dnech jsou (ručně zadaná i dřív
naimportovaná). Slouží k posouzení náhledu, jestli se něco nezdvojí.
type: array
items:
$ref: "#/MealEntry"
days:
description: Dny (YYYY-MM-DD), kterých se import dotkl, vzestupně
type: array
@@ -325,7 +365,9 @@ ImportResult:
description: Součet cen importovaných záznamů v haléřích
type: integer
entries:
description: Záznamy, které import založil (u náhledu založí)
description: |
Záznamy, které import založil. U náhledu všechny řádky, které založit
jde, bez ohledu na `selectedKeys` — uživatel v nich teprve vybírá.
type: array
items:
$ref: "#/MealEntry"
@@ -521,6 +563,13 @@ ActivityEntry:
note:
description: Poznámka uživatele k aktivitě
type: string
extraWeightGrams:
$ref: "#/ExtraWeightGrams"
multiplier:
description: |
Násobek aktivity, třeba 2 za dvakrát odcvičenou sestavu. Násobí kalorie,
uložené `calories` jsou za jedno provedení. Chybí-li, platí 1.
type: number
templateId:
description: Identifikátor šablony, ze které aktivita vznikla
type: string
@@ -568,6 +617,11 @@ ActivityInput:
note:
type: string
nullable: true
extraWeightGrams:
$ref: "#/ExtraWeightGrams"
multiplier:
description: Násobek aktivity; nevyplněno znamená 1
type: number
ActivityDay:
description: Přehled pohybu jednoho dne včetně součtu
@@ -615,6 +669,8 @@ WorkoutTemplateItem:
caloriesPer100Units:
description: Spálené kcal na 100 jednotek
type: integer
extraWeightGrams:
$ref: "#/ExtraWeightGrams"
templateRefId:
description: Identifikátor vnořené šablony. Povinný u položky druhu SABLONA.
type: string
@@ -767,10 +823,13 @@ MealTemplate:
additionalProperties: false
required:
- id
- kind
- name
properties:
id:
type: string
kind:
$ref: "#/MealTemplateKind"
name:
description: Název jídla
type: string
@@ -799,10 +858,21 @@ MealTemplate:
description: Cena za 100 g v haléřích
type: integer
note:
description: |
Poznámka nebo postup přípravy. U domácích jídel sem lze zapsat recept
volným textem; strukturované suroviny mohou přibýt později.
description: Poznámka, u receptu postup přípravy
type: string
ingredients:
description: Suroviny receptu. U hotového jídla chybí.
type: array
items:
$ref: "#/RecipeIngredient"
servings:
description: Na kolik porcí recept je. Chybí-li, počítá se s jednou.
type: integer
cookedWeight:
description: |
Hmotnost hotového jídla v gramech. Vařením se voda odpaří nebo nasákne,
takže se liší od součtu surovin; bez ní se použije součet surovin.
type: integer
MealTemplateInput:
description: |
@@ -816,6 +886,10 @@ MealTemplateInput:
id:
description: Identifikátor upravované šablony. Bez něj se založí nová.
type: string
kind:
description: Druh šablony. Bez něj se založí hotové jídlo.
allOf:
- $ref: "#/MealTemplateKind"
name:
type: string
source:
@@ -842,3 +916,64 @@ MealTemplateInput:
note:
type: string
nullable: true
ingredients:
type: array
items:
$ref: "#/RecipeIngredient"
servings:
type: integer
cookedWeight:
type: integer
ExtraWeightGrams:
description: |
Dodatečná zátěž v gramech (činky, zátěžová vesta). Eviduje se jako
informace o tréninku a kalorie nemění — žádný jednoduchý vzorec spotřebu
podle zátěže nedává, takže ji uživatel promítne do sazby na 100 jednotek.
type: integer
ImportMode:
description: |
Jak naložit s dřívějším importem týchž dnů.
PRIDAT — nové řádky se přidají, řádky už jednou naimportované se přeskočí.
NAHRADIT — v dnech, do kterých se importuje, se dřívější importované
záznamy odeberou a založí se znovu. Ručně zadaná jídla zůstávají vždy.
type: string
enum:
- PRIDAT
- NAHRADIT
MealTemplateKind:
description: |
Druh šablony jídla.
HOTOVE — objednané nebo koupené jídlo; stačí si pamatovat výsledné
hodnoty porce (kcal, cenu), aby se nemusely dohledávat znovu.
RECEPT — vařené jídlo; eviduje se, z čeho a jak vzniklo, a hodnoty
porce se dopočítají ze surovin.
type: string
enum:
- HOTOVE
- RECEPT
RecipeIngredient:
description: Jedna surovina receptu
type: object
additionalProperties: false
required:
- name
properties:
name:
description: Název suroviny
type: string
weight:
description: Použité množství v gramech
type: integer
caloriesPer100g:
description: Energie suroviny na 100 g v kcal
type: integer
calories:
description: Energie použitého množství v kcal, když nejde dopočítat z gramáže
type: integer
price:
description: Cena použitého množství v haléřích
type: integer