Sprint 11: Freunde & Chat + Phosphor-Icon-Vollmigration

- Freundschaften (pending/accepted), Nutzersuche, Anfragen per Push
- Direktnachrichten mit Polling, iMessage-Stil, Deep-Links aus Push
- Alle Seiten (map, places, diary, health, dog-profile, sitting, knigge,
  forum, wiki, walks) vollständig auf Phosphor-Icons migriert
- Wikidata-Rassen-Scraper (~833 neue Rassen, lokal gespiegelte Fotos)
- TheDogAPI lokal gespiegelt (169 Rassen + Fotos)
- Quiz-Result-Cards horizontal (korrekte Bildproportionen)
- SW by-v89
This commit is contained in:
rene 2026-04-15 21:33:53 +02:00
parent 96bd57f0ad
commit 097295c628
44 changed files with 9980 additions and 300 deletions

View file

@ -7,6 +7,7 @@ from pydantic import BaseModel
from typing import Optional
from database import db
from auth import get_current_user
from routes.push import send_push_to_user
router = APIRouter()
MEDIA_DIR = os.getenv("MEDIA_DIR", "/data/media")
@ -159,3 +160,40 @@ async def public_dog_profile(dog_id: int):
if not dog:
raise HTTPException(404, "Profil nicht gefunden oder nicht öffentlich.")
return dict(dog)
class FoundReport(BaseModel):
message: Optional[str] = None
kontakt: Optional[str] = None
# Gefunden-Meldung (kein Login nötig)
@router.post("/public/{dog_id}/found")
async def report_found(dog_id: int, data: FoundReport = FoundReport()):
with db() as conn:
row = conn.execute(
"""SELECT d.id, d.name, d.user_id
FROM dogs d
WHERE d.id=? AND d.is_public=1""",
(dog_id,)
).fetchone()
if not row:
raise HTTPException(404, "Profil nicht gefunden oder nicht öffentlich.")
dog_name = row["name"]
user_id = row["user_id"]
body = data.message.strip() if data.message and data.message.strip() \
else "Jemand hat deinen Hund gefunden. Öffne die App für Details."
if data.kontakt and data.kontakt.strip():
body += f" Kontakt: {data.kontakt.strip()}"
send_push_to_user(user_id, {
"title": f"🐾 {dog_name} wurde gefunden!",
"body": body,
"data": {"page": "diary", "found": True},
"tag": f"found-{dog_id}",
})
return {"ok": True}