- Neue Tabelle ReportDecision (nur anhängen, ohne Fremdschlüssel): jede
Moderationsentscheidung zu einer Meldung (bestätigt/abgewiesen) mit
Melder und gemeldeter Seite als Momentaufnahme.
- Geschrieben von dismissReport, deletePostAsModerator, dem neuen
upholdReport (Profil-Meldungen bestätigen) und petAdmin.delete.
- Auswertung: Abzeichen und Zahlen in der Nutzerliste, im Tier-Detail und
in der Warteschlange („Melder: häufige Fehlmeldungen“), Tab „Auswertung“
auf der Meldungen-Seite mit Ranglisten.
- Datenschutz: Tier gelöscht → Tier-/Beitrags-IDs anonymisiert, Konto
gelöscht → Owner-IDs anonymisiert, Zählung der Gegenseite bleibt. Teil der
Art.-15-Auskunft (ohne Gegenseite), Abschnitt 4e in der
Datenschutzerklärung.
Braucht vor dem Deploy: prisma db push + prisma/enable_rls_report_decisions.sql.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Der Dialog scrollt jetzt selbst (max. 90 % der Fensterhöhe), und die
Rassenliste je Tierart hat einen eigenen Scrollbereich. Bei Hunden (~300
Rassen) lagen Speichern und Abbrechen bisher außerhalb des Bildschirms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AdminAutoRefresh im Admin-Layout lädt nach jeder erfolgreichen Mutation
alle sichtbaren Daten neu (invalidateQueries, nur aktive Queries holen
sofort neu). Damit braucht keine Admin-Seite mehr F5, auch die, die bisher
nach manchen Aktionen gar nicht neu geladen haben. Die ~35 einzelnen
invalidateQueries-Aufrufe in den Seiten entfallen. Gilt nur im Admin-Panel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- postDeleteOps (src/lib/delete-post.ts): Paw-Backs anderer Tiere und deren
Meldungen fallen beim Löschen mit weg. Repost.originalPost hat kein Cascade
und blockierte bisher das Löschen solcher Beiträge, im Admin-Panel
(deletePost, deleteReportedPost) wie in posts.delete.
- assertCanModerate: sperren, shadowbannen, verwarnen und Konto löschen nur
gegen niedrigere Ränge; das Bootstrap-Konto (ADMIN_OWNER_ID) ist tabu.
- unbanUser, removeShadowban, revokeRole: fehlender Eintrag gibt NOT_FOUND
statt eines 500-Fehlers.
- deleteBlacklistEntry schreibt einen Audit-Log-Eintrag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- /app: Link-Vorschauen (Meta/Threads/Instagram, TikTok, WhatsApp, Crawler)
werden weitergeleitet, aber nicht mehr in der Download-Statistik gezählt
- Reports zu einem Beitrag werden jetzt auch beim Admin-Löschen, beim Löschen
durch den Besitzer und beim Entfernen einer Pfote zurück mitgelöscht
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Neue Tabelle PetCaretaker (max. 1 pro Tier): Code einladen (7 Tage) ->
einlösen (PENDING) -> Freigabe durch den Haupt-Besitzer (ACTIVE)
- assertPetOwnership erlaubt aktiven Mitbetreuer; assertPetMainOwner für
Löschen, Privatsphäre, Gedenkmodus, Gesundheits-Einwilligung
- pets.list/byId inkl. mitbetreuter Tiere mit Rolle; Push auch an die Geräte
des Mitbetreuers; Konto-Löschung übergibt das Tier an ihn
- Web: Verwaltung in "Profil bearbeiten", Code einlösen unter "Meine Tiere"
und im Onboarding, Link /mitbetreuen/<code>, Mitteilung CARETAKER_REQUEST
- App: dieselben Abläufe (OTA-fähig, Teilen statt Kopieren)
- Datenschutz: Absatz zum Mitbetreuer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Neue Abschnitte 4c (Push-Mitteilungen: Push-Token pro Gerät, Versand über
Expo/Apple/Google, Einwilligung im Systemdialog, Löschung) und 4d
(Vermisst-Meldung, öffentliche Seite, Suchmaschinen nur nach Einwilligung,
Kontaktdaten freiwillig und nur eigene, Löschung bei Ende der Meldung)
- Abschnitt 2, 4 (Expo, Apple, Google mit DPF) und 6 ergänzt
- Formular-Hinweis: nur eigene Kontaktdaten eintragen (Web + App)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Neue Tabelle PushToken (ein Eintrag pro Gerät, Token eindeutig, max. 10
pro Konto); owner.registerPushToken trägt zusätzlich ein statt zu
überschreiben, optional mit Plattform (alte App-Versionen funktionieren)
- Versand an alle Geräte in einem Expo-Batch; Tokens mit
„DeviceNotRegistered“ werden gelöscht; Owner.expoPushToken wird bis zur
Übernahme nur noch mitgelesen (Übernahme per enable_rls_push_tokens.sql)
- App: meldet Plattform mit und trägt das Gerät beim Abmelden aus
(clearPushToken mit Token), damit kein Push mehr fürs alte Konto kommt
- Vermisst: Telefon/E-Mail werden beim Finden bzw. Schließen gelöscht
(Datensparsamkeit); Altbestand per cleanup_lost_report_contacts.sql
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Team & Rollen: Personen mit Name/E-Mail statt Clerk-ID, Rollen-
Erklärung, „Person hinzufügen“ per Suche nach Name/E-Mail statt
eingefügter user_-ID, deutsche Dialoge; listModerators liefert Namen
- Mitteilungen, Rechtstexte, Begrüßung, Empfehlungen: einheitlicher
Seitenkopf, „Halter“ statt „Owner“
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Beiträge: Suche + Spaltenwahl beschriftet, „Kommentare“ plus Menü „…“
mit beschrifteten Aktionen statt sechs Symbolen und Hilfe-Popover,
Pfoten/Kommentare/Meldungen als Symbole statt Emojis, komplett deutsch;
Spaltenzahl per useSyncExternalStore (behebt Lint-Fehler setState im Effect)
- Tiere: Seitenkopf, „Halter“ statt „Owner“; Detailfenster zeigt Name und
E-Mail des Halters (Clerk) und deutsche Tierart/Rasse
- Werbung, Musik: Seitenkopf mit Aktion, Statusabzeichen, deutsche Texte
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Meldungen: Seitenkopf, Statusabzeichen für Schwere/Grund, beschriftete
Knöpfe „Abweisen“/„Beitrag löschen“, gemeldete Profile mit Tiername
statt ID (listReports liefert targetPet), Pfoten statt Likes
- Verifizierung: komplett deutsch, Status-Filter mit Beschriftung,
Tierart/Rasse deutsch aus den Übersetzungstabellen (taxonomy-name)
- Vermisst: Seitenkopf, Status-Tabs, Statusabzeichen
- Nachrichten: passende Höhe im neuen Rahmen, am Handy Liste ODER
Verlauf mit Zurück-Knopf, Menü-Zähler sofort aktualisiert
- Sperrliste: deutsch, Filter beschriftet, kompakte Liste
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Protokoll (/log):
- Jeder Eintrag als deutscher Satz mit Namen statt Codes/IDs, z. B.
„Daniel hat Jessi den Rang Botschafter verliehen“; Begründungen
bereinigt (Rang-IDs, Feldlisten, JSON, true/false übersetzt)
- Nach Tagen gruppiert, Filter nach Bereich (Chips) und Teammitglied
(Auswahl mit Namen); Codes, IDs und IP unter „Technische Details“
- Neuer Router adminAudit (list, moderators) löst Tiere, Halter (Clerk),
Beitrags-Autoren, Werbung, Musik und Ränge auf; formatAuditEntry
übersetzt alle rund 50 Aktionen. admin.getModerationLog entfernt (ungenutzt)
Halter (/users):
- Tabelle mit Name/E-Mail, Tieren, Status-Abzeichen und Rolle statt
Clerk-ID und sechs Knöpfen pro Zeile; Eingriffe im Menü „…“,
Details (Registrierung, Sperrgrund, Konto-ID) zum Aufklappen
- Dialoge deutsch und in eigener Komponente UserActionDialogs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Website-Theme (next-themes) überschrieb dark/color-scheme auf <html>
nachträglich → dunkler Scrollbalken, schwarzer Schalter im Hellmodus;
Admin-Wahl wird jetzt per MutationObserver durchgesetzt
- Trend bei kleiner Vergleichsbasis absolut (+15 statt +1500 %)
- Diagramm: ganzzahlige y-Achse, keine überlappenden Datumslabels, breiter
- Suche: Tierart als Unterzeile, Kürzel „/“ nur bei leerem Feld
- Kopfzeile: Platzhalter statt „Admin“, solange der Name lädt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Sidebar nach Aufgaben gruppiert (Moderation, Inhalte, Community,
Verwaltung), komplett deutsch, mit Zählern für offene Meldungen,
Verifizierungen, Vermisst-Meldungen und ungelesene Team-Nachrichten
- Kopfzeile mit Breadcrumb, globaler Suche (Tiere + Halter), Hell/Dunkel
und eigenem Namen + Rolle; hell als Standard, Wahl im Cookie
- Startseite: Kennzahlen mit Vorwochen-Vergleich, Moderationsstatus mit
Wartezeit, letzte Eingänge, Schnellzugriff, Notschalter als Schalter,
ein Aktivitäts-Diagramm mit Umschalter statt fünf Karten
- Eigene Admin-Farbtokens (Orange in beiden Modi, Statusfarben); alle
Admin-Seiten von festen Dunkel-Klassen auf Tokens umgestellt
- Neuer Router adminOverview (getQueues, getKpis, getInbox, search)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Android kürzt Alert-Titel auf zwei Zeilen. Lange Texte stehen jetzt als
Nachricht unter einem kurzen Titel (Meldung gestartet, Entwarnung, Fehler).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Admin „Vermisst“ (/p/[secret]/lost): alle Meldungen mit Status, Ort/Zeit,
Reichweite (benachrichtigte Tiere), freigegebenen Kontaktwegen; Moderatoren
schließen vergessene Meldungen (ohne Entwarnung) oder löschen Missbrauch,
beides im Audit-Log (CLOSE_/DELETE_LOST_REPORT)
- App: eigener Vermisst-Bildschirm /lost/[petId] mit Foto, Merkmalen,
Kontakt (Anrufen, E-Mail, Nachricht in PawFeed), Fotos und Teilen —
Profil-Banner und Push-Tipp auf PET_LOST führen dorthin statt in den Browser
- lostReports.byPet + gemeinsamer Lader loadLostReportView für App und
öffentliche Seite
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- LostReport (eine aktive Meldung je Tier) + Pet.lostSince als Cache fürs
Abzeichen, NotificationType PET_LOST/PET_FOUND
- lostReports.create/update/markFound/mine: nur Besitzer, nicht im
Gedenkmodus, höchstens eine Meldung pro 24 h, Zeitpunkt nicht in der Zukunft
- Mitteilung + Push an Follower und gefolgte Tiere, je Besitzer einmal, eigene
Tiere nie; optionale Entwarnung bei „Wieder da!“
- Öffentliche Seite /vermisst/<code> ohne Login: Foto, Merkmale, zuletzt
gesehen, Kontakt nach Wahl des Besitzers (Telefon/E-Mail/PawFeed),
Fotos aus dem Feed, Vorschaubild; Suchmaschinen nur wenn erlaubt;
nach dem Finden „Wieder sicher zu Hause“ ohne Kontaktdaten
- Web + App: Melden ganz oben in „Profil bearbeiten“, Vermisst-Banner im
Profil, Abzeichen neben dem Namen, Mitteilungen führen zum Profil
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
„Über die Regenbogenbrücke gegangen“ statt „verstorben“, Anteilnahme im
Bestätigungsdialog, „Tag des Abschieds“, „Profil als Erinnerung bewahren“ —
Web, App, Mitteilung und Push-Text.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pet.deceasedAt + NotificationType.PET_DECEASED (additiv)
- pets.setDeceased: nur Besitzer, kein Datum in der Zukunft, rückgängig
machbar; beim ersten Setzen einmalig stille Mitteilung (ohne Push) an
Follower anderer Besitzer
- Verstorbene Tiere bekommen keine Geburtstags-/Adoptionstag-Mitteilungen,
Impf-Erinnerungen und Tier-Vorschläge mehr und werden nicht vorgeschlagen
- Abzeichen „In Erinnerung“ (Ribbon) überall neben dem Namen, Gedenk-Banner
im Profil, Bereich „Gedenkmodus“ in „Profil bearbeiten“ (Web + App)
- Mitteilung führt zum Profil des Tiers (Liste + Push-Tap)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tester-Wunsch 04.10.: „Benachrichtigung bringt dich auf kuerzestem Weg
dorthin, wo es wichtig ist“.
- Nachrichten: notifications.list liefert die conversationId (ueber das
sortierte Tier-Paar), App und Web oeffnen direkt das Gespraech.
- Push-Mitteilungen: Antippen fuehrte bisher nur in die App. Jetzt
useNotificationTapRouting (useLastNotificationResponse, auch Kaltstart),
wechselt bei Bedarf aufs betroffene eigene Tier. Push-Daten tragen dafuer
petId, actorPetId, storyId, conversationId.
- Eine gemeinsame Zielregel fuer Liste und Push (mobile/src/lib/
notification-route.ts, getestet): Nachricht → Gespraech, Kommentar/Pfote/
Erwaehnung/Paw-Back → Beitrag, Story → Story, Follow/Vorschlag → Profil,
Geburtstag/Adoption/Impfung → Gesundheit, Rang → Einladen.
- Bei Nachrichten und Storys fuehrt auch der Name zum Ziel; Story-Viewer
laedt Name/Bild nach, wenn er per Push geoeffnet wird.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tester-Feedback 04.10. (STORY_MENTION):
- Web: Klick oeffnet die Story als Overlay an der richtigen Stelle
(initialStoryId) statt ueber das Tierprofil; abgelaufen → Profil.
- App: ganzer Eintrag inkl. Name oeffnet die Story, Viewer springt per
storyId direkt zur markierten Story.
- Unbekannte Mitteilungstypen zeigen einen neutralen Text statt des
Code-Namens (der rohe Text kam von einem Geraet mit aelterem App-Stand).
- Keine Markier-Mitteilung an eigene Tiere des Erstellers (petsOfOtherOwners).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tester-Feedback 04.10.:
- iOS: Text-Story liess sich nicht oeffnen, beim Foto aus der Galerie
verschwand alles und nur das X leuchtete auf. Ursache: der Editor lief im
Auswahl-Screen, der auf iOS ein Sheet ist; Kopfzeile umschalten und ein
weiteres natives Modal waehrend der Praesentation scheiterten. Jetzt eigener
Screen story-editor (fullScreenModal, ohne Kopfzeile, ohne Wisch-zum-
Schliessen); Texteditor und Auswahlfenster sind Ebenen (EditorLayer) statt
nativer Modals, Android-Zurueck schliesst sie.
- Android: Farbreihe im Texteditor lag hinter der Gestenleiste → echte
Safe-Area-Abstaende oben/unten.
- Tippen auf eine freie Stelle der Story oeffnet den Texteditor.
Am Android-Emulator durchgeklickt (Text-Story, Texteditor, Verschieben,
GIF-Suche live, Sticker, X zurueck). iOS nicht testbar.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Web zeigt Story-Editor-Inhalte nur an (Entscheidung: kein Web-Editor):
StoryOverlayLayer mit gleicher Geometrie/Groessen wie die App, Text-Storys
mit Farbverlauf, Markierungen fuehren ins Tierprofil, Notschalter beachtet.
Mitteilungen STORY_MENTION/COMMENT/REACTION, Hinweistexte: Follower-
Sichtbarkeit regelt jetzt auch das Markieren.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Typecheck gruen. Offen: Lint (React-Compiler-Regeln in EditableOverlay,
setState-in-effect im Viewer), Web-Anzeige, Geraetetest, Deploy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- mobile/src/lib/story-overlays.ts + story-stickers.ts (identisch zu src/lib,
plus Gesten-Geometrie fuer den Editor); Paritaetstest liegt in mobile/
(Docker-Build kennt mobile/ nicht)
- Rueckgaben von create/createText/getVideoStatus ohne overlays-JSON und
flacher Eingabetyp: Prismas rekursiver JsonValue- bzw. der tiefe Zod-Typ
sprengten sonst den App-Compiler (TS2589)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wer darf Nachrichten schreiben (dmPolicy) und wer darf die Follower sehen
(followerVisibility) waren nur im Web einstellbar. Neue PrivacySettings-
Komponente mit denselben Optionen/Texten wie im Web, speichert jede Auswahl
sofort ueber pets.update.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
found.md: Testnutzer mit "Goldene Pfote" (PROFILE_RING) sah keinen Ring —
der Ring war bewusst nur im Profilkopf. Auf Wunsch jetzt ueberall:
- petIdentitySelect liefert owner.referralRankId/referralPerks mit
(referralOwnerSelect), ebenso search, explore.listPets und pets.list.
- Web: RankRing (box-shadow, keine Layoutverschiebung) um Avatare in Feed,
Kommentaren, Suche, Explore, Nachrichten, Mitteilungen, Follower-Listen,
Meilenstein-/Repost-Karten, Story-Zuschauern/-Kommentaren; PetAvatar
nimmt owner.
- App: PetAvatar mit owner zeichnet den Ring als Overlay; an allen
Listen/Karten uebergeben.
- PawRing (Web + App): ungesehene Story-Pfote in Rangfarbe statt Orange,
ohne Story schlichter Ring in Rangfarbe; gesehene Storys bleiben grau.
Sponsor-Felder im Kartentyp optional (Identity-owner traegt nur den Rang).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Beim git mv in 7ab74f8 blieb die sed-Korrektur des Imports unstaged; im Repo
zeigte der Test noch auf ../../mobile/src/lib/date-format.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
found.md: Admin -> Tiere zeigte nur den hoechsten Rang (Cache referralRankId).
Die Liste laedt jetzt alle ReferralRankAchievements des Owners (nach Schwelle)
und zeigt sie als Symbole, unabhaengig vom Vorteil NAME_BADGE; entzogene
Raenge ausgegraut, Tooltip mit 'manuell vergeben' / 'entzogen'.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
found.md (iOS-Feedback): Push kam an, aber die Sprechblase zeigte nichts.
MessagesHeaderButton zeigt jetzt conversations.unreadCount im selben Badge
wie die Glocke (gemeinsame UnreadBadge-Komponente), aktualisiert alle 30 s;
Lesen eines Chats invalidiert den Zaehler bereits.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
found.md: Gewichtsdaten wurden nur als Liste angezeigt. Neues WeightChart
(react-native-svg, Port des Web-Diagramms) ab 2 Eintraegen ueber der Liste:
x-Achse zeitproportional (unregelmaessige Wiegetermine), runde y-Ticks
(1/2/5 x 10^n), Datumslabels nach Pixelabstand, Antippen waehlt die
naechste Messung (Wert + Datum im Kopf), Veraenderung seit erster Messung.
Linienfarbe als neues Token chartLine (#ea580c), mit dem Dataviz-Validator
gegen helle und dunkle Flaechen geprueft. Geometrie rein in
src/lib/weight-chart.ts mit Tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
found.md: Abweisen schickt dem Melder eine Team-Nachricht mit optionaler
Begruendung (auch im ModerationLog), Loeschen eines gemeldeten Beitrags
dankt jedem Melder einmal. Beides per Schalter im Admin-Dialog abschaltbar,
best-effort nach der Moderation. Die interne Loesch-Begruendung geht nicht
an den Melder.
Fix nebenbei: deleteReportedPost loescht jetzt die Reports des Beitrags
(targetPostId ist keine Relation, sie blieben bisher verwaist in der Liste).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
found.md (iOS-Feedback): Hunde-/Katzen-Rassenlisten sind lang. OptionPicker
zeigt ab 10 Eintraegen oben ein Suchfeld, das ohne Gross-/Kleinschreibung
und Akzente filtert (filterOptionsByName). Bei offener Tastatur rueckt die
Liste nach oben, damit sie nicht verdeckt wird. Wirkt in Tier anlegen,
Profil bearbeiten und Explore-Filter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>