diff --git a/VERSION b/VERSION
index ff7be53..a624bd7 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1134
\ No newline at end of file
+1133
\ No newline at end of file
diff --git a/backend/routes/dogs.py b/backend/routes/dogs.py
index 9c414d8..1c37b99 100644
--- a/backend/routes/dogs.py
+++ b/backend/routes/dogs.py
@@ -232,42 +232,15 @@ async def get_welcome_dashboard(dog_id: int, user=Depends(get_current_user)):
ORDER BY d.datum DESC, d.id DESC, dm.id ASC""",
(dog_id,)
).fetchall()
- # Cross-Plattform-stabiles Tagesfoto: einmal pro Tag pro Hund festgelegt
- # und in daily_photo_cache persistiert. Sobald ein Client (PWA oder
- # iOS) zum ersten Mal heute zugreift, wird die Wahl gespeichert; alle
- # weiteren Clients liefern dasselbe Bild.
- import datetime as _dt2
- conn.execute("""
- CREATE TABLE IF NOT EXISTS daily_photo_cache (
- dog_id INTEGER NOT NULL,
- datum TEXT NOT NULL,
- photo_url TEXT NOT NULL,
- PRIMARY KEY (dog_id, datum)
- )
- """)
- today_iso = _dt2.date.today().isoformat()
- cached = conn.execute(
- "SELECT photo_url FROM daily_photo_cache WHERE dog_id=? AND datum=?",
- (dog_id, today_iso)
- ).fetchone()
-
random_photo = None
- if cached and cached["photo_url"]:
- random_photo = {
- "url": cached["photo_url"],
- "preview_url": preview_url_from(cached["photo_url"]),
- }
- elif photos:
+ if photos:
+ import datetime as _dt2
tick = (_dt2.date.today() - _dt2.date(2024, 1, 1)).days
chosen_url = photos[tick % len(photos)]["url"]
random_photo = {
"url": chosen_url,
"preview_url": preview_url_from(chosen_url),
}
- conn.execute(
- "INSERT OR IGNORE INTO daily_photo_cache (dog_id, datum, photo_url) VALUES (?, ?, ?)",
- (dog_id, today_iso, chosen_url)
- )
# Neuester Tagebucheintrag
last_diary_row = conn.execute(
diff --git a/backend/routes/expenses.py b/backend/routes/expenses.py
index 9e32e43..9a34f27 100644
--- a/backend/routes/expenses.py
+++ b/backend/routes/expenses.py
@@ -12,15 +12,7 @@ from auth import get_current_user
router = APIRouter()
logger = logging.getLogger(__name__)
-KATEGORIE_META = {
- "futter": {"label": "Futter", "color": "#f59e0b"},
- "tierarzt": {"label": "Tierarzt", "color": "#ef4444"},
- "zubehoer": {"label": "Zubehör", "color": "#8b5cf6"},
- "versicherung": {"label": "Versicherung", "color": "#3b82f6"},
- "sitter": {"label": "Sitter", "color": "#10b981"},
- "sonstiges": {"label": "Sonstiges", "color": "#6b7280"},
-}
-KATEGORIEN = set(KATEGORIE_META.keys())
+KATEGORIEN = {"tierarzt", "futter", "zubehoer", "versicherung", "sitter", "sonstiges"}
# ------------------------------------------------------------------
@@ -83,18 +75,6 @@ def _serialize(row) -> dict:
return dict(row)
-# ------------------------------------------------------------------
-# GET /api/expenses/categories — gültige Kategorien (id + label + color)
-# Single source of truth für PWA und mobile Clients.
-# ------------------------------------------------------------------
-@router.get("/categories")
-async def list_categories():
- return [
- {"id": key, **meta}
- for key, meta in KATEGORIE_META.items()
- ]
-
-
# ------------------------------------------------------------------
# GET /api/expenses/summary — Monats- und Jahressummen
# WICHTIG: Diese Route muss VOR /{id} stehen!
diff --git a/backend/static/index.html b/backend/static/index.html
index cd373a2..1e0a5d0 100644
--- a/backend/static/index.html
+++ b/backend/static/index.html
@@ -86,14 +86,14 @@
Ban Yaro
-
+
-
-
-
-
-
+
+
+
+
+
@@ -617,11 +617,11 @@
-
-
-
-
-
+
+
+
+
+
@@ -631,7 +631,7 @@
-
+
diff --git a/backend/static/js/app.js b/backend/static/js/app.js
index e116fa3..a7b5e90 100644
--- a/backend/static/js/app.js
+++ b/backend/static/js/app.js
@@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
-const APP_VER = '1134'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
+const APP_VER = '1133'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator)
window.APP_VERSION = APP_VERSION;
diff --git a/backend/static/js/pages/onboarding.js b/backend/static/js/pages/onboarding.js
index 5ba7638..c292f03 100644
--- a/backend/static/js/pages/onboarding.js
+++ b/backend/static/js/pages/onboarding.js
@@ -15,28 +15,6 @@ window.Page_onboarding = (() => {
async function init(container, appState) {
_container = container;
_appState = appState;
-
- // Hunde frisch laden — der appState kann veraltet sein (z.B. nach
- // Anlage in mobiler App). Wenn schon ein Hund da ist, Wizard
- // komplett überspringen.
- try {
- const dogs = await API.dogs.list();
- _appState.dogs = dogs;
- if (dogs.length > 0) {
- _appState.activeDog = dogs[0];
- localStorage.setItem('by_active_dog', String(dogs[0].id));
- localStorage.setItem('by_onboarding_done', '1');
- App.renderDogSwitcher?.();
- if (window.Worlds) window.Worlds.init(_appState);
- else App.navigate('diary');
- return;
- }
- } catch (e) {
- // Lieber Wizard zeigen als komplett blockieren — wenn API down ist,
- // landet der User halt im Standard-Flow.
- console.warn('Onboarding: dog-list refresh failed', e);
- }
-
_step = 1;
_render();
}
@@ -337,12 +315,10 @@ window.Page_onboarding = (() => {
// EVENTS
// ----------------------------------------------------------
function _bindEvents() {
- // Weiter-Button (Schritt 1) — direkt ins richtige Hunde-Profil,
- // statt eines doppelten Mini-Formulars im Wizard. Onboarding gilt
- // damit als erledigt, sobald der User dort angekommen ist.
+ // Weiter-Button (Schritt 1)
_container.querySelector('#ob-next-btn')?.addEventListener('click', () => {
- localStorage.setItem('by_onboarding_done', '1');
- App.navigate('dog-profile');
+ _step = 2;
+ _render();
});
// Zurück-Button (Schritt 2)
@@ -446,24 +422,6 @@ window.Page_onboarding = (() => {
_render();
} catch (err) {
- // 403 „schon einen Hund" → kein Stuck-State, weiter zu Schritt 3
- const isAlreadyHas = err?.status === 403
- || /Pro-Feature|schon|already|maximal/i.test(err?.message || '');
- if (isAlreadyHas) {
- try {
- const dogs = await API.dogs.list();
- _appState.dogs = dogs;
- if (dogs.length > 0) {
- _appState.activeDog = dogs[0];
- localStorage.setItem('by_active_dog', String(dogs[0].id));
- App.renderDogSwitcher?.();
- }
- } catch {}
- UI.toast.info?.('Du hast bereits einen Hund — geht direkt weiter.');
- _step = 3;
- _render();
- return;
- }
UI.toast.error(err.message || 'Hund konnte nicht angelegt werden.');
} finally {
if (saveBtn) {
diff --git a/backend/static/js/worlds.js b/backend/static/js/worlds.js
index 52f3baa..c6e05eb 100644
--- a/backend/static/js/worlds.js
+++ b/backend/static/js/worlds.js
@@ -1425,7 +1425,7 @@ window.Worlds = (() => {
Lege ein Profil an und schalte alle Features frei
-