- Added support for managing IPsec peers, including editing and deleting functionality. - Introduced a new UI component for displaying peers and their details within the IPsec server grid. - Updated the IPsec user creation form to allow binding identities to specific peers. - Enhanced backend routes and services to handle peer patching and deletion requests. - Improved data structures to accommodate multiple peers and certificates for each server. - Added tests to ensure proper functionality of new peer management features.
6.5 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Страна раскрывает сервисы | Клик по стране на карте оставляет остальные страны на холсте и раскрывает справа столбец сервисов этой страны (доля от трафика страны). Данные — вложенная агрегация brand×ISO в том же hops-проходе. |
|
false |
Раскрытие сервисов страны на карте
Эталон холста — app/(main)/network-map/page.tsx (Frame не меняем: SVG, не ops-list). UX: клик по стране → справа узлы сервисов, остальные страны остаются.
flowchart LR
dest[internetPeer] --> brand[mapInternetBrand]
dest --> geo[ISO country]
brand --> nested["group cc:us"]
geo --> nested
nested --> col["столбец сервисов"]
click[клик по стране] --> col
Сейчас hops считает бренд и страну независимо в одном цикле по dstAcc (traffic-flow-map-hops.ts ~567–583). Связки «Google внутри US» в API нет — без неё UI может только гадать.
Поведение на холсте
- Режим Страны, слой «Назначения» включён: как сейчас (EN → страны).
- Клик по стране: она selected; справа появляется второй столбец сервисов этой страны; остальные страны остаются, но приглушаются (
opacityкак уisVis). - Рёбра раскрытия: страна → сервис (пунктир, те же подписи скорости). EN → страна для выбранной страны подсвечивается.
- Повторный клик по той же стране / клик по пустому холсту / смена
destMode→ свернуть столбец. - Клик по другой стране → свернуть предыдущий набор и раскрыть новый.
- Клик по сервису: selected = сервис; столбец остаётся; панель — «Сервис в {страна}».
Раскладка в lib/network-map-layout.ts: сейчас одна колонка x = W - MARGIN - SERVICE_COL_W/2. При раскрытии:
- страны сдвигаются влево на
SERVICE_COL_W(чтобы не налезать на Канаду/Вьетнам с скрина); - сервисы занимают прежний правый
x, по вертикали вокруг Y выбранной страны (новый хелперplaceCountryServiceNodes(ids, parentPos)), не общий центр EN.
Доля на узле сервиса = bytes / bytes страны (не доля окна): иначе у DE 2% все сервисы будут «0%». В панели дополнительно можно показать долю окна.
Cap вложенного слоя: тот же pickMapServices, но shareBase = байты страны, cap 8, min узлов 4. «Прочее» внутри страны — svc:other.
Контракт
В packages/contracts/src/traffic-flow.ts optional:
countryServiceGroups: z.array(z.object({
countryId: z.string(), // cc:us
services: z.array(flowMapServiceDtoSchema),
edges: z.array(flowMapServiceEdgeDtoSchema), // fromId = countryId
paths: z.array(flowMapServicePathDtoSchema), // serviceId = nested id
})).optional()
id сервиса во вложении: cc:us|svc:google (mapCountryServiceNodeId), чтобы Google в US и NL не смешивались в одном payload. Группы только для стран, прошедших pickMapServices стран.
Бэкенд
В том же цикле dstAcc: после svcId + country.id копить nestedTotals/edges/paths с ключом ${country.id}|${svcId}. Рёбра вложенного слоя: fromId = country.id (не EN). Пути: как сервисные, serviceId = nested id (enId остаётся для подсветки HR→JH→EN).
finalize по каждой стране из countriesOut.nodes.
Фронт
- Состояние
expandedCountryId(не в sessionStorage). visibleNested = groups.find(g => g.countryId === expandedCountryId).ServiceNodeдля вложенных:destMode="services"(бренд), подпись label, доля от страны.- Панель страны: текущие KPI + короткий список топ-сервисов (клик = тот же expand/select).
- Панель сервиса: бренд + «в {countryName}», доля страны, пути
visibleNested.pathsсserviceId. - Mock:
MOCK_COUNTRY_SERVICE_GROUPSдляcc:us(Google / Cloudflare / AWS).
Тесты
traffic-flow-map-hops.test.ts: ripe US → группа cc:us с брендом 8.8.8.8; кейс US+NL — сервисы не пересекают countryId; nested edges.fromId = cc:us, не svc:*.
Хелпер id — рядом с mapCountryNodeId в brands-тесте.
Вне скоупа
- Одновременное раскрытие двух стран.
- Географическая карта мира.
- Отдельный порог NetFlow для вложенных сервисов (тот же %, но база = страна).