Zum Inhalt

Carambus API-Dokumentation

Übersicht

Die Carambus API bietet RESTful-Endpunkte für die Verwaltung von Billard-Turnieren, Ligen, Spielern und Echtzeit-Scoreboard-Funktionalität. Die API ist auf Ruby on Rails aufgebaut und folgt REST-Konventionen.

Authentifizierung

Session-basierte Authentifizierung

Die meisten Endpunkte erfordern Authentifizierung über Devise. Fügen Sie Session-Cookies in Ihre Anfragen ein:

# Anmelden, um Session zu erhalten
curl -X POST http://localhost:3000/login \
  -H "Content-Type: application/json" \
  -d '{"user": {"email": "user@example.com", "password": "password"}}' \
  -c cookies.txt

# Session für authentifizierte Anfragen verwenden
curl -X GET http://localhost:3000/api/tournaments \
  -b cookies.txt

API-Token-Authentifizierung (Zukunft)

Token-basierte Authentifizierung ist für zukünftige Versionen geplant.

Basis-URL

Entwicklung: http://localhost:3000
Produktion: https://carambus.de

Antwortformat

Alle API-Antworten sind im JSON-Format:

{
  "data": {
    "id": 1,
    "type": "tournament",
    "attributes": {
      "name": "Regionalmeisterschaft 2024",
      "start_date": "2024-01-15",
      "status": "active"
    },
    "relationships": {
      "discipline": {
        "data": {
          "id": 1,
          "type": "discipline"
        }
      }
    }
  }
}

Fehlerantworten

{
  "error": {
    "code": "validation_error",
    "message": "Validierung fehlgeschlagen",
    "details": {
      "name": ["darf nicht leer sein"]
    }
  }
}

Kern-Endpunkte

Turniere

Turniere auflisten

GET /tournaments

Abfrageparameter: - page: Seitennummer (Standard: 1) - per_page: Elemente pro Seite (Standard: 25) - status: Nach Status filtern (active, completed, draft) - discipline_id: Nach Disziplin filtern - location_id: Nach Standort filtern

Antwort:

{
  "data": [
    {
      "id": 1,
      "type": "tournament",
      "attributes": {
        "name": "Regionalmeisterschaft 2024",
        "start_date": "2024-01-15",
        "end_date": "2024-01-17",
        "status": "active",
        "discipline_name": "3-Banden",
        "location_name": "Billard Club Wedel"
      }
    }
  ],
  "meta": {
    "total_count": 50,
    "total_pages": 2,
    "current_page": 1
  }
}

Turnier abrufen

GET /tournaments/{id}

Antwort:

{
  "data": {
    "id": 1,
    "type": "tournament",
    "attributes": {
      "name": "Regionalmeisterschaft 2024",
      "start_date": "2024-01-15",
      "end_date": "2024-01-17",
      "status": "active",
      "discipline_name": "3-Banden",
      "location_name": "Billard Club Wedel",
      "participant_count": 16,
      "game_count": 24
    },
    "relationships": {
      "discipline": {
        "data": {
          "id": 1,
          "type": "discipline"
        }
      },
      "location": {
        "data": {
          "id": 1,
          "type": "location"
        }
      },
      "seedings": {
        "data": [
          {
            "id": 1,
            "type": "seeding"
          }
        ]
      }
    }
  }
}

Turnier erstellen

POST /tournaments

Anfrage-Body:

{
  "tournament": {
    "name": "Neues Turnier",
    "discipline_id": 1,
    "location_id": 1,
    "start_date": "2024-02-01",
    "end_date": "2024-02-03",
    "max_participants": 16
  }
}

Turnier aktualisieren

PATCH /tournaments/{id}

Turnier löschen

DELETE /tournaments/{id}

Turnier-Aktionen

Turnier starten

POST /tournaments/{id}/start

Turnier zurücksetzen

POST /tournaments/{id}/reset

Spielplan generieren

POST /tournaments/{id}/generate_game_plan

Spieler

Spieler auflisten

GET /players

Abfrageparameter: - page: Seitennummer - per_page: Elemente pro Seite - region_id: Nach Region filtern - club_id: Nach Club filtern - search: Nach Namen suchen

Spieler abrufen

GET /players/{id}

Antwort:

{
  "data": {
    "id": 1,
    "type": "player",
    "attributes": {
      "first_name": "Max",
      "last_name": "Mustermann",
      "ba_id": "12345",
      "club_name": "Billard Club Wedel",
      "region_name": "Schleswig-Holstein",
      "ranking": 1250
    }
  }
}

Ligen

Ligen auflisten

GET /leagues

Liga abrufen

GET /leagues/{id}

Liga-Teams

GET /leagues/{id}/league_teams

Parties (Spiele)

Parties auflisten

GET /parties

Abfrageparameter: - tournament_id: Nach Turnier filtern - league_id: Nach Liga filtern - status: Nach Status filtern - date: Nach Datum filtern

Party abrufen

GET /parties/{id}

Antwort:

{
  "data": {
    "id": 1,
    "type": "party",
    "attributes": {
      "date": "2024-01-15T14:00:00Z",
      "status": "in_progress",
      "team_a_name": "Team Alpha",
      "team_b_name": "Team Beta",
      "score_a": 3,
      "score_b": 2
    },
    "relationships": {
      "league_team_a": {
        "data": {
          "id": 1,
          "type": "league_team"
        }
      },
      "league_team_b": {
        "data": {
          "id": 2,
          "type": "league_team"
        }
      }
    }
  }
}

Tisch-Monitore

Tisch-Monitor abrufen

GET /table_monitors/{id}

Antwort:

{
  "data": {
    "id": 1,
    "type": "table_monitor",
    "attributes": {
      "table_number": 1,
      "status": "active",
      "current_game": {
        "id": 123,
        "player_a": "Max Mustermann",
        "player_b": "Erika Musterfrau",
        "score_a": 15,
        "score_b": 12,
        "balls_goal": 30
      }
    }
  }
}

Tisch-Monitor aktualisieren

PATCH /table_monitors/{id}

Anfrage-Body:

{
  "table_monitor": {
    "balls_a": 16,
    "balls_b": 12
  }
}

Tisch-Monitor-Aktionen

Punkte hinzufügen

POST /table_monitors/{id}/add_one
POST /table_monitors/{id}/add_ten

Punkte abziehen

POST /table_monitors/{id}/minus_one
POST /table_monitors/{id}/minus_ten

Nächster Schritt

POST /table_monitors/{id}/next_step

Spiel starten

POST /table_monitors/{id}/start_game

Ergebnis auswerten

POST /table_monitors/{id}/evaluate_result

Echtzeit-API

Action Cable Channels

Tisch-Monitor Channel

Abonnieren Sie Echtzeit-Tisch-Monitor-Updates:

import { createConsumer } from "@rails/actioncable"

const consumer = createConsumer()
const subscription = consumer.subscriptions.create(
  { channel: "TableMonitorChannel", table_id: 1 },
  {
    connected() {
      console.log("Mit Tisch-Monitor verbunden")
    },

    disconnected() {
      console.log("Von Tisch-Monitor getrennt")
    },

    received(data) {
      console.log("Update erhalten:", data)
      // UI mit neuen Daten aktualisieren
      updateTableDisplay(data)
    }
  }
)

Channel-Ereignisse: - score_update: Punkteänderungen - game_start: Neues Spiel gestartet - game_end: Spiel beendet - status_change: Tisch-Status geändert

Scoreboard Channel

Abonnieren Sie Scoreboard-Updates:

const scoreboardSubscription = consumer.subscriptions.create(
  { channel: "ScoreboardChannel", location_id: 1 },
  {
    received(data) {
      updateScoreboard(data)
    }
  }
)

WebSocket-Nachrichtenformat

{
  "type": "score_update",
  "table_id": 1,
  "data": {
    "player_a": "Max Mustermann",
    "player_b": "Erika Musterfrau",
    "score_a": 16,
    "score_b": 12,
    "balls_goal": 30,
    "status": "in_progress"
  },
  "timestamp": "2024-01-15T14:30:00Z"
}

Datensynchronisations-API

Externe Datenquellen

BA (Billard-Verband) Sync

POST /api/sync/ba/players
POST /api/sync/ba/tournaments

CC (Competition Center) Sync

POST /api/sync/cc/competitions
POST /api/sync/cc/results

Regionsverwaltung

Regionsdaten prüfen

GET /region_ccs/{id}/check

Regionsdaten reparieren

POST /region_ccs/{id}/fix

Admin-API

Benutzerverwaltung

GET /admin/users
POST /admin/users
PATCH /admin/users/{id}
DELETE /admin/users/{id}

Systemeinstellungen

GET /settings/club_settings
POST /settings/update_club_settings
GET /settings/tournament_settings
POST /settings/update_tournament_settings

Rate Limiting

API-Anfragen sind rate-limitiert, um Missbrauch zu verhindern:

  • Authentifizierte Benutzer: 1000 Anfragen pro Stunde
  • Nicht-authentifizierte Benutzer: 100 Anfragen pro Stunde

Rate-Limit-Header sind in Antworten enthalten:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1642248000

Paginierung

Listen-Endpunkte unterstützen Paginierung mit folgenden Parametern:

  • page: Seitennummer (Standard: 1)
  • per_page: Elemente pro Seite (Standard: 25, max: 100)

Paginierungs-Metadaten sind in Antworten enthalten:

{
  "data": [...],
  "meta": {
    "total_count": 150,
    "total_pages": 6,
    "current_page": 1,
    "per_page": 25
  }
}

Filterung und Sortierung

Filterung

Die meisten Listen-Endpunkte unterstützen Filterung:

GET /tournaments?status=active&discipline_id=1&location_id=2

Sortierung

Sortierung wird auf den meisten Endpunkten unterstützt:

GET /tournaments?sort=start_date&direction=desc
GET /players?sort=last_name&direction=asc

Fehlercodes

Code Beschreibung
400 Bad Request - Ungültige Parameter
401 Unauthorized - Authentifizierung erforderlich
403 Forbidden - Unzureichende Berechtigungen
404 Not Found - Ressource nicht gefunden
422 Unprocessable Entity - Validierungsfehler
429 Too Many Requests - Rate Limit überschritten
500 Internal Server Error

SDKs und Bibliotheken

JavaScript/TypeScript

npm install carambus-api-client
import { CarambusAPI } from 'carambus-api-client'

const api = new CarambusAPI({
  baseURL: 'https://carambus.de',
  credentials: 'include'
})

// Turniere abrufen
const tournaments = await api.tournaments.list()

// Turnier erstellen
const tournament = await api.tournaments.create({
  name: 'Neues Turnier',
  discipline_id: 1,
  location_id: 1
})

Ruby

require 'carambus_api'

client = CarambusAPI::Client.new(
  base_url: 'https://carambus.de',
  session_cookies: session_cookies
)

# Turniere abrufen
tournaments = client.tournaments.list

# Turnier erstellen
tournament = client.tournaments.create(
  name: 'Neues Turnier',
  discipline_id: 1,
  location_id: 1
)

Beispiele

Vollständiger Turnier-Workflow

// 1. Turnier erstellen
const tournament = await api.tournaments.create({
  name: 'Meisterschaft 2024',
  discipline_id: 1,
  location_id: 1,
  start_date: '2024-02-01',
  max_participants: 16
})

// 2. Teilnehmer hinzufügen
for (const player of players) {
  await api.tournaments.addParticipant(tournament.id, player.id)
}

// 3. Spielplan generieren
await api.tournaments.generateGamePlan(tournament.id)

// 4. Turnier starten
await api.tournaments.start(tournament.id)

// 5. Echtzeit-Updates abonnieren
const subscription = consumer.subscriptions.create(
  { channel: "TournamentChannel", tournament_id: tournament.id },
  {
    received(data) {
      updateTournamentDisplay(data)
    }
  }
)

Echtzeit-Scoreboard-Integration

// Mit Scoreboard verbinden
const scoreboard = consumer.subscriptions.create(
  { channel: "ScoreboardChannel", location_id: 1 },
  {
    received(data) {
      // Scoreboard-Anzeige aktualisieren
      document.getElementById('scoreboard').innerHTML = 
        generateScoreboardHTML(data)
    }
  }
)

// Tisch-Punkte aktualisieren
async function updateScore(tableId, player, points) {
  await api.tableMonitors.update(tableId, {
    [`balls_${player}`]: points
  })
}

Support

Für API-Support und Fragen:


Diese API-Dokumentation wird vom Carambus-Entwicklungsteam gepflegt. Für Fragen oder Beiträge siehe den Beitragsleitfaden.