Повторный анализ кодовой базы (docs/reviews/2026-09-26-codebase-review-2.md) и доработки:
025 Ёмкость префикса — размер его подсети (а не сумма листьев); «Обзор» считает ёмкость
по корневым активным IPv4-префиксам и адреса внутри них.
026 Политика блокировки входа: 5 неудач на логин+IP, 20 на IP, 50 на логин со всех IP,
кроме известных IP (known_logins, миграция 0009) — владельца нельзя заблокировать анонимно.
027 Сериализация попыток входа по IP (advisory-lock после блокировки логина).
028 UI «Префиксы»: загрузка всех страниц (до 20 000), счётчики по total, предупреждение об усечении.
029 Advisory-lock по VRF для операций, меняющих дерево префиксов и раскладку адресов.
030 Исправление замечаний ревью 025-029: _lock_prefix (VRF блокируется до чтения префикса,
409 при одновременном переносе), константы политики входа перенесены в app/services.py.
Тесты: 14 passed (проверка ёмкости родителя приведена к семантике 025); сквозные сценарии
и гонки — docs/reviews/2026-09-26-changes-025-029-review.md, 2026-09-27-changes-030-review.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
29 lines
3.6 KiB
Markdown
29 lines
3.6 KiB
Markdown
# Итог: ёмкость и загрузка частично разбитого префикса (изменение 025)
|
||
|
||
## Что сделано
|
||
- `app/api/v1/prefixes.py`: функция `_capacities` (ёмкость родителя = сумма ёмкостей листьев) удалена; `_prefix_outs` считает ёмкость каждого префикса как `capacity(str(r.prefix))` —
|
||
размер его собственной подсети, независимо от того, есть ли у него вложенные префиксы. `used` не менялся (по-прежнему `_usage`, по поддереву CIDR того же VRF). Неиспользуемый импорт `MAX_CAPACITY` убран.
|
||
- `app/api/v1/overview.py` переписан:
|
||
- «корни» (`_ipv4_roots`) — активные IPv4-префиксы, не вложенные ни в один другой активный IPv4-префикс того же VRF по CIDR (`NOT EXISTS` с оператором `>>`, не по `parent_id`);
|
||
- `capacity` — сумма `capacity()` корней;
|
||
- `assigned`/`reserved` — один SQL-запрос: `addresses` JOIN CTE корней по `vrf_id` и `address <<= root.prefix`, `COUNT(DISTINCT id)` по статусу, только IPv4;
|
||
- `top_prefixes` («Высокая загрузка») не менялся — по-прежнему листовые IPv4-префиксы с ёмкостью > 1, по убыванию загрузки;
|
||
- `prefixes`, `vrfs`, `recent_changes` не менялись.
|
||
- `README.md`, раздел «Модель данных»: заменено правило ёмкости, описан расчёт «Обзора» по корням.
|
||
|
||
## Отклонения от плана
|
||
Нет. План выполнен как описан.
|
||
|
||
## Как проверено
|
||
1. `venv/bin/python -c 'import app.main'`, `node --check web/app.js` — без ошибок.
|
||
2. Стенд `ipam_control_006` пересобран (`docker compose -p ipam_control_006 up -d --build app`), контейнер `healthy`.
|
||
3. Сценарий из плана на временной организации (`rv3-cap-test`, скрипт в scratchpad, не в репозитории): `172.20.0.0/24` + 40 адресов → `used=40, capacity=254, utilization=16`;
|
||
после `POST /prefixes/{id}/subnets/next {length:30}` — те же `capacity=254, utilization=16` у родителя (раньше падало до `capacity=2, utilization=100`). **PASS.**
|
||
4. «Обзор»: результат API (`capacity=16843256`, `assigned=485` с учётом временных данных) сверен с прямым SQL-запросом той же логики (роли посчитаны вручную в psql) после удаления временной
|
||
организации (`capacity=16843002`, `assigned=445`) — разница ровно 254/40, что соответствует временному корню `172.20.0.0/24`. **PASS.**
|
||
5. Временная организация и все её объекты удалены по завершении проверки.
|
||
|
||
## Не проверено
|
||
- Внешний вид в браузере (браузер недоступен в этой среде) — проверено только через прямые вызовы API и сверку с SQL.
|
||
- Сценарий с несколькими VRF и IPv6-префиксами одновременно (на демо-данных стенда — только реальные данные, без специально подготовленного смешанного случая).
|