Project-Image-Uploader/README.dev.md
matthias.lotz cdb2aa95e6 feat: Add comprehensive test suite and admin API authentication
🧪 Testing Infrastructure (45 tests, 100% passing)
- Implemented Jest + Supertest framework for automated testing
- Unit tests: 5 tests for auth middleware (100% coverage)
- Integration tests: 40 tests covering admin, consent, migration, upload APIs
- Test execution time: ~10 seconds for full suite
- Coverage: 26% statements, 15% branches (realistic start)
- In-memory SQLite database for isolated testing
- Singleton server pattern for fast test execution
- Automatic cleanup and teardown

🔒 Admin API Authentication
- Bearer token authentication for all admin endpoints
- requireAdminAuth middleware with ADMIN_API_KEY validation
- Protected routes: /api/admin/*, /api/system/migration/migrate|rollback
- Complete authentication guide in AUTHENTICATION.md
- HTTP 403 for missing/invalid tokens, 500 if not configured
- Ready for production with token rotation support

📋 API Route Documentation
- Single Source of Truth: backend/src/routes/routeMappings.js
- Comprehensive route overview in backend/src/routes/README.md
- Express routing order documented (specific before generic)
- Frontend integration guide with authentication examples
- OpenAPI auto-generation integrated

🐛 Bug Fixes
- Fixed SQLite connection not properly awaited (caused test hangs)
- Fixed upload validation checking req.files.file before req.files
- Fixed Express route order (consent before admin router)
- Fixed test environment using /tmp for uploads (permission issues)

📚 Documentation Updates
- Updated README.md with testing and authentication features
- Updated README.dev.md with testing section and API development guide
- Updated CHANGELOG.md with complete feature documentation
- Updated FEATURE_PLAN-autogen-openapi.md (status: 100% complete)
- Added frontend/MIGRATION-GUIDE.md for frontend team

🚀 Frontend Impact
Frontend needs to add Bearer token to all /api/admin/* calls.
See frontend/MIGRATION-GUIDE.md for detailed instructions.

Test Status:  45/45 passing (100%)
Backend:  Production ready
Frontend: ⚠️ Migration required (see MIGRATION-GUIDE.md)
2025-11-16 18:08:48 +01:00

401 lines
11 KiB
Markdown

# Development Setup
## 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)
- **Slideshow**: http://localhost:3000/slideshow
- **Moderation**: http://localhost:3000/moderation (Entwicklung: ohne Auth)
### 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
### 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 (Bearer Token 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 (Bearer Token)**:
```bash
# .env konfigurieren:
ADMIN_API_KEY=your-secure-key-here
# API-Aufrufe:
curl -H "Authorization: Bearer your-secure-key-here" \
http://localhost:5001/api/admin/groups
```
2. **Management Portal (UUID Token)**:
```bash
# Automatisch beim Upload generiert
GET /api/manage/550e8400-e29b-41d4-a716-446655440000
```
📖 **Vollständige Doku**: `AUTHENTICATION.md`
### 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/auth.js` - Admin Authentication (Bearer Token)
- `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
```
## 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
```