diff --git a/backend/main.py b/backend/main.py index f819647..456dc43 100644 --- a/backend/main.py +++ b/backend/main.py @@ -156,15 +156,17 @@ app.add_middleware(_AppVersionMiddleware) class _CacheControlMiddleware(BaseHTTPMiddleware): """Setzt Cache-Control-Header für statische Assets. - JS/CSS: immer no-cache — SW übernimmt Caching. Immutable wäre gefährlich, - weil Browser-HTTP-Cache nach force-update nicht geleert wird und veraltete - app.js mit falschem APP_VER eine Update-Dauerschleife verursacht. + CSS/JS: no-cache (ETag-Validierung) — iOS cached sonst ewig ohne Ablaufdatum. + Versioned Assets (?v=…): immutable — URL ändert sich bei Updates. """ async def dispatch(self, request: Request, call_next): response = await call_next(request) path = request.url.path if path.startswith(("/css/", "/js/", "/icons/phosphor.svg")): - response.headers["Cache-Control"] = "no-cache, must-revalidate" + if "v=" in str(request.url.query): + response.headers["Cache-Control"] = "public, max-age=31536000, immutable" + else: + response.headers["Cache-Control"] = "no-cache, must-revalidate" return response app.add_middleware(_CacheControlMiddleware) @@ -404,7 +406,7 @@ async def serve_media(path: str, request: _Request): raise _HE(404, "Nicht gefunden.") return _media_response(filepath) -APP_VER = "890" # muss mit APP_VER in app.js übereinstimmen +APP_VER = "885" # muss mit APP_VER in app.js übereinstimmen @app.get("/.well-known/assetlinks.json") async def assetlinks(): @@ -521,11 +523,6 @@ async def info_page(): return FileResponse(f"{STATIC_DIR}/landing.html", headers={"Cache-Control": "max-age=3600"}) -@app.get("/zuechter") -async def zuechter_landing(): - return FileResponse(f"{STATIC_DIR}/zuechter.html", headers={"Cache-Control": "max-age=3600"}) - - # ------------------------------------------------------------------ # SEO: Server-gerenderete Wiki-Rassen-Übersicht /wiki/rassen # ------------------------------------------------------------------ diff --git a/backend/static/index.html b/backend/static/index.html index 39016d0..cc215cf 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -583,10 +583,10 @@
- - - - + + + + @@ -637,8 +637,11 @@ if (!sw) return; sw.addEventListener('statechange', () => { if (sw.state === 'activated') { - // Flag nur prüfen, nicht konsumieren — controllerchange konsumiert ihn - if (sessionStorage.getItem('by_skip_sw_reload')) return; + // Kein zweiter Reload nach force-update + if (sessionStorage.getItem('by_skip_sw_reload')) { + sessionStorage.removeItem('by_skip_sw_reload'); + return; + } window.location.replace('/?_t=' + Date.now()); } }); @@ -660,17 +663,9 @@ }); // Backup: controllerchange (falls updatefound nicht feuert) - // NICHT registrieren wenn diese Seite selbst durch einen SW-Reload entstand (_t= im URL) - // — verhindert Dauerschleife wenn clients.claim() erst nach Seitenstart feuert - if (!location.search.includes('_t=')) { - navigator.serviceWorker.addEventListener('controllerchange', () => { - if (sessionStorage.getItem('by_skip_sw_reload')) { - sessionStorage.removeItem('by_skip_sw_reload'); - return; - } - window.location.replace('/?_t=' + Date.now()); - }); - } + navigator.serviceWorker.addEventListener('controllerchange', () => { + window.location.replace('/?_t=' + Date.now()); + }); navigator.serviceWorker.addEventListener('message', e => { if (e.data?.type === 'QUEUE_PROCESSED') { diff --git a/backend/static/js/app.js b/backend/static/js/app.js index d701647..9c1a424 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 = '890'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '885'; // ← 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/routes.js b/backend/static/js/pages/routes.js index 32186f9..21e5d6e 100644 --- a/backend/static/js/pages/routes.js +++ b/backend/static/js/pages/routes.js @@ -700,7 +700,7 @@ window.Page_routes = (() => { ovl.querySelector('#rk-rec-startbtn').addEventListener('click', _startRecInOvl); } - async function _startRecInOvl() { + function _startRecInOvl() { if (!navigator.geolocation) { UI.toast.error('GPS nicht verfügbar.'); return; } _recActive = true; _recTrack = []; _recDistKm = 0; _recStartTime = Date.now(); diff --git a/backend/static/sw.js b/backend/static/sw.js index 250e7b2..4bb5047 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-v890'; +const CACHE_VERSION = 'by-v885'; 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 diff --git a/backend/static/zuechter.html b/backend/static/zuechter.html deleted file mode 100644 index 88f5b74..0000000 --- a/backend/static/zuechter.html +++ /dev/null @@ -1,572 +0,0 @@ - - - - - -Für Züchter
-Stammbaum, IK-Berechnung, Gesundheitstests, Wurfverwaltung, Kaufvertrag, KI-Assistent — alles in einer App. Kostenlos. In Deutschland.
-Gesundheitstests in einer Tabelle, Wurfgewichte in einer anderen, Käufer in WhatsApp, Kaufvertrag in Word. Nichts ist verknüpft. Das kostet Zeit — die du besser mit deinen Hunden verbringst.
-Welpengewichte in einer Datei, Gesundheitstests in einer anderen, Kosten irgendwo sonst. Nichts hängt zusammen.
-Inzuchtkoeffizient vor der Verpaarung prüfen? Drei Websites, manuelles Eintippen der Ahnentafel, Kopfrechnen.
-Wer wollte ein Mädchen? Wer hat wann angefragt? Wer steht wo auf der Liste? Alles in Chatverläufen vergraben.
-Altes Word-Dokument öffnen, Namen ändern, vergessen zwei Felder anzupassen, ausdrucken, faxen.
-Der Augentest muss jährlich erneuert werden. Wann war der letzte? Irgendwo auf einem Zettel steht das Datum.
-Deckgebühr, Progesterontests, Tierarzt, Futter, Material — kein Züchter kann das am Ende wirklich sagen.
-Von der Zuchtzulassung bis zur Welpenabgabe — Ban Yaro begleitet jeden Schritt. Kostenlos, ohne Installation, von jedem Gerät.
- - -Grafische Darstellung aller Vorfahren — Vater, Mutter, Großeltern, Urgroßeltern. Sofort sichtbar welche Linien sich kreuzen.
-Automatische IK-Berechnung über 8 Generationen. Ampel-Bewertung: optimal · akzeptabel · erhöht · kritisch. Keine Website, kein Kopfrechnen.
- Einzigartig -IK simulieren bevor du den Deckrüden anfragst. Welche Kombination ist genetisch am besten? Sofort sichtbar.
- Einzigartig -HD, ED, OCD, Augen (ECVO), Herz, Patella, ZTP — mit Datum, Gutachter, Zertifikatsnummer, Gültigkeitsdatum und automatischen Erinnerungen.
-MDR1, PRA, DM, vWD und weitere Marker. Automatische Risikoanalyse für die Kombination: klar × Träger × betroffen — welche Nachkommen sind zu erwarten?
-Ausstellungs-, Arbeits-, Sport-, Zucht- und Champion-Titel dokumentieren — mit Datum, Richter, Formwert. Für den öffentlichen Steckbrief des Hundes.
-Jeden Wurf anlegen mit geplanten und tatsächlichem Geburtsdatum, Elterntieren, Anzahl Welpen und Verfügbarkeitsstatus.
-Tägliche Gewichtserfassung für jeden Welpen einzeln. Wachstumskurve auf einen Blick — aus dem Smartphone heraus am Wurfplatz.
-Fotos hochladen und je Welpe zuordnen — mit Sichtbarkeitssteuerung: öffentlich, nur auf Anfrage oder privat.
-Rechtssicherer Kaufvertrag automatisch befüllt — Züchter, Käufer, Welpe, Chip, Gesundheitsstatus, Impfungen. Zum Ausdrucken oder digital unterschreiben.
- Automatisch -Automatische Bewertung jeder Verpaarung auf Basis von IK und Gentests. Bei kritischen Werten: Warnung und Admin-Meldung. Verantwortungsvolle Zucht by Default.
- Einzigartig -Kompletten Zuchtbericht als HTML (druckbereit, mit Stammbaum) oder ODS-Spreadsheet (für Excel/LibreOffice) exportieren. Deine Daten gehören dir.
-Professioneller Ankündigungstext für deinen Wurf — aus den Elterndaten, Gesundheitstests und Linienbeschreibung. In Sekunden, anpassbar.
- KI -KI bewertet die geplante Verpaarung: IK, Gesundheitsprofil beider Eltern, genetische Risiken — mit klarer Empfehlung: empfohlen / bedingt / nicht empfohlen.
- KI -Deine verfügbaren Würfe erscheinen automatisch in der Banyaro-Wurfbörse — für über tausend Hundebesitzer sichtbar, filterbar nach Rasse.
-Dein Zwingername, deine Rassen, deine verifizierten Zuchthunde — öffentlich einsehbar für Käufer die aktiv nach deiner Linie suchen.
-Automatischer Jahresrückblick für deinen Zuchtstätte: Würfe, Gesundheitstrends, Auszeichnungen — als professionelles Dokument.
- KI -Komplizierte Gentestergebnisse in verständlichem Deutsch für Käufer erklärt — automatisch, auf Knopfdruck.
- KI -Der deutsche Markt für Züchter-Software ist dünn. Hier ein ehrlicher Vergleich mit den relevantesten Alternativen.
-| Feature | -Ban Yaro | -Webreed | -Puppy Center | -Hundescout | -
|---|---|---|---|---|
| Stammbaum grafisch | ✓ | ✓ | — | ✓ |
| IK-Berechnung (Wright) | ✓ 8 Gen. | ✓ | — | ✓ |
| Probeverpaarung mit IK | ✓ | — | — | — |
| Gesundheitstests (HD, ED, …) | ✓ 7 Typen | ✓ | ✓ | ✓ |
| Gentests + Risikoanalyse | ✓ | ✓ | — | — |
| Tierschutz-Check automatisch | ✓ | — | — | — |
| Wurfverwaltung + Welpen | ✓ | ✓ | ✓ | — |
| Kaufvertrag-Generator | ✓ | ✓ | — | ✓ |
| KI-Assistent (Texte, Analyse) | ✓ 5 Features | — | — | — |
| Käufer nutzen dieselbe App | ✓ | — | — | — |
| Native Mobile App | ✓ iOS + Android | Web | ✓ | Windows only |
| Deutschsprachig | ✓ | ✓ | ✓ | ✓ |
| Server in Deutschland | ✓ | Frankreich | — | — |
| Kostenlos starten | ✓ | ✓ (mit Werbung) | ✓ (1 Hündin) | ab 99 € |
Kein anderes Züchter-Tool kann das: Webreed, Hundescout, Breedera — sie alle enden bei der Welpenabgabe. Was danach kommt, passiert woanders.
- -- Ein Käufer der Ban Yaro nutzt kann deinen Wurf direkt in der App entdecken, anfragen und den Welpen reservieren. - Bei der Abgabe überträgst du das komplette Profil — Gewichtsverlauf, alle Impfungen, Gesundheitsstatus, Stammbaum — - direkt in die App des Käufers. Kein PDF, kein Papierstapel, kein vergessener Impfausweis. - Der Käufer hat alles. Und bleibt mit dir verbunden. -
-Über tausend aktive Hundehalter nutzen Ban Yaro — die deinen Wurf in der Wurfbörse sehen, ohne dass du Werbung schalten musst.
-Käufer können dich direkt in der App kontaktieren. Wie entwickelt sich der Welpe? Hat er Fragen? Du bist erreichbar — ohne WhatsApp-Chaos.
-Nach Prüfung durch unser Team bekommst du den Verifiziert-Badge. Das schafft Vertrauen — und unterscheidet dich klar von Vermehrern.
-Kein App Store, keine Installation. Ban Yaro läuft im Browser — auf dem Smartphone genauso wie am Laptop.
-Konto anlegen und Züchter-Antrag stellen — dauert 2 Minuten. E-Mail + Zwingername reicht für den Anfang.
-Wir prüfen deinen Antrag und schalten deinen Züchter-Bereich frei — meist innerhalb von 24 Stunden.
-Deine Zuchthündinnen und -rüden mit Gesundheitstests, Gentests und Titeln erfassen. Der Stammbaum baut sich automatisch auf.
-Wurf anlegen, Welpen erfassen, Gewichte tracken, Fotos hochladen — und direkt in der Wurfbörse veröffentlichen.
-Genealogiedaten, Gesundheitszertifikate, Kaufverträge — das sind sensible Informationen. Sie gehören dir, nicht uns.
-Alle Daten liegen auf unserem Server in Deutschland. Kein US-Anbieter, kein Drittland-Transfer. DSGVO-konform by Default.
-Alle deine Daten jederzeit als HTML oder ODS exportieren. Du bist nie eingesperrt — deine Zuchtdaten gehören dir.
-Gesundheitstests, Fotos, Welpen-Status — für jeden Eintrag bestimmst du: öffentlich, nur auf Anfrage, oder privat.
-hallo@banyaro.app — kein Ticket-System, kein Bot. René antwortet persönlich.
-Züchter-Antrag stellen, Zuchthunde anlegen, ersten Wurf veröffentlichen — alles kostenlos, kein App Store, keine Kreditkarte.
- Als Züchter registrieren -Fragen? hallo@banyaro.app
-