From 53f0cb37d66ec65d73e69694f0b3ee17e207eb9c Mon Sep 17 00:00:00 2001 From: rene Date: Wed, 13 May 2026 19:58:50 +0200 Subject: [PATCH] =?UTF-8?q?Feature:=20Wurf-Buchstabe=20(A=E2=80=93Z)=20+?= =?UTF-8?q?=20Wurf-Name=20=E2=80=94=20DB,=20Backend,=20Formular,=20Kartena?= =?UTF-8?q?nzeige=20(SW=20by-v912)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/database.py | 7 +++++++ backend/main.py | 2 +- backend/routes/litters.py | 21 ++++++++++++++------- backend/static/index.html | 8 ++++---- backend/static/js/app.js | 2 +- backend/static/js/pages/litters.js | 29 ++++++++++++++++++++++++++++- backend/static/sw.js | 2 +- 7 files changed, 56 insertions(+), 15 deletions(-) diff --git a/backend/database.py b/backend/database.py index 73aa307..92bd97e 100644 --- a/backend/database.py +++ b/backend/database.py @@ -1353,6 +1353,13 @@ def _migrate(conn_factory): ); CREATE INDEX IF NOT EXISTS idx_litters_breeder ON litters(breeder_id, created_at DESC); CREATE INDEX IF NOT EXISTS idx_litters_status ON litters(status, sichtbar); + # wurf_rang + wurf_name Spalten nachrüsten + try: + conn.execute("ALTER TABLE litters ADD COLUMN wurf_rang TEXT") + except Exception: pass + try: + conn.execute("ALTER TABLE litters ADD COLUMN wurf_name TEXT") + except Exception: pass CREATE TABLE IF NOT EXISTS puppies ( id INTEGER PRIMARY KEY AUTOINCREMENT, diff --git a/backend/main.py b/backend/main.py index c92a3b7..0d43af7 100644 --- a/backend/main.py +++ b/backend/main.py @@ -406,7 +406,7 @@ async def serve_media(path: str, request: _Request): raise _HE(404, "Nicht gefunden.") return _media_response(filepath) -APP_VER = "911" # muss mit APP_VER in app.js übereinstimmen +APP_VER = "912" # muss mit APP_VER in app.js übereinstimmen @app.get("/.well-known/assetlinks.json") async def assetlinks(): diff --git a/backend/routes/litters.py b/backend/routes/litters.py index c9dde95..09250d8 100644 --- a/backend/routes/litters.py +++ b/backend/routes/litters.py @@ -27,23 +27,27 @@ def _require_breeder(user=Depends(get_current_user)): # Schemas # ------------------------------------------------------------------ class LitterCreate(BaseModel): + wurf_rang: Optional[str] = None # A, B, C … + wurf_name: Optional[str] = None # z.B. "Vatertags-Wurf" vater_name: Optional[str] = None mutter_name: Optional[str] = None - vater_id: Optional[int] = None # FK zucht_hunde - mutter_id: Optional[int] = None # FK zucht_hunde - geburt_datum: Optional[str] = None # YYYY-MM-DD - erwartetes_datum: Optional[str] = None # YYYY-MM-DD + vater_id: Optional[int] = None + mutter_id: Optional[int] = None + geburt_datum: Optional[str] = None + erwartetes_datum: Optional[str] = None welpen_gesamt: Optional[int] = None welpen_verfuegbar: Optional[int] = None beschreibung: Optional[str] = None gesundheitstests: Optional[str] = None preis_spanne: Optional[str] = None - status: str = "geplant" # geplant|geboren|verfuegbar|abgeschlossen + status: str = "geplant" sichtbar: int = 0 sichtbar_bis: Optional[str] = None class LitterUpdate(BaseModel): + wurf_rang: Optional[str] = None + wurf_name: Optional[str] = None vater_name: Optional[str] = None mutter_name: Optional[str] = None vater_id: Optional[int] = None @@ -189,13 +193,16 @@ async def create_litter(body: LitterCreate, user=Depends(_require_breeder)): cur = conn.execute( """INSERT INTO litters - (breeder_id, vater_name, mutter_name, vater_id, mutter_id, + (breeder_id, wurf_rang, wurf_name, + vater_name, mutter_name, vater_id, mutter_id, geburt_datum, erwartetes_datum, welpen_gesamt, welpen_verfuegbar, beschreibung, gesundheitstests, preis_spanne, status, sichtbar, sichtbar_bis) - VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", + VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", ( profile["id"], + body.wurf_rang, + body.wurf_name, body.vater_name, body.mutter_name, body.vater_id, diff --git a/backend/static/index.html b/backend/static/index.html index eb60b1f..c170e95 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -591,10 +591,10 @@ - - - - + + + + diff --git a/backend/static/js/app.js b/backend/static/js/app.js index c6adb33..723b0a7 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 = '911'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '912'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.5.1'; // ← semantische Version, wird bei make release gesetzt const IS_STAGING = location.hostname === 'staging.banyaro.app'; // Cache-Bust-Parameter nach Update-Reload sofort entfernen diff --git a/backend/static/js/pages/litters.js b/backend/static/js/pages/litters.js index 801200f..8f86a86 100644 --- a/backend/static/js/pages/litters.js +++ b/backend/static/js/pages/litters.js @@ -353,8 +353,13 @@ window.Page_litters = (() => {
+ ${(l.wurf_rang || l.wurf_name) ? ` +
+ ${l.wurf_rang ? `${_esc(l.wurf_rang)}-Wurf` : ''} + ${l.wurf_name ? `${_esc(l.wurf_name)}` : ''} +
` : ''}
- ${elternLabel} + ${elternLabel} ${_statusBadge(l.status)} ${sichtbarChip}
@@ -925,9 +930,29 @@ window.Page_litters = (() => { value="${_esc(currentName || '')}" placeholder="oder Namen frei eingeben">`; }; + const rangOpts = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('').map(l => + `` + ).join(''); + const body = `
+
+
+ + +
+
+ + +
+
+
@@ -1042,6 +1067,8 @@ window.Page_litters = (() => { const fd = new FormData(e.target); const payload = { + wurf_rang: fd.get('wurf_rang') || null, + wurf_name: fd.get('wurf_name')?.trim() || null, vater_name: fd.get('vater_name')?.trim() || null, mutter_name: fd.get('mutter_name')?.trim() || null, vater_id: fd.get('vater_id') ? parseInt(fd.get('vater_id')) : null, diff --git a/backend/static/sw.js b/backend/static/sw.js index 9b7b53d..dc5b7cd 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -3,7 +3,7 @@ Offline-Cache + Push Notifications + Tile-Cache ============================================================ */ -const CACHE_VERSION = 'by-v911'; +const CACHE_VERSION = 'by-v912'; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache