Store each client's play queue in the database

The queue lived in memory and was shared by all clients, so a restart or a
finished sync cleared it. Every client now has its own queue in the new
queue and queue_song tables (added to the undeployed migration 000006).

The music endpoints return the queue ID in the X-Queue-Id header and expect
it back. A request without an ID, or with an ended one, starts a new queue.
/music/reset ends the queue and returns a new ID, and a sync ends all
running queues. Ended queues are kept as history.

The deprecated legacy routes without the /api/v1 prefix are removed.
This commit is contained in:
Sansan committed 2026-10-07 20:03:03 +02:00
1 parent b5dc42b654
commit a705d7b476
28 files changed
+1103 -320

No files matched your search

+7 -7
View File
@@ -24,10 +24,10 @@ func (s *Server) RegisterRoutes() http.Handler {
// the handlers are registered but never called.
func OpenAPISpec() *huma.OpenAPI {
_, a := (&Server{}).routes()
return a.v1.OpenAPI()
return a.OpenAPI()
}
func (s *Server) routes() (*echo.Echo, apis) {
func (s *Server) routes() (*echo.Echo, huma.API) {
e := echo.New()
e.HTTPErrorHandler = httpErrorHandler
if len(s.cfg.TrustedProxies) > 0 {
@@ -43,15 +43,15 @@ func (s *Server) routes() (*echo.Echo, apis) {
e.Use(echoMiddleware.CORSWithConfig(echoMiddleware.CORSConfig{
AllowOrigins: []string{"https://*", "http://*"},
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
AllowHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
AllowHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", middleware.QueueHeader},
ExposeHeaders: []string{middleware.QueueHeader},
AllowCredentials: true,
MaxAge: 300,
}))
// The API: /api/v1 is documented at /docs and /openapi.json; legacy routes are hidden.
a := newAPIs(e)
a.v1.UseMiddleware(middleware.ClientInfo, middleware.TokenAuth(a.v1, s.q, s.cfg.DisableSessionAuth))
a.legacy.UseMiddleware(middleware.ClientInfo, middleware.Deprecation)
// The API: /api/v1 is documented at /docs and /openapi.json.
a := newAPI(e)
a.UseMiddleware(middleware.ClientInfo, middleware.TokenAuth(a, s.q, s.cfg.DisableSessionAuth))
s.registerToken(a)
s.registerMisc(a)
s.registerSync(a)