cms.c2sgmbh/prompts/Community management roadmap prompt.md
Martin Porwoll 77f70876f4 chore: add Claude Code config, prompts, and tenant setup scripts
- Add .claude/ configuration (agents, commands, hooks, get-shit-done workflows)
- Add prompts/ directory with development planning documents
- Add scripts/setup-tenants/ with tenant configuration
- Add docs/screenshots/
- Remove obsolete phase2.2-corrections-report.md
- Update pnpm-lock.yaml
- Update detect-secrets.sh to ignore setup.sh (env var usage, not secrets)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 10:18:05 +00:00

835 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Community Management System - Phasen 2.3 bis 3.0
## Kontext
Du arbeitest am Community Management System für Complex Care Solutions (CCS). Die Phasen 1.0, 2.1 und 2.2 sind abgeschlossen:
**Phase 1.0 (✅ Live):**
- Community Inbox mit Filter, Suche, Detail-View
- YouTube OAuth Integration
- Rules Engine für Automatisierung
- Export (PDF/Excel/CSV)
- Claude AI Sentiment-Analyse
**Phase 2.1 (✅ Merged):**
- Analytics Dashboard unter `/admin/views/community/analytics`
- 6 API-Endpoints (overview, sentiment-trend, response-metrics, channel-comparison, top-content, topic-cloud)
- 6 React-Komponenten mit Recharts
- Responsive Design, Dark Mode
**Phase 2.2 (✅ Merged):**
- YouTube Auto-Sync (Cron alle 15 Min)
- AI Reply Suggestions (3 Tonalitäten)
- Kanalspezifische Personas (corporate, lifestyle, business)
- ClaudeReplyService mit medizinischer Fragen-Erkennung
---
## Technischer Stack
| Komponente | Technologie |
|------------|-------------|
| Framework | Next.js 15 (App Router) |
| CMS | Payload CMS 3.x |
| Datenbank | PostgreSQL 17 |
| Styling | SCSS mit BEM-Konvention |
| Charts | Recharts |
| AI | Anthropic Claude API (claude-3-5-haiku) |
| Auth | Payload Auth + OAuth 2.0 |
| Deployment | Vercel |
---
## Bestehende Architektur
### Verzeichnisstruktur
```
src/
├── app/(payload)/
│ ├── admin/views/community/
│ │ ├── inbox/
│ │ │ ├── page.tsx
│ │ │ ├── CommunityInbox.tsx
│ │ │ └── inbox.scss
│ │ └── analytics/
│ │ ├── page.tsx
│ │ ├── AnalyticsDashboard.tsx
│ │ ├── analytics.scss
│ │ └── components/
│ └── api/community/
│ ├── stats/route.ts
│ ├── export/route.ts
│ ├── reply/route.ts
│ ├── sync/route.ts
│ ├── generate-reply/route.ts
│ └── analytics/[...]/route.ts
├── lib/
│ ├── integrations/
│ │ ├── youtube/
│ │ │ ├── YouTubeClient.ts
│ │ │ └── CommentsSyncService.ts
│ │ └── claude/
│ │ ├── ClaudeAnalysisService.ts
│ │ └── ClaudeReplyService.ts
│ └── jobs/
│ ├── JobLogger.ts
│ └── syncAllComments.ts
├── collections/
│ ├── SocialPlatforms.ts
│ ├── SocialAccounts.ts
│ ├── CommunityInteractions.ts
│ ├── CommunityTemplates.ts
│ └── CommunityRules.ts
└── types/
└── youtube.ts
```
### Datenbank-Schema (CommunityInteractions)
```typescript
{
platform: Relation<SocialPlatforms> // youtube, instagram, tiktok
socialAccount: Relation<SocialAccounts>
linkedContent?: Relation<YouTubeContent | InstagramContent | TikTokContent>
type: 'comment' | 'reply' | 'dm' | 'mention' | 'review' | 'question'
externalId: string // Plattform-spezifische ID
author: {
externalId: string
name: string
handle: string
avatarUrl?: string
isVerified: boolean
isSubscriber: boolean
followerCount?: number
}
message: string
analysis: {
sentiment: 'positive' | 'neutral' | 'negative' | 'question' | 'gratitude' | 'frustration'
sentimentScore: number
confidence: number
topics: Array<{ topic: string }>
suggestedReply?: string
}
flags: {
isMedicalQuestion: boolean
requiresEscalation: boolean
isSpam: boolean
isFromInfluencer: boolean
}
status: 'new' | 'in_review' | 'waiting' | 'replied' | 'resolved' | 'archived' | 'spam'
priority: 'urgent' | 'high' | 'normal' | 'low'
response?: {
text: string
usedTemplate?: Relation<CommunityTemplates>
sentAt: Date
sentBy: Relation<Users>
externalId?: string
}
}
```
### SocialAccounts Schema
```typescript
{
platform: Relation<SocialPlatforms>
accountName: string
accountHandle: string
channelType: 'corporate' | 'lifestyle' | 'business'
credentials: {
accessToken: string
refreshToken: string
expiresAt: Date
scope: string
}
syncSettings: {
enabled: boolean
lastSyncAt: Date
syncInterval: number // Minuten
}
stats: {
followers: number
totalInteractions: number
lastUpdated: Date
}
}
```
---
## Phase 2.3: Instagram Integration
### Ziel
Instagram-Kommentare und DMs synchronisieren, analysieren und beantworten analog zur YouTube-Integration.
### Voraussetzungen
- Instagram Business Account (verbunden mit Facebook Page)
- Meta Business Suite Zugang
- Instagram Graph API Zugang
### API-Referenz
- **Instagram Graph API:** https://developers.facebook.com/docs/instagram-api
- **Webhooks:** https://developers.facebook.com/docs/instagram-api/guides/webhooks
### Deliverables
#### 1. OAuth Flow für Instagram
```
src/app/(payload)/api/auth/instagram/
├── route.ts # OAuth initiate
└── callback/route.ts # OAuth callback
```
**Scopes benötigt:**
- `instagram_basic`
- `instagram_manage_comments`
- `instagram_manage_messages` (für DMs, falls verfügbar)
- `pages_show_list`
- `pages_read_engagement`
#### 2. Instagram Client
```
src/lib/integrations/instagram/
├── InstagramClient.ts
├── CommentsSyncService.ts
└── types.ts
```
**InstagramClient Methoden:**
```typescript
class InstagramClient {
// Auth
async refreshAccessToken(): Promise<void>
// Media (Posts, Reels, Stories)
async getMedia(accountId: string, limit?: number): Promise<InstagramMedia[]>
async getMediaComments(mediaId: string): Promise<InstagramComment[]>
// Comments
async replyToComment(commentId: string, message: string): Promise<string>
async deleteComment(commentId: string): Promise<void>
async hideComment(commentId: string): Promise<void>
// Mentions
async getMentions(accountId: string): Promise<InstagramMention[]>
// DMs (wenn verfügbar)
async getConversations(accountId: string): Promise<InstagramConversation[]>
async sendMessage(conversationId: string, message: string): Promise<void>
}
```
#### 3. Sync Service
```typescript
// CommentsSyncService.ts
class InstagramCommentsSyncService {
async syncAccount(account: SocialAccount): Promise<SyncResult>
async syncAllAccounts(): Promise<SyncResult[]>
}
```
**Sync-Logik:**
1. Alle Media-Items der letzten 30 Tage abrufen
2. Kommentare pro Media-Item abrufen
3. Neue Kommentare in DB speichern
4. Claude-Analyse triggern
5. Mentions separat abrufen und speichern
#### 4. Cron Job erweitern
```typescript
// src/app/(payload)/api/cron/social-sync/route.ts
// Erweitere bestehenden YouTube-Sync um Instagram
export async function GET(request: Request) {
// Auth check...
const results = {
youtube: await syncYouTubeComments(),
instagram: await syncInstagramComments(),
}
return Response.json({ success: true, results })
}
```
#### 5. Collection Updates
**SocialPlatforms - Neuer Eintrag:**
```typescript
{
name: 'Instagram',
slug: 'instagram',
icon: 'instagram',
features: ['comments', 'mentions', 'dms', 'stories'],
apiVersion: 'v18.0'
}
```
**InstagramContent Collection (neu):**
```typescript
// src/collections/InstagramContent.ts
{
slug: 'instagram-content',
fields: [
{ name: 'externalId', type: 'text', required: true, unique: true },
{ name: 'socialAccount', type: 'relationship', relationTo: 'social-accounts' },
{ name: 'mediaType', type: 'select', options: ['image', 'video', 'carousel', 'reel', 'story'] },
{ name: 'caption', type: 'textarea' },
{ name: 'permalink', type: 'text' },
{ name: 'thumbnailUrl', type: 'text' },
{ name: 'postedAt', type: 'date' },
{ name: 'stats', type: 'group', fields: [
{ name: 'likes', type: 'number' },
{ name: 'comments', type: 'number' },
{ name: 'shares', type: 'number' },
{ name: 'saves', type: 'number' },
{ name: 'reach', type: 'number' },
]},
]
}
```
#### 6. UI Updates
**CommunityInbox.tsx:**
- Platform-Filter um "Instagram" erweitern
- Instagram-spezifische Icons und Badges
- "Hide Comment" Action für Instagram
- Story-Mentions separat anzeigen
**ChannelComparison.tsx:**
- Instagram-Accounts in Vergleichstabelle
### Acceptance Criteria
- [ ] OAuth-Flow für Instagram Business Accounts funktioniert
- [ ] Kommentare werden alle 15 Minuten synchronisiert
- [ ] Mentions werden erkannt und importiert
- [ ] Antworten werden über API gepostet
- [ ] "Hide Comment" Funktion verfügbar
- [ ] Analytics Dashboard zeigt Instagram-Daten
- [ ] Keine TypeScript-Fehler
- [ ] Error Handling für API-Rate-Limits
### Wichtige Hinweise
1. **Long-lived Tokens:** Instagram-Tokens laufen nach 60 Tagen ab → Refresh implementieren
2. **Rate Limits:** 200 Calls/Stunde pro User → Batching implementieren
3. **Webhooks (optional):** Für Echtzeit-Updates statt Polling
4. **Story-Mentions:** Verfallen nach 24h → schnell syncen
---
## Phase 2.4: TikTok Integration
### Ziel
TikTok-Kommentare synchronisieren und beantworten.
### Voraussetzungen
- TikTok Business Account
- TikTok for Developers Zugang
- App-Genehmigung für Comment API
### API-Referenz
- **TikTok Content Posting API:** https://developers.tiktok.com/doc/content-posting-api-get-started
- **TikTok Login Kit:** https://developers.tiktok.com/doc/login-kit-web
### Deliverables
#### 1. OAuth Flow für TikTok
```
src/app/(payload)/api/auth/tiktok/
├── route.ts
└── callback/route.ts
```
**Scopes:**
- `user.info.basic`
- `video.list`
- `comment.list`
- `comment.list.manage`
#### 2. TikTok Client
```
src/lib/integrations/tiktok/
├── TikTokClient.ts
├── CommentsSyncService.ts
└── types.ts
```
**TikTokClient Methoden:**
```typescript
class TikTokClient {
async refreshAccessToken(): Promise<void>
async getVideos(openId: string, cursor?: string): Promise<TikTokVideo[]>
async getVideoComments(videoId: string, cursor?: string): Promise<TikTokComment[]>
async replyToComment(videoId: string, commentId: string, text: string): Promise<string>
}
```
#### 3. TikTokContent Collection
```typescript
// src/collections/TikTokContent.ts
{
slug: 'tiktok-content',
fields: [
{ name: 'externalId', type: 'text', required: true, unique: true },
{ name: 'socialAccount', type: 'relationship', relationTo: 'social-accounts' },
{ name: 'title', type: 'text' },
{ name: 'description', type: 'textarea' },
{ name: 'shareUrl', type: 'text' },
{ name: 'coverImageUrl', type: 'text' },
{ name: 'duration', type: 'number' },
{ name: 'postedAt', type: 'date' },
{ name: 'stats', type: 'group', fields: [
{ name: 'views', type: 'number' },
{ name: 'likes', type: 'number' },
{ name: 'comments', type: 'number' },
{ name: 'shares', type: 'number' },
]},
]
}
```
#### 4. Cron Job erweitern
```typescript
// Erweitere social-sync um TikTok
const results = {
youtube: await syncYouTubeComments(),
instagram: await syncInstagramComments(),
tiktok: await syncTikTokComments(),
}
```
### Acceptance Criteria
- [ ] OAuth-Flow für TikTok Business Accounts
- [ ] Videos werden synchronisiert
- [ ] Kommentare werden importiert und analysiert
- [ ] Antworten können gepostet werden
- [ ] Analytics Dashboard integriert TikTok
- [ ] Rate Limiting beachtet (100 Requests/Minute)
### Wichtige Hinweise
1. **API-Zugang:** TikTok Comment API erfordert App-Review → frühzeitig beantragen
2. **Sandbox Mode:** Erst in Sandbox testen, dann Production beantragen
3. **Cursor-based Pagination:** TikTok nutzt Cursor statt Offset
4. **Kein DM-Zugang:** TikTok API erlaubt keine DM-Integration
---
## Phase 2.5: Auto-Reply System
### Ziel
Vollautomatische Antworten für bestimmte Kommentar-Typen basierend auf konfigurierbaren Regeln.
### Architektur
```
┌─────────────────────────────────────────────────────────────────┐
│ AUTO-REPLY FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ New Comment ──▶ Analysis ──▶ Rule Matching ──▶ Decision │
│ │ │
│ ┌──────────┴──────────┐ │
│ ▼ ▼ │
│ [Auto-Reply] [Manual Queue] │
│ │ │
│ ▼ │
│ Generate Reply ──▶ Post ──▶ Log │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Deliverables
#### 1. AutoReplyRules Collection
```typescript
// src/collections/AutoReplyRules.ts
{
slug: 'auto-reply-rules',
admin: {
useAsTitle: 'name',
group: 'Community',
},
fields: [
{ name: 'name', type: 'text', required: true },
{ name: 'description', type: 'textarea' },
{ name: 'enabled', type: 'checkbox', defaultValue: true },
{ name: 'priority', type: 'number', defaultValue: 0 }, // Höher = wird zuerst geprüft
// Conditions
{ name: 'conditions', type: 'group', fields: [
{ name: 'platforms', type: 'relationship', relationTo: 'social-platforms', hasMany: true },
{ name: 'accounts', type: 'relationship', relationTo: 'social-accounts', hasMany: true },
{ name: 'sentiments', type: 'select', hasMany: true, options: [
'positive', 'neutral', 'negative', 'question', 'gratitude', 'frustration'
]},
{ name: 'topicsInclude', type: 'array', fields: [{ name: 'topic', type: 'text' }] },
{ name: 'topicsExclude', type: 'array', fields: [{ name: 'topic', type: 'text' }] },
{ name: 'keywordsInclude', type: 'array', fields: [{ name: 'keyword', type: 'text' }] },
{ name: 'keywordsExclude', type: 'array', fields: [{ name: 'keyword', type: 'text' }] },
{ name: 'authorMinFollowers', type: 'number' },
{ name: 'authorMaxFollowers', type: 'number' },
{ name: 'excludeVerified', type: 'checkbox', defaultValue: false },
{ name: 'excludeInfluencers', type: 'checkbox', defaultValue: true },
]},
// Exclusions (WICHTIG für Sicherheit)
{ name: 'exclusions', type: 'group', fields: [
{ name: 'excludeMedicalQuestions', type: 'checkbox', defaultValue: true },
{ name: 'excludeEscalations', type: 'checkbox', defaultValue: true },
{ name: 'excludeNegativeSentiment', type: 'checkbox', defaultValue: true },
{ name: 'excludeLongMessages', type: 'checkbox', defaultValue: true },
{ name: 'maxMessageLength', type: 'number', defaultValue: 500 },
{ name: 'confidenceThreshold', type: 'number', defaultValue: 80 }, // Mindest-Confidence für Auto-Reply
]},
// Action
{ name: 'action', type: 'group', fields: [
{ name: 'type', type: 'select', options: [
{ label: 'Template verwenden', value: 'template' },
{ label: 'AI generieren', value: 'ai_generate' },
{ label: 'Template + AI personalisieren', value: 'template_ai' },
]},
{ name: 'template', type: 'relationship', relationTo: 'community-templates' },
{ name: 'aiTone', type: 'select', options: ['freundlich', 'professionell', 'empathisch'] },
{ name: 'delay', type: 'number', defaultValue: 0 }, // Minuten bis Auto-Reply
{ name: 'addSignature', type: 'checkbox', defaultValue: true },
]},
// Limits
{ name: 'limits', type: 'group', fields: [
{ name: 'maxPerDay', type: 'number', defaultValue: 50 },
{ name: 'maxPerHour', type: 'number', defaultValue: 10 },
{ name: 'cooldownMinutes', type: 'number', defaultValue: 5 }, // Cooldown pro Autor
]},
// Stats
{ name: 'stats', type: 'group', fields: [
{ name: 'totalFired', type: 'number', defaultValue: 0 },
{ name: 'lastFiredAt', type: 'date' },
]},
]
}
```
#### 2. AutoReplyService
```typescript
// src/lib/services/AutoReplyService.ts
interface AutoReplyDecision {
shouldAutoReply: boolean
rule?: AutoReplyRule
reason: string
generatedReply?: string
}
class AutoReplyService {
/**
* Prüft ob ein Kommentar auto-replied werden soll
*/
async evaluate(interaction: CommunityInteraction): Promise<AutoReplyDecision>
/**
* Führt Auto-Reply aus
*/
async execute(interaction: CommunityInteraction, rule: AutoReplyRule): Promise<void>
/**
* Prüft Rate Limits für eine Regel
*/
private async checkLimits(rule: AutoReplyRule): Promise<boolean>
/**
* Generiert Reply basierend auf Action-Type
*/
private async generateReply(
interaction: CommunityInteraction,
rule: AutoReplyRule
): Promise<string>
/**
* Postet Reply auf Plattform
*/
private async postReply(
interaction: CommunityInteraction,
replyText: string
): Promise<string>
}
```
#### 3. Integration in Sync-Flow
```typescript
// Erweitere CommentsSyncService (alle Plattformen)
async syncComment(comment: RawComment): Promise<void> {
// 1. In DB speichern
const interaction = await this.saveInteraction(comment)
// 2. Claude-Analyse
await this.analyzeInteraction(interaction)
// 3. Auto-Reply Check (NEU)
const autoReplyService = new AutoReplyService()
const decision = await autoReplyService.evaluate(interaction)
if (decision.shouldAutoReply && decision.rule) {
await autoReplyService.execute(interaction, decision.rule)
}
}
```
#### 4. Auto-Reply Log Collection
```typescript
// src/collections/AutoReplyLogs.ts
{
slug: 'auto-reply-logs',
fields: [
{ name: 'interaction', type: 'relationship', relationTo: 'community-interactions' },
{ name: 'rule', type: 'relationship', relationTo: 'auto-reply-rules' },
{ name: 'generatedReply', type: 'textarea' },
{ name: 'postedAt', type: 'date' },
{ name: 'success', type: 'checkbox' },
{ name: 'error', type: 'text' },
{ name: 'responseTime', type: 'number' }, // ms bis Antwort gepostet
]
}
```
#### 5. Admin UI für Auto-Reply Rules
**Neue View:** `/admin/views/community/auto-reply`
```
src/app/(payload)/admin/views/community/auto-reply/
├── page.tsx
├── AutoReplyManager.tsx
└── auto-reply.scss
```
**Features:**
- Liste aller Regeln mit Enable/Disable Toggle
- Regel-Editor mit Condition Builder
- Test-Modus: Kommentar eingeben und prüfen welche Regel matcht
- Stats: Fired Count, Success Rate, Avg Response Time
- Logs: Letzte 100 Auto-Replies mit Details
#### 6. Analytics Integration
**Neue Metriken:**
- Auto-Reply Rate (% der Kommentare die auto-replied wurden)
- Auto-Reply Success Rate
- Durchschnittliche Auto-Reply Zeit
- Top Auto-Reply Rules
- Manual Override Rate (wie oft wurde Auto-Reply überschrieben)
### Acceptance Criteria
- [ ] Regel-Editor im Admin-Panel
- [ ] Conditions werden korrekt ausgewertet
- [ ] Exclusions verhindern Auto-Reply bei sensiblen Inhalten
- [ ] Rate Limits funktionieren
- [ ] Logs werden geschrieben
- [ ] Test-Modus funktioniert
- [ ] Analytics zeigen Auto-Reply Metriken
- [ ] Medizinische Fragen werden NIEMALS auto-replied
- [ ] Negative Kommentare werden NIEMALS auto-replied (außer explizit konfiguriert)
### Sicherheitsregeln (KRITISCH)
```
⚠️ NIEMALS AUTO-REPLY BEI:
1. Medizinischen Fragen (isMedicalQuestion = true)
2. Eskalationen (requiresEscalation = true)
3. Negativem Sentiment (außer explizit aktiviert)
4. Kommentaren von verifizierten Accounts (außer explizit aktiviert)
5. Langen, komplexen Nachrichten (> 500 Zeichen default)
6. Niedriger Analyse-Confidence (< 80% default)
7. Kommentaren die bereits beantwortet wurden
```
---
## Phase 3.0: Scheduled Reports & Real-time Updates
### Ziel
Automatische Reports per E-Mail und Echtzeit-Updates im Dashboard.
### Deliverables
#### 1. Scheduled Reports
**ReportSchedules Collection:**
```typescript
// src/collections/ReportSchedules.ts
{
slug: 'report-schedules',
fields: [
{ name: 'name', type: 'text', required: true },
{ name: 'enabled', type: 'checkbox', defaultValue: true },
{ name: 'frequency', type: 'select', options: ['daily', 'weekly', 'monthly'] },
{ name: 'dayOfWeek', type: 'select', options: ['monday', 'tuesday', ...] }, // für weekly
{ name: 'dayOfMonth', type: 'number', min: 1, max: 28 }, // für monthly
{ name: 'time', type: 'text' }, // HH:MM Format
{ name: 'timezone', type: 'text', defaultValue: 'Europe/Berlin' },
{ name: 'recipients', type: 'array', fields: [{ name: 'email', type: 'email' }] },
{ name: 'reportType', type: 'select', options: [
'overview', // KPI Summary
'sentiment_analysis', // Sentiment Deep-Dive
'response_metrics', // Team Performance
'content_performance', // Top Content
'full_report', // Alle oben kombiniert
]},
{ name: 'channels', type: 'relationship', relationTo: 'social-accounts', hasMany: true },
{ name: 'format', type: 'select', options: ['pdf', 'excel', 'html_email'] },
{ name: 'lastSentAt', type: 'date' },
{ name: 'nextScheduledAt', type: 'date' },
]
}
```
**ReportGeneratorService:**
```typescript
// src/lib/services/ReportGeneratorService.ts
class ReportGeneratorService {
async generateReport(schedule: ReportSchedule): Promise<Buffer>
async sendReport(schedule: ReportSchedule, report: Buffer): Promise<void>
}
```
**Cron Job:**
```typescript
// src/app/(payload)/api/cron/send-reports/route.ts
// Läuft stündlich, prüft welche Reports fällig sind
```
#### 2. Real-time Updates (WebSocket)
**Option A: Vercel Serverless (Polling-Fallback)**
```typescript
// Da Vercel keine WebSockets unterstützt, Server-Sent Events (SSE) nutzen
// src/app/(payload)/api/community/stream/route.ts
export async function GET(request: Request) {
const encoder = new TextEncoder()
const stream = new ReadableStream({
async start(controller) {
// Polling-Loop mit 5s Intervall
while (true) {
const updates = await getRecentUpdates()
controller.enqueue(encoder.encode(`data: ${JSON.stringify(updates)}\n\n`))
await sleep(5000)
}
}
})
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
}
})
}
```
**Option B: Externe WebSocket-Lösung**
- Pusher, Ably, oder Socket.io mit separatem Server
- Trigger bei DB-Änderungen via Payload Hooks
**Dashboard Integration:**
```typescript
// useRealtimeUpdates.ts Hook
function useRealtimeUpdates() {
const [updates, setUpdates] = useState<Update[]>([])
useEffect(() => {
const eventSource = new EventSource('/api/community/stream')
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data)
setUpdates(prev => [...data, ...prev].slice(0, 100))
}
return () => eventSource.close()
}, [])
return updates
}
```
**UI Updates:**
- Live-Counter für neue Kommentare
- Toast-Notifications bei wichtigen Events
- Auto-Refresh der Inbox bei neuen Items
- Pulsierender Badge wenn neue ungelesene Items
### Acceptance Criteria
**Scheduled Reports:**
- [ ] Report-Editor im Admin-Panel
- [ ] Daily/Weekly/Monthly Scheduling funktioniert
- [ ] PDF-Reports werden generiert
- [ ] E-Mail-Versand funktioniert
- [ ] Timezone-Support
**Real-time Updates:**
- [ ] SSE-Endpoint funktioniert
- [ ] Dashboard zeigt Live-Updates
- [ ] Toast-Notifications bei neuen Kommentaren
- [ ] Kein Performance-Impact bei vielen Clients
---
## Priorisierung
| Phase | Priorität | Geschätzter Aufwand | Abhängigkeiten |
|-------|-----------|---------------------|----------------|
| 2.3 Instagram | Hoch | 3-4 Tage | Meta Business Suite Zugang |
| 2.4 TikTok | Mittel | 2-3 Tage | TikTok API Approval |
| 2.5 Auto-Reply | Mittel | 3-4 Tage | Phase 2.3 (mehr Testdaten) |
| 3.0 Reports | Niedrig | 2-3 Tage | E-Mail-Service (Resend/SendGrid) |
| 3.0 Real-time | Niedrig | 2-3 Tage | Optional: Pusher Account |
---
## Code-Konventionen (Referenz)
### TypeScript
- Strict Mode aktiviert
- Interfaces für alle API-Responses
- Zod für Runtime-Validation
### SCSS
- BEM-Konvention: `.block__element--modifier`
- Payload CSS-Variablen nutzen: `--theme-elevation-X`
- Mobile-first mit Breakpoints: 480px, 768px, 1024px, 1200px
### API Routes
- Payload Auth via `getPayload({ config })`
- Konsistente Error-Responses: `{ error: string, details?: any }`
- Success-Responses: `{ success: true, data: any }`
### Testing
- Manueller Test nach jeder Komponente
- API-Tests via curl/Postman dokumentieren
- Edge Cases: Leere Daten, API-Fehler, Rate Limits
---
## Checkliste vor Merge
- [ ] Keine TypeScript-Fehler (`npm run typecheck`)
- [ ] Build erfolgreich (`npm run build`)
- [ ] Alle neuen Collections in payload.config.ts registriert
- [ ] Environment Variables dokumentiert
- [ ] API-Endpoints getestet
- [ ] UI responsiv auf Mobile
- [ ] Error States implementiert
- [ ] Loading States implementiert
---
*Erstellt: 16. Januar 2026*
*Für: Dev-KI (Claude Code)*
*Von: Konzept-KI (Claude Opus 4.5)*