Files

3.3 KiB

API-Design: Beisel Rallye 🍺

Übersicht

Die API ermöglicht server-seitige Speicherung aller Rallye-Einträge und unterstützt echte Multi-User-Funktionalität über verschiedene Geräte hinweg.

Endpunkte

1. Bezirk besuchen (POST /api/visit)

Zweck: Neuen Besuch eines Bezirks speichern

Request Body:

{
  "user_name": "Gregor",
  "district": "I. Innere Stadt",
  "beisel_name": "Schloßhotel Greising"
}

Response (201 Created):

{
  "success": true,
  "message": "Bezirk gespeichert!",
  "data": {
    "id": 6,
    "user_name": "Gregor", 
    "district": "I. Innere Stadt",
    "beisel_name": "Schloßhotel Greising",
    "timestamp": "2026-06-29T10:30:00.000Z"
  },
  "progress": {
    "visited_count": 8,
    "total_districts": 17,
    "percentage": 47
  }
}

Fehler (400 Bad Request):

{
  "success": false,
  "error": "Ungültige Eingabe",
  "details": {
    "user_name": "Pflichtfeld",
    "district": "Ungültiger Bezirk"
  }
}

2. Fortschritt abrufen (GET /api/status/:username)

Zweck: Aktuelle Rallye-Statistik für einen Benutzer laden

Response (200 OK):

{
  "user_name": "Gregor",
  "progress": {
    "visited_count": 8,
    "total_districts": 17,
    "percentage": 47
  },
  "visits": [
    {
      "district": "I. Innere Stadt",
      "beisel_name": "Schloßhotel Greising", 
      "timestamp": "2026-06-29T10:30:00.000Z"
    },
    {
      "district": "II. St. Leonhard",
      "beisel_name": "Jazzkeller",
      "timestamp": "2026-06-29T11:15:00.000Z"
    }
  ],
  "last_updated": "2026-06-29T11:15:00.000Z"
}

3. Alle Teilnehmer anzeigen (GET /api/all-users)

Zweck: Leaderboard mit allen aktiven Teilnehmern

Response (200 OK):

{
  "users": [
    {
      "user_name": "Gregor",
      "visited_count": 8,
      "last_active": "2026-06-29T11:15:00.000Z"
    },
    {
      "user_name": "Maria", 
      "visited_count": 12,
      "last_active": "2026-06-29T10:45:00.000Z"
    }
  ],
  "total_users": 2,
  "generated_at": "2026-06-29T12:00:00.000Z"
}

4. Reset für User (DELETE /api/reset/:username)

Zweck: Alle Einträge eines Users löschen

Response (200 OK):

{
  "success": true,
  "message": "Alle Einträge für 'Gregor' gelöscht",
  "deleted_count": 5
}

Fehlerbehandlung

Allgemeine Fehler (4xx/5xx)

{
  "error_code": "INTERNAL_ERROR",
  "message": "Unerwarteter Serverfehler", 
  "timestamp": "2026-06-29T12:00:00.000Z"
}

Validierungsfehler (400)

{
  "error_code": "VALIDATION_ERROR",
  "message": "Ungültige Eingabe",
  "details": {
    "field_name": ["Fehlermeldung"]
  }
}

Implementierungs-Hinweise

Datenbank-Operationen

  • Verwende sqlite3 Package für asynchrone Operationen
  • Parameterisierte Queries gegen SQL Injection schützen
  • Connection Pooling für bessere Performance

Rate Limiting

  • Max. 10 Anfragen pro Minute pro IP
  • Besonders bei POST /api/visit wichtig

Sicherheit

  • Input Validation auf allen Endpunkten
  • User-Namen sanitieren (keine Script-Injection)
  • CORS Headers setzen falls nötig

Performance

  • SQLite ist ausreichend für diese Anwendung
  • Keine komplexen Joins notwendig
  • Periodische Datenbank-Vacuum Operationen empfohlen

Stand: 2026-06-29 | Version: 1.0