Compare commits

..

65 Commits

Author SHA1 Message Date
c1f45d3ba1 Merge pull request 'BLS Stoffgruppen, Lebensmittel verwalten, etc' (#108) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m10s
Build Test / pytest-backend (push) Successful in 5s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 21s
Reviewed-on: #108
2026-09-14 13:15:10 +02:00
037e8bab47 Merge pull request 'Food Enhancesment - Rezepte. Listen, BLS Support' (#107) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m6s
Build Test / pytest-backend (push) Successful in 9s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 22s
Reviewed-on: #107
2026-09-13 15:25:21 +02:00
67b508f09b Merge pull request 'BugFix manuelle Eingabe TRainings' (#105) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m9s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 21s
Reviewed-on: #105
2026-07-22 11:14:33 +02:00
fc2905f9da Merge pull request 'feat: add DashboardConfigurePage to the frontend' (#104) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m6s
Build Test / pytest-backend (push) Successful in 9s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 19s
Reviewed-on: #104
2026-04-29 22:04:34 +02:00
0638a7d76b Merge pull request 'pdf generator' (#103) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m0s
Build Test / pytest-backend (push) Successful in 5s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 21s
Reviewed-on: #103
2026-04-29 21:55:58 +02:00
2dbfd95cca Merge pull request 'Widget Update' (#102) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m2s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 17s
Reviewed-on: #102
2026-04-23 09:12:58 +02:00
1cf3d5997d Merge pull request 'C1-C4 Diagramme' (#101) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 53s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #101
2026-04-21 08:14:07 +02:00
5cac1ededd Merge pull request 'Refaktor Level 2b' (#100) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 56s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 17s
Reviewed-on: #100
2026-04-20 17:31:02 +02:00
41d809c68c Merge pull request 'Überartbeitung History - neue Gesamtübersicht' (#99) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m4s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #99
2026-04-20 14:39:54 +02:00
d66eadf88f Merge pull request 'feat: enhance recovery metrics and dashboard with sleep debt calculations and improved visualizations' (#98) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 59s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 17s
Reviewed-on: #98
2026-04-20 12:52:20 +02:00
a1b458d228 Merge pull request 'Neue Aufbereitung Fitness Verlauf' (#97) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 55s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #97
2026-04-20 11:47:52 +02:00
6743814904 Merge pull request 'Fitness History + recovery' (#96) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 54s
Build Test / pytest-backend (push) Successful in 5s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #96
2026-04-20 08:46:25 +02:00
6ef07a77a5 Merge pull request 'Fitness historie' (#95) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 57s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #95
2026-04-20 08:26:46 +02:00
aa6644f44b Merge pull request 'Ernährungsasuwertungen' (#94) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 58s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 18s
Reviewed-on: #94
2026-04-19 21:02:28 +02:00
319a9cfafd Merge pull request 'Verlauf - Körper' (#93) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 59s
Build Test / pytest-backend (push) Successful in 9s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #93
2026-04-19 16:32:32 +02:00
0ab91416d0 Merge pull request 'feat: add reference values snapshot endpoints and data layer functions' (#92) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m1s
Build Test / pytest-backend (push) Successful in 12s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #92
2026-04-19 15:34:20 +02:00
5fbaa7cc8b Merge pull request 'feat: add relaxed arm circumference measurement and update related features' (#91) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 56s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 17s
Reviewed-on: #91
2026-04-19 10:44:18 +02:00
9b53a4ba68 Merge pull request 'feat: enhance photo upload and management features' (#90) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m0s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #90
2026-04-19 10:20:04 +02:00
9720cb57ec Merge pull request 'feat: implement photo management features in the application' (#89) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m1s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #89
2026-04-19 09:24:08 +02:00
1e1605f878 Merge pull request 'Optimierung Platzhalter Umfang' (#88) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m0s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #88
2026-04-18 10:54:36 +02:00
4575bb23ee Merge pull request 'Bug-Fixing Analyse Fehler' (#87) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 55s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #87
2026-04-18 09:54:12 +02:00
a62c952097 Merge pull request 'Erste Version Platzhalter EAV' (#86) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 52s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #86
2026-04-17 21:52:13 +02:00
a7859f0050 Merge pull request 'Erste Version - Universal CSV Importer für EAV und activity_log' (#85) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m1s
Build Test / pytest-backend (push) Successful in 8s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #85
2026-04-15 11:46:30 +02:00
19a88e4f97 Merge pull request 'feat: Enhance goal progress tracking and display' (#84) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 53s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #84
2026-04-14 11:39:58 +02:00
424270f0e8 Merge pull request 'bug fix und Debug Workflow' (#83) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m2s
Build Test / pytest-backend (push) Successful in 8s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #83
2026-04-13 18:15:06 +02:00
f34e46b04f Merge pull request 'Async Workflow' (#82) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m3s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #82
2026-04-13 11:58:01 +02:00
46b703e5a2 Merge pull request 'Bug Fixes. Workflow Engine' (#81) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m0s
Build Test / pytest-backend (push) Successful in 8s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #81
2026-04-12 14:08:43 +02:00
25c4ecfd48 Merge pull request 'Verbesserung für Tests von Prompts' (#80) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m2s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #80
2026-04-12 11:58:07 +02:00
72eb94d186 Merge pull request 'feat: Improve float parsing logic for enhanced accuracy in numeric conversions' (#79) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 55s
Build Test / pytest-backend (push) Successful in 8s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 17s
Reviewed-on: #79
2026-04-12 07:30:44 +02:00
4d81ea2cf3 Merge pull request 'feat: Update Gitea issues index and enhance data layer metrics' (#78) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m4s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #78
2026-04-11 22:17:18 +02:00
caeed3fbaa Merge pull request 'Platzhalter finalisiert - Option |d und Option |x implementiert' (#77) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m3s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #77
2026-04-11 22:10:10 +02:00
b5f745fc3e Merge pull request 'Workflow 1.1 bug fixes' (#74) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m5s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #74
2026-04-11 15:39:23 +02:00
2443b5ac3a Merge pull request 'Workflow Analysen V1.1' (#73) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 51s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #73
2026-04-11 12:38:08 +02:00
8b731313df Merge pull request 'Workflow V1' (#72) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m1s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #72
2026-04-11 10:59:39 +02:00
12893cba78 Merge pull request 'Universal CSV Importer' (#70) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 56s
Build Test / pytest-backend (push) Successful in 4s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 16s
Reviewed-on: #70
2026-04-11 07:06:47 +02:00
09439ad1a5 Merge pull request 'Indvidual Dashboard V0.9' (#67) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 1m0s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #67
2026-04-08 10:56:02 +02:00
75736dadec Merge pull request 'feat: Integrate caliper data enrichment and weight loading in API responses' (#64) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 57s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Reviewed-on: #64
2026-04-06 06:10:39 +02:00
8d56c352fc Merge pull request 'Bug Fixes' (#63) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #63
2026-04-05 17:54:00 +02:00
ebea9946a7 Merge pull request 'feat: Add admin access denial alert to Dashboard with timeout handling' (#62) from develop into main
All checks were successful
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Deploy Production / deploy (push) Successful in 55s
Reviewed-on: #62
2026-04-05 11:29:03 +02:00
9fb04af7df Merge pull request 'Responsive Gui - partially Workflow' (#61) from develop into main
Some checks failed
Deploy Production / deploy (push) Failing after 1s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #61
2026-04-05 11:27:43 +02:00
3f5b9b8b58 Merge pull request 'Platzhaltersystem für Ernährung, Körper und Aktivity' (#60) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #60
2026-04-03 09:28:13 +02:00
5bbea036c2 Merge pull request 'develop' (#59) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 53s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Reviewed-on: #59
2026-04-03 08:23:48 +02:00
c762495b6f Merge pull request 'Goals -System refactored - Platzhaltersystem enhanced (als draft)' (#53) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Reviewed-on: #53
2026-03-31 11:46:47 +02:00
979e734bd9 Merge pull request 'Bug Fix' (#52) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Reviewed-on: #52
2026-03-27 22:16:18 +01:00
79cb3e0100 Merge pull request 'V 0.9h dynamic focus area system' (#51) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #51
2026-03-27 21:14:40 +01:00
9d22e7e8af Merge pull request 'Goalsystem V1' (#50) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Reviewed-on: #50
2026-03-27 17:40:50 +01:00
f46c367c27 Merge pull request 'Flexibles KI Prompt System' (#48) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Reviewed-on: #48
2026-03-26 14:49:47 +01:00
ac4c6760d7 Merge pull request 'globaler Filter für Qualitätsgates von Trainings' (#41) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #41
2026-03-24 08:44:22 +01:00
5a6a140dfd Merge pull request 'Bugfixes: Vitals Import (German columns + decimal values)' (#23) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 56s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
2026-03-23 16:52:27 +01:00
931012c16b Merge pull request 'v9d Phase 2d: Vitals Module Refactoring (Baseline + Blood Pressure)' (#22) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 54s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
2026-03-23 16:27:03 +01:00
03f4b871a9 Merge pull request 'Production Release: RestDays Widget + Trainingstyp Fix' (#16) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Merge pull request #16: Production Release
2026-03-23 09:24:17 +01:00
601fc80178 Merge pull request 'WP 9c Phase 1' (#12) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #12
2026-03-22 14:14:34 +01:00
3ff2a1bf45 Merge pull request 'Abschluss 9c' (#11) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 54s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #11
2026-03-21 21:20:10 +01:00
51aa57f304 Merge pull request 'Final Feature 9c' (#10) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Reviewed-on: #10
2026-03-21 12:41:41 +01:00
ca4411f30f Merge pull request 'fix: update version string to v9c' (#9) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #9
2026-03-21 09:00:55 +01:00
b551365fb5 Merge pull request 'Membership-System und Bug Fixing (inkl. Nutrition)' (#8) from develop into main
Some checks failed
Deploy Production / deploy (push) Failing after 1s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 12s
Reviewed-on: #8
2026-03-21 08:48:56 +01:00
272c123952 Merge pull request '9c Phase 2' (#6) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 12s
Reviewed-on: #6
2026-03-19 14:59:25 +01:00
9387670a7b Merge pull request '9c datatables' (#5) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 55s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #5
2026-03-19 13:00:31 +01:00
d4a8401a6a Merge pull request 'Refactored Main.py' (#4) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 48s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #4
2026-03-19 11:44:32 +01:00
aaf88a6f12 Merge pull request 'fix: Migration-Fehler - meas_id Spalte in ai_insights' (#3) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #3
2026-03-19 08:41:13 +01:00
b789c1bd44 Merge pull request 'bug Fix Login' (#2) from develop into main
All checks were successful
Deploy Production / deploy (push) Successful in 55s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 13s
Reviewed-on: #2
2026-03-19 08:29:48 +01:00
5062aa8068 docker-compose.yml aktualisiert
All checks were successful
Deploy Production / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 12s
2026-03-19 08:21:12 +01:00
8a042589e7 docker-compose.yml aktualisiert
Some checks failed
Deploy Production / deploy (push) Failing after 1s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 12s
2026-03-19 08:19:19 +01:00
3898b5ad45 docker-compose.yml aktualisiert
Some checks failed
Deploy Production / deploy (push) Failing after 38s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 12s
2026-03-19 08:06:02 +01:00
9d15336144 Merge pull request 'Version 9b' (#1) from develop into main
Some checks failed
Deploy Production / deploy (push) Failing after 42s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 12s
Reviewed-on: #1
2026-03-19 08:04:01 +01:00
10 changed files with 28 additions and 221 deletions

View File

@ -48,8 +48,6 @@ Gelernte Zuordnungen und Listen lassen sich als **JSON sichern** und auf einer a
Eigene Einträge des Nutzers sind **persönlich** (`manual_user`). Der Admin legt **zentrale** Einträge für alle an (`manual_admin`). Beide speichern **dieselben Stoffwerte** wie BLS-Lebensmittel (`food_attribute_values`, immer pro 100 g). Beim Anlegen: Makros plus Suche nach weiteren Stoffen (EPA, DHA, Omega-3). Etikett „pro 8 ml“ → Portionsgröße in g angeben, Umrechnung auf 100 g erfolgt serverseitig. Einheit des Stoffs beachten (oft **g**, Etikett in mg: 1100 mg = 1,1 g). Fehlt ein Stoff im Katalog: Nutzer kann ihn selbst anlegen oder Admin → Stoffe & Attribute (Bezeichnung änderbar, Schlüssel fest). In die Makro-Haupttabelle (`nutrition_log`) fließen nur ENERCC→kcal, PROT625→protein_g, FAT→fat_g, CHO→carbs_g (Wert je 100 g × gegessene g / 100). Andere Stoffe gehen nach `nutrition_daily_nutrients`.
**Listen am Tag:** Eine Mitai-Liste (z. B. Quark-Skyr-Blaubeeren) ist zugeordnet, sobald die Tagebuchzeile `recipe_id` hat — nicht erst bei einem einzelnen `food_id`. In der Tagesübersicht erscheint „Liste: …“. Sind alle Zutaten gemappt, lassen sich die berechneten Katalog-Makros (Summe der Zutaten, skaliert auf die gegessene Menge) per Knopf in `nutrition_log` übernehmen.
**Nachträglich ändern:** Unter Ernährung → Tab **Lebensmittel** (persönliche Liste + zentrale Admin-Einträge, Suche). Persönliche Einträge legt und ändert der Owner. Zentrale Einträge liest jeder; **ändert nur ein Admin** (gleiche Liste, Zeile oder Bearbeiten). Beim Zuordnen gilt die Reihenfolge persönlich → zentral → BLS. Globale Namens-Mappings (Admin) gelten für alle, dürfen aber nicht auf ein privates Nutzer-Lebensmittel zeigen. Offizielle BLS-Einträge bleiben fest. Beim Speichern gelten die Felder als Werte je 100 g, außer die Portionsgröße wird bewusst auf die Etikett-Portion gesetzt. Betroffene Tagebuch-Tage werden im Hintergrund neu berechnet. Admin → Lebensmittelkatalog → Reiter **Manuell** zeigt **Zentral** und **Persönlich** getrennt; beide sind dort änderbar.
Weitere Quellen (USDA, Schweizer Nährwertdatenbank) kommen später als zusätzliche Katalogherkunft, nicht als zweite Wertetabelle.

View File

@ -48,5 +48,4 @@ FDDB: Items persistieren; `nutrition_log` nur bei leerem Tag oder laut Policy /
- `GET /nutrition/ingredient-names` — Distinct-Zutatennamen aller Listen inkl. Mapping-Status. Listendialog mappt manuell (`upsertMyFoodMapping`) an der Zeile.
- Mapping-Schreiben und Nährwert-Rebuild sind getrennte Transaktionen; Rebuild läuft nach der API-Antwort im Hintergrund (UI bleibt bedienbar)
- `food_name_mappings.grams_per_unit` / `source_unit` (Migration **064**)
- `GET /nutrition/items` liefert `recipe_name_de` + `recipe_complete`. `GET /nutrition/days/{date}/macros` vergleicht bestehende vs. Katalog-Tagesmakros; `POST …/apply-catalog-macros` schreibt die berechnete Summe nach `nutrition_log`. Listen-Save verknüpft passende Tagebuchzeilen (`items_linked`).
- `GET/POST /api/nutrition/food-knowledge` — portable JSON (`mitai-food-knowledge` v1): manuelle Foods, Mappings (über `bls_code` / Name, keine UUIDs), Listen. Import löst Katalog auf dem Zielsystem auf (BLS muss dort importiert sein).

View File

@ -10,10 +10,6 @@ LEADING_QTY_RE = re.compile(
r"^\s*\d+(?:[.,]\d+)?\s*(?:g|kg|ml|l|stück|stk|st\.?|portion(?:en)?)\b[\s,.:\-–]*",
re.IGNORECASE,
)
TRAILING_QTY_RE = re.compile(
r"[\s,.:\-–]+\d+(?:[.,]\d+)?\s*(?:g|kg|ml|l)\s*$",
re.IGNORECASE,
)
MULTISPACE_RE = re.compile(r"\s+")
DECIMAL_IN_NAME_RE = re.compile(r"(\d),(\d)")
@ -31,10 +27,8 @@ def normalize_food_name(raw: str | None) -> str:
s = strip_leading_quantity(raw)
if not s:
return ""
s = TRAILING_QTY_RE.sub("", s)
s = s.replace("-", " ")
s = DECIMAL_IN_NAME_RE.sub(r"\1.\2", s)
return MULTISPACE_RE.sub(" ", s).strip().lower()
return s.lower()
def item_name_keys(raw: str | None, stored_norm: str | None = None) -> set[str]:

View File

@ -326,12 +326,10 @@ def save_recipe(cur, profile_id: str, rec: dict[str, Any], recipe_id: str | None
qty["quantity_raw"], qty["quantity_g"], qty["quantity_amount"], qty["source_unit"], i,
),
)
linked, dates = link_recipes_to_items(cur, profile_id)
link_recipes_to_items(cur, profile_id)
saved = get_recipe(cur, profile_id, rid)
if not saved:
raise ValueError("Rezept konnte nicht gelesen werden")
saved["items_linked"] = linked
saved["dates_linked"] = dates
return saved

View File

@ -446,65 +446,6 @@ def _touch_item_counts(cur, profile_id: str, day: str, sums: dict) -> None:
)
def day_macro_preview(cur, profile_id: str, day: date | str) -> dict[str, Any]:
sums = compute_day_macro_sums(cur, profile_id, day)
catalog = sums.get("catalog")
existing = sums.get("existing")
mapped = int(sums.get("mapped_item_count") or 0)
return {
"date": str(day)[:10],
"existing": existing,
"catalog": catalog,
"fddb": sums.get("fddb"),
"mapped_item_count": mapped,
"unmapped_item_count": int(sums.get("unmapped_item_count") or 0),
"catalog_origin": sums.get("catalog_origin"),
"can_apply": bool(catalog) and mapped > 0,
"differs": bool(existing and catalog and macros_differ(existing, catalog)),
}
def apply_day_catalog_macros(cur, profile_id: str, day: date | str) -> dict[str, Any]:
preview = day_macro_preview(cur, profile_id, day)
if not preview["can_apply"]:
raise ValueError("Keine aus Zuordnungen berechenbaren Tagesmakros")
cur.execute(
"SELECT source FROM nutrition_log WHERE profile_id = %s AND date = %s",
(profile_id, day),
)
row = cur.fetchone()
source = (row.get("source") if row else None) or "csv"
apply_nutrition_day_macros(
cur,
profile_id,
day,
preview["catalog"],
macro_origin=preview.get("catalog_origin") or "bls",
source=source,
confirm=True,
)
rebuild_daily_nutrients(cur, profile_id, day)
preview = day_macro_preview(cur, profile_id, day)
preview["applied"] = True
return preview
def annotate_nutrition_item(cur, profile_id: str, row: dict[str, Any]) -> dict[str, Any]:
item = dict(row)
item["id"] = str(item["id"])
if item.get("food_id"):
item["food_id"] = str(item["food_id"])
if item.get("recipe_id"):
item["recipe_id"] = str(item["recipe_id"])
from data_layer.food_recipes import catalog_macros_for_recipe
item["recipe_complete"] = catalog_macros_for_recipe(
cur, profile_id, item["recipe_id"], item.get("quantity_g")
) is not None
else:
item["recipe_complete"] = False
return item
def resolve_choice_macros(sums: dict[str, Any], choice: str) -> tuple[dict[str, float], str]:
if choice == "existing":
return sums["existing"], "user_confirmed"

View File

@ -339,11 +339,9 @@ def list_nutrition_items(
if date:
cur.execute(
"""
SELECT i.*, f.name_de AS food_name_de, f.bls_code, f.catalog_kind,
r.name_raw AS recipe_name_de
SELECT i.*, f.name_de AS food_name_de, f.bls_code, f.catalog_kind
FROM nutrition_items i
LEFT JOIN food_catalog f ON f.id = i.food_id
LEFT JOIN food_recipes r ON r.id = i.recipe_id
WHERE i.profile_id=%s AND i.date=%s
ORDER BY i.logged_at NULLS LAST, i.source_name_raw
""",
@ -352,19 +350,16 @@ def list_nutrition_items(
else:
cur.execute(
"""
SELECT i.*, f.name_de AS food_name_de, f.bls_code, f.catalog_kind,
r.name_raw AS recipe_name_de
SELECT i.*, f.name_de AS food_name_de, f.bls_code, f.catalog_kind
FROM nutrition_items i
LEFT JOIN food_catalog f ON f.id = i.food_id
LEFT JOIN food_recipes r ON r.id = i.recipe_id
WHERE i.profile_id=%s
ORDER BY i.date DESC, i.logged_at NULLS LAST
LIMIT %s
""",
(pid, min(limit, 500)),
)
from data_layer.nutrition_items import annotate_nutrition_item
return [annotate_nutrition_item(cur, pid, r2d(r)) for r in cur.fetchall()]
return [r2d(r) for r in cur.fetchall()]
@router.get("/unmapped")
@ -427,13 +422,10 @@ def create_food_recipe(
session: dict = Depends(require_auth),
):
from data_layer.food_recipes import save_recipe
from data_layer.nutrition_items import schedule_daily_nutrient_rebuild
pid = get_pid(x_profile_id)
try:
with get_db() as conn:
saved = save_recipe(get_cursor(conn), pid, body.model_dump())
schedule_daily_nutrient_rebuild(pid, saved.get("dates_linked") or [], "Liste angelegt")
return saved
return save_recipe(get_cursor(conn), pid, body.model_dump())
except ValueError as e:
raise HTTPException(400, str(e)) from e
@ -446,13 +438,10 @@ def update_food_recipe(
session: dict = Depends(require_auth),
):
from data_layer.food_recipes import save_recipe
from data_layer.nutrition_items import schedule_daily_nutrient_rebuild
pid = get_pid(x_profile_id)
try:
with get_db() as conn:
saved = save_recipe(get_cursor(conn), pid, body.model_dump(), recipe_id)
schedule_daily_nutrient_rebuild(pid, saved.get("dates_linked") or [], "Liste geändert")
return saved
return save_recipe(get_cursor(conn), pid, body.model_dump(), recipe_id)
except KeyError:
raise HTTPException(404, "Rezept nicht gefunden") from None
except ValueError as e:
@ -623,35 +612,6 @@ def resolve_import_conflicts(
return {"applied": applied}
@router.get("/days/{day}/macros")
def get_day_macros(
day: str,
x_profile_id: Optional[str] = Header(default=None),
session: dict = Depends(require_auth),
):
from data_layer.nutrition_items import day_macro_preview
pid = get_pid(x_profile_id)
with get_db() as conn:
return day_macro_preview(get_cursor(conn), pid, day)
@router.post("/days/{day}/apply-catalog-macros")
def apply_catalog_macros_for_day(
day: str,
x_profile_id: Optional[str] = Header(default=None),
session: dict = Depends(require_auth),
):
from data_layer.nutrition_items import apply_day_catalog_macros
pid = get_pid(x_profile_id)
try:
with get_db() as conn:
return apply_day_catalog_macros(get_cursor(conn), pid, day)
except ValueError as e:
raise HTTPException(400, str(e)) from e
@router.put("/days/{day}/mark")
def upsert_day_mark(
day: str,

View File

@ -137,11 +137,6 @@ def test_list_name_matches_despite_quantity_prefix():
assert not names_match_list("Haferflocken", "haferflocken", "müsli mix")
def test_list_name_matches_hyphen_and_trailing_qty():
assert names_match_list("Quark-Skyr Blaubeeren", "quark-skyr blaubeeren", "quark skyr blaubeeren")
assert names_match_list("Quark skyr Blaubeeren 250 g", None, "Quark skyr Blaubeeren")
def test_unmapped_meta_includes_recent_ingredients():
batches = [
[],

View File

@ -20,7 +20,7 @@ MODULE_VERSIONS = {
"circumference": "1.0.1",
"caliper": "1.0.1",
"activity": "1.2.1", # Legacy CSV import: activity_entries feature enforcement
"nutrition": "1.3.8", # Listen in Tagesübersicht; Katalog-Makros auf den Tag übernehmen
"nutrition": "1.3.7", # Sichtbarkeit persönlich vs. zentral im Mapping
"tandoor": "1.0.1", # Router-Import ohne future-annotations (Backend startet)
"bls": "1.0.13", # Stoffe gruppiert und sortiert (BLS-Nährstoffgruppen)

View File

@ -197,63 +197,25 @@ function EntryForm({ onSaved }) {
}
// ── Data Tab (Editable Entry List) ───────────────────────────────────────────
function itemAssignment(it) {
if (it.food_name_de) return { ok: true, text: `→ ${it.food_name_de}` }
if (it.recipe_name_de || it.recipe_id) {
const name = it.recipe_name_de || 'Liste'
if (it.recipe_complete) return { ok: true, text: `→ Liste: ${name}` }
return { ok: false, text: `→ Liste: ${name} (Zutaten noch offen)` }
}
return { ok: false, text: '· noch nicht zugeordnet' }
}
function formatMacros(m) {
if (!m) return '—'
return `${Math.round(m.kcal || 0)} kcal · P ${Math.round(m.protein_g || 0)}g · F ${Math.round(m.fat_g || 0)}g · KH ${Math.round(m.carbs_g || 0)}g`
}
function DayItems({ date, onChanged }) {
function DayItems({ date }) {
const [items, setItems] = useState(null)
const [macros, setMacros] = useState(null)
const [open, setOpen] = useState(false)
const [error, setError] = useState(null)
const [applying, setApplying] = useState(false)
const load = async () => {
const [nextItems, nextMacros] = await Promise.all([
nutritionApi.listNutritionItems(date),
nutritionApi.getNutritionDayMacros(date).catch(() => null),
])
setItems(nextItems)
setMacros(nextMacros)
}
const toggle = async () => {
if (open) {
setOpen(false)
return
}
if (!items) {
try {
setError(null)
await load()
setItems(await nutritionApi.listNutritionItems(date))
} catch (e) {
setError(e.message)
return
}
}
setOpen(true)
} catch (e) {
setError(e.message)
}
}
const applyCatalog = async () => {
setApplying(true)
setError(null)
try {
const next = await nutritionApi.applyNutritionDayCatalogMacros(date)
setMacros(next)
onChanged?.()
} catch (e) {
setError(e.message)
} finally {
setApplying(false)
}
}
return (
@ -263,54 +225,16 @@ function DayItems({ date, onChanged }) {
</button>
{error && <p style={{ color: 'var(--danger)', fontSize: 12, margin: '6px 0 0' }}>{error}</p>}
{open && Array.isArray(items) && (
<>
<ul style={{ margin: '8px 0 0', paddingLeft: 18, fontSize: 13, color: 'var(--text1)' }}>
{items.length === 0 && <li style={{ color: 'var(--text3)' }}>Keine Zeilen für diesen Tag</li>}
{items.map((it) => {
const asg = itemAssignment(it)
return (
{items.map((it) => (
<li key={it.id}>
{it.source_name_raw}
{it.quantity_raw ? ` · ${it.quantity_raw}` : ''}
{' '}
<span style={{ color: asg.ok ? 'var(--accent-dark)' : 'var(--text3)' }}>{asg.text}</span>
{it.food_name_de ? ` → ${it.food_name_de}` : ' · noch nicht zugeordnet'}
</li>
)
})}
))}
</ul>
{macros && (
<div style={{ marginTop: 10, padding: '8px 10px', background: 'var(--surface2)', borderRadius: 8, fontSize: 12 }}>
<div>Aktuell in der Tagesübersicht: {formatMacros(macros.existing)}</div>
<div style={{ marginTop: 4 }}>
Aus Zuordnung berechnet
{macros.catalog_origin ? ` (${macros.catalog_origin})` : ''}:
{' '}{formatMacros(macros.catalog)}
{macros.unmapped_item_count
? ` · ${macros.unmapped_item_count} Zeile${macros.unmapped_item_count === 1 ? '' : 'n'} noch ohne vollständige Zuordnung (dort FDDB)`
: ''}
</div>
{macros.can_apply && macros.differs && (
<button
type="button"
className="btn btn-primary"
style={{ marginTop: 8, fontSize: 12 }}
disabled={applying}
onClick={applyCatalog}
>
{applying ? 'Übernehme…' : 'Berechnete Makros in den Tag übernehmen'}
</button>
)}
{macros.can_apply && !macros.differs && (
<div style={{ marginTop: 6, color: 'var(--accent-dark)' }}>Tagesmakros entsprechen bereits der Zuordnung.</div>
)}
{!macros.can_apply && (
<div style={{ marginTop: 6, color: 'var(--text3)' }}>
Noch keine berechenbaren Katalog-Makros. Liste verknüpfen und alle Zutaten zuordnen.
</div>
)}
</div>
)}
</>
)}
</div>
)
@ -452,7 +376,7 @@ function DataTab({ entries, onUpdate }) {
</div>
)}
{e.item_count > 0 ? (
<DayItems date={e.date} onChanged={onUpdate} />
<DayItems date={e.date} />
) : (
<div style={{fontSize:12, color:'var(--text3)', marginTop:6}}>Keine einzelnen Lebensmittelzeilen</div>
)}

View File

@ -281,8 +281,6 @@ export const api = {
return readJsonResponse(r)
},
listNutritionMarks: () => req('/nutrition/marks'),
getNutritionDayMacros: (date) => req(`/nutrition/days/${encodeURIComponent(date)}/macros`),
applyNutritionDayCatalogMacros: (date) => req(`/nutrition/days/${encodeURIComponent(date)}/apply-catalog-macros`, { method: 'POST' }),
putNutritionDayMark: (date, d) => req(`/nutrition/days/${date}/mark`, jput(d)),
deleteNutritionDayMark: (date) => req(`/nutrition/days/${date}/mark`, {method:'DELETE'}),
resolveNutritionConflicts: (decisions) => req('/nutrition/import-conflicts/resolve', json({decisions})),