// Создано: 2026-04-12 // Handler — контейнер зависимостей для IoT REST handlers. // Упрощённая версия из sless — только IoT-специфичные поля. // // Бизнес-логика: // - iot_device_handler.go — CRUD устройств + MQTT auth // - iot_telemetry_handler.go — чтение телеметрии // - iot_admin_stats_handler.go — админ-статистика package handler import ( "encoding/json" "log/slog" "net/http" "github.com/gorilla/mux" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" "gitea.services.ngcloud.ru/Nail/IoT/internal/storage/iotpg" ) // defaultNamespace — fallback namespace для dev/тестов. const defaultNamespace = "default" // Handler содержит зависимости для всех IoT REST-обработчиков. type Handler struct { K8s client.Client Scheme *runtime.Scheme // IoTPG — хранилище IoT телеметрии (per-tenant Postgres). nil если IOT_PG_DSN не задан. IoTPG *iotpg.IoTPostgresStore // KafkaBrokers — адреса Kafka брокеров для чтения consumer lag на admin странице. KafkaBrokers string Log *slog.Logger } // writeJSON отправляет JSON-ответ с указанным статусом. func writeJSON(w http.ResponseWriter, status int, v any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(v) } // errResp возвращает структуру ошибки для JSON. func errResp(msg string) map[string]string { return map[string]string{"error": msg} } // pathVar читает переменную пути из gorilla/mux. func pathVar(r *http.Request, key string) string { return mux.Vars(r)[key] } // namespace читает {namespace} из пути URL. func namespace(r *http.Request) string { if ns := mux.Vars(r)["namespace"]; ns != "" { return ns } return defaultNamespace }