Commit graph

8 commits

Author SHA1 Message Date
297bd22f96 Bündel 2: Zentrale Helper für DRY-Cleanup, SW by-v1114
NEUE BACKEND-MODULE:

math_utils.py
- haversine_km(lat1, lon1, lat2, lon2) — Distanz in km
- haversine_m(...) — Convenience-Wrapper in Metern
- bbox_deg_from_km(lat, radius_km) — Bounding-Box-Approximation
  für SQL-Vorfilter (statt Haversine im Python-Loop)

config.py
- DB_PATH, MEDIA_DIR, BREEDER_DOCS_DIR, SCANINPUT_DIR
- API_TIMEOUT_SHORT (5s) / DEFAULT (10s) / LONG (30s)
- HTTP_USER_AGENT, HTTP_HEADERS

errors.py
- not_found(msg), forbidden(msg), bad_request(msg), unauthorized(msg)
- conflict(msg), too_many_requests(msg, retry_after), service_unavailable(msg)
- require_or_404(row, msg) — Convenience-Helper

UI.JS ERWEITERUNGEN:

UI.time erweitert:
- formatDate(d)     → "15.03.2026"
- formatDateTime(d) → "15.03.2026, 14:30"
- weekday(d)        → "Di"
- parseISO(str)     → {year, month, day}

UI.text (neu):
- truncate(str, maxLen, ellipsis='…')
- slug(str) — URL-Slug aus String (mit DE-Umlauten)

UI.money (neu):
- format(value) → "12,34 €" (de-DE, EUR)
- formatWithSuffix(value, '/Jahr')

HAVERSINE-MIGRATION (13 Backend-Routen):
alerts.py, services.py, places.py, events.py, diary.py, playdate.py,
lost.py, poison.py, adoption.py, gassi_zeiten.py, sitting.py, routen.py,
walks.py

- Alle lokalen def _haversine/haversine_km entfernt
- Aufrufe ersetzt durch haversine_km/haversine_m je nach Einheit
- from math_utils import haversine_km|haversine_m in jeder Datei

Tests 19/19 grün.

Hinweis: Migrationen für MEDIA_DIR (19 Stellen), API-Timeouts (12),
Date-Formatter im Frontend (24) und UI.text.truncate (5) sind als
Folge-Sprints möglich. Helper sind verfügbar.
2026-05-27 11:19:06 +02:00
b5e4eab84d Push geo-filter: Giftköder-Alert nur im 30km-Radius, Standort via Alerts-Check gespeichert 2026-04-24 09:35:55 +02:00
15f854d96c Session 2026-04-23: Security, Content-Schutz, Wiki-Temperament-Migration
Security (9 Fixes):
- JWT_SECRET Pflicht-Check beim Start (Production)
- Rate-Limit: Login (10/5min), Register (5/h), KI-Training (10/h), Giftköder (3/h)
- KI-Training-Endpoint: Auth-Pflicht hinzugefügt
- Private Profile aus Freunde-Suche gefiltert
- OG-Tags XSS mit html.escape() gesichert
- Globales File-Upload-Limit 20 MB (Middleware)
- E-Mail-Maskierung für Moderatoren im Admin-Panel
- IP-Blocklist in ratelimit.py

Content-Schutz (4 Schichten):
- robots.txt: /api/ komplett Disallow, SSR-Seiten Allow
- Rate-Limit auf /api/wiki/rassen (60/min) + Detail (30/min)
- Honeypot /api/wiki/trap + unsichtbarer Link in index.html
- Wasserzeichen in KI-Enricher-Prompt

Wiki Temperament-Migration:
- 60-Wort Übersetzungsmap EN→DE
- Datenmüll-Filter (hunderasse, dog breed etc.)
- translate_existing_temperaments() + Admin-Button
- SW by-v318, APP_VER 306
2026-04-23 18:34:05 +02:00
5141ba9969 Session 2026-04-20: Medien-Konvertierung, Umami Analytics, Username/Privacy
- HEIC→JPEG, MOV/AVI→MP4 Konvertierung bei allen Upload-Endpoints (media_utils.py)
- ffmpeg im Docker-Image, Video-Thumbnails (extract_video_thumb, poster-Attribut)
- Google Analytics entfernt, Umami self-hosted eingebunden (index.html, datenschutz.js)
- Admin-Panel Analytics-Tab: Stat-Cards, Sparkline 7 Tage, Top-Seiten (Umami-API-Proxy)
- Admin-Panel Tab-Icons korrigiert (aus vorhandenem Phosphor-Sprite)
- users.real_name Spalte: Username öffentlich, echter Name privat und optional
- Registrierung: Label "Benutzername", Leerzeichen verboten, Profanity-Blockliste
- Datenschutzerklärung: GA-Abschnitt durch Umami-Text ersetzt
2026-04-20 18:36:58 +02:00
c721d051c8 Feat: Push-Notifications vollständig implementiert
- push.py: /vapid-key, /subscribe, /unsubscribe + send_push_to_user/all Helpers
- VAPID Keys in docker-compose.yml (Public + Private)
- Giftköder-Meldung löst automatisch Push an alle Subscriber aus
- ON CONFLICT(endpoint) für idempotentes Re-Subscribe
- Abgelaufene Subscriptions werden bei HTTP 410 auto-gelöscht
2026-04-13 20:47:51 +02:00
6f48ec581d Backend Sprint 2+3: Health-Modul, Multi-Dog Tagebuch, Pillow, Migrations
- database.py: diary_dogs + walk_participant_dogs Tabellen, idempotente
  Migration für Health-Felder (charge_nr, kosten, diagnose, …), Backfill
- routes/health.py: vollständiges Health-Modul (war Stub), CRUD für
  Impfung/Entwurmung/Tierarzt/Medikament/Gewicht/Allergie/Dokument
- routes/diary.py: Multi-Dog n:m via diary_dogs (dog_ids in allen Endpoints)
- routes/dogs.py: Foto-Upload konvertiert HEIC/PNG/WebP → JPEG via Pillow
- routes/poison.py: Resolve mit Grundauswahl + Soft-Delete (geloest_von/at/grund)
- ki.py: health_summary() für KI-Gesundheitsbericht
- main.py: /favicon.ico Route
- requirements.txt: Pillow 11.2.1 + pillow-heif 0.22.0
2026-04-13 19:29:51 +02:00
cc36ead720 Sprint 2: Giftköder-Alarm (poison.py + poison.js)
Backend: vollständiges CRUD (list/report/confirm/resolve/photo),
Haversine-Radius-Filter, Auto-Expiry 7 Tage, Foto-Upload.
Frontend: Leaflet-Karte + Meldungsliste + GPS-Formular.
main.py: /media StaticFiles-Mount für Foto-Serving (auch Diary).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 17:52:21 +02:00
00be2bbcd5 Sprint 0: Backend, Docker, KI-Layer mit Free/Premium-Trennung 2026-04-12 16:39:34 +02:00