Преглед на файлове

feat: expose dry-run summary via control api

tags/v0.3.0-pre
Jan Svabenik преди 1 месец
родител
ревизия
dc32142cf2
променени са 3 файла, в които са добавени 40 реда и са изтрити 4 реда
  1. +2
    -0
      docs/README.md
  2. +21
    -4
      internal/control/control.go
  3. +17
    -0
      internal/control/control_test.go

+ 2
- 0
docs/README.md Целия файл

@@ -23,6 +23,8 @@
The dry-run mode generates a synthetic, hardware-free frame summary based on the current config.
It is intended as a no-hardware smoke path for the CLI and config/control-adjacent logic.

The HTTP control plane also exposes `GET /dry-run` for quick inspection of the currently effective no-hardware summary.

## Offline generation

`cmd/offline` generates a deterministic no-hardware IQ/composite-style file using the repository's output backend path.


+ 21
- 4
internal/control/control.go Целия файл

@@ -3,11 +3,14 @@ package control
import (
"encoding/json"
"net/http"
"sync"

"github.com/jan/fm-rds-tx/internal/config"
drypkg "github.com/jan/fm-rds-tx/internal/dryrun"
)

type Server struct {
mu sync.RWMutex
cfg config.Config
}

@@ -17,6 +20,7 @@ func (s *Server) Handler() http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/healthz", s.handleHealth)
mux.HandleFunc("/status", s.handleStatus)
mux.HandleFunc("/dry-run", s.handleDryRun)
return mux
}

@@ -26,12 +30,25 @@ func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request) {
}

func (s *Server) handleStatus(w http.ResponseWriter, _ *http.Request) {
s.mu.RLock()
cfg := s.cfg
s.mu.RUnlock()

w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{
"service": "fm-rds-tx",
"backend": s.cfg.Backend.Kind,
"frequencyMHz": s.cfg.FM.FrequencyMHz,
"stereoEnabled": s.cfg.FM.StereoEnabled,
"rdsEnabled": s.cfg.RDS.Enabled,
"backend": cfg.Backend.Kind,
"frequencyMHz": cfg.FM.FrequencyMHz,
"stereoEnabled": cfg.FM.StereoEnabled,
"rdsEnabled": cfg.RDS.Enabled,
})
}

func (s *Server) handleDryRun(w http.ResponseWriter, _ *http.Request) {
s.mu.RLock()
cfg := s.cfg
s.mu.RUnlock()

w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(drypkg.Generate(cfg))
}

+ 17
- 0
internal/control/control_test.go Целия файл

@@ -35,3 +35,20 @@ func TestStatus(t *testing.T) {
t.Fatalf("unexpected service: %v", body["service"])
}
}

func TestDryRunEndpoint(t *testing.T) {
srv := NewServer(cfgpkg.Default())
req := httptest.NewRequest(http.MethodGet, "/dry-run", nil)
rec := httptest.NewRecorder()
srv.Handler().ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("unexpected status: %d", rec.Code)
}
var body map[string]any
if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil {
t.Fatalf("decode body: %v", err)
}
if body["mode"] != "dry-run" {
t.Fatalf("unexpected mode: %v", body["mode"])
}
}

Loading…
Отказ
Запис