Commit Graph
456 Commits
Author SHA1 Message Date
adminandClaude Opus 5.5 0668459c1e fix(test): Import-Pfad im verschobenen Datums-Test mitcommitten
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>
2026-10-04 15:12:07 +02:00
adminandClaude Opus 5.5 dbc416c43c feat(admin): Tierliste zeigt alle erreichten Raenge
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>
2026-10-04 15:01:51 +02:00
adminandClaude Opus 5.5 2bd4b2d973 feat(mobile): Badge fuer ungelesene Nachrichten an der Sprechblase
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>
2026-10-04 15:01:51 +02:00
adminandClaude Opus 5.5 361aba0d1d docs(mobile): found.md — Gewichtsdiagramm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 14:55:19 +02:00
adminandClaude Opus 5.5 e60abbabc6 feat(mobile): Gewichtsverlauf als Diagramm
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>
2026-10-04 14:52:38 +02:00
adminandClaude Opus 5.5 81e617ece5 fix(admin): Melder-Nachricht grammatisch korrekt (zum Beitrag/Profil)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:16:48 +02:00
adminandClaude Opus 5.5 c678c4cf27 docs(mobile): found.md — Rassensuche + Report-Rückmeldung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:16:12 +02:00
adminandClaude Opus 5.5 f51b158989 feat(admin): Team-Nachricht an Melder bei abgewiesenem/bestaetigtem Report
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>
2026-10-04 13:09:39 +02:00
adminandClaude Opus 5.5 01459c7e0e feat(mobile): Suchfeld im Rassen-Dropdown
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>
2026-10-04 13:09:38 +02:00
adminandClaude Opus 5.5 a2af4eda6a docs(mobile): found.md — iOS-Tastatur verdeckt Datumsfeld
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:56:09 +02:00
adminandClaude Opus 5.5 333ba16573 fix(mobile): iOS-Tastatur verdeckt Eingabefelder nicht mehr
Profil bearbeiten (Geburtstag/Adoptionstag), Gesundheit, neuer Beitrag,
neuer Meilenstein, Tier anlegen/Onboarding und Einladen hatten keinen
Tastatur-Ausgleich: das fokussierte Feld lag unter der Tastatur.
automaticallyAdjustKeyboardInsets setzt den unteren Inset und scrollt
das aktive Feld in den sichtbaren Bereich (RN Fabric ScrollView),
keyboardShouldPersistTaps="handled" laesst Feldwechsel ohne Zuklappen zu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:54:35 +02:00
adminandClaude Opus 5.5 9136981af7 docs(mobile): found.md — Impf-Erinnerung live
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:52:20 +02:00
adminandClaude Opus 5.5 7ab74f8077 fix: Datums-Test nach mobile/ verschieben (Docker-Build ohne mobile/)
Der Test in src/__tests__ importierte aus mobile/, das .dockerignore und
die Web-tsconfig ausschliessen -> next build brach beim Typecheck ab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:50:35 +02:00
adminandClaude Opus 5.5 4214a26bd7 docs: Cron vaccine-reminders im NAS-Zeitplan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:48:38 +02:00
adminandClaude Opus 5.5 6a88214186 docs(mobile): found.md — Datum TT.MM.JJJJ + Impf-Erinnerung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:46:30 +02:00
adminandClaude Opus 5.5 c74bbffccb feat: Datumseingabe TT.MM.JJJJ (App) + Erinnerung an Folgeimpfung
Datum (found.md, iOS-Feedback): neue DateField-Komponente mit Ziffern-
tastatur und automatisch eingefügten Punkten (TT.MM.JJJJ) für Geburtstag,
Adoptionstag, Gewicht, Tierarzt und Impfungen. Parser akzeptiert weiter
"-" und "/" sowie einstellige Tage/Monate. Wheel-Picker bleibt in
PENDING-NATIVE-BUILD.md (natives Modul).

Impf-Erinnerung (found.md, iOS-Feedback): täglicher Cron
/api/cron/vaccine-reminders erinnert einmalig 30 Tage vor
Vaccine.nextDueDate per Mitteilung (VACCINE_DUE) + Push mit Impfname und
Datum. Schema: NotificationType.VACCINE_DUE, Notification.vaccineId
(Cascade), Vaccine.reminderSentAt (Claim gegen Doppelversand, wird bei
Fehler wieder freigegeben). Web + App zeigen die Mitteilung an, Tippen
öffnet die Gesundheitsseite. App: Schnellauswahl +1/+3 Jahre für den
Folgetermin plus Hinweis auf die Erinnerung.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:42:20 +02:00
adminandClaude Opus 5.5 7169840000 fix(mobile): Apple-Login hängt nicht mehr still bei fehlenden Pflichtfeldern
Fehlen nach dem Apple-Login noch Pflichtangaben (z. B. Vor-/Nachname,
die Apple nur bei der allerersten Autorisierung schickt), zeigt der
Button jetzt eine Fehlermeldung und meldet die Felder an Sentry, statt
kommentarlos nichts zu tun.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:01:19 +02:00
adminandClaude Opus 5.5 f112d36f4a feat: neues Tier folgt dem Kurator-Tier zurück
Bisher folgte nur "PawFeed Team" dem neuen Tier, der Feed des neuen
Nutzers startete leer. welcomeNewPet legt jetzt auch den Follow in
Gegenrichtung an und befüllt den Redis-Feed per backfillOnFollow mit den
letzten Team-Posts. Gleicher Admin-Schalter (autoFollowEnabled),
Beschriftung im Kurator-Panel angepasst.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 19:49:46 +02:00
adminandClaude Opus 5.5 80e27a7f0b docs(mobile): found.md — Upload-Fortschritt Video-Storys
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:47:03 +02:00
adminandClaude Opus 5.5 5606a81dd2 feat(mobile): Fortschrittsbalken beim Video-Story-Upload
Statt nur Spinner: „Upload wird vorbereitet …“, dann Balken + Prozent aus
expo-file-system File.upload onProgress (nativ seit 57.0.7 im 1.0.6-Build,
daher OTA). Vorschau ist während des Uploads nicht mehr antippbar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:44:35 +02:00
adminandClaude Opus 5.5 6979447b6d docs(mobile): found.md — Video-Storys per OTA live
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:29:48 +02:00
adminandClaude Opus 5.5 69e2c1364e feat(mobile): Video-Storys in der App (Upload + Wiedergabe)
Merged feature/mobile-video-stories (Gitea #37) auf den seit 02.10.
umgebauten Story-Viewer: Galerie-Picker nimmt Videos bis 30 s, Upload
direkt zu Mux, Viewer spielt READY-Videos ab (Fortschritt aus der echten
Wiedergabe, Weiter bei playToEnd) und zeigt PROCESSING/ERROR. Offene
Kommentar-/Zuschauer-Sheets pausieren das Video wie den Foto-Timer.
Nur JS — expo-video ist seit dem 1.0.6-Build nativ enthalten, also OTA.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:25:24 +02:00
adminandClaude Opus 5.5 a9b6a57585 docs(mobile): found.md — HEIF-Fix vom Nutzer bestätigt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:37:50 +02:00
adminandClaude Opus 5.5 00fb0db168 docs: CLAUDE.md — Dashboard-Kachel Tierarten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:34:19 +02:00
adminandClaude Opus 5.5 f1ccc78005 feat: Dashboard-Kachel Tierarten klappbar (standardmäßig zu, Zustand gemerkt)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:31:09 +02:00
adminandClaude Opus 5.5 9adba560a7 feat: Admin-Dashboard — Verteilung der Tiere nach Tierart und Rasse
- petAdmin.speciesDistribution: Anzahl pro Tierart (auch Arten ohne Tiere)
  und pro Rasse, deutsche Namen, ohne das Kurator-Tier „PawFeed Team“
- Karte "Tierarten" auf dem Dashboard: sortiertes Balkendiagramm (eine
  Reihe, Markenorange), Anzahl + Anteil als Text, Tooltip bei Hover/Fokus,
  Klick klappt die Rassen der Art auf

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:17:21 +02:00
adminandClaude Opus 5.5 efc82d636d docs: CLAUDE.md — Tierverwaltung, deletePetCompletely, Rang-Sperre
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:05:05 +02:00
adminandClaude Opus 5.5 566a2eedd0 feat: Admin-Tierverwaltung + vollständiges Löschen von Tieren
Admin /p/[secret]/pets:
- Liste mit Suche (Name, Spitzname, Empfehlungscode, ID), Filtern und
  Sortierung; Detail-Panel mit Kennzahlen, Owner, Profiltexten, Beiträgen
- Verifiziert / Gründungsmitglied pro Tier umschalten
- Empfehlungsränge des Owners: dauerhaft entziehen (bis zur Freigabe),
  freigeben oder manuell vergeben (besondere Leistung)
- Inhalte leeren (Profilbild, Bio, Adoptionsgeschichte, Spitzname) und Tier
  löschen — jeweils mit Begründung, Owner per Team-DM informiert bzw. per
  E-Mail, wenn es sein einziges Tier war

Ränge: ReferralRankAchievement bekommt revokedAt/revokeReason/
grantedManually; entzogene Ränge werden weder neu vergeben noch im Cache
berücksichtigt (awardRanks, recomputeReferralRanks, referrals.me, Export).

Fix: deletePetCompletely (src/lib/delete-pet.ts) für Owner-Löschen,
Kontolöschung und Admin — vorher konnte das Löschen an StoryView/Report/
Repost-Fremdschlüsseln ohne Cascade scheitern, und die Zähler an fremden
Beiträgen/Storys wurden nicht verringert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:03:05 +02:00
adminandClaude Opus 5.5 7a064d8a36 docs: CLAUDE.md — Download-Weiterleitung /app
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:41:49 +02:00
adminandClaude Opus 5.5 94c143e17d feat: Download-Weiterleitung /app für Flyer und QR-Codes (D3)
- Android → Google Play, UTM-Werte als Play-referrer (Play Console)
- iPhone → App Store, sobald APP_STORE_URL gesetzt ist (D5); bis dahin Web
- sonst → Web-Startseite; ?ref=<Code> führt auf die Einladungsseite /r/<Code>
- nur sichere UTM-Werte werden übernommen, nie gecacht (302, no-store)
- Zählung pro Tag/Quelle/Gerät in Redis, Anzeige im Admin unter
  Empfehlungen → Übersicht (30 Tage)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:39:40 +02:00
adminandClaude Opus 5.5 8143e7b667 docs: CLAUDE.md — Gründungsmitglieder und Kurator-Begrüßung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:33:30 +02:00
adminandClaude Opus 5.5 307b76e8fd feat: Gründungsmitglieder (erste 250 Tiere) und Kurator-Begrüßung
- Pet.isFoundingMember: in pets.create per bewachter SQL-Anweisung für die
  ersten 250 Tiere gesetzt, nie entzogen; Abzeichen (Spross) in Feed und
  Profil, Web + App, unabhängig vom Empfehlungsprogramm
- Kurator "PawFeed Team": folgt jedem neuen Tier und schickt eine
  Begrüßungs-Direktnachricht (DE/EN nach Sprache beim Anlegen), im
  Hintergrund — blockiert das Onboarding nicht
- CuratorSettings + Admin-Seite /p/[secret]/curator: Schalter, Texte mit
  Pflicht-Platzhalter {name} und Vorschau, Zähler der Gründungsmitglieder
- prisma/backfill_founding_members.sql, prisma/enable_rls_curator.sql

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:26:43 +02:00
adminandClaude Opus 5.5 9f7acf1d98 docs(mobile): found.md — 7-Tage-Story-Ansicht deployt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:35:46 +02:00
adminandClaude Opus 5.5 2c0680cef9 feat: 7-Tage-Ansicht der eigenen Storys für den Ersteller (Web + App)
- stories.listActive: der Owner bekommt seine Storys der letzten 7 Tage mit
  isExpired, alle anderen weiterhin nur die aktiven 24 Stunden
- stories.hasActiveStory: optional includeOwnRecent → grauer Ring
  (expiredOnly) nur in der Story-Leiste, nicht an Profilbildern im Feed
- Viewer: Hinweis "Abgelaufen – nur für dich sichtbar", Kommentare bei
  abgelaufenen Storys nur lesbar, Pfote nur als Zähler; Löschen und
  Zuschauerliste bleiben

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:30:22 +02:00
adminandClaude Opus 5.5 a01c58e5f0 feat: Aufräum-Job für Storys älter als 7 Tage
- /api/cron/cleanup-stories (CRON_SECRET): löscht Storys älter als 7 Tage
  samt Aufrufen, Pfoten, Kommentaren, Supabase-Bild und Mux-Asset; max. 200
  pro Lauf, Fehler einzelner Storys brechen den Lauf nicht ab
- gemeinsame Funktion deleteStoryWithMedia (src/lib/story-cleanup.ts), auch
  von stories.delete genutzt
- Datenschutzerklärung Abschnitt 6: Storys spätestens nach 7 Tagen gelöscht
- Datenexport: Story-Block heißt "stories" statt "activeStories"
- CLAUDE.md: Cron-Jobs laufen über die NAS-Crontab + docker/run-cron.sh
  (der alte Hinweis "nichts ruft trim-feeds auf" war veraltet)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:43:07 +02:00
adminandClaude Opus 5.5 ac664d488d docs(mobile): found.md — Story löschen deployt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:21:12 +02:00
adminandClaude Opus 5.5 81d9c6da30 feat: eigene Story löschen (Web + App)
- stories.delete: nur Owner; Aufrufe, Story (Pfoten/Kommentare per Cascade),
  danach Bild in Supabase Storage bzw. Mux-Asset best-effort
- Web: Papierkorb neben der Zuschauerzahl + Rückfrage, Timer pausiert,
  gelöscht wird die beim Antippen gemerkte Story
- App: gleicher Papierkorb mit nativer Rückfrage, Timer pausiert
- found.md: Nutzer-Feedback "Story löschbar" erledigt, 7-Tage-Wunsch mit
  Befund als offener Punkt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:17:16 +02:00
adminandClaude Opus 5.5 4ec5d8c5f4 docs(mobile): found.md — Story-Fixes deployt (Web + OTA)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:03:06 +02:00
adminandClaude Opus 5.5 ccebfa46a6 feat: Story-Kommentare, Pfoten und Zuschauerliste in der App
- App-Viewer: Pfote, Kommentar-Sheet (schreiben, eigene löschen) und für die
  eigene Story die Zuschauerliste; Timer pausiert, solange ein Sheet offen ist
- stories.listActive: optionales viewerPetId → reactedByViewer, damit die
  Pfote gefüllt startet (abwärtskompatibel für alte App-Builds)
- Web-StoryPawButton nutzt reactedByViewer ebenfalls und wird pro Story
  neu initialisiert

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:59:02 +02:00
adminandClaude Opus 5.5 204d5f6831 fix: eigene Story als Ring "Deine Story" in der Story-Leiste (Web + App)
Die Leiste zeigte nur Storys gefolgter Tiere — das eigene aktive Tier war
nie enthalten, man konnte die eigene Story nach dem Posten nicht ansehen.
Neuer Ring direkt nach der "+"-Kachel, solange stories.hasActiveStory für
das aktive Tier true ist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:46:29 +02:00
adminandClaude Opus 5.5 1a24ebae89 docs(mobile): found.md — HEIC-Fix deployt (Web + OTA)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:32:11 +02:00
adminandClaude Opus 5.5 1bf0f9282a fix: HEIF/HEIC-Fotos (Apple) für Beiträge und Storys annehmen
- App: post-new.tsx sortierte HEIC/HEIF still aus, obwohl resizeForUpload()
  ohnehin in JPEG umwandelt — jetzt erlaubt, plus Hinweis bei übersprungenen
  Fotos
- Web: neues src/lib/heic-to-jpeg.ts wandelt HEIC vor dem Upload im Browser
  in JPEG um (Safari kann HEIC nativ dekodieren); eingebaut in Beiträge,
  Storys, Meilensteine und Tierbild, accept um HEIC ergänzt. Browser ohne
  HEIC-Dekodierung bekommen eine klare Meldung statt "falsches Format".
- Server-Whitelist (JPEG/PNG/WebP) bleibt unverändert

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:26:24 +02:00
adminandClaude Opus 5.5 8f8fc8d75e fix: Tierbild auf der Einladungsseite /r/[code] größer darstellen
Die Avatar-Variante "lg" setzt per data-Attribut fest size-10 (40 px) und
überstimmte die eigene Größe — jetzt Standardvariante mit size-28 / sm:size-36
und dezentem Ring in Markenfarbe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 19:23:08 +02:00
adminandClaude Opus 5.5 18f25ce316 fix: DSGVO-Lücken des Empfehlungsprogramms schließen (Auskunft + Löschung)
- Datenexport (Art. 15): neuer Block referralProgram mit eigenem Code,
  Herkunftsangabe, "eingeladen von", gemachten Einladungen, erreichten Rängen,
  aktuellen Vorteilen und den früheren Einmal-Codes. Andere Personen nur über
  den Tiernamen — invitedById (Clerk-ID eines Dritten) fliegt aus dem Export.
- Kontolöschung: invitedById bei Eingeladenen und usedById bei Beta-Codes
  werden geleert, damit keine Clerk-ID der gelöschten Person zurückbleibt.
  Gezählte Einladungen bleiben gezählt.
- Einlösen sperrt jetzt auch über invitedAt, damit nach dem Leeren von
  invitedById kein zweiter Code eingelöst werden kann.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 18:57:59 +02:00
adminandClaude Opus 5.5 32ba01f7cf refactor: altes Einladungs-Gate (InviteCode/pf_invite) durch Empfehlungsprogramm ersetzen
- Proxy-Sperre für /sign-up, INVITE_REQUIRED, set-invite/consume-invite,
  invites-Router, Admin-Invite-Seite und -Prozeduren, Startcodes in
  pets.create entfernt — Registrierung ist offen
- /join?code=… leitet auf /r/<code> um, /invite auf /einladen; alte geteilte
  Links laufen nicht ins Leere
- InviteCode-Tabelle bleibt nur als Historie (Kontolöschung räumt sie weiter auf)
- Datenschutzerklärung 4b (Empfehlungsprogramm, Herkunftsangabe, pf_ref-Cookie)
  und Nutzungsbedingungen 3b (Programmbedingungen, Bestandsschutz, Missbrauch)
- CLAUDE.md: Abschnitt "Referral program" statt "Invite system"

Build, Typecheck und alle Tests grün.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:35:22 +02:00
adminandClaude Opus 5.5 78e16c9210 feat(mobile): Empfehlungsprogramm in der App
- Bildschirm "Freunde einladen" (/invite, aus den Einstellungen erreichbar):
  eigener Code mit nativem Teilen-Dialog, Rangleiter mit Fortschritt,
  eingeladene Tiere, nachträgliche Code-Eingabe im Einlösefenster
- Onboarding-Schritt "Wie hast du von PawFeed erfahren?" mit Code-Eingabe,
  einmal pro Owner (referrals.onboardingState)
- Rang-Abzeichen in PetIdentityBadges (Feed und Profil), Profilring in
  Rangfarbe, "Eingeladen von …" im Tierprofil
- Benachrichtigungen REFERRAL_JOINED / REFERRAL_RANK_UP
- Keine neuen nativen Module (React Native Share) — per OTA auslieferbar

Typecheck grün; nicht auf einem Gerät getestet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:30:11 +02:00
adminandClaude Opus 5.5 4d0aa7ab9e feat: Clerk-unabhängiges Empfehlungsprogramm mit einstellbaren Rängen (Web + Admin)
Persönliche, unbegrenzt nutzbare Empfehlungscodes (z. B. BUBI-7K3M), die erst
nach der Registrierung im Onboarding eingelöst werden — keine Kopplung an den
Clerk-Sign-up-Ablauf mehr. Registrierung ohne Code bleibt möglich.

- Schema (rein additiv): Owner-Felder für Code, Einladungsstatus, Zähler und
  Rang-Cache, ReferralRank / ReferralRankAchievement / ReferralSettings,
  AcquisitionSource, NotificationType REFERRAL_JOINED / REFERRAL_RANK_UP
- Kernlogik src/lib/referrals.ts: Einlösen (7-Tage-Fenster, kein eigener Code,
  keine Kreis-Einladungen, gesperrte Einladende ungültig), gegenseitiges
  Folgen, Qualifizierung erst nach Tier + erstem Beitrag (Foto oder fertiges
  Video), Tageslimit mit Prüf-Markierung, Ränge mit Bestandsschutz
- Web: /einladen, öffentliche Seite /r/[code], Onboarding-Schritt
  "Wie hast du von PawFeed erfahren?", Rang-Abzeichen, Profilring,
  "Eingeladen von …", neue Benachrichtigungen
- Admin /p/[secret]/referrals: Ränge anlegen/bearbeiten/deaktivieren mit
  Live-Vorschau, Einstellungen, Übersicht mit Prüfung und Aberkennung;
  bevorzugte Verifizierung als Vorteil
- prisma/scripts/referral-setup.ts: Start-Ränge, Settings, Code-Backfill,
  optional --credit-existing für Alt-Einladungen

Noch offen: Mobile-App, Abbau des alten InviteCode-Ablaufs, Rechtstexte,
db push + Deploy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:25:13 +02:00
adminandClaude Opus 5.5 02662528cf chore(mobile/ios): bump iOS build number to 3
Build 2 was rejected in TestFlight beta review (missing demo credentials)
and cannot be resubmitted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 06:01:25 +02:00
adminandClaude Opus 5.5 959d67cc29 chore(mobile/ios): bump iOS build number to 2
Build 1.0.6 (1) was expired in TestFlight and cannot be re-used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:21:57 +02:00
adminandClaude Opus 5.5 2cd13537f7 docs(mobile): found.md — gesture-bar and story-ring fixes shipped via OTA
Also includes the user's own pending found.md edits (new entries, iOS
section header, trailing-whitespace cleanup).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:43:26 +02:00