Files
ayurishchevandClaude Sonnet 5 a846d30872 IPAM Manager: API, UI-админка, журнал аудита
Backend (FastAPI, SQLAlchemy 2, Alembic, PostgreSQL 16):
- организации, VRF, префиксы (дерево, использование, автоназначение),
  адреса, операторы связи, устройства и типы устройств; JWT, роли admin/viewer;
- VRF принадлежит организации (составной FK), смена VRF у префикса
  переносит поддерево, имя VRF уникально в организации;
- журнал аудита: поиск и фильтры, ротация (срок/количество), очистка
  по паролю с блокировкой, IP клиента и метаданные запроса
  (X-Forwarded-For только от TRUSTED_PROXIES).

UI (web/, без сборки): экраны и диалоги по макетам «IPAM Manager»,
кликабельные строки реестров, локальные шрифты IBM Plex,
собственные выпадающие списки.

Окружение: docker-compose (postgres + app), миграции Alembic 0001-0004,
scripts/gen_env.py, scripts/seed_demo.py, 11 автотестов (pytest).
Документация: README.md и docs/changes/001-005 (планы и итоги).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 12:27:47 +03:00

6.1 KiB

План: смена VRF у префикса и целостность «VRF ⊂ организация» (изменение 002)

Контекст

VRF — часть адресного плана организации. Сейчас:

  • уникальность VRF уже в пределах организации: UNIQUE(organization_id, name) — одно имя допустимо в разных организациях;
  • несколько префиксов организации могут быть в одном VRF (UNIQUE(vrf_id, prefix) — дубль CIDR запрещён только внутри VRF);
  • смена VRF у существующего префикса невозможна: нет ни поля в UI (web/app.js, prefixDialog), ни vrf_id в PrefixUpdate (app/schemas.py);
  • принадлежность VRF организации префикса проверяется только в коде (create_prefix), в БД гарантии нет.

Цель: разрешить смену VRF только среди VRF той же организации, сохранив целостность дерева, и закрепить правило на уровне БД.

Правила

  1. Организация префикса неизменна; целевой VRF обязан принадлежать той же организации (иначе 422).
  2. Смена VRF переносит префикс вместе со всем поддеревом (вложенные по parent_id), чтобы дерево не «разрывалось» между VRF.
  3. Дубль (vrf, prefix) у любого переносимого префикса в целевом VRF → 409 с перечнем конфликтующих CIDR; перенос отменяется целиком.
  4. После переноса родитель корня поддерева пересчитывается в целевом VRF (самый узкий объемлющий); префиксы целевого VRF, лежащие внутри перенесённого, переподчиняются ему — та же логика, что при создании (выносим в общую функцию attach_to_tree).
  5. Адреса остаются у своих префиксов (prefix_id не меняется); использование/ёмкость пересчитываются автоматически.
  6. CIDR и родитель в окне редактирования по-прежнему не меняются (родитель определяется автоматически).

Изменения

Backend

  • app/schemas.py: PrefixUpdate.vrf_id: int | None.
  • app/api/v1/prefixes.py: в update_prefix — валидация правил 1–3, перенос поддерева, attach_to_tree (рефакторинг из create_prefix), запись в audit {vrf: "old → new", moved: N}.
  • Alembic 0002:
    • UNIQUE(id, organization_id) на vrfs + составной FK prefixes(vrf_id, organization_id) → vrfs(id, organization_id) — БД не даст связать префикс с VRF чужой организации;
    • уникальность имени VRF без учёта регистра в пределах организации: индекс (organization_id, lower(name)) вместо UNIQUE(organization_id, name); перед применением — проверка на существующие дубли.

UI (web/app.js)

  • В окне редактирования префикса показать поле «VRF» (только VRF текущей организации, уже загружены в S.vrfs).
  • При выборе другого VRF — подсказка «Вместе с префиксом будет перенесено N вложенных» (N считается из S.prefixes); ошибки 409/422 — в стандартном баннере окна.
  • Вёрстка — из существующего окна создания (макета редактирования нет, отступлений от дизайна не появляется).

Тесты (2 новых, всего 6)

  1. Одноимённый VRF в двух организациях — ок; повтор в одной (в т.ч. другим регистром) — 409.
  2. Смена VRF: поддерево переехало, родитель пересчитан, дубль в целевом VRF — 409 без частичных изменений, VRF другой организации — 422.

Порядок работ

  1. Рефакторинг attach_to_tree (поведение создания не меняется, тесты зелёные).
  2. Миграция 0002 (сначала проверка дублей, затем применение через docker compose up).
  3. PrefixUpdate + логика переноса.
  4. UI: поле VRF и подсказка.
  5. Тесты в контейнерах, прогон e2e-сценария UI, сверка окна с макетом «Новый префикс».
  6. Обновить README.md (правила VRF), написать SUMMARY.md в этой папке.

Риски

  • Составной FK требует, чтобы prefixes.organization_id всегда совпадал с организацией VRF — уже так; миграция проверит данные и откажется применяться при расхождении.
  • Перенос крупного поддерева — одна транзакция; при 409 откат целиком.

Допущения (скажите, если не так)

  • Переносится всё поддерево, а не только выбранный префикс (альтернатива — запретить смену VRF у префиксов с вложенными).
  • Регистронезависимая уникальность имён VRF в организации допустима (Lab и lab считаются одним VRF).