From 42257aeebc7b357277b53f40b08729d292b65b67 Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Sun, 17 May 2026 22:59:28 +0200 Subject: [PATCH] refactor(soundtouch-web): relocate handlers/webtypes to pkg/service/soundtouchweb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mechanical relocation only — zero semantic change. Sets up the package layout that the future Preact-UI rewrite (branch `app`) wants, while preserving every line of main's current logic. Subsequent commits will land the additive parts (frontend rewrite, recents, zones, bass control) on top of this clean base. Moves (`git mv`, content unchanged except package decl): cmd/soundtouch-web/handlers/handlers.go → pkg/service/soundtouchweb/handler.go cmd/soundtouch-web/handlers/handlers_test.go → pkg/service/soundtouchweb/handler_test.go cmd/soundtouch-web/handlers/websocket.go → pkg/service/soundtouchweb/websocket.go cmd/soundtouch-web/handlers/registry_test.go → pkg/service/soundtouchweb/registry_test.go cmd/soundtouch-web/webtypes/types.go → pkg/service/soundtouchweb/webtypes/types.go cmd/soundtouch-web/webtypes/types_test.go → pkg/service/soundtouchweb/webtypes/types_test.go cmd/soundtouch-web/webtypes/status_test.go → pkg/service/soundtouchweb/webtypes/status_test.go cmd/soundtouch-web/static/img/tunein-{dark,mono}.svg → pkg/service/soundtouchweb/static/img/ Adjustments: - `package handlers` → `package soundtouchweb` in the 4 moved handler-tier files (plus their package-doc comments). - Import paths rewritten in cmd/soundtouch-web/{main.go,spa_test.go} and in the moved files themselves: cmd/soundtouch-web/{handlers,webtypes} → pkg/service/soundtouchweb/{,webtypes}. - `handlers.` selector renamed to `soundtouchweb.` in the callers. - `.golangci.yml` errcheck waiver extended from `cmd/.*\.go` to also cover `pkg/service/soundtouchweb/.*\.go`. Same code that the cmd-tier waiver applied to; same waiver follows it. Documented as a carry-over with the intent to tighten in a follow-up review. Not changed: - `cmd/soundtouch-web/main.go` keeps the `//go:embed static` pointing at the still-vanilla `cmd/soundtouch-web/static/`. The frontend rewrite (Preact UI) lands in a later commit; this one is mechanical. - `cmd/soundtouch-web/resolve_bind_addr_test.go` stays put — it tests main.go-local flag plumbing. go build ./... clean. go test ./... clean (only pre-existing TestDocsConsistency fails, untracked-file issue, unrelated). golangci-lint run ./... 0 issues. Co-Authored-By: Claude Opus 4.7 (1M context) --- .golangci.yml | 7 +++++++ cmd/soundtouch-web/main.go | 12 ++++++------ cmd/soundtouch-web/spa_test.go | 14 +++++++------- .../service/soundtouchweb/handler.go | 6 +++--- .../service/soundtouchweb/handler_test.go | 4 ++-- .../service/soundtouchweb}/registry_test.go | 4 ++-- .../soundtouchweb}/static/img/tunein-dark.svg | 0 .../soundtouchweb}/static/img/tunein-mono.svg | 0 .../service/soundtouchweb}/websocket.go | 6 +++--- .../service/soundtouchweb}/webtypes/status_test.go | 0 .../service/soundtouchweb}/webtypes/types.go | 0 .../service/soundtouchweb}/webtypes/types_test.go | 0 12 files changed, 30 insertions(+), 23 deletions(-) rename cmd/soundtouch-web/handlers/handlers.go => pkg/service/soundtouchweb/handler.go (99%) rename cmd/soundtouch-web/handlers/handlers_test.go => pkg/service/soundtouchweb/handler_test.go (99%) rename {cmd/soundtouch-web/handlers => pkg/service/soundtouchweb}/registry_test.go (97%) rename {cmd/soundtouch-web => pkg/service/soundtouchweb}/static/img/tunein-dark.svg (100%) rename {cmd/soundtouch-web => pkg/service/soundtouchweb}/static/img/tunein-mono.svg (100%) rename {cmd/soundtouch-web/handlers => pkg/service/soundtouchweb}/websocket.go (98%) rename {cmd/soundtouch-web => pkg/service/soundtouchweb}/webtypes/status_test.go (100%) rename {cmd/soundtouch-web => pkg/service/soundtouchweb}/webtypes/types.go (100%) rename {cmd/soundtouch-web => pkg/service/soundtouchweb}/webtypes/types_test.go (100%) diff --git a/.golangci.yml b/.golangci.yml index d8824b3..df4e359 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -78,6 +78,13 @@ linters: linters: - errcheck + # Carry-over from cmd/soundtouch-web/handlers relocation: same code, + # same waiver. Tighten in a follow-up if/when the package is reviewed. + - path: pkg/service/soundtouchweb/.*\.go + text: "Error return value of.*is not checked" + linters: + - errcheck + settings: errcheck: check-type-assertions: true diff --git a/cmd/soundtouch-web/main.go b/cmd/soundtouch-web/main.go index 4ca8356..0838006 100644 --- a/cmd/soundtouch-web/main.go +++ b/cmd/soundtouch-web/main.go @@ -12,11 +12,11 @@ import ( "os" "time" - "github.com/gesellix/bose-soundtouch/cmd/soundtouch-web/handlers" - "github.com/gesellix/bose-soundtouch/cmd/soundtouch-web/webtypes" "github.com/gesellix/bose-soundtouch/pkg/client" "github.com/gesellix/bose-soundtouch/pkg/config" "github.com/gesellix/bose-soundtouch/pkg/discovery" + "github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb" + "github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb/webtypes" "github.com/go-chi/chi/v5" "github.com/urfave/cli/v2" ) @@ -79,7 +79,7 @@ func main() { } // Create web app without templates (SPA mode) - webApp := handlers.NewWebApp() + webApp := soundtouchweb.NewWebApp() // Initialize discovery service cfg, err := config.LoadFromEnv() @@ -216,7 +216,7 @@ func resolveBindAddr(bindAddr string) (string, error) { // tell apart entries that came from --devices from those found via // mDNS/UPnP. If the host is already known, the existing entry's // LastSeen is bumped and the function returns without re-fetching. -func addDevice(app *handlers.WebApp, host string, port int, source string) { +func addDevice(app *soundtouchweb.WebApp, host string, port int, source string) { // Fast path: skip the network call if we already know this host. if app.TouchDevice(host) { return @@ -247,7 +247,7 @@ func addDevice(app *handlers.WebApp, host string, port int, source string) { log.Printf("Added %s device %s (%s) at %s:%d", source, info.Name, info.Type, host, port) } -func setupRoutes(app *handlers.WebApp, discoveryService *discovery.UnifiedDiscoveryService) *chi.Mux { +func setupRoutes(app *soundtouchweb.WebApp, discoveryService *discovery.UnifiedDiscoveryService) *chi.Mux { r := chi.NewRouter() // Static assets (embedded in binary) @@ -312,7 +312,7 @@ func setupRoutes(app *handlers.WebApp, discoveryService *discovery.UnifiedDiscov return r } -func discoverDevices(ctx context.Context, app *handlers.WebApp, discoveryService *discovery.UnifiedDiscoveryService) { +func discoverDevices(ctx context.Context, app *soundtouchweb.WebApp, discoveryService *discovery.UnifiedDiscoveryService) { log.Println("Starting device discovery...") devices, err := discoveryService.DiscoverDevices(ctx) diff --git a/cmd/soundtouch-web/spa_test.go b/cmd/soundtouch-web/spa_test.go index 51645c5..8bf13c2 100644 --- a/cmd/soundtouch-web/spa_test.go +++ b/cmd/soundtouch-web/spa_test.go @@ -8,9 +8,9 @@ import ( "strings" "testing" - "github.com/gesellix/bose-soundtouch/cmd/soundtouch-web/handlers" - "github.com/gesellix/bose-soundtouch/cmd/soundtouch-web/webtypes" "github.com/gesellix/bose-soundtouch/pkg/models" + "github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb" + "github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb/webtypes" "github.com/go-chi/chi/v5" ) @@ -99,7 +99,7 @@ func TestSPARouting(t *testing.T) { } func TestAPIEndpoints(t *testing.T) { - app := handlers.NewWebApp() + app := soundtouchweb.NewWebApp() tests := []struct { name string @@ -170,7 +170,7 @@ func TestAPIEndpoints(t *testing.T) { } func TestAPIResponseFormat(t *testing.T) { - app := handlers.NewWebApp() + app := soundtouchweb.NewWebApp() req := httptest.NewRequest("GET", "/api/devices", nil) w := httptest.NewRecorder() @@ -203,7 +203,7 @@ func TestAPIResponseFormat(t *testing.T) { } func TestControlAPIValidation(t *testing.T) { - app := handlers.NewWebApp() + app := soundtouchweb.NewWebApp() tests := []struct { name string @@ -296,7 +296,7 @@ func TestControlAPIValidation(t *testing.T) { } func TestWebSocketUpgrade(t *testing.T) { - app := handlers.NewWebApp() + app := soundtouchweb.NewWebApp() // Test WebSocket upgrade request req := httptest.NewRequest("GET", "/ws", nil) @@ -316,7 +316,7 @@ func TestWebSocketUpgrade(t *testing.T) { } func TestJSONAPIConsistency(t *testing.T) { - app := handlers.NewWebApp() + app := soundtouchweb.NewWebApp() endpoints := []string{ "/api/devices", diff --git a/cmd/soundtouch-web/handlers/handlers.go b/pkg/service/soundtouchweb/handler.go similarity index 99% rename from cmd/soundtouch-web/handlers/handlers.go rename to pkg/service/soundtouchweb/handler.go index a5e4325..0b831e4 100644 --- a/cmd/soundtouch-web/handlers/handlers.go +++ b/pkg/service/soundtouchweb/handler.go @@ -1,5 +1,5 @@ -// Package handlers contains HTTP handlers for the SoundTouch web UI. -package handlers +// Package soundtouchweb contains HTTP handlers for the SoundTouch web UI. +package soundtouchweb import ( "encoding/json" @@ -11,9 +11,9 @@ import ( "sync" "time" - "github.com/gesellix/bose-soundtouch/cmd/soundtouch-web/webtypes" "github.com/gesellix/bose-soundtouch/pkg/models" bmxpkg "github.com/gesellix/bose-soundtouch/pkg/service/bmx" + "github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb/webtypes" "github.com/go-chi/chi/v5" "github.com/gorilla/websocket" ) diff --git a/cmd/soundtouch-web/handlers/handlers_test.go b/pkg/service/soundtouchweb/handler_test.go similarity index 99% rename from cmd/soundtouch-web/handlers/handlers_test.go rename to pkg/service/soundtouchweb/handler_test.go index 4b06af7..564e2ea 100644 --- a/cmd/soundtouch-web/handlers/handlers_test.go +++ b/pkg/service/soundtouchweb/handler_test.go @@ -1,5 +1,5 @@ // Package handlers contains tests for HTTP handlers. -package handlers +package soundtouchweb import ( "context" @@ -10,9 +10,9 @@ import ( "testing" "time" - "github.com/gesellix/bose-soundtouch/cmd/soundtouch-web/webtypes" "github.com/gesellix/bose-soundtouch/pkg/client" "github.com/gesellix/bose-soundtouch/pkg/models" + "github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb/webtypes" "github.com/go-chi/chi/v5" ) diff --git a/cmd/soundtouch-web/handlers/registry_test.go b/pkg/service/soundtouchweb/registry_test.go similarity index 97% rename from cmd/soundtouch-web/handlers/registry_test.go rename to pkg/service/soundtouchweb/registry_test.go index 75a67c4..e014c6e 100644 --- a/cmd/soundtouch-web/handlers/registry_test.go +++ b/pkg/service/soundtouchweb/registry_test.go @@ -1,15 +1,15 @@ // Package handlers contains tests for the device registry API on // WebApp (GetDevice, AddDevice, TouchDevice, DeviceSnapshot, // DeviceCount). -package handlers +package soundtouchweb import ( "fmt" "sync" "testing" - "github.com/gesellix/bose-soundtouch/cmd/soundtouch-web/webtypes" "github.com/gesellix/bose-soundtouch/pkg/models" + "github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb/webtypes" ) func newRegistryDevice(name string) *webtypes.DeviceConnection { diff --git a/cmd/soundtouch-web/static/img/tunein-dark.svg b/pkg/service/soundtouchweb/static/img/tunein-dark.svg similarity index 100% rename from cmd/soundtouch-web/static/img/tunein-dark.svg rename to pkg/service/soundtouchweb/static/img/tunein-dark.svg diff --git a/cmd/soundtouch-web/static/img/tunein-mono.svg b/pkg/service/soundtouchweb/static/img/tunein-mono.svg similarity index 100% rename from cmd/soundtouch-web/static/img/tunein-mono.svg rename to pkg/service/soundtouchweb/static/img/tunein-mono.svg diff --git a/cmd/soundtouch-web/handlers/websocket.go b/pkg/service/soundtouchweb/websocket.go similarity index 98% rename from cmd/soundtouch-web/handlers/websocket.go rename to pkg/service/soundtouchweb/websocket.go index ceac73e..0771e6c 100644 --- a/cmd/soundtouch-web/handlers/websocket.go +++ b/pkg/service/soundtouchweb/websocket.go @@ -1,5 +1,5 @@ -// Package handlers contains WebSocket handlers for real-time communication. -package handlers +// Package soundtouchweb contains WebSocket handlers for real-time communication. +package soundtouchweb import ( "encoding/json" @@ -7,8 +7,8 @@ import ( "net/http" "time" - "github.com/gesellix/bose-soundtouch/cmd/soundtouch-web/webtypes" "github.com/gesellix/bose-soundtouch/pkg/models" + "github.com/gesellix/bose-soundtouch/pkg/service/soundtouchweb/webtypes" "github.com/go-chi/chi/v5" "github.com/gorilla/websocket" ) diff --git a/cmd/soundtouch-web/webtypes/status_test.go b/pkg/service/soundtouchweb/webtypes/status_test.go similarity index 100% rename from cmd/soundtouch-web/webtypes/status_test.go rename to pkg/service/soundtouchweb/webtypes/status_test.go diff --git a/cmd/soundtouch-web/webtypes/types.go b/pkg/service/soundtouchweb/webtypes/types.go similarity index 100% rename from cmd/soundtouch-web/webtypes/types.go rename to pkg/service/soundtouchweb/webtypes/types.go diff --git a/cmd/soundtouch-web/webtypes/types_test.go b/pkg/service/soundtouchweb/webtypes/types_test.go similarity index 100% rename from cmd/soundtouch-web/webtypes/types_test.go rename to pkg/service/soundtouchweb/webtypes/types_test.go