# Frontend Migration Guide - API Umstrukturierung

**Datum:** 16. November 2025  
**Betrifft:** ALLE API-Aufrufe im Frontend  
**Status:** ⚠️ Aktion erforderlich - ALLE Routen prüfen!

---

## � BREAKING CHANGE: Konsistente `/api` Prefixes

**ALLE API-Routen haben sich geändert!**

### Vorher (inkonsistent):
```javascript
// Teils mit /api
fetch('/api/upload/batch')
fetch('/api/manage/xyz')

// Teils OHNE /api - FALSCH!
fetch('/groups/123')
fetch('/groups/123/approve')
fetch('/moderation/groups/123')
```

### Jetzt (konsistent):
```javascript
// ALLE Routen mit /api Prefix
fetch('/api/upload/batch')
fetch('/api/manage/xyz')
fetch('/api/groups/123')              // Public
fetch('/api/admin/groups/123/approve') // Admin
fetch('/api/admin/groups/123')        // Admin
```

---

## 🔒 Admin API Authentication

Alle Admin-Endpoints (`/api/admin/*` und `/api/system/*`) benötigen jetzt **Bearer Token Authentication**.

### Route-Hierarchie

1. **Public API**: `/api/*` 
   - Öffentlich zugänglich
   - `/api/upload`, `/api/groups`, `/api/download`, etc.

2. **Management API**: `/api/manage/*`
   - Token-basiert (UUID aus Upload-Response)
   - Für Gruppenbesitzer

3. **Admin API**: `/api/admin/*` ⚠️ **BEARER TOKEN ERFORDERLICH**
   - Moderation, Logs, Consents
   - `/api/admin/groups`, `/api/admin/deletion-log`, etc.

4. **System API**: `/api/system/migration/*` ⚠️ **BEARER TOKEN ERFORDERLICH**
   - Wartungsfunktionen

### Betroffene Admin-Endpoints

- `/api/admin/groups` - Gruppen auflisten
- `/api/admin/groups/:id` - Gruppe abrufen
- `/api/admin/groups/:id/approve` - Gruppe genehmigen
- `/api/admin/groups/:id` - Gruppe löschen
- `/api/admin/groups/:id/images/:imageId` - Bild löschen
- `/api/admin/groups/by-consent` - Nach Consent filtern
- `/api/admin/consents/export` - Consent-Export
- `/api/admin/social-media/platforms` - Plattformen auflisten
- `/api/admin/reorder/:groupId/images` - Bilder neu anordnen
- `/api/admin/deletion-log` - Deletion Log
- `/api/admin/cleanup/*` - Cleanup-Funktionen
- `/api/admin/rate-limiter/stats` - Rate-Limiter-Statistiken
- `/api/admin/management-audit` - Audit-Log

**System-Endpoints:**
- `/api/system/migration/migrate` - Migration ausführen
- `/api/system/migration/rollback` - Migration zurückrollen

---

## 📝 Erforderliche Änderungen

### 1. ALLE API-Routen prüfen und `/api` hinzufügen

**Schritt 1**: Finde alle API-Aufrufe im Frontend:

```bash
# Alle fetch/axios Aufrufe finden
grep -r "fetch\(" frontend/src/
grep -r "axios\." frontend/src/
```

**Schritt 2**: Prüfe jede Route und füge `/api` Prefix hinzu (falls fehlend):

```javascript
// ❌ FALSCH (alte Routen)
fetch('/groups/123')
fetch('/groups/123/approve')
fetch('/moderation/groups/123')

// ✅ RICHTIG (neue Routen)
fetch('/api/groups/123')                    // Public
fetch('/api/admin/groups/123/approve')      // Admin (+ Bearer Token!)
fetch('/api/admin/groups/123')              // Admin (+ Bearer Token!)
```

### 2. Admin-Session & CSRF einrichten

Die Admin-API verwendet jetzt serverseitige Sessions mit CSRF-Schutz. Statt Tokens in `.env` zu hinterlegen, erfolgt die Authentifizierung über Login-Endpunkte:

1. **Setup-Status abfragen** – `GET /auth/setup/status` → `{ needsSetup, hasSession }`
2. **Ersten Admin anlegen** – `POST /auth/setup/initial-admin` (nur einmal nötig)
3. **Login** – `POST /auth/login` mit `{ username, password }`
4. **CSRF Token holen** – `GET /auth/csrf-token` (liefert `csrfToken` und setzt HttpOnly Session-Cookie)

Alle nachfolgenden Admin-Requests senden automatisch das Session-Cookie (`credentials: 'include'`) und den `X-CSRF-Token` Header.

### 3. API-Aufrufe für Admin-Endpoints anpassen

#### Vorher (ohne Session):
```javascript
const response = await fetch('/api/admin/groups');
```

#### Nachher (mit Session + CSRF):
```javascript
const response = await fetch('/api/admin/groups', {
  method: 'GET',
  credentials: 'include',
  headers: {
    'X-CSRF-Token': csrfToken, // nur bei mutierenden Requests zwingend nötig
  }
});
```

### 3. Zentrale API-Helper-Funktion erstellen

**Empfohlen**: Nutze `src/services/adminApi.js` als einzige Stelle, die Session- und CSRF-Handling kapselt:

```javascript
const SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
let csrfToken = null;

const ensureCsrfToken = async () => {
  if (!csrfToken) {
    const response = await fetch('/auth/csrf-token', { credentials: 'include' });
    const data = await response.json();
    csrfToken = data.csrfToken;
  }
  return csrfToken;
};

export const adminFetch = async (url, options = {}) => {
  const method = (options.method || 'GET').toUpperCase();
  const headers = new Headers(options.headers || {});

  if (!SAFE_METHODS.has(method)) {
    headers.set('X-CSRF-Token', await ensureCsrfToken());
  }

  const response = await fetch(url, {
    ...options,
    method,
    credentials: 'include',
    headers
  });

  if (!response.ok) {
    throw await parseError(response);
  }

  return response;
};
```

### 4. Error Handling erweitern

```javascript
try {
  const response = await adminFetch('/api/admin/groups');
  const data = await response.json();
  // ...
} catch (error) {
  if (error.status === 401) {
    // Session abgelaufen
    redirectToLogin();
  } else if (error.status === 403 && error.reason === 'CSRF_INVALID') {
    // CSRF neu anfordern
    await adminSession.refreshStatus();
  } else if (error.status === 429) {
    notifyRateLimit();
  } else {
    console.error('Admin API error:', error);
  }
}
```

---

## 🔍 Betroffene Dateien finden

### Alle API-Calls prüfen (KRITISCH!)

```bash
cd frontend/src

# ALLE API-Calls finden (fetch + axios):
grep -rn "fetch(" --include="*.js" --include="*.jsx"
grep -rn "axios\." --include="*.js" --include="*.jsx"

# Spezifisch nach alten Routen OHNE /api suchen:
grep -rn "fetch('/groups" --include="*.js"
grep -rn "fetch('/moderation" --include="*.js"

# Admin-API-Calls finden:
grep -rn "/api/admin" --include="*.js" --include="*.jsx"
```

**Bekannte betroffene Dateien:**

### Routen ohne `/api` Prefix (MÜSSEN GEFIXT WERDEN):
- `Components/Pages/ModerationGroupsPage.js`
  - ❌ `/groups/${groupId}/approve` → ✅ `/api/admin/groups/${groupId}/approve`
  - ❌ `/groups/${groupId}` (DELETE) → ✅ `/api/admin/groups/${groupId}`
  - ✅ `/api/admin/social-media/platforms` für Moderationsfilter
  - ✅ `/api/social-media/platforms` für öffentliche Formulare (keine Session nötig)

- `Components/Pages/ModerationGroupImagesPage.js`
  - ❌ `/moderation/groups/${groupId}` → ✅ `/api/admin/groups/${groupId}`

- `Components/Pages/PublicGroupImagesPage.js`
  - ❌ `/groups/${groupId}` → ✅ `/api/groups/${groupId}`

### Admin-Endpoints (Session + CSRF erforderlich):
- `Components/Pages/ModerationGroupsPage.js` - Alle Moderations-Calls
- `Components/Pages/ModerationGroupImagesPage.js` - Gruppe laden + Bilder löschen
- `Components/ComponentUtils/DeletionLogSection.js` - Deletion Log
- `Components/ComponentUtils/ConsentManager.js` - Consent-Export (Admin)
- `services/reorderService.js` - Admin-Reorder (falls im Einsatz)

### Public/Management Endpoints (nur Pfad prüfen):
- `Utils/batchUpload.js` - Bereits korrekt (`/api/...`)
- `Components/Pages/ManagementPortalPage.js` - Bereits korrekt (`/api/manage/...`)
- `Utils/sendRequest.js` - Bereits korrekt (axios)

---

## ✅ Checkliste

### Phase 1: Route-Prefixes (ALLE Dateien)
- [ ] Alle `fetch()` und `axios` Calls gefunden (grep)
- [ ] Alle Routen ohne `/api` Prefix identifiziert
- [ ] `/api` Prefix zu Public-Routen hinzugefügt (`/api/groups`, `/api/upload`)
- [ ] Admin-Routen auf `/api/admin/*` geändert
- [ ] Management-Routen auf `/api/manage/*` geprüft (sollten schon korrekt sein)

### Phase 2: Admin Authentication (Session)
- [ ] `AdminSessionProvider` wrappt die App
- [ ] `AdminSessionGate` schützt alle Moderationsseiten
- [ ] `adminApi.js` nutzt `credentials: 'include'` + `X-CSRF-Token`
- [ ] Login- und Initial-Setup-Formulare eingebunden
- [ ] Fehlerbehandlung für `401/403 (SESSION_REQUIRED/CSRF_INVALID)` ergänzt

### Phase 3: Testing & Deployment
- [ ] Frontend lokal getestet (alle Routen)
- [ ] Admin-Funktionen getestet (Approve, Delete, etc.)
- [ ] Public-Routen getestet (Gruppe laden, Upload)
- [ ] Production `.env` aktualisiert

---

## 🧪 Testing

### Lokales Testing

1. Backend starten (`npm run dev`) – stellt Session- & Auth-Routen bereit.
2. Frontend starten (`npm start`).
3. `/moderation` öffnen:
  - **Falls kein Admin existiert** → Setup-Formular ausfüllen.
  - Danach mit frisch erstellten Credentials anmelden.
4. Moderationsfunktionen (Approve/Delete/Reorder/Consent-Export) durchspielen.

### Test-Fälle

- ✅ Moderation funktioniert mit aktiver Session
- ✅ Login/Logout ändert sofort den Zugriff auf Seiten
- ✅ CSRF-geschützte Aktionen schlagen fehl, wenn Token manipuliert wird
- ✅ Consent-Export & Reorder funktionieren weiterhin
- ✅ Öffentliche Routen bleiben ohne Login erreichbar

---

## 📚 Weitere Dokumentation

- **Backend Auth-Doku**: `AUTHENTICATION.md`
- **API Route-Übersicht**: `backend/src/routes/README.md`
- **Route-Konfiguration**: `backend/src/routes/routeMappings.js`
- **OpenAPI Spec**: `backend/docs/openapi.json`
- **Swagger UI**: http://localhost:5001/api/docs/ (dev only)

---

## 🆘 Troubleshooting

### Problem: "Session Required" / 403 Fehler

**Ursachen:**
1. Session abgelaufen (Inaktivität, Browser geschlossen)
2. Cookies blockiert (Third-Party/SameSite Einstellungen)

**Lösung:**
- Seite neu laden → Login-Formular erscheint
- Browser-Einstellungen prüfen: Cookies für Host erlauben

### Problem: "CSRF invalid"

**Ursachen:**
- CSRF-Token nicht gesetzt oder veraltet

**Lösung:**
- `AdminSessionGate` neu laden → holt automatisch neues Token
- Sicherstellen, dass `adminApi` bei mutierenden Calls `X-CSRF-Token` setzt

### Problem: Setup-Formular erscheint nicht

**Ursachen:**
- Bereits ein Admin vorhanden

**Lösung:**
- Bestehende Admin-Credentials verwenden
- Falls vergessen: über Datenbank (Tabelle `admin_users`) neuen Admin eintragen oder Passwort zurücksetzen

### Problem: Login schlägt wiederholt fehl

**Checks:**
1. Backend-Logs prüfen (Rate-Limits? falsches Passwort?)
2. Prüfen, ob `ADMIN_SESSION_SECRET` gesetzt ist (sonst keine stabilen Sessions)
3. Browser-Konsole → Network Request `POST /auth/login` analysieren

---

## 🚀 Deployment

### Production Checklist

- [ ] Sicheres `ADMIN_SESSION_SECRET` (>= 32 random bytes) gesetzt
- [ ] HTTPS aktiviert (Cookies: `Secure`, `SameSite=Strict`)
- [ ] Session-DB Pfad (`ADMIN_SESSION_DIR`/`ADMIN_SESSION_DB`) persistent gemacht
- [ ] Admin-Benutzer erstellt und dokumentiert (kein Secret im Frontend)
- [ ] Monitoring/Alerting für fehlgeschlagene Logins eingerichtet

### Docker Deployment

```yaml
# docker-compose.yml
services:
  backend:
    environment:
      - ADMIN_SESSION_SECRET=${ADMIN_SESSION_SECRET}
      - ADMIN_SESSION_DIR=/data/sessions
      # optional weitere Backend-ENV Variablen
  frontend:
    environment:
      - PUBLIC_URL=${PUBLIC_URL:-/}
```

```bash
# .env (nicht in Git!)
ADMIN_SESSION_SECRET=$(openssl rand -hex 32)
```

---

**Fragen?** Siehe `AUTHENTICATION.md` für detaillierte Backend-Dokumentation.

**Status der Backend-Changes:** ✅ Vollständig implementiert und getestet (45/45 Tests passing)
