diff --git a/doc/thinking/2026-04-04-02.md b/doc/thinking/2026-04-04-02.md index 9f0f908..4ba794e 100644 --- a/doc/thinking/2026-04-04-02.md +++ b/doc/thinking/2026-04-04-02.md @@ -267,3 +267,124 @@ MQTT WebSocket уже работает: `ws://iot.kube5s.ru:80/mqtt`. 2. INSERT в iot_telemetry из mqtt-bridge 3. REST API для чтения телеметрии 4. Заполнить вкладку "Телеметрия" в UI + +--- +# Агент: GitHub Copilot (Claude Sonnet 4.6) — продолжение сессии 2026-04-04 + +## Исправления и улучшения IoT Console UI (v0.1.53 → v0.1.58) + +### Проблема 1: `crypto.subtle.digest` — Cannot read properties of undefined + +**Симптом:** Пользователь вставил токен, получил ошибку "Cannot read properties of undefined (reading 'digest')". + +**Анализ:** `crypto.subtle` доступен ТОЛЬКО на HTTPS-страницах (Secure Context). Консоль раздавалась по HTTP (`http://iot.kube5s.ru/console`). На HTTP `crypto.subtle === undefined`. + +**Решение:** Перевести консоль на HTTPS — это устранит корень проблемы и заодно уберёт необходимость в pure-JS SHA256. Попытка написать pure-JS SHA256 была правильной как fallback, но правильнее — исправить инфраструктуру. + +**Действия:** +1. `emqx-ws-ingress.yaml`: добавлена TLS-секция + `cert-manager.io/cluster-issuer: letsencrypt-prod`, `ssl-redirect: "true"`, `secretName: iot-kube5s-ru-tls` +2. `router.go`: CORS `Allow-Origin`: `http://` → `https://iot.kube5s.ru` +3. `iot-console.html`: дефолт MQTT брокера `ws://` → `wss://` +4. cert-manager автоматически выпустил сертификат Let's Encrypt (READY: True за ~34 сек) +5. Собрали v0.1.54, задеплоили + +**Косяк при apply:** `kubectl apply` взял старый Ingress из кэша (только путь `/mqtt`, без `/console`). Пришлось использовать `kubectl replace` вместо `apply`. + +**Итог:** `https://iot.kube5s.ru/console` → 200, TLS v1.3, `CN=iot.kube5s.ru`, Let's Encrypt R13. `crypto.subtle` заработал. + +--- + +### Проблема 2: 404 после перехода на HTTPS (v0.1.54) + +**Симптом:** После `kubectl apply` + rollout — curl возвращал 404. + +**Анализ:** Запрос доходил до пода (видно в логах), но оператор отвечал 404. Значит маршрут `/console` не регистрировался. Проверили: файл `iot-console.html` существует на диске, `go:embed` прописан, маршрут в `router.go` есть. **Причина:** первый `docker build` взял Go-слои из кэша Docker — старый бинарь без `/console` маршрута. + +**Решение:** Пересборка с `--no-cache`. После пуша нового диджеста и `kubectl rollout restart` — заработало. + +--- + +### Улучшение: убрать поля API/MQTT из формы входа (v0.1.56) + +**Анализ:** Пользователь справедливо спросил "ЗАЧЕМ юзеру это вводить?" — адреса `https://sless.kube5s.ru` и `wss://iot.kube5s.ru/mqtt` фиксированы для данного деплоя. Пользователь не должен их трогать. + +**Решение:** Удалены `` и `` из формы. В `doLogin()` адреса берутся из хардкода, не из DOM. Форма стала: только поле токена + кнопка "Войти". + +**Параллельно:** Добавлен блок `
` внизу страницы устройства — 5 шагов инструкции: Credentials → формат JSON → Эмулятор → Авто → Телеметрия (скоро). + +--- + +### Ребрендинг: Nubes brand design (v0.1.57) + +**Задача:** "Оформи чтобы строго, чётко — как на terra.k8c.ru". + +**Исследование:** +- Скачал SVG логотипа: `https://terra.k8c.ru/docs/nubes/nubes/2.0.2/30_registry/assets/logo.svg` +- Логотип залит `#001C34` — это основной Nubes Navy цвет +- Сайт nubes.ru использует тёмно-синий (#001C34) как бренд-прайм + +**Палитра:** +| Переменная | Цвет | Назначение | +|----------------|------------|------------------------------| +| brand primary | `#001C34` | Navbar, карточки, логотип | +| page bg | `#001120` | Фон страницы | +| card surface | `#001929` | Карточки .card | +| borders | `#0b2d50` | Границы, разделители | +| accent | `#1a7fd4` | Кнопки, табы, ссылки | +| text primary | `#e2ecf6` | Основной текст | +| text secondary | `#6b8eaa` | Метки, подписи | +| text muted | `#2d5070` | Отключённые, подсказки | + +**Изменения в CSS:** +- Navbar: `background: #001C34`, логотип SVG с `filter: brightness(0) invert(1)` (белый) +- Badges: прямоугольные (`border-radius: 4px`), UPPERCASE, компактные +- Кнопки: `font-weight: 600`, `letter-spacing: 0.02em` +- Таблицы: заголовки `color: #2d5070` — строгие, тихие +- `.help-num`: квадратные (4px), не круглые + +**Форма входа:** логотип SVG (инвертированный) вместо `⚡`, подпись `IoT Console` uppercase вместо названия по-русски. + +--- + +### Favicon (v0.1.58) + +**Задача:** Иконка вкладки браузера — как у Nubes docs. + +**Исследование:** `curl https://terra.k8c.ru/docs/nubes/nubes/2.0.2/` → `` + +**URL:** `https://terra.k8c.ru/docs/nubes/nubes/2.0.2/30_registry/assets/favicon.png` + +**Решение:** Добавлена одна строка в ``: +```html + +``` + +--- + +## Итоговые версии + +| Версия | Изменение | Коммит | +|---------|-------------------------------------------------|----------| +| v0.1.54 | TLS на iot.kube5s.ru, wss://, CORS https | fb6f9d4 | +| v0.1.55 | Help-блок на странице устройства | e547871 | +| v0.1.56 | Убраны поля API/MQTT из формы входа | e547871 | +| v0.1.57 | Nubes brand rebrand — палитра, логотип | 0400f97 | +| v0.1.58 | Favicon Nubes | 93e87a3 | + +## Текущее состояние + +- ✅ `https://iot.kube5s.ru/console` — работает, TLS, Nubes-дизайн, favicon +- ✅ MQTT: `wss://iot.kube5s.ru/mqtt` +- ✅ `crypto.subtle` работает (HTTPS) +- ✅ Форма входа: только токен +- ✅ Namespace скрыт от пользователя +- ❌ Телеметрия — заглушка, бэкенд не написан + +## Следующий шаг + +Бэкенд телеметрии: +1. Postgres StatefulSet в namespace `iot` +2. Tenant provisioning при создании IoTDevice +3. INSERT в mqtt-bridge +4. REST API чтения +5. Вкладка Телеметрия в UI