const swaggerJsdoc = require('swagger-jsdoc'); const options = { definition: { openapi: '3.0.0', info: { title: 'Ninja Cross Parkour API', version: '1.0.0', description: 'API für das Ninja Cross Parkour System im Schwimmbad', contact: { name: 'Ninja Cross Parkour', email: 'admin@ninjacross.com' }, license: { name: 'MIT', url: 'https://opensource.org/licenses/MIT' } }, servers: [ { url: 'https://ninja.reptilfpv.de', description: 'Production server' } ], components: { securitySchemes: { ApiKeyAuth: { type: 'apiKey', in: 'header', name: 'X-API-Key', description: 'API Key für Authentifizierung' }, BearerAuth: { type: 'http', scheme: 'bearer', bearerFormat: 'JWT', description: 'JWT Token für Supabase Authentifizierung' } }, schemas: { Player: { type: 'object', properties: { id: { type: 'string', format: 'uuid', description: 'Eindeutige Spieler-ID' }, firstname: { type: 'string', description: 'Vorname des Spielers' }, lastname: { type: 'string', description: 'Nachname des Spielers' }, birthdate: { type: 'string', format: 'date', description: 'Geburtsdatum des Spielers' }, rfiduid: { type: 'string', description: 'RFID UID der Karte (Format: XX:XX:XX:XX)' }, supabase_user_id: { type: 'string', format: 'uuid', description: 'Supabase User ID für Verknüpfung' }, created_at: { type: 'string', format: 'date-time', description: 'Erstellungsdatum' } } }, Time: { type: 'object', properties: { id: { type: 'string', format: 'uuid', description: 'Eindeutige Zeit-ID' }, player_id: { type: 'string', format: 'uuid', description: 'ID des Spielers' }, location_id: { type: 'string', format: 'uuid', description: 'ID des Standorts' }, recorded_time: { type: 'object', description: 'Aufgezeichnete Zeit als Intervall', properties: { seconds: { type: 'number' }, minutes: { type: 'number' }, milliseconds: { type: 'number' } } }, created_at: { type: 'string', format: 'date-time', description: 'Erstellungsdatum' } } }, Location: { type: 'object', properties: { id: { type: 'string', format: 'uuid', description: 'Eindeutige Standort-ID' }, name: { type: 'string', description: 'Name des Standorts' }, latitude: { type: 'number', format: 'float', description: 'Breitengrad' }, longitude: { type: 'number', format: 'float', description: 'Längengrad' }, time_threshold: { type: 'object', description: 'Zeitschwelle für den Standort', properties: { seconds: { type: 'number' }, minutes: { type: 'number' } } }, created_at: { type: 'string', format: 'date-time', description: 'Erstellungsdatum' } } }, Achievement: { type: 'object', properties: { id: { type: 'string', format: 'uuid', description: 'Eindeutige Achievement-ID' }, name: { type: 'string', description: 'Name des Achievements' }, description: { type: 'string', description: 'Beschreibung des Achievements' }, category: { type: 'string', enum: ['consistency', 'improvement', 'seasonal', 'monthly'], description: 'Kategorie des Achievements' }, condition_type: { type: 'string', description: 'Typ der Bedingung' }, condition_value: { type: 'integer', description: 'Wert der Bedingung' }, icon: { type: 'string', description: 'Emoji-Icon für das Achievement' }, points: { type: 'integer', description: 'Punkte für das Achievement' }, is_active: { type: 'boolean', description: 'Ob das Achievement aktiv ist' } } }, PlayerAchievement: { type: 'object', properties: { id: { type: 'string', format: 'uuid', description: 'Eindeutige Player-Achievement-ID' }, player_id: { type: 'string', format: 'uuid', description: 'ID des Spielers' }, achievement_id: { type: 'string', format: 'uuid', description: 'ID des Achievements' }, progress: { type: 'integer', description: 'Aktueller Fortschritt' }, is_completed: { type: 'boolean', description: 'Ob das Achievement abgeschlossen ist' }, earned_at: { type: 'string', format: 'date-time', description: 'Wann das Achievement erreicht wurde' } } }, Error: { type: 'object', properties: { success: { type: 'boolean', example: false }, message: { type: 'string', description: 'Fehlermeldung' } } }, Success: { type: 'object', properties: { success: { type: 'boolean', example: true }, message: { type: 'string', description: 'Erfolgsmeldung' }, data: { type: 'object', description: 'Daten der Antwort' } } } } }, tags: [ { name: 'Public API', description: 'Öffentliche API-Endpoints ohne Authentifizierung' }, { name: 'Private API', description: 'Private API-Endpoints mit API-Key Authentifizierung' }, { name: 'Web API', description: 'Web-API-Endpoints für das Frontend' }, { name: 'Admin API', description: 'Admin-API-Endpoints für Verwaltung' }, { name: 'Achievements', description: 'Achievement-System Endpoints' } ] }, apis: ['./routes/api.js'] // Pfad zu deiner API-Datei }; const specs = swaggerJsdoc(options); module.exports = specs;