hub: actually send start/stop commands over MQTT
Build (Dev) / build (push) Successful in 11s
CI / quality (push) Successful in 11s
CI / quality (pull_request) Successful in 11s

The /cameras/{id}/start and /stop handlers only wrote a recording_events
row — they never published the command, so the camera never recorded.
Add Subscriber.PublishCommand (publishes {"command":...} to
remoterig/cameras/<id>/command, which the XIAO forwards to the ESP-01S),
thread a CommandPublisher into the recording handlers, and wire mqttSub in
via apiRouter. Tests pass nil (publish skipped).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Joshua King
2026-06-05 20:28:26 -04:00
parent b1ed8cdb20
commit d538dd3b70
4 changed files with 44 additions and 8 deletions
+4 -4
View File
@@ -89,7 +89,7 @@ func main() {
})
// API routes (auth required if API key is configured)
r.Mount("/api/v1", auth.Middleware(cfg.APIKey)(apiRouter(sseHub, sqlDB)))
r.Mount("/api/v1", auth.Middleware(cfg.APIKey)(apiRouter(sseHub, sqlDB, mqttSub)))
// Serve embedded React frontend with SPA fallback
r.Mount("/", frontendHandler())
@@ -122,7 +122,7 @@ func main() {
}
// apiRouter creates the API route tree.
func apiRouter(sseHub *events.Hub, database *db.DB) http.Handler {
func apiRouter(sseHub *events.Hub, database *db.DB, pub api.CommandPublisher) http.Handler {
r := chi.NewRouter()
// Camera management routes
@@ -131,8 +131,8 @@ func apiRouter(sseHub *events.Hub, database *db.DB) http.Handler {
r.Get("/cameras/{id}", api.GetCameraDetail(database))
// Recording control routes
r.Post("/cameras/{id}/start", api.StartRecording(database))
r.Post("/cameras/{id}/stop", api.StopRecording(database))
r.Post("/cameras/{id}/start", api.StartRecording(database, pub))
r.Post("/cameras/{id}/stop", api.StopRecording(database, pub))
// Status ingestion (from ESP32 nodes)
r.Post("/cameras/{id}/status", api.PushStatus(database))