Commit Graph
39 Commits
Author SHA1 Message Date
Repinoid b205f886b6 chore(iot): удалить легаси-код (оператор/CRD/старый API/standalone bridge)
Удалён кластер старого IoT, не импортировавшийся активным монолитом:
- cmd/iot-operator/, controllers/, api/v1alpha1/ — k8s-оператор + CRD
- internal/api/ — старый REST API + UI-embeds (заменён internal/service/api)
- cmd/mqtt-bridge/ — standalone bridge (заменён internal/service/bridge)

go mod tidy убрал k8s-зависимости (k8s.io/*, controller-runtime).
2026-10-10 18:11:05 +03:00
Repinoid ecf6b41131 docs(review): Opus code-review of iot-service (bridge->SQS->consumer) verbatim 2026-10-10 18:02:59 +03:00
Repinoid 18e4352a47 chore(P2-14/п.4): удалён legacy cmd/sqs-consumer
Не собирался Dockerfile/Makefile (только ./cmd/iot-service/) → в образ/деплой
не попадал; логика поглощена internal/service/consumer/. Был источником пустого
message_id (обход дедупа). message_id оставлен nullable — единственный пишущий
путь (bridge) всегда ставит UUID. LEGACY.md обновлён. Плюс исправлена неточность
в HISTORY про поведение без DLQ.
2026-10-07 07:50:29 +03:00
Repinoid 59ed2d59d0 doc(HISTORY): п.2 сделан; п.4 — открытая развилка (NOT NULL vs nullable+удалить legacy) 2026-10-07 07:47:36 +03:00
Repinoid e8873fa24d fix(telemetry): ts = время приёма (ReceivedAt), а не момент INSERT
Раньше ts проставлялся now() в БД при INSERT → при батчинге и параллельных
записях порядок телеметрии (ORDER BY ts DESC) ломался. Теперь в ts идёт
ReceivedAt из envelope (серверное время приёма, ставит bridge); битый/пустой
received_at → zero → стор подставляет now(). Схема не меняется (используется
существующая колонка ts). Обновлены callers: consumer/processor.go и legacy
cmd/sqs-consumer.
2026-10-07 07:47:10 +03:00
Repinoid f2768568d3 doc(HISTORY): реализация п.1 (retryable/permanent) и п.3 (DLQ) зафиксирована 2026-10-07 07:41:22 +03:00
Repinoid 4ee0fc3b61 fix(telemetry): различать retryable/permanent ошибки flush (не залипать на ядовитом батче)
isRetryableFlushErr: '08' (connection) и 57P01/02/03 (shutdown/crash) — retryable
(возврат в буфер); '22' (data exception) и '23' (integrity violation) — permanent
(батч выбрасывается с логом, НЕ возвращается в буфер). Иначе один невалидный
payload зацикливал flush namespace навсегда (вечные 200мс-ретраи). Относится к
обоим путям: flushAll и InsertTelemetry(full).
2026-10-07 07:41:05 +03:00
Repinoid 4031882cae feat(consumer): битые envelope → DLQ вместо потери
processTelemetry теперь возвращает sentinel errInvalidEnvelope при битом JSON
(раньше — молчаливый nil → mусор подтверждался и терялся). Consumer при этой
ошибке кладёт тело в DLQ (SQS_DLQ_NAME, дефолт iot-telemetry-dlq) и подтверждает
основное сообщение; без DLQ — только логирует, но НЕ подтверждает (оседает).
Добавлены SQSDLQName в config + DefaultSQSDLQName. Реальные ошибки PG (не invalid)
по-прежнему не подтверждаются и уходят в ретрай после visibility timeout.
2026-10-07 07:40:09 +03:00
Repinoid 2b3838680f doc(HISTORY): архитекторский разбор телеметрии — 5 проблем и решение 2026-10-07 07:38:27 +03:00
Repinoid b6c083e80f fix(telemetry): не терять строки при ошибке flush (flushAll + InsertTelemetry)
flushAll и InsertTelemetry (путь заполнения батча) вынимали строки из буфера и
подменяли буфер ДО записи: при ошибке flushTenant строки исчезали. Хуже —
фоновый flusher мог забрать строки, которые consumer ждал в Flush, тогда Flush
видел пустой буфер, возвращал nil, и consumer подтверждал SQS-сообщение с
незаписанными данными (потеря). Теперь при ошибке строки возвращаются в буфер
в обоих путях. ctx проброшен в flushAll/flushTenant. Consumer хранит receipt
handle значением (string), не указателем SDK.
2026-10-07 07:32:00 +03:00
Repinoid 38602b7560 P0-8: идемпотентность телеметрии (dedup по message_id)
Envelope получил MessageID (UUID); таблица iot_telemetry — столбец message_id +
UNIQUE(device_id,message_id); батч-INSERT ON CONFLICT DO NOTHING. Дубли при
at-least-once повторе из SQS больше не вставляются. Пустой message_id → NULL
(без ложного дедупа).
2026-10-07 07:26:50 +03:00
Repinoid 3036572ccc P1-9: readiness-проба /ready отражает состояние bridge/consumer
/health остаётся liveness (процесс жив); /ready возвращает 503, если bridge или
consumer не в строю (горутина упала/не поднялась). Добавлен api.Readiness с
atomic-флагами, NewRouter принимает *Readiness, main поднимает/опускает флаги
вокруг фоновых горутин.
2026-10-07 07:25:09 +03:00
Repinoid f19ab47c29 HISTORY: журнал сессии 2026-10-07 (IoT P0-1/P0-2, P1-4, P0-3.2, P0-7) 2026-10-07 07:23:52 +03:00
Repinoid 3175605931 P0-7: подтверждение из SQS только после успешного flush телеметрии в БД
InsertTelemetry лишь буферизует и возвращает nil до фактической записи. Consumer
удалял сообщение сразу после processTelemetry == nil — краш/flush-ошибка в этом
окне = безвозвратная потеря. Теперь: копим receipt handles, вызываем store.Flush,
и только при успехе DeleteMessage; при ошибке flush — не удаляем (сообщения
вернутся после visibility timeout). Добавлен iotpg.Flush().
2026-10-07 07:23:25 +03:00
Repinoid a4e786d03b P0-3 (часть 2): не отдавать пароль устройства повторно через GET
GetIoTDevice больше не возвращает mqtt_password (deviceToResponse получает ).
Пароль остаётся доступен только один раз — при создании устройства.
Хэширование паролей в БД + перевод EMQX на алгоритм хэша (часть 1) требует
изменения emqx.conf и миграции — отдельным шагом.
2026-10-06 19:06:02 +03:00
Repinoid c97b63b190 P1-4: убрать неаутентифицированные /internal/mqtt/auth|acl из роутера
EMQX ходит в PostgreSQL напрямую (backend=postgresql), эти HTTP-эндпоинты были
неиспользуемым fallback и висели на публичном порту без аутентификации (перебор
паролей устройств / выдача ACL). Удалены из роутера.
2026-10-06 19:05:12 +03:00
Repinoid 4afee5cdf9 P0-1/P0-2: tenant-граница по sub + обязательная подпись JWT
validateJWT теперь возвращает sub; middleware сверяет sub с {namespace} из URL
(несовпадение → 403) — закрывает горизонтальный доступ к чужим namespace.
Вне AUTH_TEST_MODE подпись HS256 обязательна: без JWT_HMAC_SECRET middleware
отказывает (fail-closed, 500), а config.Load требует секрет на старте.
2026-10-06 19:04:54 +03:00
“Naeel” f76383a2ef chore: убрать __pycache__ из трекинга, расширить .gitignore (pyc/бинарники/мусор) 2026-08-17 08:20:44 +04:00
“Naeel” da4c3d10d0 docs(thinking): Nubes DevOps report — network issues + fixes 2026-08-16 20:43:03 +04:00
“Naeel” ce9e20266c feat(landing): vertical large pipeline diagram; v0.1.13 2026-08-16 19:16:58 +04:00
“Naeel” 30e7da8cf8 feat(landing): hand-drawn pipeline SVG diagram; v0.1.12 2026-08-16 19:11:17 +04:00
“Naeel” 0f71e715be docs(landing): rewrite as clear how-to (4 steps with copy-paste commands); v0.1.9 2026-08-16 18:51:59 +04:00
“Naeel” ce01b6f9f8 feat(api): landing page with Nubes design (logo+favicon), /static; v0.1.8 2026-08-16 18:46:17 +04:00
“Naeel” 68becfd6bc fix: review findings (async SQS dispatcher, backoff, batch insert, shutdown order, pagination, HMAC) + loadtest fixes; v0.1.6 2026-08-16 18:24:09 +04:00
“Naeel” 10716aeace test(loadtests): 10 load scenarios + verifier; docs: Sonnet review findings 2026-08-16 16:59:29 +04:00
“Naeel” 649a880182 docs: no-kubectl deployment procedure (tail 4) + HISTORY 28-29 2026-08-16 16:20:07 +04:00
“Naeel” 8b3f3ab5df feat(emqx): PG-auth in EMQX v0.2.4 + EnsureBridgeDevice v0.1.2 (tail 3) 2026-08-16 16:18:49 +04:00
“Naeel” 12b43e7999 fix(bridge): resubscribe on every (re)connect; emqx v0.2.1 dashboard off; iot-service v0.1.1 2026-08-16 15:24:26 +04:00
“Naeel” 85f646cfe4 fix(emqx): v0.2.0 от официальной базы + резолвимые auth-заглушки — EMQX работает (502 устранён); HISTORY: развязка задокументирована 2026-08-16 14:22:35 +04:00
“Naeel” b19e5ec638 fix(emqx): mqtt_path→websocket.mqtt_path (v0.1.4, локально OK); HISTORY: на платформе boot висит — задокументировано 2026-08-16 13:48:26 +04:00
“Naeel” b6ffd52e00 fix(emqx): v0.1.2 — procps для launcher (502 из-за ps: command not found); HISTORY: ошибки deck/502 задокументированы 2026-08-16 13:28:41 +04:00
“Naeel” 1f30d13e95 fix(emqx): v0.1.1 — сборка от debian, единственный EXPOSE 8083 (deck-UI берёт порт из образа, поле applicationUsePort в форме отсутствует) 2026-08-16 13:22:39 +04:00
“Naeel” 7d4384b79a fix(emqx): EXPOSE только 8083 + комментарий про applicationUsePort в deck-UI 2026-08-16 13:17:43 +04:00
“Naeel” 0363b8b56a feat: EMQX-образ для платформы (naeel/iot-emqx) — конфиг вшит, auth/ACL URL через env 2026-08-16 10:13:17 +04:00
“Naeel” 7647627052 feat: монолит iot-service (Фаза 1) — config/store/api/bridge/consumer без k8s, устройства в PG, новые Dockerfile/Makefile 2026-08-16 10:07:51 +04:00
“Naeel” a7b655acdb refactor: старые артефакты IoT перенесены в legacy/ (git mv, история сохранена); активное дерево очищено, go build OK 2026-08-16 09:48:34 +04:00
“Naeel” ad6e6f1d24 docs: аудит вмешательства старого IoT — k8s-зависимости только в 3 хендлерах; Dockerfile помечен ЛЕГАСИ; правило монолита зафиксировано 2026-08-16 09:44:45 +04:00
“Naeel” d3693b681e docs: пометка ЛЕГАСИ всего старого IoT (манифесты, CRD, оператор, документы, examples, Makefile) + корневой LEGACY.md; удалений нет 2026-08-16 09:37:29 +04:00
“Naeel” 31b6a2771f feat(ws-probe): тестовый WS echo-сервер для проверки wss на платформе Nubes (v0.1.0, образ naeel/iot-ws-probe) 2026-08-16 08:18:18 +04:00