# 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) Für Deployments ohne HTTPS muss `docker/prod/docker-compose.yml` die Zeile `- ADMIN_SESSION_COOKIE_SECURE=false` enthalten. Ein vorgefertigtes Pre-Commit-Hook stellt sicher, dass diese Zeile vorhanden ist bzw. automatisch korrigiert wird: ```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. Entfernen kannst du ihn 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 ```