Feature: Trauer-Feature, Futter-Verträglichkeit, Multi-Hund-Fixes, Wetter-Ort (Sprint 47)

- dog-profile.js: Verstorben-Button, Gedenkseite, KI-Abschiedstext
- database.py: futter_eintraege/reaktionen, route_dogs, exercise_progress.dog_id
- routes/ernaehrung.py: Futter-Verträglichkeit mit 20 Reaktionstypen + Analyse
- routes/routen.py: route_dogs Many-to-Many, Routen editierbar
- routes/training.py: exercise_progress per dog_id
- routes/ki.py: /ki/abschied Trauer-KI
- weather.py: Nominatim Ortsname parallel geladen
- ui.js: dogChip/bindDogChip, visualViewport-Modal
- api.js: gedenken, gedenkseite, futter-Methoden, route_dogs
- worlds.js: Ortsname im Wetter-Chip
- uebungen.js: _progressLoaded-Flag, dog-spezifischer Fortschritt
- trainingsplaene.js: dog_id Unterstützung
- diary.js/health.js: P-Badge Cleanup
- map.js: Wetter-Ort-Anzeige entfernt
- wetter.js: Ort in Wetter-Detail
This commit is contained in:
rene 2026-05-11 19:28:38 +02:00
parent 1ce802c8dc
commit bda61a0e40
16 changed files with 713 additions and 181 deletions

View file

@ -142,6 +142,15 @@ const API = (() => {
deletePhoto(id) { return del(`/dogs/${id}/photo`); },
getSkills(id) { return get(`/dogs/${id}/skills`); },
welcomeDashboard(dogId) { return get(`/dogs/${dogId}/welcome-dashboard`); },
gedenken(id, datum) { return post(`/dogs/${id}/gedenken`, { verstorben_am: datum }); },
gedenkseite(id) { return get(`/dogs/${id}/gedenkseite`); },
futterList(id) { return get(`/dogs/${id}/futter`); },
futterCreate(id, data) { return post(`/dogs/${id}/futter`, data); },
futterDelete(id, eid) { return del(`/dogs/${id}/futter/${eid}`); },
reaktionList(id) { return get(`/dogs/${id}/futter/reaktionen`); },
reaktionCreate(id, d) { return post(`/dogs/${id}/futter/reaktion`, d); },
reaktionDelete(id, rid) { return del(`/dogs/${id}/futter/reaktion/${rid}`); },
futterAnalyse(id) { return get(`/dogs/${id}/futter/analyse`); },
};
// ----------------------------------------------------------
@ -287,6 +296,7 @@ const API = (() => {
rate(id, wertung) { return post(`/routes/${id}/rate`, { wertung }); },
walked(id, walked_km, progress_pct) { return post(`/routes/${id}/walked`, { walked_km, progress_pct }); },
reverse(id) { return post(`/routes/${id}/reverse`, {}); },
updateDogs(id, dog_ids) { return patch(`/routes/${id}/dogs`, { dog_ids }); },
addPhoto(id, file) {
const fd = new FormData();
fd.append('file', file);
@ -300,11 +310,11 @@ const API = (() => {
// TRAINING & ÜBUNGSFORTSCHRITT
// ----------------------------------------------------------
const training = {
getProgress() { return get('/training/progress'); },
setProgress(id, status) { return post('/training/progress', { exercise_id: id, status }); },
getSuggestions() { return get('/training/suggestions'); },
getPlanProgress() { return get('/training/plan-progress'); },
setPlanProgress(key, checked) { return post('/training/plan-progress', { item_key: key, checked }); },
getProgress(dogId) { return get(`/training/progress${dogId ? `?dog_id=${dogId}` : ''}`); },
setProgress(id, status, dogId){ return post('/training/progress', { exercise_id: id, status, dog_id: dogId || null }); },
getSuggestions(dogId) { return get(`/training/suggestions${dogId ? `?dog_id=${dogId}` : ''}`); },
getPlanProgress(dogId) { return get(`/training/plan-progress${dogId ? `?dog_id=${dogId}` : ''}`); },
setPlanProgress(key, checked, dogId) { return post('/training/plan-progress', { item_key: key, checked, dog_id: dogId || null }); },
getRecommendations(dogId) { return get(`/training/recommendations?dog_id=${dogId}`); },
};