Commit graph

4 commits

Author SHA1 Message Date
a0eb2ff5f1 Пакування: образи, повний стек, TLS, CI, процедура бекапу
Some checks are pending
CI / web (push) Waiting to run
CI / server (push) Waiting to run
CI / agent (push) Waiting to run
Два образи замість пʼяти: серверні команди їдуть з одного модуля й
мусять ходити в схему БД однією версією, а зонд лишається окремо —
у чужій мережі йому не місце з DSN і ключами шифрування.

Стек піднімає БД, кеш, міграції, API, колектор і Caddy з автоматичним
TLS. Міграції окремою службою, бо API піднімається в кількох
примірниках і гонка за схему нікому не потрібна.

deploy/README.md описує бекап як три речі: дамп, DEK і JWT-ключ.
Без DEK дамп не відновлюється — у БД лише шифротекст.

Дорогою виправлено .gitignore: голі "netpulse-agent" і
"netpulse-server" ігнорували ще й каталоги cmd/ з кодом команд.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 12:47:54 +03:00
205dd5e079 Пакування: runner міграцій і вшитий у бінарник фронтенд
netpulse-migrate замість PowerShell-скрипта: у контейнері немає ані
psql, ані PowerShell, а тягнути клієнт Postgres в образ заради одного
запуску — це половина дистрибутива на порожньому місці.

Міграції вшиті через embed і переїхали в server/migrations: embed не
бачить нічого за межами кореня свого модуля, а міграції поруч із
бінарником, який їх накочує, не можуть розійтися версіями.

Накочування під advisory-блокуванням: два інстанси при rolling update
інакше застосували б ту саму міграцію двічі. Кожен файл в одній
транзакції разом із записом у schema_migrations; виняток — continuous
aggregates, які TimescaleDB забороняє в транзакції. Змінена вже
застосована міграція зупиняє запуск: у різних інсталяціях інакше
опиниться різна схема під одним номером.

Перевірено на чистій базі: 23 міграції, 101 таблиця, повторний запуск
каже «схема актуальна».

Веб віддає сам API через embed: на self-hosted це прибирає з інструкції
встановлення цілий компонент. Три політики кешування — назавжди для
assets із хешем у імені, ніколи для index.html, коротко для решти.

Знайдено живим прогоном: невідомий шлях під /api/ віддавав 200 з
index.html, і клієнт падав на розборі HTML як JSON замість чесного 404.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 01:01:55 +03:00
3de5643b98 Етап 4: фронтенд — мапа мережі в браузері
React Flow поверх наявного API: вузли фарбуються статусом, ребра
кольором із порогів, точка на ребрі біжить зі швидкістю, оберненою до
завантаження каналу. WebSocket дає живі статуси й util, реконект
повертає підписку сам.

Робота з живим UI знайшла дві вади:

1. Ревізія мапи росла від самих кліків — React Flow віддає
   onNodeDragStop на будь-яке натискання, і кожен клік писав порожню
   ревізію, змушуючи інші відкриті полотна перечитуватись.
2. Після збереження хук оновлював лише номер ревізії, тож наступна
   подія device.status відкидала щойно перетягнутий вузол назад.

Перевірено в браузері проти повного стека зі справжнім snmpd: два
зелені вузли з живим RTT, ребро eth0 з util і capacity 10 Гбіт/с,
індикатор "наживо", кнопка автопобудови з topo.links.

Драг через автоматизацію відтворити не вдалося — синтетичні події не
запускають d3-drag; цей шлях покритий тестами сервера.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 16:28:37 +03:00
15d22a8d8a Етап 1-2: схема БД та protobuf-контракт агент-сервер
Схема PostgreSQL 16+/TimescaleDB: 11 міграцій, 7 схем, топологія
(neighbors -> links -> maps -> nodes/edges), time-series з CAGG,
NCM, alerting, білінг з entitlements, RLS.

Контракт agent<->server: 6 proto-файлів, gRPC, інтернування серій,
at-least-once з ack, чанкування конфігів.

Перевірено на стенді Debian 13 / PG 17.11 / TimescaleDB 2.29.1:
міграції + 8 функціональних перевірок схеми, buf lint + 5 наскрізних
gRPC-тестів контракту.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 03:28:40 +03:00