Задача 042: свёртка свободных адресов в раскрывающиеся диапазоны
В списке адресов префикса подряд идущие свободные адреса сворачиваются в строку «начало – конец · Свободно: N» (параметр group_free, группировка на сервере — пагинация по строкам после свёртки); раскрытие — существующим status=free&offset=free_offset порциями по 500. Без group_free ответ API прежний. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9301069c29
commit
d1a2efd683
7 files changed
+176
-12
No files matched your search
@@ -0,0 +1,52 @@
|
||||
# Свёртка свободных адресов в раскрывающиеся диапазоны (изменение 042)
|
||||
|
||||
## Context
|
||||
В списке адресов префикса (`screens.address`) для подсетей до /20 занятые и свободные адреса идут вперемешку, каждый свободный — отдельной строкой.
|
||||
В почти пустой /24 это ~250 строк «Свободен», которые оттесняют занятые адреса. Нужно сворачивать **подряд идущие свободные адреса**
|
||||
в одну строку-диапазон: «10.0.0.5 – 10.0.0.20 · свободно 16». По клику строка раскрывается в отдельные адреса, повторный клик сворачивает.
|
||||
|
||||
## Решение
|
||||
Группировка на сервере. Если сворачивать на клиенте в пределах страницы, диапазоны рвутся на границе пагинации,
|
||||
а страница в 100 строк почти целиком занята свободными. С группировкой на сервере страница из 100 строк показывает 100 занятых адресов или диапазонов.
|
||||
|
||||
### API — `app/api/v1/prefixes.py::list_addresses`
|
||||
- Новый параметр `group_free: bool = False`: по умолчанию поведение прежнее (совместимость, тесты).
|
||||
Действует только в смешанном режиме (`mixed`: без фильтра статуса и поиска, подсеть до `FREE_LISTING_LIMIT`).
|
||||
- Подряд идущие свободные адреса (серия ≥ 2) сворачиваются в одну строку `AddressOut`:
|
||||
- `status="free_range"`, `address` — первый адрес, `range_end` — последний;
|
||||
- `range_count` — число адресов;
|
||||
- `free_offset` — сколько свободных адресов подсети идёт до начала диапазона.
|
||||
Одиночный свободный адрес остаётся обычной строкой `free`. `total` и пагинация считаются по строкам после свёртки.
|
||||
- `app/schemas.py::AddressOut`: `range_end: str | None = None`, `range_count: int | None = None`, `free_offset: int | None = None`.
|
||||
- Раскрытие диапазона — существующий `GET …/addresses?status=free&offset=<free_offset>&limit=<n>`:
|
||||
`free_page` уже считает страницу свободных арифметически, новых эндпоинтов не нужно.
|
||||
|
||||
### UI — `web/app.js::screens.address`
|
||||
- Запрос списка — с `group_free: true`.
|
||||
- Строка `free_range`: шеврон ▸/▾, текст «<начало> – <конец>», в колонке статуса — бейдж «Свободно: N». Остальные колонки — «—».
|
||||
Действия «Назначить адрес» у свёрнутой строки нет: назначают из раскрытых строк. Строка не выбирается чекбоксом.
|
||||
- Клик по строке диапазона раскрывает или сворачивает её. Раскрытое состояние — `S.freeOpen`: множество начальных адресов,
|
||||
сбрасывается при смене префикса, фильтра или поиска.
|
||||
При раскрытии: `api(…/addresses, {status: "free", offset: free_offset, limit: min(range_count, 500)})`, строки вставляются под диапазоном
|
||||
с отступом, как обычные строки «Свободен», с действием «Назначить адрес».
|
||||
Если в диапазоне больше 500 адресов, после первых 500 показывается строка «ещё N — показать», она подгружает следующую порцию.
|
||||
- «Показано X из Y» учитывает строки после свёртки.
|
||||
- Стиль — существующие классы и токены (`.tr.free`, `badge`, `I.chevR`/`I.chevD` как в дереве префиксов); литеральных цветов нет, тёмная тема работает.
|
||||
|
||||
## Тест (минимально)
|
||||
В существующем тесте `tests/test_api.py`, работающем с адресами малой подсети (например, `test_tree_utilization_and_next_free`), проверить:
|
||||
`GET /prefixes/{leaf}/addresses?group_free=true` → строка `free_range` с корректными `address`, `range_end`, `range_count`, `free_offset`;
|
||||
`status=free&offset=<free_offset>&limit=<range_count>` возвращает ровно адреса этого диапазона.
|
||||
|
||||
## Документация
|
||||
- `README.md`: «Адреса» и «Интерфейс» — свёртка свободных; строка 042 в истории.
|
||||
- `SUMMARY.md` — по завершении.
|
||||
|
||||
## Исполнение
|
||||
По принятой схеме: код и тест пишет агент на Sonnet, он же пересобирает стенд с `--force-recreate`. Моя часть — ревью и `pytest`.
|
||||
UI проверяет пользователь.
|
||||
|
||||
## Проверка
|
||||
- `pytest -q` — все зелёные.
|
||||
- API: `/24` с парой назначенных адресов → 3–5 строк вместо ~254; `free_offset` и раскрытие дают ровно адреса диапазона; IPv6 `/120` — тоже.
|
||||
- Без `group_free` ответ идентичен прежнему.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Итог: свёртка свободных адресов в раскрывающиеся диапазоны (изменение 042)
|
||||
|
||||
План: `PLAN.md`. В списке адресов префикса подряд идущие свободные адреса сворачиваются в строку-диапазон
|
||||
«начало – конец · Свободно: N»; клик раскрывает её в отдельные адреса, повторный — сворачивает. Одиночный свободный адрес — обычная строка.
|
||||
|
||||
## Что сделано
|
||||
| Файл | Изменение |
|
||||
|---|---|
|
||||
| `app/api/v1/prefixes.py` | `list_addresses(group_free=False)`: в смешанном режиме (без фильтра и поиска, подсеть ≤ `FREE_LISTING_LIMIT`) серии свободных ≥ 2 сворачиваются одним проходом по отсортированному списку в строку `free_range`. `total` и пагинация — по строкам после свёртки. Без `group_free` ответ прежний |
|
||||
| `app/schemas.py` | `AddressOut.range_end`, `range_count`, `free_offset` |
|
||||
| `web/app.js` | Список запрашивается с `group_free`. Строка диапазона: шеврон как в дереве префиксов, бейдж «Свободно: N», без чекбокса и действий. Раскрытие — существующий `status=free&offset=free_offset`, порциями по 500 со строкой «ещё N — показать». Состояние в `S.freeOpen`/`S.freeLoaded`, сброс при смене фильтра, поиска или префикса. Подсказка адреса в «Назначить адрес» учитывает `free_range` |
|
||||
| `tests/test_api.py` | В `test_tree_utilization_and_next_free`: `free_range` с корректными границами и `free_offset`; раскрытие даёт ровно адреса диапазона; без `group_free` ответ не изменился |
|
||||
| `README.md` | Свёртка свободных адресов; строка 042 |
|
||||
|
||||
## Проверки
|
||||
- `pytest -q` — 17 passed.
|
||||
- На стенде (временная организация, удалена):
|
||||
- `10.242.0.0/24` с 3 назначенными — 5 строк вместо 254;
|
||||
- `fd00:242::/120` с 3 назначенными — 5 строк вместо 256;
|
||||
- раскрытие каждого диапазона через `status=free&offset&limit` совпадает по первому и последнему адресу и количеству.
|
||||
- UI — проверка пользователя.
|
||||
Reference in new issue
Block a user