# ADR-002: Zentraler Auth-Client

**Status:** Akzeptiert
**Datum:** 2025-10-08
**Kontext:** PoC questra-data Python Package

## Kontext und Problemstellung

Das questra-data Package interagiert mit mehreren GraphQL-Endpoints (dyno, dynamic, etc.). Jeder dieser Endpoints benötigt Authentifizierung über OAuth2-Tokens.

Die Frage ist: Soll jeder GraphQL-Client seine eigene Authentifizierung verwalten, oder sollte es einen zentralen Auth-Client geben?

## Entscheidung

Wir verwenden einen **zentralen Auth-Client**, der in die einzelnen GraphQL-Clients hineingereicht wird (Dependency Injection).

## Begründung

### Pro

- **Weniger Authentifizierungen:** Token-Refresh und Login müssen nur einmal statt mehrfach pro Client durchgeführt werden
- **Einheitliches Token-Handling:** Token-Refresh, Expiry-Checks und Retry-Logic an zentraler Stelle
- **Bessere Testbarkeit:** Ein Mock für Auth reicht aus, um alle Clients zu testen
- **Single Responsibility:** Auth-Logik ist gekapselt und nicht über mehrere Clients verteilt
- **Einfachere Konfiguration:** Credentials müssen nur einmal übergeben werden
- **Konsistentes Fehlerhandling:** Auth-Fehler (401, 403) werden zentral behandelt
- **Performance:** Token wird wiederverwendet, keine redundanten Auth-Requests

### Contra

- **Zusätzliche Abstraktion:** Eine weitere Komponente in der Architektur
- **Shared State:** Token-State wird zwischen Clients geteilt (bei Multi-Threading ggf. problematisch)
- **Dependency Injection erforderlich:** Clients müssen Auth-Client als Parameter entgegennehmen
- **Zentraler Failure Point:** Wenn Auth-Client fehlerhaft ist, sind alle Clients betroffen

## Alternativen

### Dezentrale Authentifizierung pro Client

- **Pro:** Jeder Client ist unabhängig, keine Shared State
- **Contra:** Code-Duplikation, mehrfache Logins, inkonsistentes Token-Handling

### Globale Singleton-Instanz

- **Pro:** Einfacher Zugriff ohne Dependency Injection
- **Contra:** Schwer testbar, globaler Zustand, Import-Dependencies

## Konsequenzen

### Positiv

- Reduzierte Netzwerk-Requests durch Token-Wiederverwendung
- Zentrales Monitoring und Logging von Auth-Ereignissen
- Einfachere Unit-Tests durch Mock-Injection
- Klarere Verantwortlichkeiten (Separation of Concerns)

### Negativ

- Auth-Client muss Thread-Safe implementiert werden (bei parallelen Requests)
- Breaking Change bei späterer Umstellung auf dezentrale Auth

## Implementation

```python
# Zentraler Auth-Client
auth_client = AuthClient(
    client_id="...",
    client_secret="...",
    token_url="..."
)

# Injection in GraphQL-Clients
dyno_client = DynoClient(auth_client=auth_client)
dynamic_client = DynamicClient(auth_client=auth_client)
```

## Notizen

Diese Entscheidung folgt dem Dependency Injection Pattern und ermöglicht bessere Testbarkeit und Wartbarkeit. Bei Multi-Threading-Szenarien muss Thread-Safety des Auth-Clients sichergestellt werden (z.B. durch Locks beim Token-Refresh).
