# API Routes - Developer Guide

## 📁 Single Source of Truth

**`routeMappings.js`** ist die zentrale Konfigurationsdatei für alle API-Routen.

```javascript
// ✅ HIER ändern (Single Source of Truth)
module.exports = [
    { router: 'upload', prefix: '/api', file: 'upload.js' },
    // ...
];
```

**Verwendet von:**
- `routes/index.js` → Server-Routing
- `generate-openapi.js` → OpenAPI-Dokumentation

**❌ NICHT direkt in `routes/index.js` oder `generate-openapi.js` ändern!**

---

## 🆕 Neue Route hinzufügen

### 1. Router-Datei erstellen

```bash
touch backend/src/routes/myNewRoute.js
```

```javascript
// backend/src/routes/myNewRoute.js
const express = require('express');
const router = express.Router();

/**
 * #swagger.tags = ['My Feature']
 * #swagger.description = 'Beschreibung der Route'
 */
router.get('/my-endpoint', async (req, res) => {
    res.json({ success: true });
});

module.exports = router;
```

### 2. In `routeMappings.js` registrieren

```javascript
// backend/src/routes/routeMappings.js
module.exports = [
    // ... bestehende Routes
    { router: 'myNewRoute', prefix: '/api/my-feature', file: 'myNewRoute.js' }
];
```

### 3. In `routes/index.js` importieren

```javascript
// backend/src/routes/index.js
const myNewRouteRouter = require('./myNewRoute');

const routerMap = {
    // ... bestehende Router
    myNewRoute: myNewRouteRouter
};
```

### 4. OpenAPI regenerieren

OpenAPI wird **automatisch** bei jedem Server-Start (Dev-Mode) generiert.

**Manuell generieren:**
```bash
npm run generate-openapi
```

**OpenAPI-Pfade testen:**
```bash
npm run test-openapi  # Prüft alle Routen gegen localhost:5000
```

✅ **Fertig!** Route ist unter `/api/my-feature/my-endpoint` verfügbar.

---

## 🔄 OpenAPI-Dokumentation generieren

### Automatisch bei Server-Start (Dev-Mode) ⭐

Im Development-Modus wird die OpenAPI-Spezifikation **automatisch generiert**, wenn der Server startet:

```bash
cd backend
npm run dev  # oder npm run server
```

**Ausgabe:**
```
🔄 Generating OpenAPI specification...
✓ OpenAPI spec generated
📊 Total paths: 35
📋 Tags: Upload, Management Portal, Admin - ...
```

Die Datei `backend/docs/openapi.json` wird bei jedem Start aktualisiert.

### Manuell (für Produktions-Builds)

```bash
cd backend
npm run generate-openapi
```

**Generiert:** `backend/docs/openapi.json`

**Zugriff:** http://localhost:5001/api/docs/ (nur dev-mode)

### Was wird generiert?

- Alle Routen aus `routeMappings.js`
- Mount-Prefixes werden automatisch angewendet
- Swagger-Annotations aus Route-Dateien werden erkannt
- **Automatisch im Dev-Mode:** Bei jedem Server-Start (nur wenn `NODE_ENV !== 'production'`)
- **Manuell:** Mit `npm run generate-openapi`

### Swagger-Annotations verwenden

**Wichtig:** swagger-autogen nutzt `#swagger` Comments (nicht `@swagger`)!

```javascript
router.get('/groups', async (req, res) => {
    /* 
        #swagger.tags = ['Groups']
        #swagger.summary = 'Alle Gruppen abrufen'
        #swagger.description = 'Liefert alle freigegebenen Gruppen mit Bildern'
        #swagger.responses[200] = {
            description: 'Liste der Gruppen',
            schema: {
                groups: [{
                    groupId: 'cTV24Yn-a',
                    year: 2024,
                    title: 'Familie Mueller'
                }],
                totalCount: 73
            }
        }
        #swagger.responses[500] = {
            description: 'Server error'
        }
    */
    // Route implementation...
});
```

**Mit Parametern:**

```javascript
router.get('/groups/:groupId', async (req, res) => {
    /* 
        #swagger.tags = ['Groups']
        #swagger.summary = 'Einzelne Gruppe abrufen'
        #swagger.parameters['groupId'] = {
            in: 'path',
            required: true,
            type: 'string',
            description: 'Unique group ID',
            example: 'cTV24Yn-a'
        }
        #swagger.responses[200] = {
            description: 'Group details',
            schema: { groupId: 'cTV24Yn-a', title: 'Familie Mueller' }
        }
        #swagger.responses[404] = {
            description: 'Group not found'
        }
    */
    // Route implementation...
});
```

**Mit Request Body:**

```javascript
router.post('/groups', async (req, res) => {
    /* 
        #swagger.tags = ['Groups']
        #swagger.summary = 'Neue Gruppe erstellen'
        #swagger.parameters['body'] = {
            in: 'body',
            required: true,
            schema: {
                title: 'Familie Mueller',
                year: 2024,
                description: 'Weihnachtsfeier'
            }
        }
        #swagger.responses[201] = {
            description: 'Group created',
            schema: { groupId: 'abc123', message: 'Created successfully' }
        }
    */
    // Route implementation...
});
```

---

## 🗂️ API-Struktur

### Public API (`/api`)
- **Zugriff:** Öffentlich, keine Authentifizierung
- **Routen:** Upload, Download, Groups (lesend)
- **Dateien:** `upload.js`, `download.js`, `batchUpload.js`, `groups.js`

### Management API (`/api/manage`)
- **Zugriff:** Token-basiert (UUID v4)
- **Routen:** Selbstverwaltung von eigenen Gruppen
- **Dateien:** `management.js`
- **Beispiel:** `PUT /api/manage/:token/reorder`

### Admin API (`/api/admin`)
- **Zugriff:** Geschützt (Middleware erforderlich)
- **Routen:** Moderation, Deletion Logs, Cleanup
- **Dateien:** `admin.js`, `consent.js`, `reorder.js`
- **Beispiel:** `GET /api/admin/groups`, `DELETE /api/admin/groups/:id`

### System API (`/api/system`)
- **Zugriff:** Intern (Wartungsfunktionen)
- **Routen:** Datenbank-Migrationen
- **Dateien:** `migration.js`

---

## 🔒 Mehrfach-Mount (z.B. Reorder)

Manche Routen sind an mehreren Stellen verfügbar:

```javascript
// routeMappings.js
module.exports = [
    // Admin-Zugriff (geschützt)
    { router: 'reorder', prefix: '/api/admin', file: 'reorder.js' },
    
    // Management-Zugriff (in management.js integriert)
    // { router: 'management', prefix: '/api/manage', file: 'management.js' }
    // → enthält PUT /:token/reorder
];
```

**Hinweis:** Reorder ist direkt in `management.js` implementiert, nicht als separater Mount.

---

## ⚠️ Wichtige Regeln

### 1. Relative Pfade in Router-Dateien

```javascript
// ✅ RICHTIG (ohne Prefix)
router.get('/groups', ...)
router.get('/groups/:id', ...)

// ❌ FALSCH (Prefix gehört in routeMappings.js)
router.get('/api/groups', ...)
```

### 2. String-Literale verwenden

```javascript
// ✅ RICHTIG
router.get('/upload', ...)

// ❌ FALSCH (swagger-autogen kann Variablen nicht auflösen)
const ROUTES = { UPLOAD: '/upload' };
router.get(ROUTES.UPLOAD, ...)
```

### 3. Mount-Prefix nur in routeMappings.js

```javascript
// routeMappings.js
{ router: 'groups', prefix: '/api', file: 'groups.js' }

// ✅ Ergebnis: /api/groups
```

---

## 🧪 Testen

### Backend-Tests mit curl

```bash
# Public API
curl http://localhost:5000/api/groups

# Management API (Token erforderlich)
curl http://localhost:5000/api/manage/YOUR-TOKEN-HERE

# Admin API
curl http://localhost:5000/api/admin/groups
```

### OpenAPI-Spec validieren

```bash
cd backend
npm run test-openapi
```

**Ausgabe:**
```
🔍 Testing 35 paths from openapi.json against http://localhost:5000

✅ GET /api/groups → 200
✅ GET /api/upload → 405 (expected, needs POST)
...
```

### Swagger UI öffnen

```
http://localhost:5001/api/docs/
```

**Hinweis:** Nur im Development-Modus verfügbar!

---

## 🐛 Troubleshooting

### OpenAPI-Generierung hängt

**Problem:** `generate-openapi.js` lädt Router-Module, die wiederum andere Module laden → Zirkelbezüge

**Lösung:** `routeMappings.js` enthält nur Konfiguration, keine Router-Imports

### Route nicht in OpenAPI

1. Prüfe `routeMappings.js` → Route registriert?
2. Prüfe Router-Datei → String-Literale verwendet?
3. Regeneriere: `npm run generate-openapi` (oder starte Server neu im Dev-Mode)

### Route funktioniert nicht

1. Prüfe `routes/index.js` → Router in `routerMap` eingetragen?
2. Prüfe Console → Fehler beim Server-Start?
3. Teste mit curl → Exakte URL prüfen

---

## 📚 Weitere Dokumentation

- **Feature-Plan:** `docs/FEATURE_PLAN-autogen-openapi.md`
- **OpenAPI-Spec:** `backend/docs/openapi.json`
- **API-Tests:** `backend/test-openapi-paths.js`
