Hier ist eine Liste, die ich erhalten habe, mit einer aufstellung der wichtigsten Admin-Funktion.
Diese liste einmal mit unserem bestand abgleichen. Fehlende Elemente oder Funktionen. Auflisten und mit mir besprechen
Admin Dashboard Spec: Social Media Platform
1. Benutzerverwaltung (User Management)
Nutzer-Übersicht: Suchen, Filtern (Status, Datum, Rolle) und Paginierung aller Accounts.
Profeleinsicht: Stammdaten, Verifizierungsstatus, Verknüpfungen (E-Mail/Telefon) und Registrierungs-IP.
Bin den kompletten admin.ts-Router (32 Prozeduren) und alle 8 Admin-Seiten (/p/[secret]/{users,moderators,posts,reports,ads,invites,legal} + Dashboard) durchgegangen. Legende: ✅ vorhanden · ⚠️ teilweise · ❌ fehlt
1. Benutzerverwaltung
Spec-Punkt
Status
Notiz
Nutzer-Übersicht (Liste, Paginierung)
✅
listUsers
Suchen/Filtern (Status, Datum, Rolle)
❌
nur Pagination, keine Such-/Filterfunktion
Profileinsicht (Stammdaten, Pets, E-Mail/Name)
✅
inkl. Clerk-Batch-Fetch
Verifizierungsstatus / Verknüpfungen
❌
kein „verified"-Flag im Schema
Registrierungs-IP
❌
nirgends gespeichert
Rollen & Rechte (RBAC)
⚠️
nur 2 Stufen: SUPER_ADMIN / MODERATOR, kein „Support"
Passwort-Reset / 2FA-Reset anstoßen
❌
kein Admin-Trigger (Clerk übernimmt Auth selbst)
Konten sperren: Temp-Ban / Permanent-Ban
✅
banUser mit optionalem expiresAt
Shadowban
❌
nicht implementiert
Verifizierungs-Haken vergeben
❌
DSGVO-Export
✅
nur JSON, kein PDF
DSGVO-Löschung auf Anfrage
⚠️
existiert nur selbstständig durch den Nutzer (/api/account/delete), kein Admin-Button
nur Löschen oder Dismiss, kein „Ausblenden ohne Löschen"
Blacklist (Wörter/Links/Hashtags)
❌
nicht vorhanden
Auto-Mod (Spam-Schutz, KI-Erkennung)
❌
nicht vorhanden
Verwarnungssystem mit Historie
❌
nur Ban/Unban, keine separate Verwarnung
3. Analytics
Spec-Punkt
Status
Notiz
Owner/Pet/Post-Totals
✅
getStats
Owner-Wachstumskurve
✅
getOwnerGrowth
Post-Volumen über Zeit
✅
getPostsOverTime
DAU/MAU, Churn-Rate
❌
nicht vorhanden
Content-Performance aggregiert
⚠️
pro Post vorhanden, keine Plattform-Aggregat-Charts
System-Gesundheit (API-Latenz, Fehlerquote)
⚠️
über GlitchTip abgedeckt, nicht im Admin-Dashboard sichtbar
Moderations-Durchsatz pro Moderator
❌
ModerationLog existiert, aber keine Auswertung darauf
4. Plattform-Konfiguration
Spec-Punkt
Status
Notiz
Feature Flags / Wartungsmodus
❌
nicht vorhanden
System-Mitteilungen (Push/Banner/E-Mail)
❌
Notification-Modell ist nur pet-zu-pet, kein Broadcast
Trends & Promotion (Pinning, Trend-Hashtags)
❌
kein Pinning-Feld, keine kuratierte Empfehlungsliste
5. Monetarisierung
Spec-Punkt
Status
Notiz
Werbeanzeigen-Verwaltung
✅
voll da: CRUD + Species/Breed-Targeting + Zeitraum
Budget-Freigaben, Werbekonten-Sperren
❌
kein Advertiser-Account-Konzept
Abos / In-App-Käufe / Creator-Payouts
❌
keine Monetarisierung der Nutzer, kein Payment-System
Refund-Handling
❌
entfällt, da keine Zahlungen
6. Sicherheit & Compliance
Spec-Punkt
Status
Notiz
Audit Log
⚠️
ModerationLog existiert, protokolliert aber NICHT Ad-Erstellung/-Änderung und Rollenvergabe (grantRole/revokeRole)
IP-/Bot-Management, VPN-Erkennung
❌
nicht vorhanden
API-Key- & Webhook-Verwaltung
❌
Mux-Webhook existiert im Code, aber keine Admin-UI
Fazit: Solide abgedeckt sind Ads, Reports, Bans, Basis-Analytics und (seit letzter Woche) GDPR-Export/Team-Chat. Größte Lücken: Nutzer-Suche/-Filter, Auto-Mod/Blacklist, Feature Flags & System-Broadcasts, lückenloseres Audit-Log (Ads/Rollen fehlen), DAU/MAU-Analytics. Monetarisierung über Ads hinaus (Abos, Payouts) ist aktuell komplett out-of-scope für PawFeed — würde ich auch nicht empfehlen nachzubauen, das liest sich eher wie generische SaaS-Boilerplate-Spec statt etwas, das PawFeed konkret braucht.
Nächster Schritt: sinnvolle Nacharbeitungs-Reihenfolge festlegen (reine UI-Ergänzungen vs. Punkte, die neue Backend-Funktionen/Schema-Änderungen brauchen).
## Abgleich mit dem Bestand (Stand 2026-08-12)
Bin den kompletten `admin.ts`-Router (32 Prozeduren) und alle 8 Admin-Seiten (`/p/[secret]/{users,moderators,posts,reports,ads,invites,legal}` + Dashboard) durchgegangen. Legende: ✅ vorhanden · ⚠️ teilweise · ❌ fehlt
### 1. Benutzerverwaltung
| Spec-Punkt | Status | Notiz |
|---|---|---|
| Nutzer-Übersicht (Liste, Paginierung) | ✅ | `listUsers` |
| Suchen/Filtern (Status, Datum, Rolle) | ❌ | nur Pagination, keine Such-/Filterfunktion |
| Profileinsicht (Stammdaten, Pets, E-Mail/Name) | ✅ | inkl. Clerk-Batch-Fetch |
| Verifizierungsstatus / Verknüpfungen | ❌ | kein „verified"-Flag im Schema |
| Registrierungs-IP | ❌ | nirgends gespeichert |
| Rollen & Rechte (RBAC) | ⚠️ | nur 2 Stufen: `SUPER_ADMIN` / `MODERATOR`, kein „Support" |
| Passwort-Reset / 2FA-Reset anstoßen | ❌ | kein Admin-Trigger (Clerk übernimmt Auth selbst) |
| Konten sperren: Temp-Ban / Permanent-Ban | ✅ | `banUser` mit optionalem `expiresAt` |
| Shadowban | ❌ | nicht implementiert |
| Verifizierungs-Haken vergeben | ❌ | |
| DSGVO-Export | ✅ | nur JSON, kein PDF |
| DSGVO-Löschung auf Anfrage | ⚠️ | existiert nur selbstständig durch den Nutzer (`/api/account/delete`), kein Admin-Button |
### 2. Moderation & Content
| Spec-Punkt | Status | Notiz |
|---|---|---|
| Report-Queue | ✅ | `listReports`, `dismissReport`, `deleteReportedPost` |
| Priorisierung nach Schweregrad | ❌ | reine `createdAt`-Sortierung, kein Severity-Feld |
| Content-Vorschau im Kontext | ✅ | Bild/Video-Thumbnail + Post-Kontext |
| Schnellaktionen (Ausblenden/Löschen/Sicher markieren) | ⚠️ | nur Löschen oder Dismiss, kein „Ausblenden ohne Löschen" |
| Blacklist (Wörter/Links/Hashtags) | ❌ | nicht vorhanden |
| Auto-Mod (Spam-Schutz, KI-Erkennung) | ❌ | nicht vorhanden |
| Verwarnungssystem mit Historie | ❌ | nur Ban/Unban, keine separate Verwarnung |
### 3. Analytics
| Spec-Punkt | Status | Notiz |
|---|---|---|
| Owner/Pet/Post-Totals | ✅ | `getStats` |
| Owner-Wachstumskurve | ✅ | `getOwnerGrowth` |
| Post-Volumen über Zeit | ✅ | `getPostsOverTime` |
| DAU/MAU, Churn-Rate | ❌ | nicht vorhanden |
| Content-Performance aggregiert | ⚠️ | pro Post vorhanden, keine Plattform-Aggregat-Charts |
| System-Gesundheit (API-Latenz, Fehlerquote) | ⚠️ | über GlitchTip abgedeckt, nicht im Admin-Dashboard sichtbar |
| Moderations-Durchsatz pro Moderator | ❌ | `ModerationLog` existiert, aber keine Auswertung darauf |
### 4. Plattform-Konfiguration
| Spec-Punkt | Status | Notiz |
|---|---|---|
| Feature Flags / Wartungsmodus | ❌ | nicht vorhanden |
| System-Mitteilungen (Push/Banner/E-Mail) | ❌ | Notification-Modell ist nur pet-zu-pet, kein Broadcast |
| Trends & Promotion (Pinning, Trend-Hashtags) | ❌ | kein Pinning-Feld, keine kuratierte Empfehlungsliste |
### 5. Monetarisierung
| Spec-Punkt | Status | Notiz |
|---|---|---|
| Werbeanzeigen-Verwaltung | ✅ | voll da: CRUD + Species/Breed-Targeting + Zeitraum |
| Budget-Freigaben, Werbekonten-Sperren | ❌ | kein Advertiser-Account-Konzept |
| Abos / In-App-Käufe / Creator-Payouts | ❌ | keine Monetarisierung der Nutzer, kein Payment-System |
| Refund-Handling | ❌ | entfällt, da keine Zahlungen |
### 6. Sicherheit & Compliance
| Spec-Punkt | Status | Notiz |
|---|---|---|
| Audit Log | ⚠️ | `ModerationLog` existiert, protokolliert aber NICHT Ad-Erstellung/-Änderung und Rollenvergabe (`grantRole`/`revokeRole`) |
| IP-/Bot-Management, VPN-Erkennung | ❌ | nicht vorhanden |
| API-Key- & Webhook-Verwaltung | ❌ | Mux-Webhook existiert im Code, aber keine Admin-UI |
---
**Fazit:** Solide abgedeckt sind Ads, Reports, Bans, Basis-Analytics und (seit letzter Woche) GDPR-Export/Team-Chat. Größte Lücken: Nutzer-Suche/-Filter, Auto-Mod/Blacklist, Feature Flags & System-Broadcasts, lückenloseres Audit-Log (Ads/Rollen fehlen), DAU/MAU-Analytics. Monetarisierung über Ads hinaus (Abos, Payouts) ist aktuell komplett out-of-scope für PawFeed — würde ich auch nicht empfehlen nachzubauen, das liest sich eher wie generische SaaS-Boilerplate-Spec statt etwas, das PawFeed konkret braucht.
Nächster Schritt: sinnvolle Nacharbeitungs-Reihenfolge festlegen (reine UI-Ergänzungen vs. Punkte, die neue Backend-Funktionen/Schema-Änderungen brauchen).
Sortiert nach Aufwandsklasse, nicht nach Spec-Kategorie — also danach, ob es eine reine Query-Erweiterung, ein additiver Schema-Change, oder ein Cross-Cutting-Eingriff über viele Dateien ist.
Nutzer-Suche/-Filter in listUsers (Name/E-Mail, Ban-Status, Rolle)
Audit-Log-Lücke schließen: moderationLog.create() in createAd/updateAd/deleteAd/grantRole/revokeRole ergänzt
Moderations-Durchsatz pro Moderator (groupBy auf ModerationLog, sichtbar auf der Moderators-Seite)
Bonus (auf Wunsch vorgezogen): neue SUPPORT-Rolle im AdminRoleType-Enum ergänzt
Bonus: Rechte-Matrix (SUPPORT/MODERATOR/SUPER_ADMIN) erarbeitet und umgesetzt — siehe eigener Kommentar unten. assertAdmin() prüft jetzt eine Mindest-Rolle pro Prozedur statt nur "irgendein Admin"
Bonus: ModerationLog protokolliert jetzt zusätzlich moderatorRole und ipAddress bei jedem Eintrag (login-Missbrauchs-Nachweis, rechtssicher)
Bonus: neue Audit-Log-Übersichtsseite /p/[secret]/log mit Filter (Action/Target-Type/Moderator), nur sichtbar/zugänglich ab MODERATOR-Rolle (Commit e099763, deployed). Dabei nebenbei einen Bug behoben: layout.tsx hätte sonst jeden SUPPORT-Account komplett aus dem Panel ausgesperrt (neue admin.getMyRole-Prozedur als Fix)
Registrierungs-IP speichern ⚠️ DSGVO-relevant — müsste in die Datenschutzerklärung, nur bei konkretem Bedarf (z. B. Betrugsprävention)
Passwort-/2FA-Reset-Trigger über Clerk Admin API (braucht Recherche)
Explizit nicht empfohlen / out of scope
Abos, In-App-Käufe, Creator-Payouts, Refund-Handling — kein Payment-System vorhanden
IP-/Bot-Management mit VPN-Erkennung — braucht Drittanbieter-Service, für aktuelle Größe überdimensioniert
API-Key/Webhook-Verwaltungs-UI — Mux-Secret ist ein Env-Var, kein akuter Bedarf
Vorschlag: Phase 1 komplett in einer Session, danach aus Phase 2 gezielt auswählen.
## Nacharbeitungs-Reihenfolge (Stand 2026-08-12)
Sortiert nach Aufwandsklasse, nicht nach Spec-Kategorie — also danach, ob es eine reine Query-Erweiterung, ein additiver Schema-Change, oder ein Cross-Cutting-Eingriff über viele Dateien ist.
### Phase 1 — Quick Wins, kein Schema-Change ✅ erledigt (Commit `2d656bd`, deployed)
- [x] Nutzer-Suche/-Filter in `listUsers` (Name/E-Mail, Ban-Status, Rolle)
- [x] Audit-Log-Lücke schließen: `moderationLog.create()` in `createAd`/`updateAd`/`deleteAd`/`grantRole`/`revokeRole` ergänzt
- [x] Moderations-Durchsatz pro Moderator (`groupBy` auf `ModerationLog`, sichtbar auf der Moderators-Seite)
- [x] Bonus (auf Wunsch vorgezogen): neue `SUPPORT`-Rolle im `AdminRoleType`-Enum ergänzt
- [x] Bonus: Rechte-Matrix (SUPPORT/MODERATOR/SUPER_ADMIN) erarbeitet und umgesetzt — siehe eigener Kommentar unten. `assertAdmin()` prüft jetzt eine Mindest-Rolle pro Prozedur statt nur "irgendein Admin"
- [x] Bonus: `ModerationLog` protokolliert jetzt zusätzlich `moderatorRole` und `ipAddress` bei jedem Eintrag (login-Missbrauchs-Nachweis, rechtssicher)
- [x] Bonus: neue Audit-Log-Übersichtsseite `/p/[secret]/log` mit Filter (Action/Target-Type/Moderator), nur sichtbar/zugänglich ab MODERATOR-Rolle (Commit `e099763`, deployed). Dabei nebenbei einen Bug behoben: `layout.tsx` hätte sonst jeden SUPPORT-Account komplett aus dem Panel ausgesperrt (neue `admin.getMyRole`-Prozedur als Fix)
### Phase 2 — kleine additive Schema-Änderungen + überschaubare UI ✅ erledigt (Commit `54fb0d5`, deployed)
- [x] Verwarnungssystem (neues `Warning`-Modell, an Owner gehängt, append-only mit Historie) — Badge + Dialog auf der Users-Seite
- [x] Verifizierungs-Haken (`Pet.isVerified` — bewusst am Pet statt am Owner, Pets sind die Social-Identity) + Toggle im Admin + Badge im öffentlichen Profil
- [x] Report-Priorisierung nach Schweregrad (aus `reason` abgeleitet: HARASSMENT/INAPPROPRIATE = Hoch, MISINFORMATION = Mittel, SPAM/OTHER = Niedrig), Liste jetzt severity-first sortiert
- [x] Admin-getriggerte DSGVO-Löschung — Self-Delete-Logik in `deleteOwnerAccount()` extrahiert, `admin.deleteUserAccount` (nur SUPER_ADMIN, Tipp-Bestätigung der exakten Owner-ID, blockt Selbstlöschung) nutzt dieselbe Funktion
- Alle vier neuen/geänderten Mutations loggen mit Rolle+IP ins Audit Log (gleiches Muster wie Phase 1)
### Phase 3 — größere Cross-Cutting-Eingriffe (viele Dateien betroffen, mehr Testaufwand)
- [ ] „Ausblenden ohne Löschen" (`hiddenAt` auf Post — muss in jeder Leseabfrage berücksichtigt werden: Feed, Explore, Profil, Suche, Hashtag)
- [ ] Shadowban (`UserBan` erweitern + Enforcement in denselben Leseabfragen, Sonderfall „Owner sieht eigenen Content trotzdem")
- [ ] Blacklist (Wörter/Links/Hashtags) + Validierung beim Post-/Kommentar-Erstellen
- [ ] DAU/MAU/Churn (braucht erst Aktivitäts-Tracking, existiert aktuell nicht)
### Phase 4 — neue Subsysteme (brauchen auch Produkt-/Design-Entscheidungen, nicht nur Code)
- [ ] Feature Flags / Wartungsmodus (Infra-Gate in `proxy.ts`/Layout)
- [ ] System-Mitteilungen/Broadcast (bestehendes Notification-Modell ist strikt pet-zu-pet, braucht neues Muster)
- [ ] Trends & Promotion (Pinning, Trend-Hashtags, Empfehlungen — braucht Definition „was ist trending")
- [ ] Registrierungs-IP speichern ⚠️ DSGVO-relevant — müsste in die Datenschutzerklärung, nur bei konkretem Bedarf (z. B. Betrugsprävention)
- [ ] Passwort-/2FA-Reset-Trigger über Clerk Admin API (braucht Recherche)
### Explizit nicht empfohlen / out of scope
- Abos, In-App-Käufe, Creator-Payouts, Refund-Handling — kein Payment-System vorhanden
- IP-/Bot-Management mit VPN-Erkennung — braucht Drittanbieter-Service, für aktuelle Größe überdimensioniert
- API-Key/Webhook-Verwaltungs-UI — Mux-Secret ist ein Env-Var, kein akuter Bedarf
---
Vorschlag: Phase 1 komplett in einer Session, danach aus Phase 2 gezielt auswählen.
assertAdmin() prüft jetzt eine Mindest-Rolle pro Prozedur (SUPPORT < MODERATOR < SUPER_ADMIN, ADMIN_OWNER_ID-Bootstrap-Account hat immer vollen Zugriff) statt nur „irgendein Admin reicht". So ist es final verdrahtet:
ModerationLog bekommt bei jedem neuen Eintrag zusätzlich:
moderatorRole — die Rolle des Handelnden zum Zeitpunkt der Aktion (SUPPORT/MODERATOR/SUPER_ADMIN, oder BOOTSTRAP für den ADMIN_OWNER_ID-Account)
ipAddress — die Client-IP zum Zeitpunkt der Aktion (aus dem bestehenden ctx.ip, das auch für Rate-Limiting genutzt wird)
Beide Felder sind nullable, weil die Tabelle bereits Bestandsdaten aus vorherigen Sessions hatte (historische Einträge zeigen ehrlich null, statt einen erfundenen Default zu bekommen). Ab sofort werden beide Felder bei jedem Schreibvorgang zwingend gesetzt.
Hinweis zur Datenschutz-Seite: Die IP-Erfassung hier betrifft ausschließlich Admin-/Moderator-Aktionen (Missbrauchsprävention bei Login/Account-Kompromittierung, berechtigtes Interesse nach Art. 6 Abs. 1 lit. f DSGVO) — nicht die reguläre Nutzer-IP-Erfassung, die in der Roadmap unter Phase 4 separat und bewusst zurückgestellt ist.
Bekannte Lücke, nicht Teil dieses Changes
getModerationLog (die Abfrage selbst) hat aktuell keine Admin-UI, die es anzeigt — das Log wird zuverlässig geschrieben, ist aber nur per direktem DB-Zugriff einsehbar. Wenn eine Einsicht über das Panel gewünscht ist, wäre das ein eigener kleiner Folge-Task.
## Rechte-Matrix — umgesetzt (Commit `c94e60a`, deployed)
`assertAdmin()` prüft jetzt eine **Mindest-Rolle** pro Prozedur (`SUPPORT < MODERATOR < SUPER_ADMIN`, `ADMIN_OWNER_ID`-Bootstrap-Account hat immer vollen Zugriff) statt nur „irgendein Admin reicht". So ist es final verdrahtet:
### Analytics & Übersicht
| Prozedur | Min.-Rolle |
|---|---|
| `getStats`, `getPostsOverTime`, `getOwnerGrowth` | SUPPORT |
| `getModerationLog`, `getModeratorThroughput` | MODERATOR |
### Content-Moderation
| Prozedur | Min.-Rolle |
|---|---|
| `listPosts`, `listComments`, `listReports` | SUPPORT |
| `deletePost`, `deleteComment`, `dismissReport`, `deleteReportedPost` | MODERATOR |
### Nutzerverwaltung
| Prozedur | Min.-Rolle |
|---|---|
| `listUsers`, `startTeamConversation`, `exportUserData` | SUPPORT |
| `banUser`, `unbanUser` | MODERATOR |
### Werbeanzeigen
| Prozedur | Min.-Rolle |
|---|---|
| `listAds` | MODERATOR |
| `createAd`, `updateAd`, `deleteAd`, `getAdImagePresignedUrl` | SUPER_ADMIN |
### Rollen & Einladungen
| Prozedur | Min.-Rolle |
|---|---|
| `listModerators`, `listInviteCodes`, `revokeInvite` | MODERATOR |
| `grantRole`, `revokeRole`, `createRootInvite`, `backfillInviteCodes` | SUPER_ADMIN |
### Rechtstexte
| Prozedur | Min.-Rolle |
|---|---|
| `legal.listVersions` | MODERATOR |
| `legal.publish` | SUPER_ADMIN |
---
## Audit-Log-Erweiterung (login-Missbrauch, Rechtssicherheit)
`ModerationLog` bekommt bei **jedem** neuen Eintrag zusätzlich:
- **`moderatorRole`** — die Rolle des Handelnden zum Zeitpunkt der Aktion (`SUPPORT`/`MODERATOR`/`SUPER_ADMIN`, oder `BOOTSTRAP` für den `ADMIN_OWNER_ID`-Account)
- **`ipAddress`** — die Client-IP zum Zeitpunkt der Aktion (aus dem bestehenden `ctx.ip`, das auch für Rate-Limiting genutzt wird)
Beide Felder sind nullable, weil die Tabelle bereits Bestandsdaten aus vorherigen Sessions hatte (historische Einträge zeigen ehrlich `null`, statt einen erfundenen Default zu bekommen). Ab sofort werden beide Felder bei jedem Schreibvorgang zwingend gesetzt.
**Hinweis zur Datenschutz-Seite:** Die IP-Erfassung hier betrifft ausschließlich Admin-/Moderator-Aktionen (Missbrauchsprävention bei Login/Account-Kompromittierung, berechtigtes Interesse nach Art. 6 Abs. 1 lit. f DSGVO) — nicht die reguläre Nutzer-IP-Erfassung, die in der Roadmap unter Phase 4 separat und bewusst zurückgestellt ist.
## Bekannte Lücke, nicht Teil dieses Changes
`getModerationLog` (die Abfrage selbst) hat aktuell **keine Admin-UI**, die es anzeigt — das Log wird zuverlässig geschrieben, ist aber nur per direktem DB-Zugriff einsehbar. Wenn eine Einsicht über das Panel gewünscht ist, wäre das ein eigener kleiner Folge-Task.
In den Reports, sind die Gemeldeten Hinhalte nicht anklickbar, somit ist es für den Moderator/Support nicht möglich den inhalt genau zu analysieren und eine beurteilung zu fällen. wichtig wäre hier was für kommentare wurden geschrieben und von wem, wer hat geliked, bild anklickbar für optische analyse des Supports/Moderators (Lightbox)
In den Reports, sind die Gemeldeten Hinhalte nicht anklickbar, somit ist es für den Moderator/Support nicht möglich den inhalt genau zu analysieren und eine beurteilung zu fällen. wichtig wäre hier was für kommentare wurden geschrieben und von wem, wer hat geliked, bild anklickbar für optische analyse des Supports/Moderators (Lightbox)
Verifizierungs-Antragsflow (Option B) — umgesetzt (Commit a4c4568, deployed)
Bugfix aus der letzten Diskussion: der Verify-Button auf der Users-Seite hatte kein Error-Handling — Fehlschläge blieben unsichtbar. Jetzt mit Erfolgs-/Fehler-Toast (Commit bc2dfa9).
Zusätzlich der besprochene Self-Service-Flow:
Nutzer: Antrag mit Begründung über die eigene Pet-Bearbeiten-Seite. Zeigt danach den Status (Ausstehend/Abgelehnt+Grund/Verifiziert).
Moderator: neue Queue-Seite /p/[secret]/verification (nur ab Moderator-Rolle). Review läuft über eine verpflichtende 4-Punkt-Checkliste — keine freie Ja/Nein-Entscheidung:
Echtheits-/Verwechslungsrisiko
Vollständiges Profil
Sauberer Stand (kein Ban/keine offene Verwarnung)
Etablierte Präsenz
Alle vier angehakt → automatisch genehmigt (Pet.isVerified wird gesetzt). Irgendein Punkt nicht angehakt → automatisch abgelehnt, mit einer Notiz, die genau auflistet, welche Kriterien fehlten (plus optionaler Freitext-Zusatz vom Moderator).
Benachrichtigung: Der Nutzer wird in jedem Fall automatisch informiert — über eine System-Nachricht vom „PawFeed Team"-Account (nutzt die bestehende DM-Infrastruktur, landet auch als normale Benachrichtigung).
Jede Review-Entscheidung landet mit Rolle+IP im Audit Log, wie alle anderen Aktionen dieser Session.
## Verifizierungs-Antragsflow (Option B) — umgesetzt (Commit `a4c4568`, deployed)
Bugfix aus der letzten Diskussion: der Verify-Button auf der Users-Seite hatte kein Error-Handling — Fehlschläge blieben unsichtbar. Jetzt mit Erfolgs-/Fehler-Toast (Commit `bc2dfa9`).
Zusätzlich der besprochene Self-Service-Flow:
- **Nutzer:** Antrag mit Begründung über die eigene Pet-Bearbeiten-Seite. Zeigt danach den Status (Ausstehend/Abgelehnt+Grund/Verifiziert).
- **Moderator:** neue Queue-Seite `/p/[secret]/verification` (nur ab Moderator-Rolle). Review läuft über eine **verpflichtende 4-Punkt-Checkliste** — keine freie Ja/Nein-Entscheidung:
1. Echtheits-/Verwechslungsrisiko
2. Vollständiges Profil
3. Sauberer Stand (kein Ban/keine offene Verwarnung)
4. Etablierte Präsenz
**Alle vier angehakt → automatisch genehmigt** (Pet.isVerified wird gesetzt). **Irgendein Punkt nicht angehakt → automatisch abgelehnt**, mit einer Notiz, die genau auflistet, welche Kriterien fehlten (plus optionaler Freitext-Zusatz vom Moderator).
- **Benachrichtigung:** Der Nutzer wird in jedem Fall automatisch informiert — über eine System-Nachricht vom „PawFeed Team"-Account (nutzt die bestehende DM-Infrastruktur, landet auch als normale Benachrichtigung).
- Jede Review-Entscheidung landet mit Rolle+IP im Audit Log, wie alle anderen Aktionen dieser Session.
Typecheck sauber, volle Testsuite grün (132 Tests), Docker-Build erfolgreich, live verifiziert.
UI Anpassung im Admin-Dashoard - Users - Die Buttons Warning, Export und Message sind schlecht lesbar und schlecht erkennbar. bitte farblich abheben jede funktion eine farbe so wie bei Shadowban und Ban klar erkennbare unterschiede und sofort lesbar
UI Anpassung im Admin-Dashoard - Users - Die Buttons Warning, Export und Message sind schlecht lesbar und schlecht erkennbar. bitte farblich abheben jede funktion eine farbe so wie bei Shadowban und Ban klar erkennbare unterschiede und sofort lesbar
Wir haben die PawFeed Team - Kommunikation ja schon aktiv geschaltet.
diese müsste aus dem Admin-Bereich erreichbar sein, also eine Message Funktion direkt aus dem Admin-Dashboard, damit jeder Support/Moderator/Admin den selben inhalt sieht. kannst du das einrichten
Wir haben die PawFeed Team - Kommunikation ja schon aktiv geschaltet.
diese müsste aus dem Admin-Bereich erreichbar sein, also eine Message Funktion direkt aus dem Admin-Dashboard, damit jeder Support/Moderator/Admin den selben inhalt sieht. kannst du das einrichten
Post-Vorschau in Reports ist jetzt klickbar, öffnet Detail-Dialog mit vollständigen Bildern (statt nur 4 Thumbnails), „Geliked von"-Liste (Pet-Avatare+Namen) und komplettem Kommentarverlauf. Neue admin.getReportedPostDetail-Query (Bilder+Reaktionen) — Kommentarliste nutzt bewusst die bereits vorhandene admin.listComments weiter statt sie zu duplizieren.
Button-Farben Users-Seite (zu Kommentar oben)
Message (sky), Export (blau), Warning (amber) — analog zum bestehenden Ban(rot)/Shadowban(violett)-Muster, vorher alle drei identisch neutral-grau.
DAU/MAU + erweiterte Dashboard-Statistiken (Phase 3, letzter der 4 Teile — schließt die komplette Phase 3 ab)
Kein bestehendes Activity-Tracking vorhanden, daher Redis-basiert gebaut (gleiches Muster wie das bestehende Rate-Limiting): täglicher SADD in visits:YYYY-MM-DD, ausgelöst einmal pro Request im (app)-Layout — idempotent, kein Client-seitiges Once-per-day-Gedöns nötig. DAU = SCARD von heute, MAU = SUNION über die letzten 30 Tage. Kein neues Postgres-Schema.
tsc/Lint/Tests sauber (132 Tests), Docker-Build inkl. TS-Check erfolgreich, deployed. Live im Admin-Panel selbst noch nicht durchgeklickt (fehlende Admin-Session lokal) — bitte kurz gegenchecken.
Damit ist Phase 3 komplett abgeschlossen (Ausblenden, Shadowban, Blacklist, Analytics — alle vier Teile).
## Reports anklickbar + Button-Farben + DAU/MAU-Analytics (Commits `a35cb66`, `4000a1e`, deployed)
### Gemeldete Inhalte anklickbar (zu Kommentar oben)
Post-Vorschau in Reports ist jetzt klickbar, öffnet Detail-Dialog mit vollständigen Bildern (statt nur 4 Thumbnails), „Geliked von"-Liste (Pet-Avatare+Namen) und komplettem Kommentarverlauf. Neue `admin.getReportedPostDetail`-Query (Bilder+Reaktionen) — Kommentarliste nutzt bewusst die bereits vorhandene `admin.listComments` weiter statt sie zu duplizieren.
### Button-Farben Users-Seite (zu Kommentar oben)
Message (sky), Export (blau), Warning (amber) — analog zum bestehenden Ban(rot)/Shadowban(violett)-Muster, vorher alle drei identisch neutral-grau.
### DAU/MAU + erweiterte Dashboard-Statistiken (Phase 3, letzter der 4 Teile — schließt die komplette Phase 3 ab)
Kein bestehendes Activity-Tracking vorhanden, daher Redis-basiert gebaut (gleiches Muster wie das bestehende Rate-Limiting): täglicher `SADD` in `visits:YYYY-MM-DD`, ausgelöst einmal pro Request im `(app)`-Layout — idempotent, kein Client-seitiges Once-per-day-Gedöns nötig. DAU = `SCARD` von heute, MAU = `SUNION` über die letzten 30 Tage. Kein neues Postgres-Schema.
Dashboard neu: 6 StatCards (DAU, MAU, Shadowban-Anzahl, Blacklist-Einträge, Verifikationen offen/geschlossen) + 3 Zeitreihen-Charts (Visits, Comments, Likes — Tag/Woche/Monat umschaltbar, gleiche Chart-Komponente wie die bestehenden Posts/Owner-Charts).
tsc/Lint/Tests sauber (132 Tests), Docker-Build inkl. TS-Check erfolgreich, deployed. Live im Admin-Panel selbst noch nicht durchgeklickt (fehlende Admin-Session lokal) — bitte kurz gegenchecken.
---
Damit ist **Phase 3 komplett abgeschlossen** (Ausblenden, Shadowban, Blacklist, Analytics — alle vier Teile).
Team-Postfach im Admin-Dashboard (Commit 72ae462, deployed)
Der Bug dahinter war schon im Code dokumentiert: Der bisherige „Message"-Button auf der Users-Seite leitete in die normale /messages-Ansicht — die prüft assertPetOwnership, und der „PawFeed Team"-Pet gehört fest der ADMIN_OWNER_ID. Für jeden anderen Support/Moderator/Admin lief das ins Leere (stiller FORBIDDEN).
Neue Seite „Messages" im Admin-Nav (/p/[secret]/messages): geteiltes Postfach mit Konversationsliste links, Chat-Verlauf + Antwortfeld rechts. Drei neue Prozeduren (listTeamConversations, getTeamConversationThread, sendTeamReply), gegated über die normale Admin-Rechteprüfung statt Pet-Ownership — jeder Support+ sieht denselben Verlauf und kann als „PawFeed Team" antworten. Öffnen einer Konversation markiert sie für alle als gelesen (geteiltes Postfach). Der „Message"-Button auf der Users-Seite verlinkt jetzt direkt dorthin.
tsc/Lint/Tests sauber, Docker-Build erfolgreich, deployed. Bitte live gegenchecken, ob die geteilte Sichtbarkeit so funktioniert wie gewünscht.
## Team-Postfach im Admin-Dashboard (Commit `72ae462`, deployed)
Der Bug dahinter war schon im Code dokumentiert: Der bisherige „Message"-Button auf der Users-Seite leitete in die normale `/messages`-Ansicht — die prüft `assertPetOwnership`, und der „PawFeed Team"-Pet gehört fest der `ADMIN_OWNER_ID`. Für jeden anderen Support/Moderator/Admin lief das ins Leere (stiller FORBIDDEN).
Neue Seite **„Messages"** im Admin-Nav (`/p/[secret]/messages`): geteiltes Postfach mit Konversationsliste links, Chat-Verlauf + Antwortfeld rechts. Drei neue Prozeduren (`listTeamConversations`, `getTeamConversationThread`, `sendTeamReply`), gegated über die normale Admin-Rechteprüfung statt Pet-Ownership — jeder Support+ sieht denselben Verlauf und kann als „PawFeed Team" antworten. Öffnen einer Konversation markiert sie für alle als gelesen (geteiltes Postfach). Der „Message"-Button auf der Users-Seite verlinkt jetzt direkt dorthin.
tsc/Lint/Tests sauber, Docker-Build erfolgreich, deployed. Bitte live gegenchecken, ob die geteilte Sichtbarkeit so funktioniert wie gewünscht.
Status-Übersicht (Stand 2026-08-14) — Aufräumen der bisherigen Kommentare
Das Issue ist mit 9 Kommentaren unübersichtlich geworden. Hier eine gebündelte Bestandsaufnahme, gegen den aktuellen Code verifiziert (prisma/schema.prisma, admin.ts).
Phase 3 komplett — im Schema bestätigt: Post.hiddenAt (Ausblenden ohne Löschen), Shadowban-Modell, BlacklistEntry-Modell, DAU/MAU-Analytics (Redis-basiert) — Commits a35cb66, 4000a1e
Reports anklickbar (Antwort auf den Kommentar dazu weiter oben: Lightbox, „Geliked von"-Liste, voller Kommentarverlauf) — Commit a35cb66
Button-Farben Users-Seite (Antwort auf den Kommentar dazu weiter oben: Message/Export/Warning jetzt farblich abgesetzt) — Commit a35cb66
Team-Postfach im Admin-Dashboard (Antwort auf den Kommentar dazu weiter oben: neue Seite /p/[secret]/messages, geteiltes Postfach für Support/Moderator/Admin) — Commit 72ae462
⏳ Nur Live-Bestätigung ausstehend (kein offener Code-Punkt)
DAU/MAU-Dashboard — laut vorletztem Kommentar „live im Admin-Panel noch nicht durchgeklickt"
Team-Postfach — laut letztem Kommentar „bitte live gegenchecken", ob geteilte Sichtbarkeit wie gewünscht funktioniert
Registrierungs-IP speichern (DSGVO-relevant — nur bei konkretem Bedarf, z. B. Betrugsprävention)
Passwort-/2FA-Reset-Trigger über Clerk Admin API
Explizit zurückgestellt / nicht empfohlen
Abos, In-App-Käufe, Creator-Payouts, Refund-Handling, IP-/Bot-Management mit VPN-Erkennung, API-Key/Webhook-Verwaltungs-UI — Begründung siehe Kommentar weiter oben, weiterhin unverändert.
Fazit: Von der ursprünglichen Spec sind nur noch die zwei Live-Bestätigungen und Phase 4 offen. Vorschlag: kurz DAU/MAU-Dashboard und Team-Postfach durchklicken, danach gemeinsam entscheiden, ob/welche Phase-4-Punkte als Nächstes drankommen.
## Status-Übersicht (Stand 2026-08-14) — Aufräumen der bisherigen Kommentare
Das Issue ist mit 9 Kommentaren unübersichtlich geworden. Hier eine gebündelte Bestandsaufnahme, gegen den aktuellen Code verifiziert (`prisma/schema.prisma`, `admin.ts`).
### ✅ Vollständig erledigt & im Code bestätigt
- **Phase 1** — Nutzer-Suche/-Filter, Audit-Log-Lücke geschlossen, Moderations-Durchsatz, SUPPORT-Rolle, Rechte-Matrix (`assertAdmin()` mit Mindest-Rolle), Audit-Log-Seite `/p/[secret]/log` — Commits `2d656bd`, `c94e60a`, `e099763`
- **Phase 2** — Verwarnungssystem, Verifizierungs-Haken (`Pet.isVerified`), Report-Priorisierung nach Schweregrad, Admin-getriggerte DSGVO-Löschung — Commit `54fb0d5`
- **Verifizierungs-Antragsflow** — Self-Service-Antrag + Moderator-Review mit verpflichtender 4-Punkt-Checkliste — Commit `a4c4568`
- **Phase 3 komplett** — im Schema bestätigt: `Post.hiddenAt` (Ausblenden ohne Löschen), `Shadowban`-Modell, `BlacklistEntry`-Modell, DAU/MAU-Analytics (Redis-basiert) — Commits `a35cb66`, `4000a1e`
- **Reports anklickbar** (Antwort auf den Kommentar dazu weiter oben: Lightbox, „Geliked von"-Liste, voller Kommentarverlauf) — Commit `a35cb66`
- **Button-Farben Users-Seite** (Antwort auf den Kommentar dazu weiter oben: Message/Export/Warning jetzt farblich abgesetzt) — Commit `a35cb66`
- **Team-Postfach im Admin-Dashboard** (Antwort auf den Kommentar dazu weiter oben: neue Seite `/p/[secret]/messages`, geteiltes Postfach für Support/Moderator/Admin) — Commit `72ae462`
### ⏳ Nur Live-Bestätigung ausstehend (kein offener Code-Punkt)
- DAU/MAU-Dashboard — laut vorletztem Kommentar „live im Admin-Panel noch nicht durchgeklickt"
- Team-Postfach — laut letztem Kommentar „bitte live gegenchecken", ob geteilte Sichtbarkeit wie gewünscht funktioniert
### 📋 Genuin offen — Phase 4 (noch nicht begonnen)
- [ ] Feature Flags / Wartungsmodus
- [ ] System-Mitteilungen/Broadcast (Push/Banner/E-Mail)
- [ ] Trends & Promotion (Pinning, Trend-Hashtags)
- [ ] Registrierungs-IP speichern (DSGVO-relevant — nur bei konkretem Bedarf, z. B. Betrugsprävention)
- [ ] Passwort-/2FA-Reset-Trigger über Clerk Admin API
### Explizit zurückgestellt / nicht empfohlen
Abos, In-App-Käufe, Creator-Payouts, Refund-Handling, IP-/Bot-Management mit VPN-Erkennung, API-Key/Webhook-Verwaltungs-UI — Begründung siehe Kommentar weiter oben, weiterhin unverändert.
---
**Fazit:** Von der ursprünglichen Spec sind nur noch die zwei Live-Bestätigungen und Phase 4 offen. Vorschlag: kurz DAU/MAU-Dashboard und Team-Postfach durchklicken, danach gemeinsam entscheiden, ob/welche Phase-4-Punkte als Nächstes drankommen.
Registrierungs-IP speichern (DSGVO-relevant — nur bei konkretem Bedarf)
Passwort-/2FA-Reset-Trigger über Clerk Admin API
Alles andere aus diesem Issue ist erledigt und verifiziert.
## Live-Bestätigung erhalten (Stand 2026-08-14)
Beide offenen Live-Checks aus der letzten Status-Übersicht sind bestätigt:
- **DAU/MAU-Dashboard** — läuft sauber
- **Team-Postfach** — läuft sauber (geteilte Sichtbarkeit funktioniert wie gewünscht)
Damit ist von der ursprünglichen Spec-Liste nur noch **Phase 4** offen (5 Punkte, siehe oben, unverändert):
- [ ] Feature Flags / Wartungsmodus
- [ ] System-Mitteilungen/Broadcast (Push/Banner/E-Mail)
- [ ] Trends & Promotion (Pinning, Trend-Hashtags)
- [ ] Registrierungs-IP speichern (DSGVO-relevant — nur bei konkretem Bedarf)
- [ ] Passwort-/2FA-Reset-Trigger über Clerk Admin API
Alles andere aus diesem Issue ist erledigt und verifiziert.
Von den 5 Phase-4-Punkten: 3 umgesetzt, 1 gestrichen, 1 zurückgestellt.
✅ Wartungsmodus (Teilmenge von „Feature Flags")
Redis-Flag (maintenance:enabled), Gate in proxy.ts — blockiert alle Seiten außer Admin-Panel, API-Routen (Webhooks/Cron/CSP-Report), den festsprachigen Rechtsseiten und Login/Clerk-Routen (damit ein ausgesperrter Admin sich immer noch einloggen kann, um den Modus wieder abzuschalten). Fail-open bei Redis-Ausfall — ein Redis-Blip darf nie die ganze Seite lahmlegen. Toggle nur für SUPER_ADMIN sichtbar, oben auf dem Dashboard.
✅ Registrierungs-IP
Owner.registrationIp wird defensiv an jederowner.upsert-Create-Stelle erfasst (Invite-Consume, legal.acknowledge, legal.acknowledgeUploadConsent, pets.create, owner.setThemePreference) — nötig, weil sich beim Review herausstellte, dass kein einzelner Onboarding-Schritt codegarantiert immer zuerst läuft (hängt vom Invite-Status und davon ab, ob bereits Legal-Docs publiziert sind). Datenschutzerklärung um einen Punkt mit Rechtsgrundlage (Art. 6 Abs. 1 lit. f DSGVO) und Aufbewahrungsdauer (mit dem Konto gelöscht) ergänzt — Text wurde dir vorgelegt und ist freigegeben.
✅ Trends & Promotion
Post.pinnedAt-Feld, admin.pinPost/unpinPost (gleiches Muster wie hidePost/unhidePost), explore.getTrending zeigt gepinnte Posts zuerst unabhängig vom 48h-Fenster. Pin/Unpin-Button + Trending-Hashtags-Panel (7-Tage-Fenster, bereits vorhandene Query wiederverwendet) auf der Admin-Posts-Seite.
❌ Gestrichen: Passwort-/2FA-Reset über Clerk Admin API
User kann jederzeit selbst über Clerks Self-Service-Flow zurücksetzen — kein Admin-Trigger nötig.
⏸ Zurückgestellt: System-Mitteilungen/Broadcast
Braucht noch eine gemeinsame Konzeption — Notification ist bewusst pet-zu-pet-scoped, kein Owner-weites Broadcast-Konzept vorhanden, und der Mailer hat keine Queue für Massenversand.
Code-Review vor dem Deploy gefunden & behoben:
Registrierungs-IP wäre für echte Nutzer nie gesetzt worden (siehe oben — ursprüngliche Annahme zum „garantiert ersten Touchpoint" war falsch)
Postgres sortiert NULL bei ORDER BY ... DESC standardmäßig zuerst — ungepinnte Posts wären vor gepinnten erschienen, jetzt mit nulls: "last" explizit korrigiert
Wartungsmodus-Gate hätte einen Admin mit abgelaufener Session ausgesperrt (/log-in, /sign-up, /__clerk/* fehlten in der Ausnahmeliste)
Audit-Log-Filter-Dropdown und Schema-Kommentare um die neuen Actions/SYSTEM-Target-Type ergänzt
tsc/Lint/Tests sauber (155 Tests, 14 davon neu), Docker-Build erfolgreich, live verifiziert (pawfeed.org + /datenschutz → HTTP 200).
## Phase 4 (Teil 1) umgesetzt — Wartungsmodus, Registrierungs-IP, Trends & Promotion (Commit `f5f788b`, deployed)
Von den 5 Phase-4-Punkten: 3 umgesetzt, 1 gestrichen, 1 zurückgestellt.
### ✅ Wartungsmodus (Teilmenge von „Feature Flags")
Redis-Flag (`maintenance:enabled`), Gate in `proxy.ts` — blockiert alle Seiten außer Admin-Panel, API-Routen (Webhooks/Cron/CSP-Report), den festsprachigen Rechtsseiten und Login/Clerk-Routen (damit ein ausgesperrter Admin sich immer noch einloggen kann, um den Modus wieder abzuschalten). Fail-open bei Redis-Ausfall — ein Redis-Blip darf nie die ganze Seite lahmlegen. Toggle nur für SUPER_ADMIN sichtbar, oben auf dem Dashboard.
### ✅ Registrierungs-IP
`Owner.registrationIp` wird defensiv an **jeder** `owner.upsert`-Create-Stelle erfasst (Invite-Consume, `legal.acknowledge`, `legal.acknowledgeUploadConsent`, `pets.create`, `owner.setThemePreference`) — nötig, weil sich beim Review herausstellte, dass kein einzelner Onboarding-Schritt codegarantiert immer zuerst läuft (hängt vom Invite-Status und davon ab, ob bereits Legal-Docs publiziert sind). Datenschutzerklärung um einen Punkt mit Rechtsgrundlage (Art. 6 Abs. 1 lit. f DSGVO) und Aufbewahrungsdauer (mit dem Konto gelöscht) ergänzt — Text wurde dir vorgelegt und ist freigegeben.
### ✅ Trends & Promotion
`Post.pinnedAt`-Feld, `admin.pinPost`/`unpinPost` (gleiches Muster wie `hidePost`/`unhidePost`), `explore.getTrending` zeigt gepinnte Posts zuerst unabhängig vom 48h-Fenster. Pin/Unpin-Button + Trending-Hashtags-Panel (7-Tage-Fenster, bereits vorhandene Query wiederverwendet) auf der Admin-Posts-Seite.
### ❌ Gestrichen: Passwort-/2FA-Reset über Clerk Admin API
User kann jederzeit selbst über Clerks Self-Service-Flow zurücksetzen — kein Admin-Trigger nötig.
### ⏸ Zurückgestellt: System-Mitteilungen/Broadcast
Braucht noch eine gemeinsame Konzeption — `Notification` ist bewusst pet-zu-pet-scoped, kein Owner-weites Broadcast-Konzept vorhanden, und der Mailer hat keine Queue für Massenversand.
---
**Code-Review vor dem Deploy gefunden & behoben:**
- Registrierungs-IP wäre für echte Nutzer nie gesetzt worden (siehe oben — ursprüngliche Annahme zum „garantiert ersten Touchpoint" war falsch)
- Postgres sortiert `NULL` bei `ORDER BY ... DESC` standardmäßig zuerst — ungepinnte Posts wären vor gepinnten erschienen, jetzt mit `nulls: "last"` explizit korrigiert
- Wartungsmodus-Gate hätte einen Admin mit abgelaufener Session ausgesperrt (`/log-in`, `/sign-up`, `/__clerk/*` fehlten in der Ausnahmeliste)
- Audit-Log-Filter-Dropdown und Schema-Kommentare um die neuen Actions/`SYSTEM`-Target-Type ergänzt
tsc/Lint/Tests sauber (155 Tests, 14 davon neu), Docker-Build erfolgreich, live verifiziert (`pawfeed.org` + `/datenschutz` → HTTP 200).
System-Mitteilungen / Broadcast (Push/Banner/E-Mail) — braucht noch eine gemeinsame Konzeption, da Notification bewusst pet-zu-pet-scoped ist (kein Owner-weites Broadcast-Konzept) und der Mailer keine Queue für Massenversand hat.
Explizit zurückgestellt / nicht empfohlen (unverändert)
Abos, In-App-Käufe, Creator-Payouts, Refund-Handling, IP-/Bot-Management mit VPN-Erkennung, API-Key/Webhook-Verwaltungs-UI.
Fazit: Von der kompletten ursprünglichen Spec-Liste ist nur noch der Broadcast-Punkt offen. Sag Bescheid, ob wir den jetzt gemeinsam konzipieren, ob er zurückgestellt bleibt (dann könnten wir das Issue schließen und bei Bedarf einen neuen, fokussierten Broadcast-Issue aufmachen), oder ob das Issue einfach offen bleiben soll als Merkposten.
## Finale Bestandsaufnahme (Stand 2026-08-15)
Dieses Issue ist inzwischen sehr umfangreich geworden (12 Kommentare) — hier die konsolidierte Endabrechnung gegen die ursprüngliche Spec.
### ✅ Vollständig erledigt, live bestätigt
- **Phase 1** — Nutzer-Suche/-Filter, Audit-Log-Lücke geschlossen, Moderations-Durchsatz, SUPPORT-Rolle, Rechte-Matrix, Audit-Log-Seite
- **Phase 2** — Verwarnungssystem, Verifizierungs-Haken, Report-Priorisierung nach Schweregrad, Admin-DSGVO-Löschung
- **Verifizierungs-Antragsflow** — Self-Service-Antrag + Moderator-Review mit 4-Punkt-Checkliste
- **Phase 3** — Ausblenden ohne Löschen, Shadowban, Blacklist, DAU/MAU-Analytics (live bestätigt)
- **Reports anklickbar** — Lightbox, „Geliked von"-Liste, voller Kommentarverlauf
- **Button-Farben Users-Seite** — Message/Export/Warning farblich abgesetzt
- **Team-Postfach** — geteiltes Admin-Postfach für Support/Moderator/Admin (live bestätigt)
- **Phase 4, Teil 1** — Wartungsmodus, Registrierungs-IP (an allen 5 Owner-Erstellungsstellen), Post-Pinning + Trending-Hashtags-Panel
- **Passwort-/2FA-Reset** — bewusst gestrichen, Clerk-Self-Service reicht
### 📋 Genuin offen — einziger verbleibender Punkt
- [ ] **System-Mitteilungen / Broadcast** (Push/Banner/E-Mail) — braucht noch eine gemeinsame Konzeption, da `Notification` bewusst pet-zu-pet-scoped ist (kein Owner-weites Broadcast-Konzept) und der Mailer keine Queue für Massenversand hat.
### Explizit zurückgestellt / nicht empfohlen (unverändert)
Abos, In-App-Käufe, Creator-Payouts, Refund-Handling, IP-/Bot-Management mit VPN-Erkennung, API-Key/Webhook-Verwaltungs-UI.
---
**Fazit:** Von der kompletten ursprünglichen Spec-Liste ist nur noch der Broadcast-Punkt offen. Sag Bescheid, ob wir den jetzt gemeinsam konzipieren, ob er zurückgestellt bleibt (dann könnten wir das Issue schließen und bei Bedarf einen neuen, fokussierten Broadcast-Issue aufmachen), oder ob das Issue einfach offen bleiben soll als Merkposten.
Nach Abwägung von drei Optionen (reines In-App-Banner / direkter E-Mail-Massenversand / gestufte Kombination) fällt die Wahl auf die Kombination, in zwei Phasen ausgerollt:
Phase 1 — jetzt: In-App-Banner (Pull-Prinzip)
Wiederverwendung des bereits bewährten Musters aus LegalUpdateBanner.tsx (Bestandsnutzer-Hinweis bei neuen AGB/Datenschutz-Versionen) — kein Fan-out über Notification-Zeilen pro Pet, sondern ein Abgleich beim App-Start.
Design-Entscheidung für die Nachverfolgung:
Jede versendete Mitteilung bekommt eine eigene Broadcast-ID.
Pro Owner wird in der DB festgehalten, ob die Mitteilung zugestellt (im Banner angezeigt) und ob sie gelesen/bestätigt wurde — Bestätigung über einen einfachen "Gelesen"-Button (keine erzwungene Blockier-Logik wie beim Rechtstexte-Banner, unkompliziert gehalten).
Diese Zustellungs-/Lese-Tabelle ist bewusst so gebaut, dass sie die Grundlage für Phase 2 mit liefert (siehe unten) — kein Mehraufwand, wenn wir es jetzt gleich sauber mitdenken.
Phase 2 — später: E-Mail-Eskalation, ab ~100 Nutzern
Bewusst zurückgestellt, bis die Nutzerbasis eine Größe erreicht hat (Richtwert: 100 registrierte Nutzer), bei der proaktive Erreichbarkeit außerhalb der App tatsächlich relevant wird. Grund für den Aufschub, nicht nur Kapazität:
Zustellbarkeits-/Reputationsrisiko: Das SMTP-Postfach (mail.ts, Strato) ist ein geteiltes Konto für sämtliche Mails der Domain (Passwort-Reset, Einladungen, DSGVO-Export-Links). Ein schlecht laufender Massenversand (Spam-Beschwerden, Bounces) würde die Zustellbarkeit der GESAMTEN Domain gefährden, nicht nur der Broadcast-Mails.
Rechtsgrundlage: muss vor dem ersten Versand geklärt sein (berechtigtes Interesse reicht für rein betriebliche Hinweise, bei Marketing-artigem Inhalt ggf. Opt-in/Abmelde-Pflicht nach UWG/ePrivacy).
Kein Undo: anders als beim Banner (sofort korrigierbar) ist eine raus gegangene Mail nicht rückholbar — braucht mindestens einen Testmail-Schritt vor dem Echtversand.
Cron-Zuverlässigkeit: Batch-Versand über den bestehenden Cron/CRON_SECRET-Mechanismus, mit Status pro Empfänger (versendet/ausstehend/fehlgeschlagen) statt einer naiven Schleife — Duplikate/Ausfälle bei Job-Abbruch sonst nicht auszuschließen.
Die Phase-1-Zustellungs-/Lese-Tabelle (Broadcast-ID pro Owner) liefert für Phase 2 bereits die Grundlage, um gezielt nur die Owner per Mail zu erreichen, die die Mitteilung im Banner noch nicht gesehen haben — die Eskalationslogik selbst kommt dann als eigener, separat zu planender Schritt.
## Entscheidung: Broadcast/System-Mitteilungen — gestufter Ansatz
Nach Abwägung von drei Optionen (reines In-App-Banner / direkter E-Mail-Massenversand / gestufte Kombination) fällt die Wahl auf die **Kombination, in zwei Phasen ausgerollt**:
### Phase 1 — jetzt: In-App-Banner (Pull-Prinzip)
Wiederverwendung des bereits bewährten Musters aus `LegalUpdateBanner.tsx` (Bestandsnutzer-Hinweis bei neuen AGB/Datenschutz-Versionen) — kein Fan-out über Notification-Zeilen pro Pet, sondern ein Abgleich beim App-Start.
**Design-Entscheidung für die Nachverfolgung:**
- Jede versendete Mitteilung bekommt eine eigene **Broadcast-ID**.
- Pro Owner wird in der DB festgehalten, ob die Mitteilung **zugestellt** (im Banner angezeigt) und ob sie **gelesen/bestätigt** wurde — Bestätigung über einen einfachen "Gelesen"-Button (keine erzwungene Blockier-Logik wie beim Rechtstexte-Banner, unkompliziert gehalten).
- Diese Zustellungs-/Lese-Tabelle ist bewusst so gebaut, dass sie die Grundlage für Phase 2 mit liefert (siehe unten) — kein Mehraufwand, wenn wir es jetzt gleich sauber mitdenken.
### Phase 2 — später: E-Mail-Eskalation, ab ~100 Nutzern
Bewusst zurückgestellt, bis die Nutzerbasis eine Größe erreicht hat (Richtwert: **100 registrierte Nutzer**), bei der proaktive Erreichbarkeit außerhalb der App tatsächlich relevant wird. Grund für den Aufschub, nicht nur Kapazität:
- **Zustellbarkeits-/Reputationsrisiko:** Das SMTP-Postfach (`mail.ts`, Strato) ist ein **geteiltes Konto für sämtliche Mails der Domain** (Passwort-Reset, Einladungen, DSGVO-Export-Links). Ein schlecht laufender Massenversand (Spam-Beschwerden, Bounces) würde die Zustellbarkeit der GESAMTEN Domain gefährden, nicht nur der Broadcast-Mails.
- **Rechtsgrundlage:** muss vor dem ersten Versand geklärt sein (berechtigtes Interesse reicht für rein betriebliche Hinweise, bei Marketing-artigem Inhalt ggf. Opt-in/Abmelde-Pflicht nach UWG/ePrivacy).
- **Kein Undo:** anders als beim Banner (sofort korrigierbar) ist eine raus gegangene Mail nicht rückholbar — braucht mindestens einen Testmail-Schritt vor dem Echtversand.
- **Cron-Zuverlässigkeit:** Batch-Versand über den bestehenden Cron/`CRON_SECRET`-Mechanismus, mit Status pro Empfänger (versendet/ausstehend/fehlgeschlagen) statt einer naiven Schleife — Duplikate/Ausfälle bei Job-Abbruch sonst nicht auszuschließen.
Die Phase-1-Zustellungs-/Lese-Tabelle (Broadcast-ID pro Owner) liefert für Phase 2 bereits die Grundlage, um gezielt nur die Owner per Mail zu erreichen, die die Mitteilung im Banner noch nicht gesehen haben — die Eskalationslogik selbst kommt dann als eigener, separat zu planender Schritt.
**Nächster Schritt:** Phase 1 (Banner + Broadcast-ID + Zustellungs-/Lese-Tracking) wird jetzt umgesetzt.
Admins koennen unter /p/[secret]/broadcasts (Sidebar "Mitteilungen") system-weite Mitteilungen an alle Owner senden. Owner sehen sie als dismissbaren Banner beim naechsten App-Start und bestaetigen mit "Gelesen".
Umsetzung:
Neue Modelle Broadcast + BroadcastReceipt (per-Broadcast Empfangs-/Lese-Tracking statt einem einzelnen rollierenden Timestamp - ermoeglicht Delivered/Read-Zahlen pro Mitteilung und spaeteres gezieltes Targeting fuer Phase 2)
broadcast.getPending / broadcast.markRead (Owner-seitig, pull-basiert wie beim Legal-Update-Banner)
admin.createBroadcast (SUPER_ADMIN) / admin.listBroadcasts (MODERATOR+) inkl. Delivered/Read-Zahlen im Admin-Verlauf
Audit-Log-Eintrag SEND_BROADCAST pro Versand
42 neue Tests (Vitest), Typecheck + Lint sauber
Phase 2 (E-Mail-Eskalation) bewusst zurueckgestellt bis ca. 100 aktive Nutzer - Schema ist bereits so ausgelegt, dass sie darauf aufbauen kann.
Deployed und verifiziert (HTTP 200 intern + ueber pawfeed.org).
**Broadcast Phase 1 - live**
Admins koennen unter `/p/[secret]/broadcasts` (Sidebar "Mitteilungen") system-weite Mitteilungen an alle Owner senden. Owner sehen sie als dismissbaren Banner beim naechsten App-Start und bestaetigen mit "Gelesen".
Umsetzung:
- Neue Modelle `Broadcast` + `BroadcastReceipt` (per-Broadcast Empfangs-/Lese-Tracking statt einem einzelnen rollierenden Timestamp - ermoeglicht Delivered/Read-Zahlen pro Mitteilung und spaeteres gezieltes Targeting fuer Phase 2)
- `broadcast.getPending` / `broadcast.markRead` (Owner-seitig, pull-basiert wie beim Legal-Update-Banner)
- `admin.createBroadcast` (SUPER_ADMIN) / `admin.listBroadcasts` (MODERATOR+) inkl. Delivered/Read-Zahlen im Admin-Verlauf
- Audit-Log-Eintrag `SEND_BROADCAST` pro Versand
- 42 neue Tests (Vitest), Typecheck + Lint sauber
Phase 2 (E-Mail-Eskalation) bewusst zurueckgestellt bis ca. 100 aktive Nutzer - Schema ist bereits so ausgelegt, dass sie darauf aufbauen kann.
Deployed und verifiziert (HTTP 200 intern + ueber pawfeed.org).
Das Admin-Dashboard ist nicht Mobil Abrufbar, im sinne von Responsiv.
Habe es eben als Mobil-Version offen gehabt, leider erkennt man gar nichts. alles ist in sich zusammen geschoben.
bitte beheben
Das Admin-Dashboard ist nicht Mobil Abrufbar, im sinne von Responsiv.
Habe es eben als Mobil-Version offen gehabt, leider erkennt man gar nichts. alles ist in sich zusammen geschoben.
bitte beheben
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Hier ist eine Liste, die ich erhalten habe, mit einer aufstellung der wichtigsten Admin-Funktion.
Diese liste einmal mit unserem bestand abgleichen. Fehlende Elemente oder Funktionen. Auflisten und mit mir besprechen
Admin Dashboard Spec: Social Media Platform
1. Benutzerverwaltung (User Management)
2. Moderation & Content-Management
3. Analytics & Plattform-Metriken
4. Plattform-Konfiguration
5. Monetarisierung & Finanzen
6. Sicherheit & Compliance
Abgleich mit dem Bestand (Stand 2026-08-12)
Bin den kompletten
admin.ts-Router (32 Prozeduren) und alle 8 Admin-Seiten (/p/[secret]/{users,moderators,posts,reports,ads,invites,legal}+ Dashboard) durchgegangen. Legende: ✅ vorhanden · ⚠️ teilweise · ❌ fehlt1. Benutzerverwaltung
listUsersSUPER_ADMIN/MODERATOR, kein „Support"banUsermit optionalemexpiresAt/api/account/delete), kein Admin-Button2. Moderation & Content
listReports,dismissReport,deleteReportedPostcreatedAt-Sortierung, kein Severity-Feld3. Analytics
getStatsgetOwnerGrowthgetPostsOverTimeModerationLogexistiert, aber keine Auswertung darauf4. Plattform-Konfiguration
5. Monetarisierung
6. Sicherheit & Compliance
ModerationLogexistiert, protokolliert aber NICHT Ad-Erstellung/-Änderung und Rollenvergabe (grantRole/revokeRole)Fazit: Solide abgedeckt sind Ads, Reports, Bans, Basis-Analytics und (seit letzter Woche) GDPR-Export/Team-Chat. Größte Lücken: Nutzer-Suche/-Filter, Auto-Mod/Blacklist, Feature Flags & System-Broadcasts, lückenloseres Audit-Log (Ads/Rollen fehlen), DAU/MAU-Analytics. Monetarisierung über Ads hinaus (Abos, Payouts) ist aktuell komplett out-of-scope für PawFeed — würde ich auch nicht empfehlen nachzubauen, das liest sich eher wie generische SaaS-Boilerplate-Spec statt etwas, das PawFeed konkret braucht.
Nächster Schritt: sinnvolle Nacharbeitungs-Reihenfolge festlegen (reine UI-Ergänzungen vs. Punkte, die neue Backend-Funktionen/Schema-Änderungen brauchen).
Nacharbeitungs-Reihenfolge (Stand 2026-08-12)
Sortiert nach Aufwandsklasse, nicht nach Spec-Kategorie — also danach, ob es eine reine Query-Erweiterung, ein additiver Schema-Change, oder ein Cross-Cutting-Eingriff über viele Dateien ist.
Phase 1 — Quick Wins, kein Schema-Change ✅ erledigt (Commit
2d656bd, deployed)listUsers(Name/E-Mail, Ban-Status, Rolle)moderationLog.create()increateAd/updateAd/deleteAd/grantRole/revokeRoleergänztgroupByaufModerationLog, sichtbar auf der Moderators-Seite)SUPPORT-Rolle imAdminRoleType-Enum ergänztassertAdmin()prüft jetzt eine Mindest-Rolle pro Prozedur statt nur "irgendein Admin"ModerationLogprotokolliert jetzt zusätzlichmoderatorRoleundipAddressbei jedem Eintrag (login-Missbrauchs-Nachweis, rechtssicher)/p/[secret]/logmit Filter (Action/Target-Type/Moderator), nur sichtbar/zugänglich ab MODERATOR-Rolle (Commite099763, deployed). Dabei nebenbei einen Bug behoben:layout.tsxhätte sonst jeden SUPPORT-Account komplett aus dem Panel ausgesperrt (neueadmin.getMyRole-Prozedur als Fix)Phase 2 — kleine additive Schema-Änderungen + überschaubare UI ✅ erledigt (Commit
54fb0d5, deployed)Warning-Modell, an Owner gehängt, append-only mit Historie) — Badge + Dialog auf der Users-SeitePet.isVerified— bewusst am Pet statt am Owner, Pets sind die Social-Identity) + Toggle im Admin + Badge im öffentlichen Profilreasonabgeleitet: HARASSMENT/INAPPROPRIATE = Hoch, MISINFORMATION = Mittel, SPAM/OTHER = Niedrig), Liste jetzt severity-first sortiertdeleteOwnerAccount()extrahiert,admin.deleteUserAccount(nur SUPER_ADMIN, Tipp-Bestätigung der exakten Owner-ID, blockt Selbstlöschung) nutzt dieselbe FunktionPhase 3 — größere Cross-Cutting-Eingriffe (viele Dateien betroffen, mehr Testaufwand)
hiddenAtauf Post — muss in jeder Leseabfrage berücksichtigt werden: Feed, Explore, Profil, Suche, Hashtag)UserBanerweitern + Enforcement in denselben Leseabfragen, Sonderfall „Owner sieht eigenen Content trotzdem")Phase 4 — neue Subsysteme (brauchen auch Produkt-/Design-Entscheidungen, nicht nur Code)
proxy.ts/Layout)Explizit nicht empfohlen / out of scope
Vorschlag: Phase 1 komplett in einer Session, danach aus Phase 2 gezielt auswählen.
Rechte-Matrix — umgesetzt (Commit
c94e60a, deployed)assertAdmin()prüft jetzt eine Mindest-Rolle pro Prozedur (SUPPORT < MODERATOR < SUPER_ADMIN,ADMIN_OWNER_ID-Bootstrap-Account hat immer vollen Zugriff) statt nur „irgendein Admin reicht". So ist es final verdrahtet:Analytics & Übersicht
getStats,getPostsOverTime,getOwnerGrowthgetModerationLog,getModeratorThroughputContent-Moderation
listPosts,listComments,listReportsdeletePost,deleteComment,dismissReport,deleteReportedPostNutzerverwaltung
listUsers,startTeamConversation,exportUserDatabanUser,unbanUserWerbeanzeigen
listAdscreateAd,updateAd,deleteAd,getAdImagePresignedUrlRollen & Einladungen
listModerators,listInviteCodes,revokeInvitegrantRole,revokeRole,createRootInvite,backfillInviteCodesRechtstexte
legal.listVersionslegal.publishAudit-Log-Erweiterung (login-Missbrauch, Rechtssicherheit)
ModerationLogbekommt bei jedem neuen Eintrag zusätzlich:moderatorRole— die Rolle des Handelnden zum Zeitpunkt der Aktion (SUPPORT/MODERATOR/SUPER_ADMIN, oderBOOTSTRAPfür denADMIN_OWNER_ID-Account)ipAddress— die Client-IP zum Zeitpunkt der Aktion (aus dem bestehendenctx.ip, das auch für Rate-Limiting genutzt wird)Beide Felder sind nullable, weil die Tabelle bereits Bestandsdaten aus vorherigen Sessions hatte (historische Einträge zeigen ehrlich
null, statt einen erfundenen Default zu bekommen). Ab sofort werden beide Felder bei jedem Schreibvorgang zwingend gesetzt.Hinweis zur Datenschutz-Seite: Die IP-Erfassung hier betrifft ausschließlich Admin-/Moderator-Aktionen (Missbrauchsprävention bei Login/Account-Kompromittierung, berechtigtes Interesse nach Art. 6 Abs. 1 lit. f DSGVO) — nicht die reguläre Nutzer-IP-Erfassung, die in der Roadmap unter Phase 4 separat und bewusst zurückgestellt ist.
Bekannte Lücke, nicht Teil dieses Changes
getModerationLog(die Abfrage selbst) hat aktuell keine Admin-UI, die es anzeigt — das Log wird zuverlässig geschrieben, ist aber nur per direktem DB-Zugriff einsehbar. Wenn eine Einsicht über das Panel gewünscht ist, wäre das ein eigener kleiner Folge-Task.In den Reports, sind die Gemeldeten Hinhalte nicht anklickbar, somit ist es für den Moderator/Support nicht möglich den inhalt genau zu analysieren und eine beurteilung zu fällen. wichtig wäre hier was für kommentare wurden geschrieben und von wem, wer hat geliked, bild anklickbar für optische analyse des Supports/Moderators (Lightbox)
Verifizierungs-Antragsflow (Option B) — umgesetzt (Commit
a4c4568, deployed)Bugfix aus der letzten Diskussion: der Verify-Button auf der Users-Seite hatte kein Error-Handling — Fehlschläge blieben unsichtbar. Jetzt mit Erfolgs-/Fehler-Toast (Commit
bc2dfa9).Zusätzlich der besprochene Self-Service-Flow:
Nutzer: Antrag mit Begründung über die eigene Pet-Bearbeiten-Seite. Zeigt danach den Status (Ausstehend/Abgelehnt+Grund/Verifiziert).
Moderator: neue Queue-Seite
/p/[secret]/verification(nur ab Moderator-Rolle). Review läuft über eine verpflichtende 4-Punkt-Checkliste — keine freie Ja/Nein-Entscheidung:Alle vier angehakt → automatisch genehmigt (Pet.isVerified wird gesetzt). Irgendein Punkt nicht angehakt → automatisch abgelehnt, mit einer Notiz, die genau auflistet, welche Kriterien fehlten (plus optionaler Freitext-Zusatz vom Moderator).
Benachrichtigung: Der Nutzer wird in jedem Fall automatisch informiert — über eine System-Nachricht vom „PawFeed Team"-Account (nutzt die bestehende DM-Infrastruktur, landet auch als normale Benachrichtigung).
Jede Review-Entscheidung landet mit Rolle+IP im Audit Log, wie alle anderen Aktionen dieser Session.
Typecheck sauber, volle Testsuite grün (132 Tests), Docker-Build erfolgreich, live verifiziert.
UI Anpassung im Admin-Dashoard - Users - Die Buttons Warning, Export und Message sind schlecht lesbar und schlecht erkennbar. bitte farblich abheben jede funktion eine farbe so wie bei Shadowban und Ban klar erkennbare unterschiede und sofort lesbar
Wir haben die PawFeed Team - Kommunikation ja schon aktiv geschaltet.
diese müsste aus dem Admin-Bereich erreichbar sein, also eine Message Funktion direkt aus dem Admin-Dashboard, damit jeder Support/Moderator/Admin den selben inhalt sieht. kannst du das einrichten
Reports anklickbar + Button-Farben + DAU/MAU-Analytics (Commits
a35cb66,4000a1e, deployed)Gemeldete Inhalte anklickbar (zu Kommentar oben)
Post-Vorschau in Reports ist jetzt klickbar, öffnet Detail-Dialog mit vollständigen Bildern (statt nur 4 Thumbnails), „Geliked von"-Liste (Pet-Avatare+Namen) und komplettem Kommentarverlauf. Neue
admin.getReportedPostDetail-Query (Bilder+Reaktionen) — Kommentarliste nutzt bewusst die bereits vorhandeneadmin.listCommentsweiter statt sie zu duplizieren.Button-Farben Users-Seite (zu Kommentar oben)
Message (sky), Export (blau), Warning (amber) — analog zum bestehenden Ban(rot)/Shadowban(violett)-Muster, vorher alle drei identisch neutral-grau.
DAU/MAU + erweiterte Dashboard-Statistiken (Phase 3, letzter der 4 Teile — schließt die komplette Phase 3 ab)
Kein bestehendes Activity-Tracking vorhanden, daher Redis-basiert gebaut (gleiches Muster wie das bestehende Rate-Limiting): täglicher
SADDinvisits:YYYY-MM-DD, ausgelöst einmal pro Request im(app)-Layout — idempotent, kein Client-seitiges Once-per-day-Gedöns nötig. DAU =SCARDvon heute, MAU =SUNIONüber die letzten 30 Tage. Kein neues Postgres-Schema.Dashboard neu: 6 StatCards (DAU, MAU, Shadowban-Anzahl, Blacklist-Einträge, Verifikationen offen/geschlossen) + 3 Zeitreihen-Charts (Visits, Comments, Likes — Tag/Woche/Monat umschaltbar, gleiche Chart-Komponente wie die bestehenden Posts/Owner-Charts).
tsc/Lint/Tests sauber (132 Tests), Docker-Build inkl. TS-Check erfolgreich, deployed. Live im Admin-Panel selbst noch nicht durchgeklickt (fehlende Admin-Session lokal) — bitte kurz gegenchecken.
Damit ist Phase 3 komplett abgeschlossen (Ausblenden, Shadowban, Blacklist, Analytics — alle vier Teile).
Team-Postfach im Admin-Dashboard (Commit
72ae462, deployed)Der Bug dahinter war schon im Code dokumentiert: Der bisherige „Message"-Button auf der Users-Seite leitete in die normale
/messages-Ansicht — die prüftassertPetOwnership, und der „PawFeed Team"-Pet gehört fest derADMIN_OWNER_ID. Für jeden anderen Support/Moderator/Admin lief das ins Leere (stiller FORBIDDEN).Neue Seite „Messages" im Admin-Nav (
/p/[secret]/messages): geteiltes Postfach mit Konversationsliste links, Chat-Verlauf + Antwortfeld rechts. Drei neue Prozeduren (listTeamConversations,getTeamConversationThread,sendTeamReply), gegated über die normale Admin-Rechteprüfung statt Pet-Ownership — jeder Support+ sieht denselben Verlauf und kann als „PawFeed Team" antworten. Öffnen einer Konversation markiert sie für alle als gelesen (geteiltes Postfach). Der „Message"-Button auf der Users-Seite verlinkt jetzt direkt dorthin.tsc/Lint/Tests sauber, Docker-Build erfolgreich, deployed. Bitte live gegenchecken, ob die geteilte Sichtbarkeit so funktioniert wie gewünscht.
Status-Übersicht (Stand 2026-08-14) — Aufräumen der bisherigen Kommentare
Das Issue ist mit 9 Kommentaren unübersichtlich geworden. Hier eine gebündelte Bestandsaufnahme, gegen den aktuellen Code verifiziert (
prisma/schema.prisma,admin.ts).✅ Vollständig erledigt & im Code bestätigt
assertAdmin()mit Mindest-Rolle), Audit-Log-Seite/p/[secret]/log— Commits2d656bd,c94e60a,e099763Pet.isVerified), Report-Priorisierung nach Schweregrad, Admin-getriggerte DSGVO-Löschung — Commit54fb0d5a4c4568Post.hiddenAt(Ausblenden ohne Löschen),Shadowban-Modell,BlacklistEntry-Modell, DAU/MAU-Analytics (Redis-basiert) — Commitsa35cb66,4000a1ea35cb66a35cb66/p/[secret]/messages, geteiltes Postfach für Support/Moderator/Admin) — Commit72ae462⏳ Nur Live-Bestätigung ausstehend (kein offener Code-Punkt)
📋 Genuin offen — Phase 4 (noch nicht begonnen)
Explizit zurückgestellt / nicht empfohlen
Abos, In-App-Käufe, Creator-Payouts, Refund-Handling, IP-/Bot-Management mit VPN-Erkennung, API-Key/Webhook-Verwaltungs-UI — Begründung siehe Kommentar weiter oben, weiterhin unverändert.
Fazit: Von der ursprünglichen Spec sind nur noch die zwei Live-Bestätigungen und Phase 4 offen. Vorschlag: kurz DAU/MAU-Dashboard und Team-Postfach durchklicken, danach gemeinsam entscheiden, ob/welche Phase-4-Punkte als Nächstes drankommen.
Live-Bestätigung erhalten (Stand 2026-08-14)
Beide offenen Live-Checks aus der letzten Status-Übersicht sind bestätigt:
Damit ist von der ursprünglichen Spec-Liste nur noch Phase 4 offen (5 Punkte, siehe oben, unverändert):
Alles andere aus diesem Issue ist erledigt und verifiziert.
Phase 4 (Teil 1) umgesetzt — Wartungsmodus, Registrierungs-IP, Trends & Promotion (Commit
f5f788b, deployed)Von den 5 Phase-4-Punkten: 3 umgesetzt, 1 gestrichen, 1 zurückgestellt.
✅ Wartungsmodus (Teilmenge von „Feature Flags")
Redis-Flag (
maintenance:enabled), Gate inproxy.ts— blockiert alle Seiten außer Admin-Panel, API-Routen (Webhooks/Cron/CSP-Report), den festsprachigen Rechtsseiten und Login/Clerk-Routen (damit ein ausgesperrter Admin sich immer noch einloggen kann, um den Modus wieder abzuschalten). Fail-open bei Redis-Ausfall — ein Redis-Blip darf nie die ganze Seite lahmlegen. Toggle nur für SUPER_ADMIN sichtbar, oben auf dem Dashboard.✅ Registrierungs-IP
Owner.registrationIpwird defensiv an jederowner.upsert-Create-Stelle erfasst (Invite-Consume,legal.acknowledge,legal.acknowledgeUploadConsent,pets.create,owner.setThemePreference) — nötig, weil sich beim Review herausstellte, dass kein einzelner Onboarding-Schritt codegarantiert immer zuerst läuft (hängt vom Invite-Status und davon ab, ob bereits Legal-Docs publiziert sind). Datenschutzerklärung um einen Punkt mit Rechtsgrundlage (Art. 6 Abs. 1 lit. f DSGVO) und Aufbewahrungsdauer (mit dem Konto gelöscht) ergänzt — Text wurde dir vorgelegt und ist freigegeben.✅ Trends & Promotion
Post.pinnedAt-Feld,admin.pinPost/unpinPost(gleiches Muster wiehidePost/unhidePost),explore.getTrendingzeigt gepinnte Posts zuerst unabhängig vom 48h-Fenster. Pin/Unpin-Button + Trending-Hashtags-Panel (7-Tage-Fenster, bereits vorhandene Query wiederverwendet) auf der Admin-Posts-Seite.❌ Gestrichen: Passwort-/2FA-Reset über Clerk Admin API
User kann jederzeit selbst über Clerks Self-Service-Flow zurücksetzen — kein Admin-Trigger nötig.
⏸ Zurückgestellt: System-Mitteilungen/Broadcast
Braucht noch eine gemeinsame Konzeption —
Notificationist bewusst pet-zu-pet-scoped, kein Owner-weites Broadcast-Konzept vorhanden, und der Mailer hat keine Queue für Massenversand.Code-Review vor dem Deploy gefunden & behoben:
NULLbeiORDER BY ... DESCstandardmäßig zuerst — ungepinnte Posts wären vor gepinnten erschienen, jetzt mitnulls: "last"explizit korrigiert/log-in,/sign-up,/__clerk/*fehlten in der Ausnahmeliste)SYSTEM-Target-Type ergänzttsc/Lint/Tests sauber (155 Tests, 14 davon neu), Docker-Build erfolgreich, live verifiziert (
pawfeed.org+/datenschutz→ HTTP 200).Finale Bestandsaufnahme (Stand 2026-08-15)
Dieses Issue ist inzwischen sehr umfangreich geworden (12 Kommentare) — hier die konsolidierte Endabrechnung gegen die ursprüngliche Spec.
✅ Vollständig erledigt, live bestätigt
📋 Genuin offen — einziger verbleibender Punkt
Notificationbewusst pet-zu-pet-scoped ist (kein Owner-weites Broadcast-Konzept) und der Mailer keine Queue für Massenversand hat.Explizit zurückgestellt / nicht empfohlen (unverändert)
Abos, In-App-Käufe, Creator-Payouts, Refund-Handling, IP-/Bot-Management mit VPN-Erkennung, API-Key/Webhook-Verwaltungs-UI.
Fazit: Von der kompletten ursprünglichen Spec-Liste ist nur noch der Broadcast-Punkt offen. Sag Bescheid, ob wir den jetzt gemeinsam konzipieren, ob er zurückgestellt bleibt (dann könnten wir das Issue schließen und bei Bedarf einen neuen, fokussierten Broadcast-Issue aufmachen), oder ob das Issue einfach offen bleiben soll als Merkposten.
Entscheidung: Broadcast/System-Mitteilungen — gestufter Ansatz
Nach Abwägung von drei Optionen (reines In-App-Banner / direkter E-Mail-Massenversand / gestufte Kombination) fällt die Wahl auf die Kombination, in zwei Phasen ausgerollt:
Phase 1 — jetzt: In-App-Banner (Pull-Prinzip)
Wiederverwendung des bereits bewährten Musters aus
LegalUpdateBanner.tsx(Bestandsnutzer-Hinweis bei neuen AGB/Datenschutz-Versionen) — kein Fan-out über Notification-Zeilen pro Pet, sondern ein Abgleich beim App-Start.Design-Entscheidung für die Nachverfolgung:
Phase 2 — später: E-Mail-Eskalation, ab ~100 Nutzern
Bewusst zurückgestellt, bis die Nutzerbasis eine Größe erreicht hat (Richtwert: 100 registrierte Nutzer), bei der proaktive Erreichbarkeit außerhalb der App tatsächlich relevant wird. Grund für den Aufschub, nicht nur Kapazität:
mail.ts, Strato) ist ein geteiltes Konto für sämtliche Mails der Domain (Passwort-Reset, Einladungen, DSGVO-Export-Links). Ein schlecht laufender Massenversand (Spam-Beschwerden, Bounces) würde die Zustellbarkeit der GESAMTEN Domain gefährden, nicht nur der Broadcast-Mails.CRON_SECRET-Mechanismus, mit Status pro Empfänger (versendet/ausstehend/fehlgeschlagen) statt einer naiven Schleife — Duplikate/Ausfälle bei Job-Abbruch sonst nicht auszuschließen.Die Phase-1-Zustellungs-/Lese-Tabelle (Broadcast-ID pro Owner) liefert für Phase 2 bereits die Grundlage, um gezielt nur die Owner per Mail zu erreichen, die die Mitteilung im Banner noch nicht gesehen haben — die Eskalationslogik selbst kommt dann als eigener, separat zu planender Schritt.
Nächster Schritt: Phase 1 (Banner + Broadcast-ID + Zustellungs-/Lese-Tracking) wird jetzt umgesetzt.
Broadcast Phase 1 - live
Admins koennen unter
/p/[secret]/broadcasts(Sidebar "Mitteilungen") system-weite Mitteilungen an alle Owner senden. Owner sehen sie als dismissbaren Banner beim naechsten App-Start und bestaetigen mit "Gelesen".Umsetzung:
Broadcast+BroadcastReceipt(per-Broadcast Empfangs-/Lese-Tracking statt einem einzelnen rollierenden Timestamp - ermoeglicht Delivered/Read-Zahlen pro Mitteilung und spaeteres gezieltes Targeting fuer Phase 2)broadcast.getPending/broadcast.markRead(Owner-seitig, pull-basiert wie beim Legal-Update-Banner)admin.createBroadcast(SUPER_ADMIN) /admin.listBroadcasts(MODERATOR+) inkl. Delivered/Read-Zahlen im Admin-VerlaufSEND_BROADCASTpro VersandPhase 2 (E-Mail-Eskalation) bewusst zurueckgestellt bis ca. 100 aktive Nutzer - Schema ist bereits so ausgelegt, dass sie darauf aufbauen kann.
Deployed und verifiziert (HTTP 200 intern + ueber pawfeed.org).
Das Admin-Dashboard ist nicht Mobil Abrufbar, im sinne von Responsiv.
Habe es eben als Mobil-Version offen gehabt, leider erkennt man gar nichts. alles ist in sich zusammen geschoben.
bitte beheben