462 lines
14 KiB
Markdown
462 lines
14 KiB
Markdown
# Development Setup
|
||
|
||
## ⚠️ Wichtige Hinweise für Frontend-Entwickler
|
||
|
||
### 🔴 BREAKING CHANGES - API-Umstrukturierung (November 2025)
|
||
|
||
Im Rahmen der OpenAPI-Auto-Generation wurden **massive Änderungen** an der API-Struktur vorgenommen:
|
||
|
||
- **Authentication**: Admin-Endpoints laufen jetzt über serverseitige Sessions + CSRF Tokens
|
||
- **Route-Struktur**: Einige Pfade haben sich geändert (Single Source of Truth: `routeMappings.js`)
|
||
- **Error Handling**: Neue HTTP-Status-Codes (403 für Auth-Fehler)
|
||
|
||
**📖 Siehe:**
|
||
- **`frontend/MIGRATION-GUIDE.md`** - Detaillierte Migrations-Anleitung für Frontend
|
||
- **`backend/src/routes/README.md`** - Vollständige API-Route-Dokumentation
|
||
- **`AUTHENTICATION.md`** - Auth-System-Setup und Verwendung
|
||
|
||
|
||
---
|
||
|
||
## Schnellstart
|
||
|
||
### Starten (Development Environment)
|
||
|
||
```bash
|
||
# Mit Script (empfohlen):
|
||
./dev.sh
|
||
|
||
# Oder manuell:
|
||
docker compose -f docker/dev/docker-compose.yml up -d
|
||
```
|
||
|
||
### Zugriff
|
||
- **Frontend**: http://localhost:3000 (Hot Module Reloading aktiv)
|
||
- **Backend**: http://localhost:5001 (API)
|
||
- **API Documentation**: http://localhost:5001/api/docs/ (Swagger UI, nur in Development verfügbar)
|
||
- **Slideshow**: http://localhost:3000/slideshow
|
||
- **Moderation**: http://localhost:3000/moderation (Login über Admin Session)
|
||
|
||
### Logs verfolgen
|
||
```bash
|
||
# Alle Services:
|
||
docker compose -f docker/dev/docker-compose.yml logs -f
|
||
|
||
# Nur Frontend:
|
||
docker compose -f docker/dev/docker-compose.yml logs -f frontend-dev
|
||
|
||
# Nur Backend:
|
||
docker compose -f docker/dev/docker-compose.yml logs -f backend-dev
|
||
```
|
||
|
||
## API-Entwicklung
|
||
|
||
### ⚠️ BREAKING CHANGES - Frontend Migration erforderlich
|
||
|
||
**Massive API-Änderungen im November 2025:**
|
||
- Session + CSRF Authentication für alle Admin-Endpoints
|
||
- Route-Pfade umstrukturiert (siehe `routeMappings.js`)
|
||
- Neue Error-Response-Formate
|
||
|
||
**📖 Frontend Migration Guide**: `frontend/MIGRATION-GUIDE.md`
|
||
|
||
### Route-Struktur
|
||
|
||
Die API verwendet eine **Single Source of Truth** für Route-Mappings:
|
||
|
||
📄 **`backend/src/routes/routeMappings.js`** - Zentrale Route-Konfiguration
|
||
|
||
Siehe auch: **`backend/src/routes/README.md`** für vollständige API-Übersicht
|
||
|
||
**Wichtige Route-Gruppen:**
|
||
- `/api/upload`, `/api/download` - Öffentliche Upload/Download-Endpoints
|
||
- `/api/manage/:token` - Self-Service Management Portal (UUID-Token)
|
||
- `/api/admin/*` - Admin-Endpoints (Session + CSRF Authentication)
|
||
- `/api/system/migration/*` - Datenbank-Migrationen
|
||
|
||
**⚠️ Express Route-Reihenfolge beachten:**
|
||
Router mit spezifischen Routes **vor** generischen Routes mounten!
|
||
```javascript
|
||
// ✅ RICHTIG: Spezifisch vor generisch
|
||
{ router: 'consent', prefix: '/api/admin' }, // /groups/by-consent
|
||
{ router: 'admin', prefix: '/api/admin' }, // /groups/:groupId
|
||
|
||
// ❌ FALSCH: Generisch fängt alles ab
|
||
{ router: 'admin', prefix: '/api/admin' }, // /groups/:groupId matched auf 'by-consent'!
|
||
{ router: 'consent', prefix: '/api/admin' }, // Wird nie erreicht
|
||
```
|
||
|
||
### Authentication
|
||
|
||
**Zwei Auth-Systeme parallel:**
|
||
|
||
1. **Admin API (Session + CSRF)**:
|
||
```bash
|
||
# .env konfigurieren:
|
||
ADMIN_SESSION_SECRET=$(openssl rand -hex 32)
|
||
|
||
# Initialen Admin anlegen (falls benötigt)
|
||
curl -c cookies.txt http://localhost:5001/auth/setup/status
|
||
curl -X POST -H "Content-Type: application/json" \
|
||
-c cookies.txt -b cookies.txt \
|
||
-d '{"username":"admin","password":"SuperSicher123"}' \
|
||
http://localhost:5001/auth/setup/initial-admin
|
||
|
||
# Login + CSRF Token holen
|
||
curl -X POST -H "Content-Type: application/json" \
|
||
-c cookies.txt -b cookies.txt \
|
||
-d '{"username":"admin","password":"SuperSicher123"}' \
|
||
http://localhost:5001/auth/login
|
||
CSRF=$(curl -sb cookies.txt http://localhost:5001/auth/csrf-token | jq -r '.csrfToken')
|
||
|
||
# Authentifizierter Admin-Request
|
||
curl -b cookies.txt -H "X-CSRF-Token: $CSRF" \
|
||
http://localhost:5001/api/admin/groups
|
||
```
|
||
|
||
2. **Management Portal (UUID Token)**:
|
||
User, die Bilder hochladen, erhalten automatisch einen UUID-Token für das Self-Service Management Portal.
|
||
Über diesen Token / Link können sie ihre hochgeladenen Gruppen verwalten:
|
||
```bash
|
||
# Automatisch beim Upload generiert
|
||
GET /api/manage/550e8400-e29b-41d4-a716-446655440000
|
||
```
|
||
|
||
📖 **Vollständige Doku**: `AUTHENTICATION.md`
|
||
|
||
#### Admin-Hinweise: Logout & neue Nutzer
|
||
|
||
- **Logout:** Der Moderationsbereich enthält jetzt einen Logout-Button (Icon in der Kopfzeile). Klick → `POST /auth/logout` → Session beendet, Login erscheint erneut. Für Skripte kannst du weiterhin `curl -b cookies.txt -X POST http://localhost:5001/auth/logout` verwenden.
|
||
- **Weiterer Admin:** Verwende das neue API-basierte Skript `./scripts/create_admin_user.sh --server http://localhost:5001 --username zweiteradmin --password 'SuperPasswort123!' [--admin-user bestehend --admin-password ... --role ... --require-password-change]`. Das Skript erledigt Login, CSRF, Duplikats-Check und legt zusätzliche Admins über `/api/admin/users` an (Fallback: `backend/src/scripts/createAdminUser.js`).
|
||
|
||
### OpenAPI-Spezifikation
|
||
|
||
Die OpenAPI-Spezifikation wird **automatisch beim Backend-Start** generiert:
|
||
|
||
```bash
|
||
# Generiert: backend/docs/openapi.json
|
||
# Swagger UI: http://localhost:5001/api/docs/
|
||
|
||
# Manuelle Generierung:
|
||
cd backend
|
||
node src/generate-openapi.js
|
||
```
|
||
|
||
**Swagger-Annotationen in Routes:**
|
||
```javascript
|
||
router.get('/example', async (req, res) => {
|
||
/*
|
||
#swagger.tags = ['Example']
|
||
#swagger.summary = 'Get example data'
|
||
#swagger.responses[200] = { description: 'Success' }
|
||
*/
|
||
});
|
||
```
|
||
|
||
## Entwicklung
|
||
|
||
### Frontend-Entwicklung
|
||
- Code in `frontend/src/` editieren → Hot Module Reload übernimmt Änderungen
|
||
- Volumes: Source-Code wird live in Container gemountet
|
||
- Container-Namen: `image-uploader-frontend-dev`
|
||
|
||
**Wichtige Komponenten:**
|
||
- `Components/Pages/MultiUploadPage.js` - Upload-Interface mit Consent-Management
|
||
- `Components/ComponentUtils/MultiUpload/ConsentCheckboxes.js` - GDPR-konforme Consent-UI
|
||
- `Components/Pages/ModerationGroupsPage.js` - Moderation mit Consent-Filtern
|
||
- `services/reorderService.js` - Drag-and-Drop Logik
|
||
- `hooks/useImagePreloader.js` - Slideshow-Preloading
|
||
|
||
### Backend-Entwicklung
|
||
- Code in `backend/src/` editieren → Nodemon übernimmt Änderungen automatisch
|
||
- Container-Namen: `image-uploader-backend-dev`
|
||
- Environment: `NODE_ENV=development`
|
||
|
||
**Wichtige Module:**
|
||
- `routes/routeMappings.js` - Single Source of Truth für Route-Konfiguration
|
||
- `repositories/GroupRepository.js` - Consent-Management & CRUD
|
||
- `repositories/SocialMediaRepository.js` - Plattform- & Consent-Verwaltung
|
||
- `routes/batchUpload.js` - Upload mit Consent-Validierung
|
||
- `middlewares/session.js` - Express-Session + SQLite Store
|
||
- `middlewares/auth.js` - Admin Session-Guard & CSRF-Pflicht
|
||
- `database/DatabaseManager.js` - Automatische Migrationen
|
||
- `services/GroupCleanupService.js` - 7-Tage-Cleanup-Logik
|
||
|
||
### Datenbank-Entwicklung
|
||
|
||
#### Migrationen erstellen
|
||
```bash
|
||
# Neue Migration anlegen:
|
||
touch backend/src/database/migrations/XXX_description.sql
|
||
|
||
# Migrationen werden automatisch beim Backend-Start ausgeführt
|
||
# Manuell: docker compose -f docker/dev/docker-compose.yml restart backend-dev
|
||
```
|
||
|
||
#### Datenbank-Zugriff
|
||
```bash
|
||
# SQLite Shell:
|
||
docker compose -f docker/dev/docker-compose.yml exec backend-dev sqlite3 /usr/src/app/src/data/db/image_uploader.db
|
||
|
||
# Schnellabfragen:
|
||
docker compose -f docker/dev/docker-compose.yml exec backend-dev sqlite3 /usr/src/app/src/data/db/image_uploader.db "SELECT * FROM groups LIMIT 5;"
|
||
|
||
# Schema anzeigen:
|
||
docker compose -f docker/dev/docker-compose.yml exec backend-dev sqlite3 /usr/src/app/src/data/db/image_uploader.db ".schema"
|
||
```
|
||
|
||
#### Migrationen debuggen
|
||
```bash
|
||
# Migration-Status prüfen:
|
||
docker compose -f docker/dev/docker-compose.yml exec backend-dev sqlite3 /usr/src/app/src/data/db/image_uploader.db "SELECT * FROM schema_migrations;"
|
||
|
||
# Backend-Logs mit Migration-Output:
|
||
docker compose -f docker/dev/docker-compose.yml logs backend-dev | grep -i migration
|
||
```
|
||
|
||
### Konfiguration anpassen
|
||
- **Frontend**: `docker/dev/frontend/config/.env`
|
||
- **Backend**: `docker/dev/backend/config/.env`
|
||
- **Nginx**: `docker/dev/frontend/nginx.conf`
|
||
|
||
## Testing
|
||
|
||
### Automatisierte Tests
|
||
|
||
Das Backend verfügt über eine umfassende Test-Suite mit 45 Tests:
|
||
|
||
```bash
|
||
# Alle Tests ausführen:
|
||
cd backend
|
||
npm test
|
||
|
||
# Einzelne Test-Suite:
|
||
npm test -- tests/api/admin.test.js
|
||
|
||
# Mit Coverage-Report:
|
||
npm test -- --coverage
|
||
|
||
# Watch-Mode (während Entwicklung):
|
||
npm test -- --watch
|
||
```
|
||
|
||
**Test-Struktur:**
|
||
- `tests/unit/` - Unit-Tests (z.B. Auth-Middleware)
|
||
- `tests/api/` - Integration-Tests (API-Endpoints)
|
||
- `tests/setup.js` - Globale Test-Konfiguration
|
||
- `tests/testServer.js` - Test-Server-Helper
|
||
|
||
**Test-Features:**
|
||
- Jest + Supertest Framework
|
||
- In-Memory SQLite Database (isoliert)
|
||
- Singleton Server Pattern (schnell)
|
||
- 100% Test-Success-Rate (45/45 passing)
|
||
- ~10 Sekunden Ausführungszeit
|
||
- Coverage: 26% Statements, 15% Branches
|
||
|
||
**Test-Umgebung:**
|
||
- Verwendet `/tmp/test-image-uploader/` für Upload-Tests
|
||
- Eigene Datenbank `:memory:` (kein Konflikt mit Dev-DB)
|
||
- Environment: `NODE_ENV=test`
|
||
- Automatisches Cleanup nach Test-Run
|
||
|
||
**Neue Tests hinzufügen:**
|
||
```javascript
|
||
// tests/api/example.test.js
|
||
const { getRequest } = require('../testServer');
|
||
|
||
describe('Example API', () => {
|
||
it('should return 200', async () => {
|
||
const response = await getRequest()
|
||
.get('/api/example')
|
||
.expect(200);
|
||
|
||
expect(response.body).toHaveProperty('data');
|
||
});
|
||
});
|
||
```
|
||
|
||
### Manuelles Testing
|
||
|
||
### Consent-System testen
|
||
```bash
|
||
# 1. Upload mit und ohne Workshop-Consent
|
||
# 2. Social Media Checkboxen testen (Facebook, Instagram, TikTok)
|
||
# 3. Moderation-Filter prüfen:
|
||
# - Alle Gruppen
|
||
# - Nur Werkstatt
|
||
# - Facebook / Instagram / TikTok
|
||
# 4. Export-Funktion (CSV/JSON) testen
|
||
```
|
||
|
||
### Cleanup-System testen
|
||
```bash
|
||
# Test-Script verwenden:
|
||
./tests/test-cleanup.sh
|
||
|
||
# Oder manuell:
|
||
# 1. Upload ohne Approval
|
||
# 2. Gruppe zurückdatieren (Script verwendet)
|
||
# 3. Preview: GET http://localhost:5001/api/admin/cleanup/preview
|
||
# 4. Trigger: POST http://localhost:5001/api/admin/cleanup/trigger
|
||
# 5. Log prüfen: GET http://localhost:5001/api/admin/deletion-log
|
||
```
|
||
|
||
### API-Tests
|
||
|
||
```bash
|
||
# Consent-Endpoints:
|
||
curl http://localhost:5001/api/social-media/platforms
|
||
curl http://localhost:5001/api/groups/by-consent?workshopConsent=true
|
||
curl http://localhost:5001/api/admin/consents/export
|
||
|
||
# Upload testen (mit Consents):
|
||
curl -X POST http://localhost:5001/api/upload-batch \
|
||
-F "images=@test.jpg" \
|
||
-F "year=2025" \
|
||
-F "title=Test" \
|
||
-F "name=Developer" \
|
||
-F 'consents={"workshopConsent":true,"socialMediaConsents":[{"platformId":1,"consented":true}]}'
|
||
```
|
||
|
||
## Container-Management
|
||
|
||
```bash
|
||
# Status anzeigen:
|
||
docker compose -f docker/dev/docker-compose.yml ps
|
||
|
||
# Container neustarten:
|
||
docker compose -f docker/dev/docker-compose.yml restart
|
||
|
||
# Container neu bauen (nach Package-Updates):
|
||
docker compose -f docker/dev/docker-compose.yml build --no-cache
|
||
|
||
# Stoppen:
|
||
docker compose -f docker/dev/docker-compose.yml down
|
||
|
||
# Mit Volumes löschen (ACHTUNG: Löscht Datenbank!):
|
||
docker compose -f docker/dev/docker-compose.yml down -v
|
||
```
|
||
|
||
### Shell-Zugriff
|
||
|
||
```bash
|
||
# Frontend Container:
|
||
docker compose -f docker/dev/docker-compose.yml exec frontend-dev bash
|
||
|
||
# Backend Container:
|
||
docker compose -f docker/dev/docker-compose.yml exec backend-dev bash
|
||
|
||
# Datenbank-Shell:
|
||
docker compose -f docker/dev/docker-compose.yml exec backend-dev sqlite3 /usr/src/app/src/data/db/image_uploader.db
|
||
```
|
||
|
||
## Debugging
|
||
|
||
### Backend Debugging
|
||
```bash
|
||
# Live-Logs:
|
||
docker compose -f docker/dev/docker-compose.yml logs -f backend-dev
|
||
|
||
# Nodemon Restart:
|
||
# → Änderungen in backend/src/** werden automatisch erkannt
|
||
|
||
# Fehlerhafte Migration fixen:
|
||
# 1. Migration-Eintrag löschen:
|
||
docker compose -f docker/dev/docker-compose.yml exec backend-dev sqlite3 /usr/src/app/src/data/db/image_uploader.db "DELETE FROM schema_migrations WHERE migration_name='XXX.sql';"
|
||
# 2. Backend neustarten:
|
||
docker compose -f docker/dev/docker-compose.yml restart backend-dev
|
||
```
|
||
|
||
### Frontend Debugging
|
||
```bash
|
||
# React DevTools im Browser verwenden
|
||
# Network Tab für API-Calls prüfen
|
||
# Console für Fehler checken
|
||
|
||
# Nginx-Reload (bei Konfig-Änderungen):
|
||
docker compose -f docker/dev/docker-compose.yml exec frontend-dev nginx -s reload
|
||
```
|
||
|
||
### Datenbank-Backup & Restore
|
||
```bash
|
||
# Backup:
|
||
docker cp image-uploader-backend-dev:/usr/src/app/src/data/db/image_uploader.db ./backup.db
|
||
|
||
# Restore:
|
||
docker cp ./backup.db image-uploader-backend-dev:/usr/src/app/src/data/db/image_uploader.db
|
||
docker compose -f docker/dev/docker-compose.yml restart backend-dev
|
||
```
|
||
|
||
## Häufige Probleme
|
||
|
||
### "Migration failed" Fehler
|
||
**Problem**: Inline-Kommentare in SQL-Statements
|
||
**Lösung**: DatabaseManager entfernt diese automatisch (seit Commit 8e62475)
|
||
|
||
### "No such column: display_in_workshop"
|
||
**Problem**: Migration 005 nicht ausgeführt
|
||
**Lösung**: Backend neu starten oder manuell Migration ausführen
|
||
|
||
### Port 3000 bereits belegt
|
||
**Problem**: Anderer Prozess nutzt Port 3000
|
||
**Lösung**:
|
||
```bash
|
||
lsof -ti:3000 | xargs kill -9
|
||
# Oder Port in docker/dev/docker-compose.yml ändern
|
||
```
|
||
|
||
### Consent-Filter zeigt nichts
|
||
**Problem**: `display_in_workshop` fehlt in groupFormatter
|
||
**Lösung**: Bereits gefixt (Commit f049c47)
|
||
|
||
## Git Workflow
|
||
|
||
```bash
|
||
# Feature Branch erstellen:
|
||
git checkout -b feature/my-feature
|
||
|
||
# Änderungen committen:
|
||
git add .
|
||
git commit -m "feat: Add new feature"
|
||
|
||
# Vor Merge: Code testen!
|
||
# - Upload-Flow mit Consents
|
||
# - Moderation mit Filtern
|
||
# - Slideshow-Funktionalität
|
||
# - Cleanup-System
|
||
|
||
# Push:
|
||
git push origin feature/my-feature
|
||
```
|
||
|
||
### Git Hook (optional Absicherung)
|
||
|
||
Standard-Deployments sollten `ADMIN_SESSION_COOKIE_SECURE=true` behalten, damit das Session-Cookie nur über HTTPS übertragen wird.
|
||
Das bereitgestellte Pre-Commit-Hook stellt sicher, dass der Wert in `docker/prod/docker-compose.yml` automatisch auf `true` zurückgesetzt wird, falls er versehentlich verändert wurde (z. B. nach einem Test auf HTTP-only Hardware):
|
||
|
||
```bash
|
||
ln -s ../../scripts/git-hooks/pre-commit .git/hooks/pre-commit
|
||
```
|
||
|
||
Nach der Installation aktualisiert der Hook die Datei bei Bedarf und staged sie direkt.
|
||
Für lokale HTTP-Lab-Deployments nutze eine separate (gitignorierte) `docker-compose.override.yml`, um `ADMIN_SESSION_COOKIE_SECURE=false` nur zur Laufzeit zu setzen. Entfernen kannst du den Hook jederzeit über `rm .git/hooks/pre-commit`.
|
||
|
||
## Nützliche Befehle
|
||
|
||
```bash
|
||
# Alle Container-IDs:
|
||
docker ps -a
|
||
|
||
# Speicherplatz prüfen:
|
||
docker system df
|
||
|
||
# Ungenutztes aufräumen:
|
||
docker system prune -a
|
||
|
||
# Logs durchsuchen:
|
||
docker compose -f docker/dev/docker-compose.yml logs | grep ERROR
|
||
|
||
# Performance-Monitoring:
|
||
docker stats
|
||
``` |