diff --git a/backend/main.py b/backend/main.py index 456dc43..f819647 100644 --- a/backend/main.py +++ b/backend/main.py @@ -156,17 +156,15 @@ app.add_middleware(_AppVersionMiddleware) class _CacheControlMiddleware(BaseHTTPMiddleware): """Setzt Cache-Control-Header für statische Assets. - CSS/JS: no-cache (ETag-Validierung) — iOS cached sonst ewig ohne Ablaufdatum. - Versioned Assets (?v=…): immutable — URL ändert sich bei Updates. + 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. """ 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")): - 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" + response.headers["Cache-Control"] = "no-cache, must-revalidate" return response app.add_middleware(_CacheControlMiddleware) @@ -406,7 +404,7 @@ async def serve_media(path: str, request: _Request): raise _HE(404, "Nicht gefunden.") return _media_response(filepath) -APP_VER = "885" # muss mit APP_VER in app.js übereinstimmen +APP_VER = "890" # muss mit APP_VER in app.js übereinstimmen @app.get("/.well-known/assetlinks.json") async def assetlinks(): @@ -523,6 +521,11 @@ 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 cc215cf..39016d0 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -583,10 +583,10 @@
- - - - + + + + @@ -637,11 +637,8 @@ if (!sw) return; sw.addEventListener('statechange', () => { if (sw.state === 'activated') { - // Kein zweiter Reload nach force-update - if (sessionStorage.getItem('by_skip_sw_reload')) { - sessionStorage.removeItem('by_skip_sw_reload'); - return; - } + // Flag nur prüfen, nicht konsumieren — controllerchange konsumiert ihn + if (sessionStorage.getItem('by_skip_sw_reload')) return; window.location.replace('/?_t=' + Date.now()); } }); @@ -663,9 +660,17 @@ }); // Backup: controllerchange (falls updatefound nicht feuert) - navigator.serviceWorker.addEventListener('controllerchange', () => { - window.location.replace('/?_t=' + Date.now()); - }); + // 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('message', e => { if (e.data?.type === 'QUEUE_PROCESSED') { diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 9c1a424..d701647 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 = '885'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '890'; // ← 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 21e5d6e..32186f9 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); } - function _startRecInOvl() { + async 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 4bb5047..250e7b2 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-v885'; +const CACHE_VERSION = 'by-v890'; 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 new file mode 100644 index 0000000..88f5b74 --- /dev/null +++ b/backend/static/zuechter.html @@ -0,0 +1,572 @@ + + + + + +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
+