286 lines
7.7 KiB
JavaScript
286 lines
7.7 KiB
JavaScript
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;
|