# Community Management System - Roadmap 2.3 bis 3.0 (Erweitert)

**Version:** 2.0 (Erweitert mit Facebook-Integration)
**Datum:** 16. Januar 2026
**Erstellt von:** Dev-KI nach Analyse des Konzept-Prompts

---

## Analyse des Original-Prompts

### Umsetzbarkeit in aktueller Implementierung

| Komponente | Status | Bewertung |
|------------|--------|-----------|
| SocialPlatforms Collection | ✅ Existiert | Instagram, Facebook bereits definiert |
| SocialAccounts Collection | ✅ Existiert | OAuth-Credentials-Struktur vorhanden |
| CommunityInteractions | ✅ Existiert | Plattform-agnostisch, erweiterbar |
| Rules Engine | ✅ Existiert | Basis für Auto-Reply vorhanden |
| ClaudeAnalysisService | ✅ Existiert | Wiederverwendbar für alle Plattformen |
| ClaudeReplyService | ✅ Existiert | Wiederverwendbar für alle Plattformen |
| E-Mail Service | ✅ Existiert | Für Reports nutzbar |
| YouTubeClient Pattern | ✅ Vorlage | Replizierbar für Meta/TikTok |

### Identifizierte Synergien

1. **Facebook + Instagram**: Beide nutzen Meta Graph API → Gemeinsame Auth-Basis
2. **CommentsSyncService**: Pattern kann für alle Plattformen verwendet werden
3. **Rules Engine → Auto-Reply**: Natürliche Erweiterung der bestehenden Logik

---

## Restrukturierte Phasen (Logisch aufgeteilt)

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                        IMPLEMENTIERUNGSREIHENFOLGE                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Phase 2.3a   Phase 2.3b   Phase 2.3c   Phase 2.4   Phase 2.5a  Phase 2.5b │
│  ┌───────┐    ┌───────┐    ┌───────┐    ┌───────┐   ┌───────┐   ┌───────┐  │
│  │ Meta  │───▶│Facebook│───▶│Insta- │───▶│TikTok │──▶│Auto-  │──▶│Auto-  │  │
│  │ OAuth │    │ Integr.│    │ gram  │    │       │   │Reply  │   │Reply  │  │
│  └───────┘    └───────┘    └───────┘    └───────┘   │Service│   │  UI   │  │
│                                                      └───────┘   └───────┘  │
│       │                                                    │                │
│       ▼                                                    ▼                │
│  Phase 3.0a                                          Phase 3.0b             │
│  ┌───────────┐                                      ┌───────────┐           │
│  │ Scheduled │                                      │ Real-time │           │
│  │  Reports  │                                      │  Updates  │           │
│  └───────────┘                                      └───────────┘           │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

---

## Phase 2.3a: Meta OAuth & Basis-Infrastruktur

**Dauer:** 1-2 Tage
**Abhängigkeiten:** Meta Business Suite Zugang, App-Konfiguration

### Ziel
Gemeinsame OAuth-Infrastruktur für Facebook und Instagram (beide nutzen Meta Graph API).

### Voraussetzungen
- Facebook Developer Account
- Meta Business Suite mit verbundener Facebook Page
- Instagram Business Account (mit Facebook Page verknüpft)
- App in Meta for Developers erstellt

### Deliverables

#### 1. Meta OAuth Flow
```
src/app/(payload)/api/auth/meta/
├── route.ts              # OAuth initiate
└── callback/route.ts     # OAuth callback (für FB + IG)
```

**OAuth Configuration:**
```typescript
// src/lib/integrations/meta/oauth.ts

const META_OAUTH_CONFIG = {
  authorizationUrl: 'https://www.facebook.com/v19.0/dialog/oauth',
  tokenUrl: 'https://graph.facebook.com/v19.0/oauth/access_token',
  scopes: [
    // Facebook
    'pages_show_list',
    'pages_read_engagement',
    'pages_manage_posts',
    'pages_read_user_content',
    'pages_manage_engagement',

    // Instagram
    'instagram_basic',
    'instagram_manage_comments',
    'instagram_manage_messages',

    // Business
    'business_management',
  ],
}

export async function getAuthUrl(state: string): Promise<string>
export async function exchangeCodeForTokens(code: string): Promise<MetaTokens>
export async function refreshAccessToken(token: string): Promise<MetaTokens>
export async function getLongLivedToken(shortLivedToken: string): Promise<string>
```

#### 2. Meta Base Client
```typescript
// src/lib/integrations/meta/MetaBaseClient.ts

export class MetaBaseClient {
  protected accessToken: string
  protected apiVersion: string = 'v19.0'
  protected baseUrl: string = 'https://graph.facebook.com'

  constructor(accessToken: string)

  protected async request<T>(
    endpoint: string,
    method?: 'GET' | 'POST' | 'DELETE',
    params?: Record<string, any>
  ): Promise<T>

  async getMe(): Promise<MetaUser>
  async getPages(): Promise<FacebookPage[]>
  async getInstagramAccounts(pageId: string): Promise<InstagramAccount[]>
}
```

#### 3. Types
```typescript
// src/types/meta.ts

export interface MetaTokens {
  access_token: string
  token_type: string
  expires_in: number
}

export interface FacebookPage {
  id: string
  name: string
  access_token: string  // Page-spezifischer Token
  category: string
  instagram_business_account?: {
    id: string
  }
}

export interface InstagramAccount {
  id: string
  username: string
  profile_picture_url: string
  followers_count: number
  media_count: number
}

export interface MetaComment {
  id: string
  message: string
  from: {
    id: string
    name: string
  }
  created_time: string
  like_count?: number
  comment_count?: number
  is_hidden?: boolean
}
```

#### 4. API Endpoint
```typescript
// src/app/(payload)/api/auth/meta/route.ts

export async function GET(request: NextRequest) {
  // 1. State generieren mit accountType (facebook | instagram)
  // 2. Auth URL generieren
  // 3. Redirect zu Meta OAuth
}

// src/app/(payload)/api/auth/meta/callback/route.ts

export async function GET(request: NextRequest) {
  // 1. Code aus Query extrahieren
  // 2. Token austauschen
  // 3. Long-lived Token holen (60 Tage gültig)
  // 4. Pages/IG Accounts abrufen
  // 5. In SocialAccounts speichern
  // 6. Redirect zu Admin mit Erfolg
}
```

### Environment Variables
```bash
# .env
META_APP_ID=your_app_id
META_APP_SECRET=your_app_secret
META_REDIRECT_URI=https://your-domain.com/api/auth/meta/callback
```

### Acceptance Criteria
- [ ] OAuth-Flow leitet korrekt zu Meta weiter
- [ ] Callback verarbeitet Token korrekt
- [ ] Long-lived Token wird generiert (60 Tage)
- [ ] Pages und IG-Accounts werden erkannt
- [ ] Credentials werden sicher gespeichert
- [ ] Fehler werden benutzerfreundlich angezeigt

---

## Phase 2.3b: Facebook Integration

**Dauer:** 2-3 Tage
**Abhängigkeiten:** Phase 2.3a abgeschlossen

### Ziel
Facebook Page Kommentare und Nachrichten synchronisieren, analysieren und beantworten.

### Deliverables

#### 1. FacebookClient
```typescript
// src/lib/integrations/meta/FacebookClient.ts

import { MetaBaseClient } from './MetaBaseClient'

export class FacebookClient extends MetaBaseClient {
  private pageId: string
  private pageAccessToken: string

  constructor(pageAccessToken: string, pageId: string)

  // Posts
  async getPagePosts(limit?: number, since?: Date): Promise<FacebookPost[]>
  async getPostComments(postId: string, limit?: number): Promise<MetaComment[]>

  // Comments
  async replyToComment(commentId: string, message: string): Promise<string>
  async hideComment(commentId: string): Promise<void>
  async unhideComment(commentId: string): Promise<void>
  async deleteComment(commentId: string): Promise<void>
  async likeComment(commentId: string): Promise<void>

  // Page Messages (Messenger)
  async getConversations(limit?: number): Promise<FacebookConversation[]>
  async getMessages(conversationId: string): Promise<FacebookMessage[]>
  async sendMessage(recipientId: string, message: string): Promise<string>

  // Page Info
  async getPageInsights(metrics: string[], period: string): Promise<PageInsight[]>
}
```

#### 2. Facebook Types
```typescript
// src/types/facebook.ts

export interface FacebookPost {
  id: string
  message?: string
  story?: string
  full_picture?: string
  permalink_url: string
  created_time: string
  shares?: { count: number }
  reactions?: { summary: { total_count: number } }
  comments?: { summary: { total_count: number } }
}

export interface FacebookConversation {
  id: string
  participants: {
    data: Array<{ id: string; name: string }>
  }
  updated_time: string
  message_count: number
}

export interface FacebookMessage {
  id: string
  message: string
  from: { id: string; name: string }
  created_time: string
  attachments?: Array<{
    type: string
    url: string
  }>
}
```

#### 3. FacebookContent Collection
```typescript
// src/collections/FacebookContent.ts

{
  slug: 'facebook-content',
  admin: {
    useAsTitle: 'title',
    group: 'Social Media',
    defaultColumns: ['title', 'socialAccount', 'type', 'postedAt'],
  },
  fields: [
    { name: 'externalId', type: 'text', required: true, unique: true },
    { name: 'socialAccount', type: 'relationship', relationTo: 'social-accounts', required: true },
    { name: 'type', type: 'select', options: ['post', 'photo', 'video', 'link', 'event'] },
    { name: 'title', type: 'text' },  // Erste Zeile der Message
    { name: 'message', type: 'textarea' },
    { name: 'permalinkUrl', type: 'text' },
    { name: 'imageUrl', type: 'text' },
    { name: 'postedAt', type: 'date' },
    { name: 'stats', type: 'group', fields: [
      { name: 'reactions', type: 'number', defaultValue: 0 },
      { name: 'comments', type: 'number', defaultValue: 0 },
      { name: 'shares', type: 'number', defaultValue: 0 },
      { name: 'reach', type: 'number', defaultValue: 0 },
    ]},
  ],
}
```

#### 4. FacebookSyncService
```typescript
// src/lib/integrations/meta/FacebookSyncService.ts

export class FacebookSyncService {
  constructor(payload: Payload)

  async syncAccount(account: SocialAccount): Promise<SyncResult>

  private async syncPosts(client: FacebookClient, account: SocialAccount): Promise<number>
  private async syncComments(client: FacebookClient, post: FacebookContent): Promise<number>
  private async syncMessages(client: FacebookClient, account: SocialAccount): Promise<number>
  private async processComment(comment: MetaComment, account: SocialAccount, content: FacebookContent): Promise<'new' | 'updated' | 'skipped'>
  private async processMessage(message: FacebookMessage, account: SocialAccount, conversation: FacebookConversation): Promise<'new' | 'updated' | 'skipped'>
}
```

#### 5. UI Updates

**CommunityInbox.tsx Erweiterungen:**
- Facebook-Icon und Badge
- "Hide Comment" / "Unhide Comment" Actions
- "Like Comment" Action
- Messenger-Konversationen in separatem Tab
- Facebook-spezifische Filter (Posts, Messenger)

**Platform-Icon Mapping:**
```typescript
const platformIcons = {
  youtube: <YouTubeIcon />,
  facebook: <FacebookIcon />,
  instagram: <InstagramIcon />,
  tiktok: <TikTokIcon />,
}
```

### Acceptance Criteria
- [ ] Posts werden synchronisiert (letzte 30 Tage)
- [ ] Kommentare werden importiert und analysiert
- [ ] Antworten werden über API gepostet
- [ ] Hide/Unhide funktioniert
- [ ] Messenger-Nachrichten werden synchronisiert
- [ ] Messenger-Antworten funktionieren
- [ ] Analytics zeigt Facebook-Daten
- [ ] Rate Limiting wird beachtet (200 calls/hour)

---

## Phase 2.3c: Instagram Integration

**Dauer:** 2 Tage
**Abhängigkeiten:** Phase 2.3a abgeschlossen (Phase 2.3b parallel möglich)

### Ziel
Instagram-Kommentare und DMs synchronisieren, analysieren und beantworten.

### Deliverables

#### 1. InstagramClient
```typescript
// src/lib/integrations/meta/InstagramClient.ts

import { MetaBaseClient } from './MetaBaseClient'

export class InstagramClient extends MetaBaseClient {
  private igAccountId: string

  constructor(accessToken: string, igAccountId: string)

  // Media
  async getMedia(limit?: number, since?: Date): Promise<InstagramMedia[]>
  async getMediaComments(mediaId: string): Promise<MetaComment[]>

  // Comments
  async replyToComment(commentId: string, message: string): Promise<string>
  async hideComment(commentId: string): Promise<void>
  async deleteComment(commentId: string): Promise<void>

  // Mentions & Tags
  async getMentions(): Promise<InstagramMention[]>
  async getTaggedMedia(): Promise<InstagramMedia[]>

  // Stories (Mentions)
  async getStoryMentions(): Promise<InstagramStoryMention[]>

  // DMs (wenn Scope verfügbar)
  async getConversations(): Promise<InstagramConversation[]>
  async sendMessage(conversationId: string, message: string): Promise<string>

  // Account Info
  async getAccountInsights(metrics: string[], period: string): Promise<AccountInsight[]>
}
```

#### 2. Instagram Types
```typescript
// src/types/instagram.ts

export interface InstagramMedia {
  id: string
  media_type: 'IMAGE' | 'VIDEO' | 'CAROUSEL_ALBUM' | 'REELS'
  media_url?: string
  thumbnail_url?: string
  permalink: string
  caption?: string
  timestamp: string
  like_count: number
  comments_count: number
}

export interface InstagramMention {
  id: string
  caption?: string
  media_type: string
  permalink: string
  timestamp: string
  username: string  // Who mentioned us
}

export interface InstagramStoryMention {
  id: string
  media_type: string
  media_url: string
  timestamp: string
  // Story mentions expire after 24h!
}

export interface InstagramConversation {
  id: string
  participants: Array<{ id: string; username: string }>
  updated_time: string
}
```

#### 3. InstagramContent Collection
```typescript
// src/collections/InstagramContent.ts

{
  slug: 'instagram-content',
  admin: {
    useAsTitle: 'caption',
    group: 'Social Media',
    defaultColumns: ['caption', 'socialAccount', 'mediaType', 'postedAt'],
  },
  fields: [
    { name: 'externalId', type: 'text', required: true, unique: true },
    { name: 'socialAccount', type: 'relationship', relationTo: 'social-accounts', required: true },
    { name: 'mediaType', type: 'select', options: ['image', 'video', 'carousel', 'reel', 'story'] },
    { name: 'caption', type: 'textarea' },
    { name: 'permalink', type: 'text' },
    { name: 'mediaUrl', type: 'text' },
    { name: 'thumbnailUrl', type: 'text' },
    { name: 'postedAt', type: 'date' },
    { name: 'stats', type: 'group', fields: [
      { name: 'likes', type: 'number', defaultValue: 0 },
      { name: 'comments', type: 'number', defaultValue: 0 },
      { name: 'saves', type: 'number', defaultValue: 0 },
      { name: 'reach', type: 'number', defaultValue: 0 },
      { name: 'impressions', type: 'number', defaultValue: 0 },
    ]},
  ],
}
```

#### 4. InstagramSyncService
```typescript
// src/lib/integrations/meta/InstagramSyncService.ts

export class InstagramSyncService {
  constructor(payload: Payload)

  async syncAccount(account: SocialAccount): Promise<SyncResult>

  private async syncMedia(client: InstagramClient, account: SocialAccount): Promise<number>
  private async syncComments(client: InstagramClient, media: InstagramContent): Promise<number>
  private async syncMentions(client: InstagramClient, account: SocialAccount): Promise<number>
  private async syncStoryMentions(client: InstagramClient, account: SocialAccount): Promise<number>
}
```

### Wichtige Hinweise

1. **Story Mentions:** Verfallen nach 24h → Sync alle 6 Stunden oder Webhooks
2. **Token Refresh:** Alle 60 Tage → Automatischen Refresh implementieren
3. **DM Scope:** `instagram_manage_messages` erfordert App-Review

### Acceptance Criteria
- [ ] Media wird synchronisiert (letzte 30 Tage)
- [ ] Kommentare werden importiert und analysiert
- [ ] Antworten werden über API gepostet
- [ ] Mentions werden erkannt und importiert
- [ ] Story-Mentions werden erfasst (falls verfügbar)
- [ ] Hide Comment funktioniert
- [ ] Analytics Dashboard integriert

---

## Phase 2.4: TikTok Integration

**Dauer:** 2-3 Tage
**Abhängigkeiten:** Keine (parallel zu Meta möglich, aber API-Approval erforderlich)

### Ziel
TikTok-Kommentare synchronisieren und beantworten.

### Voraussetzungen
- TikTok Business Account
- TikTok for Developers Zugang
- **App-Genehmigung für Comment API** (WICHTIG: Frühzeitig beantragen!)

### Deliverables

#### 1. TikTok OAuth
```typescript
// src/lib/integrations/tiktok/oauth.ts

const TIKTOK_OAUTH_CONFIG = {
  authorizationUrl: 'https://www.tiktok.com/v2/auth/authorize/',
  tokenUrl: 'https://open.tiktokapis.com/v2/oauth/token/',
  scopes: [
    'user.info.basic',
    'video.list',
    'comment.list',
    'comment.list.manage',
  ],
}

export async function getAuthUrl(state: string): Promise<string>
export async function exchangeCodeForTokens(code: string): Promise<TikTokTokens>
export async function refreshAccessToken(refreshToken: string): Promise<TikTokTokens>
```

#### 2. TikTokClient
```typescript
// src/lib/integrations/tiktok/TikTokClient.ts

export class TikTokClient {
  private accessToken: string
  private openId: string

  constructor(accessToken: string, openId: string)

  // Videos
  async getVideos(cursor?: number, maxCount?: number): Promise<{
    videos: TikTokVideo[]
    cursor: number
    hasMore: boolean
  }>

  // Comments
  async getVideoComments(videoId: string, cursor?: number): Promise<{
    comments: TikTokComment[]
    cursor: number
    hasMore: boolean
  }>

  async replyToComment(videoId: string, commentId: string, text: string): Promise<string>

  // User Info
  async getUserInfo(): Promise<TikTokUser>
}
```

#### 3. TikTok Types
```typescript
// src/types/tiktok.ts

export interface TikTokVideo {
  id: string
  title: string
  description: string
  create_time: number  // Unix timestamp
  cover_image_url: string
  share_url: string
  duration: number
  like_count: number
  comment_count: number
  share_count: number
  view_count: number
}

export interface TikTokComment {
  id: string
  text: string
  create_time: number
  like_count: number
  reply_count: number
  user: {
    open_id: string
    display_name: string
    avatar_url: string
  }
  parent_comment_id?: string  // Für Replies
}

export interface TikTokTokens {
  access_token: string
  refresh_token: string
  expires_in: number
  open_id: string
  scope: string
}
```

#### 4. TikTokContent Collection
```typescript
// src/collections/TikTokContent.ts

{
  slug: 'tiktok-content',
  admin: {
    useAsTitle: 'title',
    group: 'Social Media',
  },
  fields: [
    { name: 'externalId', type: 'text', required: true, unique: true },
    { name: 'socialAccount', type: 'relationship', relationTo: 'social-accounts', required: true },
    { 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', defaultValue: 0 },
      { name: 'likes', type: 'number', defaultValue: 0 },
      { name: 'comments', type: 'number', defaultValue: 0 },
      { name: 'shares', type: 'number', defaultValue: 0 },
    ]},
  ],
}
```

### Wichtige Hinweise

1. **API-Zugang:** Comment API erfordert App-Review (1-4 Wochen)
2. **Sandbox Mode:** Erst in Sandbox testen
3. **Cursor-based Pagination:** Kein Offset-Support
4. **Kein DM-Zugang:** TikTok API erlaubt keine DMs
5. **Rate Limits:** 100 Requests/Minute

### Acceptance Criteria
- [ ] OAuth-Flow funktioniert
- [ ] Videos werden synchronisiert
- [ ] Kommentare werden importiert und analysiert
- [ ] Antworten können gepostet werden
- [ ] Analytics integriert

---

## Phase 2.5a: Auto-Reply Service

**Dauer:** 2-3 Tage
**Abhängigkeiten:** Mindestens eine Social Platform integriert (YouTube reicht)

### Ziel
Backend-Logik für vollautomatische Antworten basierend auf konfigurierbaren Regeln.

### Architektur

```
┌─────────────────────────────────────────────────────────────────┐
│                     AUTO-REPLY FLOW                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  New Comment ──▶ Claude Analysis ──▶ Safety Check               │
│                                           │                     │
│                              ┌────────────┴────────────┐        │
│                              ▼                         ▼        │
│                      [SAFE TO AUTO-REPLY]     [MANUAL QUEUE]    │
│                              │                                  │
│                              ▼                                  │
│                      Rule Matching (Priority-sorted)            │
│                              │                                  │
│                      ┌───────┴───────┐                          │
│                      ▼               ▼                          │
│               [RULE MATCH]    [NO MATCH]                        │
│                      │               │                          │
│                      ▼               ▼                          │
│               Generate Reply   Manual Queue                     │
│                      │                                          │
│                      ▼                                          │
│               Rate Limit Check                                  │
│                      │                                          │
│               ┌──────┴──────┐                                   │
│               ▼             ▼                                   │
│          [ALLOWED]     [LIMITED]                                │
│               │             │                                   │
│               ▼             ▼                                   │
│          Post Reply    Queue for Later                          │
│               │                                                 │
│               ▼                                                 │
│          Log & Update Stats                                     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

### Deliverables

#### 1. AutoReplyRules Collection
```typescript
// src/collections/AutoReplyRules.ts

{
  slug: 'auto-reply-rules',
  admin: {
    useAsTitle: 'name',
    group: 'Community',
    defaultColumns: ['name', 'enabled', 'priority', 'stats.totalFired'],
  },
  fields: [
    // Basis
    { name: 'name', type: 'text', required: true },
    { name: 'description', type: 'textarea' },
    { name: 'enabled', type: 'checkbox', defaultValue: false },  // Default: AUS
    { name: 'priority', type: 'number', defaultValue: 100 },  // Niedriger = höher

    // Scope
    {
      name: 'scope',
      type: 'group',
      fields: [
        { name: 'platforms', type: 'relationship', relationTo: 'social-platforms', hasMany: true },
        { name: 'accounts', type: 'relationship', relationTo: 'social-accounts', hasMany: true },
        { name: 'channelTypes', type: 'select', hasMany: true, options: ['corporate', 'lifestyle', 'business'] },
      ]
    },

    // Conditions (Wann feuert die Regel?)
    {
      name: 'conditions',
      type: 'group',
      fields: [
        { name: 'sentiments', type: 'select', hasMany: true, options: [
          { label: 'Positiv', value: 'positive' },
          { label: 'Dankbarkeit', value: 'gratitude' },
          { label: 'Neutral', value: 'neutral' },
          { label: 'Frage', value: 'question' },
        ]},
        { name: 'minConfidence', type: 'number', defaultValue: 80, min: 0, max: 100 },
        { name: 'keywordsInclude', type: 'array', fields: [{ name: 'keyword', type: 'text' }] },
        { name: 'keywordsExclude', type: 'array', fields: [{ name: 'keyword', type: 'text' }] },
        { name: 'topicsInclude', type: 'array', fields: [{ name: 'topic', type: 'text' }] },
        { name: 'topicsExclude', type: 'array', fields: [{ name: 'topic', type: 'text' }] },
        { name: 'maxMessageLength', type: 'number', defaultValue: 300 },
      ]
    },

    // Sicherheits-Ausschlüsse (NIEMALS überschreiben!)
    {
      name: 'safetyExclusions',
      type: 'group',
      admin: { description: '⚠️ Diese Ausschlüsse können nicht deaktiviert werden!' },
      fields: [
        { name: 'excludeMedicalQuestions', type: 'checkbox', defaultValue: true, admin: { readOnly: true } },
        { name: 'excludeEscalations', type: 'checkbox', defaultValue: true, admin: { readOnly: true } },
        { name: 'excludeNegativeSentiment', type: 'checkbox', defaultValue: true },
        { name: 'excludeFrustration', type: 'checkbox', defaultValue: true },
        { name: 'excludeVerifiedAccounts', type: 'checkbox', defaultValue: true },
        { name: 'excludeInfluencers', type: 'checkbox', defaultValue: true },
        { name: 'influencerThreshold', type: 'number', defaultValue: 10000 },
      ]
    },

    // Action
    {
      name: 'action',
      type: 'group',
      fields: [
        { name: 'type', type: 'select', required: true, 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',
          admin: { condition: (data) => data?.action?.type === 'template' || data?.action?.type === 'template_ai' }
        },
        { name: 'aiTone', type: 'select', options: ['freundlich', 'professionell', 'empathisch'],
          admin: { condition: (data) => data?.action?.type === 'ai_generate' || data?.action?.type === 'template_ai' }
        },
        { name: 'delayMinutes', type: 'number', defaultValue: 2, min: 0, max: 60 },
        { name: 'addSignature', type: 'checkbox', defaultValue: true },
      ]
    },

    // Rate Limits
    {
      name: 'limits',
      type: 'group',
      fields: [
        { name: 'maxPerHour', type: 'number', defaultValue: 10 },
        { name: 'maxPerDay', type: 'number', defaultValue: 50 },
        { name: 'cooldownPerAuthor', type: 'number', defaultValue: 60, admin: { description: 'Minuten bis gleicher Autor wieder Auto-Reply bekommt' } },
      ]
    },

    // Stats
    {
      name: 'stats',
      type: 'group',
      admin: { readOnly: true },
      fields: [
        { name: 'totalFired', type: 'number', defaultValue: 0 },
        { name: 'successCount', type: 'number', defaultValue: 0 },
        { name: 'failCount', type: 'number', defaultValue: 0 },
        { name: 'lastFiredAt', type: 'date' },
      ]
    },
  ],
}
```

#### 2. AutoReplyLogs Collection
```typescript
// src/collections/AutoReplyLogs.ts

{
  slug: 'auto-reply-logs',
  admin: {
    group: 'Community',
    defaultColumns: ['interaction', 'rule', 'success', 'createdAt'],
  },
  fields: [
    { name: 'interaction', type: 'relationship', relationTo: 'community-interactions', required: true },
    { name: 'rule', type: 'relationship', relationTo: 'auto-reply-rules', required: true },
    { name: 'decision', type: 'group', fields: [
      { name: 'shouldAutoReply', type: 'checkbox' },
      { name: 'reason', type: 'text' },
      { name: 'blockedBy', type: 'text' },  // z.B. "safety:medical", "limit:hourly"
    ]},
    { name: 'generatedReply', type: 'textarea' },
    { name: 'postedReply', type: 'textarea' },  // Falls abweichend (z.B. gekürzt)
    { name: 'externalReplyId', type: 'text' },
    { name: 'success', type: 'checkbox' },
    { name: 'error', type: 'text' },
    { name: 'processingTime', type: 'number' },  // ms
    { name: 'postedAt', type: 'date' },
  ],
}
```

#### 3. AutoReplyService
```typescript
// src/lib/services/AutoReplyService.ts

interface AutoReplyDecision {
  shouldAutoReply: boolean
  rule?: AutoReplyRule
  reason: string
  blockedBy?: string
}

interface AutoReplyResult {
  success: boolean
  replyId?: string
  error?: string
  processingTime: number
}

export class AutoReplyService {
  private payload: Payload
  private claudeReply: ClaudeReplyService

  constructor(payload: Payload)

  /**
   * Haupteinsprungspunkt: Prüft und führt Auto-Reply aus
   */
  async processInteraction(interaction: CommunityInteraction): Promise<AutoReplyResult | null>

  /**
   * Schritt 1: Safety-Check (NIEMALS umgehen!)
   */
  private async checkSafety(interaction: CommunityInteraction): Promise<{
    safe: boolean
    reason?: string
  }>

  /**
   * Schritt 2: Finde passende Regel
   */
  private async findMatchingRule(interaction: CommunityInteraction): Promise<AutoReplyRule | null>

  /**
   * Schritt 3: Prüfe Rate Limits
   */
  private async checkRateLimits(rule: AutoReplyRule, authorId: string): Promise<{
    allowed: boolean
    reason?: string
  }>

  /**
   * Schritt 4: Generiere Reply
   */
  private async generateReply(interaction: CommunityInteraction, rule: AutoReplyRule): Promise<string>

  /**
   * Schritt 5: Poste Reply
   */
  private async postReply(interaction: CommunityInteraction, replyText: string): Promise<string>

  /**
   * Schritt 6: Logging
   */
  private async logResult(
    interaction: CommunityInteraction,
    rule: AutoReplyRule,
    decision: AutoReplyDecision,
    result: AutoReplyResult
  ): Promise<void>
}
```

#### 4. Safety Rules (KRITISCH - Nicht änderbar!)
```typescript
// src/lib/services/AutoReplyService.ts - Safety Check Implementation

private async checkSafety(interaction: CommunityInteraction): Promise<SafetyResult> {
  const flags = interaction.flags
  const analysis = interaction.analysis

  // ABSOLUTE BLOCKS - NIEMALS Auto-Reply
  if (flags?.isMedicalQuestion) {
    return { safe: false, reason: 'Medizinische Frage erkannt' }
  }

  if (flags?.requiresEscalation) {
    return { safe: false, reason: 'Eskalation erforderlich' }
  }

  if (interaction.status !== 'new') {
    return { safe: false, reason: 'Bereits bearbeitet' }
  }

  if (interaction.response?.sentAt) {
    return { safe: false, reason: 'Bereits beantwortet' }
  }

  // CONFIGURABLE BLOCKS (können in Rule überschrieben werden)
  // ... sentiment, influencer, verified, etc.

  return { safe: true }
}
```

#### 5. Integration in Sync-Flow
```typescript
// Erweitere alle CommentsSyncServices

async processComment(comment: RawComment): Promise<void> {
  // 1. In DB speichern
  const interaction = await this.saveInteraction(comment)

  // 2. Claude-Analyse
  const analysis = await this.claudeAnalysis.analyzeComment(interaction.message)
  await this.updateAnalysis(interaction.id, analysis)

  // 3. Rules Engine (bestehend)
  await this.rulesEngine.evaluate(interaction)

  // 4. Auto-Reply Check (NEU)
  if (this.autoReplyEnabled) {
    const autoReplyService = new AutoReplyService(this.payload)
    await autoReplyService.processInteraction(interaction)
  }
}
```

### Acceptance Criteria
- [ ] Safety-Check blockiert medizinische Fragen IMMER
- [ ] Safety-Check blockiert Eskalationen IMMER
- [ ] Rules werden nach Priorität sortiert ausgewertet
- [ ] Rate Limits funktionieren (per Stunde/Tag/Autor)
- [ ] Logs werden vollständig geschrieben
- [ ] Stats werden aktualisiert
- [ ] Delay vor Antwort funktioniert

---

## Phase 2.5b: Auto-Reply UI & Testing

**Dauer:** 2 Tage
**Abhängigkeiten:** Phase 2.5a abgeschlossen

### Ziel
Admin-UI für Auto-Reply Konfiguration und Testing.

### Deliverables

#### 1. Auto-Reply Manager View
```
src/app/(payload)/admin/views/community/auto-reply/
├── page.tsx
├── AutoReplyManager.tsx
├── components/
│   ├── RulesList.tsx
│   ├── RuleEditor.tsx
│   ├── RuleTester.tsx
│   ├── RuleStats.tsx
│   └── RecentLogs.tsx
└── auto-reply.scss
```

#### 2. UI Features

**Rules List:**
- Alle Regeln mit Enable/Disable Toggle
- Sortiert nach Priorität
- Quick Stats (Fired Count, Success Rate)
- Drag & Drop für Prioritäts-Änderung

**Rule Editor:**
- Vollständiger Regel-Editor
- Condition Builder mit Preview
- Action-Konfiguration
- Limit-Einstellungen

**Rule Tester:**
```typescript
// Test-Input
interface TestInput {
  message: string
  sentiment?: string
  platform?: string
  authorFollowers?: number
}

// Test-Output
interface TestOutput {
  wouldAutoReply: boolean
  matchedRule?: string
  reason: string
  generatedReply?: string
  warnings: string[]
}
```

**Recent Logs:**
- Letzte 100 Auto-Reply Entscheidungen
- Filter: Success/Failed, Rule, Platform
- Details mit Interaction-Link

#### 3. Analytics Integration

**Neue Metriken für Dashboard:**
```typescript
// /api/community/analytics/auto-reply/route.ts

interface AutoReplyStats {
  totalProcessed: number
  autoReplied: number
  autoReplyRate: number
  blockedByMedical: number
  blockedByEscalation: number
  blockedByRateLimit: number
  topRules: Array<{
    rule: string
    fired: number
    successRate: number
  }>
  avgProcessingTime: number
}
```

### Acceptance Criteria
- [ ] Rules können erstellt/bearbeitet werden
- [ ] Enable/Disable funktioniert
- [ ] Tester zeigt korrekte Entscheidungen
- [ ] Logs werden angezeigt
- [ ] Analytics zeigen Auto-Reply Metriken

---

## Phase 3.0a: Scheduled Reports

**Dauer:** 2-3 Tage
**Abhängigkeiten:** E-Mail-Service (existiert bereits)

### Ziel
Automatische Community-Reports per E-Mail.

### Deliverables

#### 1. ReportSchedules Collection
```typescript
// src/collections/ReportSchedules.ts

{
  slug: 'report-schedules',
  admin: {
    useAsTitle: 'name',
    group: 'Community',
  },
  fields: [
    { name: 'name', type: 'text', required: true },
    { name: 'enabled', type: 'checkbox', defaultValue: true },

    // Schedule
    { name: 'frequency', type: 'select', required: true, options: [
      { label: 'Täglich', value: 'daily' },
      { label: 'Wöchentlich', value: 'weekly' },
      { label: 'Monatlich', value: 'monthly' },
    ]},
    { name: 'dayOfWeek', type: 'select', options: [
      { label: 'Montag', value: 'monday' },
      // ... andere Tage
    ], admin: { condition: (data) => data?.frequency === 'weekly' }},
    { name: 'dayOfMonth', type: 'number', min: 1, max: 28,
      admin: { condition: (data) => data?.frequency === 'monthly' }},
    { name: 'time', type: 'text', defaultValue: '08:00', admin: { description: 'Format: HH:MM' }},
    { name: 'timezone', type: 'text', defaultValue: 'Europe/Berlin' },

    // Recipients
    { name: 'recipients', type: 'array', fields: [
      { name: 'email', type: 'email', required: true },
      { name: 'name', type: 'text' },
    ]},

    // Report Configuration
    { name: 'reportType', type: 'select', required: true, options: [
      { label: 'Übersicht', value: 'overview' },
      { label: 'Sentiment-Analyse', value: 'sentiment' },
      { label: 'Team-Performance', value: 'response_metrics' },
      { label: 'Content-Performance', value: 'content' },
      { label: 'Vollständiger Report', value: 'full' },
    ]},
    { name: 'channels', type: 'relationship', relationTo: 'social-accounts', hasMany: true },
    { name: 'format', type: 'select', options: ['pdf', 'excel', 'html_email'], defaultValue: 'pdf' },

    // Stats
    { name: 'lastSentAt', type: 'date' },
    { name: 'nextScheduledAt', type: 'date' },
    { name: 'sendCount', type: 'number', defaultValue: 0 },
  ],
}
```

#### 2. ReportGeneratorService
```typescript
// src/lib/services/ReportGeneratorService.ts

export class ReportGeneratorService {
  async generateReport(schedule: ReportSchedule): Promise<{
    content: Buffer
    filename: string
    mimeType: string
  }>

  async sendReport(schedule: ReportSchedule): Promise<void>

  private async generatePdfReport(data: ReportData): Promise<Buffer>
  private async generateExcelReport(data: ReportData): Promise<Buffer>
  private async generateHtmlEmail(data: ReportData): Promise<string>

  private async collectReportData(schedule: ReportSchedule): Promise<ReportData>
}
```

#### 3. Cron Job
```typescript
// src/app/(payload)/api/cron/send-reports/route.ts

export async function GET(request: NextRequest) {
  // Auth check...

  const now = new Date()
  const dueReports = await findDueReports(now)

  for (const schedule of dueReports) {
    try {
      const generator = new ReportGeneratorService()
      await generator.sendReport(schedule)

      // Update nextScheduledAt
      await updateNextSchedule(schedule)
    } catch (error) {
      console.error(`Report ${schedule.id} failed:`, error)
    }
  }

  return Response.json({ success: true, sent: dueReports.length })
}
```

#### 4. vercel.json Update
```json
{
  "crons": [
    {
      "path": "/api/cron/youtube-sync",
      "schedule": "*/15 * * * *"
    },
    {
      "path": "/api/cron/send-reports",
      "schedule": "0 * * * *"
    }
  ]
}
```

### Acceptance Criteria
- [ ] Reports werden generiert (PDF/Excel/HTML)
- [ ] E-Mail-Versand funktioniert
- [ ] Scheduling funktioniert (daily/weekly/monthly)
- [ ] Timezone-Support
- [ ] Error Handling bei fehlgeschlagenem Versand

---

## Phase 3.0b: Real-time Updates

**Dauer:** 2-3 Tage
**Abhängigkeiten:** Keine

### Ziel
Live-Updates im Dashboard ohne manuellen Refresh.

### Deliverables

#### 1. Server-Sent Events Endpoint
```typescript
// src/app/(payload)/api/community/stream/route.ts

export async function GET(request: NextRequest) {
  // Auth check...

  const encoder = new TextEncoder()

  const stream = new ReadableStream({
    async start(controller) {
      let lastCheck = new Date()

      const sendUpdate = async () => {
        try {
          const updates = await getUpdatesSince(lastCheck)
          lastCheck = new Date()

          if (updates.length > 0) {
            controller.enqueue(
              encoder.encode(`data: ${JSON.stringify(updates)}\n\n`)
            )
          }
        } catch (error) {
          console.error('Stream error:', error)
        }
      }

      // Initial send
      await sendUpdate()

      // Poll every 5 seconds
      const interval = setInterval(sendUpdate, 5000)

      // Cleanup on close
      request.signal.addEventListener('abort', () => {
        clearInterval(interval)
        controller.close()
      })
    }
  })

  return new Response(stream, {
    headers: {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
    }
  })
}
```

#### 2. React Hook
```typescript
// src/hooks/useRealtimeUpdates.ts

interface Update {
  type: 'new_interaction' | 'status_change' | 'new_reply'
  data: any
  timestamp: string
}

export function useRealtimeUpdates() {
  const [updates, setUpdates] = useState<Update[]>([])
  const [connected, setConnected] = useState(false)

  useEffect(() => {
    const eventSource = new EventSource('/api/community/stream')

    eventSource.onopen = () => setConnected(true)
    eventSource.onerror = () => setConnected(false)

    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data)
      setUpdates(prev => [...data, ...prev].slice(0, 100))
    }

    return () => {
      eventSource.close()
      setConnected(false)
    }
  }, [])

  return { updates, connected }
}
```

#### 3. UI Integration

**Dashboard Updates:**
- Live-Counter Badge bei neuen Items
- Toast-Notifications bei wichtigen Events
- Auto-Refresh der Liste bei neuen Items
- Pulsierender Indicator wenn verbunden

### Acceptance Criteria
- [ ] SSE-Verbindung funktioniert
- [ ] Updates werden in Echtzeit angezeigt
- [ ] Toast-Notifications bei neuen Kommentaren
- [ ] Reconnect bei Verbindungsabbruch
- [ ] Kein Performance-Impact bei vielen Clients

---

## Zusammenfassung der Phasen

| Phase | Name | Dauer | Abhängigkeiten | Priorität |
|-------|------|-------|----------------|-----------|
| 2.3a | Meta OAuth | 1-2 Tage | Meta App Setup | Hoch |
| 2.3b | Facebook Integration | 2-3 Tage | 2.3a | Hoch |
| 2.3c | Instagram Integration | 2 Tage | 2.3a | Hoch |
| 2.4 | TikTok Integration | 2-3 Tage | API Approval | Mittel |
| 2.5a | Auto-Reply Service | 2-3 Tage | Keine | Mittel |
| 2.5b | Auto-Reply UI | 2 Tage | 2.5a | Mittel |
| 3.0a | Scheduled Reports | 2-3 Tage | Keine | Niedrig |
| 3.0b | Real-time Updates | 2-3 Tage | Keine | Niedrig |

**Gesamtdauer:** ~16-21 Tage

---

## Empfohlene Reihenfolge

```
Woche 1:  2.3a (Meta OAuth) → 2.3b (Facebook) + 2.3c (Instagram parallel)
Woche 2:  2.5a (Auto-Reply Service) → 2.5b (Auto-Reply UI)
Woche 3:  2.4 (TikTok, falls API approved) + 3.0a (Reports)
Woche 4:  3.0b (Real-time) + Testing & Polish
```

---

*Erstellt: 16. Januar 2026*
*Basierend auf: Community Management Roadmap Prompt (Konzept-KI)*
*Erweitert um: Facebook-Integration, Logische Aufteilung*
*Für: Dev-KI (Claude Code)*
