From 76c11d5476ebb0800f307fffc257652396583429 Mon Sep 17 00:00:00 2001 From: Naeel Date: Tue, 21 Apr 2026 07:20:12 +0300 Subject: [PATCH] fix: rename query param device->device_id in telemetry API (v0.2.6) - GET /telemetry?device_id= now consistently uses device_id - was: ?device= (inconsistent with response field name) - found during extended test suite --- .github/copilot-instructions.md | 205 +----------------- .github/pravila.md | 56 +++++ deployments/k8s/iot-mqtt-bridge.yaml | 2 +- deployments/k8s/iot-operator.yaml | 4 +- deployments/k8s/iot-sqs-consumer.yaml | 2 +- internal/api/handler/iot_telemetry_handler.go | 2 +- 6 files changed, 69 insertions(+), 202 deletions(-) create mode 100644 .github/pravila.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 59c5272..18abd2e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,199 +1,10 @@ -# Правила работы агента в проекте IoT +# Правила -## ГЛАВНОЕ ПРАВИЛО +> Подробные правила: [`.github/pravila.md`](pravila.md) -**НЕ "СОВЕРШЕНСТВОВАТЬ" РАБОЧИЙ КОД БЕЗ ЯВНОГО УКАЗАНИЯ.** - ---- - -## ЗАПРЕТ НА ВЫДУМКИ - -**КАТЕГОРИЧЕСКИ ЗАПРЕЩАЕТСЯ придумывать, догадываться или предполагать:** -- значения параметров, которые не видны в коде или документации -- допустимые значения enum/ролей/типов — если не взяты из реального источника -- поведение API, провайдеров, библиотек — если не подтверждено кодом или документацией -- любые факты о системе, которые агент "знает" из общих соображений - -**Если информации нет — спросить у пользователя. Не угадывать.** - -Если код работает — не трогать. Никаких: -- рефакторингов "попутно" -- улучшений стиля -- добавления комментариев / docstring -- переименований переменных -- "пока уж заодно поправлю" - -Делай только то, о чём явно попросили. Ничего лишнего. - ---- - -## 🚫 ДОКУМЕНТАЦИЮ НЕ СТИРАТЬ — ТОЛЬКО ДОПОЛНЯТЬ - -**СТРОГОЕ ПРАВИЛО: любую документацию в `doc/` ЗАПРЕЩЕНО удалять или перезаписывать.** - -- Старый текст — это база знаний. Даже если он устарел (Kafka, RabbitMQ, и т.д.) — он остаётся. -- Новую информацию **дописывать** в конец файла или добавлять новые секции с датой. -- Если архитектура изменилась — добавить секцию `## Актуальная архитектура (ГГГГ-ММ-ДД)`, НЕ удаляя старую. -- Если решение отменено — не стирать, а добавить пометку `> ⚠️ Отменено ГГГГ-ММ-ДД: причина`. - -Это касается ВСЕХ файлов в `doc/`, включая `progress.md`, `decisions/`, `thinking/`, `api/`, `architecture/`. - ---- - -## ⚠️ ФАЙЛОВАЯ СИСТЕМА — ОБЩАЯ - -**`~/remote_dev/` на локальной машине = `~/terra/` на ВМ. Это одна и та же файловая система (монтирование).** - -- Редактирование файлов через VS Code автоматически видно на ВМ. **НЕ копировать файлы через scp.** -- Пример: `/home/naeel/remote_dev/IoT/` === `/home/naeel/terra/IoT/` на ВМ. -- Файлы редактировать ТОЛЬКО через SSH на ВМ. НЕ использовать VS Code инструменты (replace_string_in_file, create_file и т.д.). -- Команды (git, go, docker, kubectl) — тоже ТОЛЬКО через SSH на ВМ. - ---- - -## ⚠️ ВЫПОЛНЕНИЕ КОМАНД — ТОЛЬКО НА УДАЛЁННОЙ МАШИНЕ - -- Все команды (git, go, docker, kubectl, make и т.д.) выполнять **ТОЛЬКО на удалённой машине** через SSH. -- **На локальной машине команды не запускать вообще.** -- Если для задачи необходимо выполнить что-то локально — **спросить явное разрешение у пользователя** перед запуском. - -### Параметры удалённой машины - -| Параметр | Значение | -|---|---| -| Хост | `5.172.178.213` | -| Пользователь | `naeel` | -| SSH-ключ | `~/.ssh/id_ed25519` | -| Рабочий каталог | `/home/naeel/terra/IoT` | - -### Шаблон команды - -```bash -ssh -i ~/.ssh/id_ed25519 \ - -o StrictHostKeyChecking=no \ - -o ConnectTimeout=10 \ - naeel@5.172.178.213 \ - 'cd /home/naeel/terra/IoT && <КОМАНДА>' -``` - -### Примеры - -```bash -# git статус -ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 \ - 'cd /home/naeel/terra/IoT && git status' - -# commit + push -ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 \ - 'cd /home/naeel/terra/IoT && git add -A && git commit -m "..." && git push' - -# сборка go -ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 \ - 'cd /home/naeel/terra/IoT && go build ./...' -``` - -### Git / Gitea - -- Remote: `https://gitea.services.ngcloud.ru/Nail/IoT.git` (HTTPS) -- SSH до Gitea **недоступен** с удалённой машины — использовать только HTTPS. -- Credentials сохранены на удалённой машине в `~/.git-credentials`. - ---- - -## О проекте - -IoT managed service — отдельная репа, вынесенная из sless. -Go модуль: `gitea.services.ngcloud.ru/Nail/IoT` -Репа: https://gitea.services.ngcloud.ru/Nail/IoT - -### Компоненты (3 бинарника из одного образа): -1. **iot-operator** (`cmd/iot-operator/`) — controller-manager (IoTDevice CRD) + REST API на :9090 -2. **mqtt-bridge** (`cmd/mqtt-bridge/`) — MQTT (EMQX) → Kafka bridge -3. **kafka-consumer** (`cmd/kafka-consumer/`) — Kafka → Postgres pipeline - -### Стек: -- Go 1.25, controller-runtime v0.14, gorilla/mux -- CRD: `iot.kube5s.ru/v1alpha1` (IoTDevice) -- EMQX — MQTT брокер, Kafka — очередь телеметрии -- PostgreSQL — per-tenant databases для телеметрии -- Docker Hub: `naeel/iot-operator` - -### Структура: -``` -cmd/iot-operator/ — точка входа (controller + API сервер) -cmd/mqtt-bridge/ — MQTT→Kafka bridge -cmd/kafka-consumer/ — Kafka→Postgres -api/v1alpha1/ — CRD Go types (IoTDevice) -controllers/ — IoTDevice reconciler -internal/api/ — REST handlers, router, middleware, UI (go:embed) -internal/storage/ — iotpg (per-tenant Postgres) -config/crd/ — CRD YAML manifests -deployments/k8s/ — k8s deployment YAMLs -doc/ — документация -examples/ — примеры (Terraform, handler.py) -``` - ---- - -## Комментарии в коде - -Комментарии — обязательны: -- В начале каждого файла при создании или правке — дата и время изменения -- На каждой функции/методе — краткое назначение -- На нетривиальной логике — **почему** сделано именно так (не "что делает", а "зачем") - -Цель: любой агент в новом чате должен понять логику без дополнительных вопросов. - ---- - -## Темп работы - -Не спешить. Перед каждым шагом — убедиться что предыдущий понят и согласован. - ---- - -## Документация - -Всё важное фиксировать в `doc/`: -- `doc/architecture/` — архитектура, стек, схемы -- `doc/api/` — дизайн API -- `doc/decisions/` — принятые решения с обоснованием -- `doc/infrastructure/` — инфраструктура, кластер, сервисы -- `doc/errors/` — ошибки и как решили -- `doc/progress.md` — трекер задач - -Обновлять после каждого значимого изменения. - ---- - -## Именование - -Имена должны быть **уникальными и осмысленными по всему проекту**: -- имена файлов -- имена функций/методов -- имена переменных/констант -- имена ресурсов (Terraform, Kubernetes и т.д.) - -Цель: чтобы поиск по проекту находил нужные сущности без неоднозначности, а имя сразу отражало назначение. - -Запрещены безликие и повторяющиеся имена вида `handler.py`, `handle`, `data`, `value`, `temp` без контекста. - ---- - -## Лог мышления (обязательно) - -Каждый агент в каждом чате **обязан** вести лог своих рассуждений: -- Папка: `doc/thinking/` -- Файл: `ГГГГ-ММ-ДД.md` (по дате сессии) -- В начале файла указать имя агента и модель -- Если файл на текущую дату уже существует — дописывать в конец, добавив разделитель `---` и имя агента -- Записывать **полный** ход мыслей: что анализирую, какие гипотезы, что нашёл, что отбросил, к чему пришёл, почему -- Записывать **до** начала действий (план) и **после** (результат) - -Цель: пользователь должен видеть весь процесс рассуждений в читаемом виде. - ---- - -## Git - -Коммитить и пушить после каждого завершённого этапа. +1. Не трогать рабочий код без явного указания. +2. Файлы редактировать локально — `~/remote_dev/` = `~/terra/` на ВМ (sshfs), SCP не нужен. +3. Все команды — **только через SSH**, никогда локально: + ```bash + ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 'КОМАНДА' + ``` diff --git a/.github/pravila.md b/.github/pravila.md new file mode 100644 index 0000000..be15fff --- /dev/null +++ b/.github/pravila.md @@ -0,0 +1,56 @@ +# Правила работы агента + +## Файловая система + +`~/remote_dev/` (локально) примонтирован через sshfs к `~/terra/` на ВМ — **одна ФС**. +Файлы, сохранённые локально, мгновенно видны на ВМ. SCP не нужен. + +Монтирование может слетать. Признак: файлы рассинхронизированы. + +```bash +# Размонтировать +fusermount -u ~/remote_dev +# Если завис: sudo umount -l /home/naeel/remote_dev + +# Примонтировать +sshfs naeel@5.172.178.213:/home/naeel/terra ~/remote_dev \ + -o cache=no -o no_readahead -o reconnect \ + -o ServerAliveInterval=15 -o ServerAliveCountMax=3 \ + -o IdentityFile=~/.ssh/naeel_vm_id_ed25519 +``` + +## SSH + +Все команды — только через SSH на ВМ. Локально — только читать и редактировать файлы. + +```bash +ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no -o ConnectTimeout=10 naeel@5.172.178.213 'КОМАНДА' +``` + +Запрещено локально: `go`, `docker`, `kubectl`, `helm`, `terraform`, `curl/wget`, `git push/pull`, любые скрипты проекта. + +## Документация + +- `doc/thinking/` — лог рассуждений агента (обязательно) +- `doc/progress.md` — трекер задач +- Старые файлы `doc/` не перезаписывать — новое в новых файлах с датой + +## Git + +Коммитить и пушить через SSH после каждого завершённого этапа. + +Версионирование тегами: `vMAJOR.MINOR.PATCH` +- Patch — любое изменение кода +- Minor — новая фича / компонент +- Major — breaking change + +```bash +git tag vX.Y.Z && git push origin vX.Y.Z +``` + +## Поведение агента + +- Не трогать рабочий код без явного указания +- Не делать ничего сверх того, о чём явно попросили +- Деструктивные операции (`kubectl delete`, `rm -rf`, `terraform destroy` и др.) — только после явного подтверждения с указанием конкретных объектов +- Отвечать кратко, без вступлений, извинений, благодарностей и прочей воды diff --git a/deployments/k8s/iot-mqtt-bridge.yaml b/deployments/k8s/iot-mqtt-bridge.yaml index 1fd2fe3..779a50a 100644 --- a/deployments/k8s/iot-mqtt-bridge.yaml +++ b/deployments/k8s/iot-mqtt-bridge.yaml @@ -38,7 +38,7 @@ spec: - name: mqtt-bridge # Тот же образ что и оператор — оба бинаря в одном слое (manager + iot-mqtt-bridge). # При смене версии оператора — менять тег и здесь. - image: naeel/iot-operator:v0.2.5 + image: naeel/iot-operator:v0.2.6 imagePullPolicy: Always command: ["/mqtt-bridge"] env: diff --git a/deployments/k8s/iot-operator.yaml b/deployments/k8s/iot-operator.yaml index de5898a..0e4cb1a 100644 --- a/deployments/k8s/iot-operator.yaml +++ b/deployments/k8s/iot-operator.yaml @@ -3,7 +3,7 @@ # # Компоненты: # - ServiceAccount + ClusterRole + ClusterRoleBinding (RBAC для CRD controller) -# - Deployment: naeel/iot-operator:v0.2.5 +# - Deployment: naeel/iot-operator:v0.2.6 # - Service: ClusterIP :9090 (REST API, MQTT auth/acl, admin UI) # # iot-operator обслуживает: @@ -85,7 +85,7 @@ spec: serviceAccountName: iot-operator containers: - name: operator - image: naeel/iot-operator:v0.2.5 + image: naeel/iot-operator:v0.2.6 imagePullPolicy: Always ports: - name: api diff --git a/deployments/k8s/iot-sqs-consumer.yaml b/deployments/k8s/iot-sqs-consumer.yaml index e214215..ca93981 100644 --- a/deployments/k8s/iot-sqs-consumer.yaml +++ b/deployments/k8s/iot-sqs-consumer.yaml @@ -36,7 +36,7 @@ spec: containers: - name: sqs-consumer # Тот же образ что и оператор — все IoT бинари в одном образе. - image: naeel/iot-operator:v0.2.5 + image: naeel/iot-operator:v0.2.6 imagePullPolicy: Always command: ["/sqs-consumer"] env: diff --git a/internal/api/handler/iot_telemetry_handler.go b/internal/api/handler/iot_telemetry_handler.go index c8cffa0..80556ff 100644 --- a/internal/api/handler/iot_telemetry_handler.go +++ b/internal/api/handler/iot_telemetry_handler.go @@ -28,7 +28,7 @@ func (h *Handler) ListIoTTelemetry(w http.ResponseWriter, r *http.Request) { } ns := mux.Vars(r)["namespace"] - deviceID := r.URL.Query().Get("device") + deviceID := r.URL.Query().Get("device_id") limit := 50 if ls := r.URL.Query().Get("limit"); ls != "" { if n, err := strconv.Atoi(ls); err == nil && n > 0 {