Überblick#
MusicVoting besteht aus einem Quarkus-Backend, einem Angular-Frontend (mit drei Rollen-Ansichten), einer PostgreSQL-Datenbank und einer optionalen SwiftUI-iOS-App. Die Musik wird über den Spotify Web Playback SDK im Browser des Monitors/TVs abgespielt.
Komponenten#
| Komponente | Technologie | Aufgabe |
|---|---|---|
| Backend | Quarkus (Java 21), JAX-RS, SSE | API, Party-Lebenszyklus, Provider-Anbindung |
| Frontend | Angular | Guest-, Host- und TV-Ansichten |
| Datenbank | PostgreSQL 16, Hibernate ORM Panache | Persistenz von Party, Queue, Votes |
| Mobile | SwiftUI (iOS) | Native Guest- und Admin-Ansicht (optional) |
| Provider | Spotify Web API + Web Playback SDK | Suche und Wiedergabe |
Wichtige Architekturentscheidungen#
- DB ist die Quelle der Wahrheit. Queue, aktueller Track und Fortschritt kommen aus der
Datenbank, nicht aus Spotify.
GET /track/currentruft die Spotify-„currently-playing“-API nicht auf (siehe Datenbankschema und die Playback-Spec). Partyvs.PartyEntity.Partyist die In-Memory-Repräsentation in derPartyRegistry,PartyEntitydie Panache-Entity der DB-Tabelleparty. Sie sind bewusst getrennt und werden nicht zusammengeführt.- Restart-fest. Endpunkte lösen eine Party bei Bedarf aus der DB auf, wenn sie nicht in der In-Memory-Registry liegt – ein Backend-Neustart führt nicht zu 404.
- Ein Provider pro Party. Über
ProviderKind(Spotify implementiert, YouTube vorgesehen), abstrahiert durch dasMusicProvider-Interface und dieMusicProviderFactory. - Live-Updates über SSE, nicht über Polling (siehe Realtime / SSE).
Datenfluss (Beispiel: Gast fügt einen Song hinzu)#
- Gast sucht (
GET /api/party/{id}/track/search?q=…) → Spotify-Treffer. - Gast tippt „+“ →
POST /api/party/{id}/track/addToPlaylist. - Backend schreibt eine
queue_entry-Zeile und sendet einqueue-updated-SSE-Event. - Alle verbundenen Clients (TV, Host, andere Gäste) laden die Queue neu.
Hintergrundprozesse#
PartyExpirySchedulerbeendet Partys automatisch nach 2 Tagen und löscht beendete Partys 1 Monat nachendedAt(siehe Datenbankschema).