Files
ipam_control/docs/changes/001-ipam-backend/PLAN.md
T
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

97 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IPAM Manager — backend (Python + PostgreSQL) и UI-админка
## Context
Есть макеты «IPAM Manager» (страница 2 канваса): Обзор, Префиксы (дерево, VRF), Адреса в подсети,
Организации, Операторы связи, Устройства (+ типы), Журнал, диалоги создания/редактирования.
Проект пуст. Нужно спроектировать и реализовать API-first приложение: backend на Python с PostgreSQL,
UI-админка — отдельный лёгкий фронт (без сборки), который только визуализирует ответы API.
Решения (согласованы): FastAPI + SQLAlchemy 2 + Alembic + psycopg3; UI — статический SPA (Alpine.js + fetch),
раздаётся тем же приложением; auth — локальные пользователи + JWT; окружение — Docker Compose (postgres + app),
venv в корне для тестов/линтеров.
## Доменная модель (PostgreSQL)
Нативные типы `CIDR` / `INET` — сравнения, вложенность (`<<=`, `>>=`) и семейство (`family()`) считает БД.
| Таблица | Ключевые поля |
|---|---|
| `organizations` | name, short_name, inn (uniq), address, contact_person, phone, email, note |
| `vrfs` | organization_id, name, route_target, note; uniq(org, name) |
| `prefixes` | organization_id, vrf_id, prefix CIDR, description, status (active/reserved/deprecated), parent_id (авто по вложенности, можно задать), is_pool, note; uniq(vrf, prefix) |
| `addresses` | prefix_id, address INET, status (assigned/reserved/deprecated), dns_name, description, device_id, note, updated_at; uniq(prefix, address); CHECK «адрес ∈ префикс» на уровне сервиса |
| `isps` | name, organization_id, contract_number, hotline, note |
| `isp_networks` | isp_id, cidr (несколько IP-блоков на оператора) |
| `device_types` | name (uniq), is_default |
| `devices` | name (hostname), device_type_id, mac, organization_id, note |
| `users` | username (uniq), password_hash (argon2), role (admin/viewer), is_active |
| `audit_log` | ts, user_id, entity_type, entity_id, entity_label, action (created/updated/deleted/assigned), diff JSONB |
Вычисляемое (не хранится): использование префикса (назначено/ёмкость), «свободные» адреса (в макете статус
«Свободен» — пропуски в диапазоне), число префиксов/адресов у организации, число устройств у типа, число IP у устройства.
Правила: VRF/тип нельзя удалить, пока используются (в макете кнопка disabled) → 409.
## API (`/api/v1`, OpenAPI на `/docs`)
- `auth`: `POST /auth/login`, `GET /auth/me` (logout — на клиенте, токен короткоживущий).
- `overview`: `GET /overview` — карточки (префиксов, VRF, адресов, использование, резерв), топ загрузки, последние изменения.
- `organizations`, `isps`, `devices`, `device-types`, `vrfs`: CRUD; списки с `q`, `limit`, `offset`, фильтры (org, тип, vrf).
- `prefixes`: CRUD; `GET /prefixes?org=&vrf=&status=&family=&q=` (дерево через parent_id + utilization);
счётчики вкладок VRF; `GET /prefixes/{id}`.
- `prefixes/{id}/addresses`: список (`status`, `q`, `limit`/`offset` — «Показать ещё 100»), `POST` назначить,
`POST .../next` — автоназначение из пула (`is_pool`), сводка «назначено/резерв/свободно».
- `addresses/{id}`: PATCH/DELETE.
- `audit`: `GET /audit` (фильтры, пагинация) — источник «Последних изменений»; полный экран «Журнал» — вне этого этапа.
- Единый формат ошибок `{code, message, fields}`; валидация CIDR/IP/MAC/FQDN в pydantic; 409 на дубли и пересечения.
- Запись в `audit_log` — в сервисном слое в одной транзакции с изменением.
## Структура репозитория
```
app/ main.py config.py db.py security.py
models/ schemas/ services/ api/v1/
alembic/ (миграция 0001 — вся схема + seed: admin, типы устройств)
web/ index.html, app.js, api.js, styles.css (IBM Plex, токены цвета из макетов)
tests/ (минимум)
docs/changes/001-ipam-backend/ PLAN.md, SUMMARY.md
docker-compose.yml Dockerfile .env.example requirements.txt README.md venv/ (в .gitignore)
```
## UI (web/)
Экраны 1:1 с макетами: логин, Обзор, Префиксы (вкладки VRF, фильтры, «Управление VRF»), Адреса подсети,
Организации, Операторы, Устройства («Управление типами»), модальные формы. Только `fetch` к `/api/v1`, JWT в
`sessionStorage`; 401 → экран логина. Пункт «Журнал» — заглушка со ссылкой на `/audit` (по вопросу №1 из макета).
## Порядок работ (по артефактам из CLAUDE.md)
0. Создать `docs/changes/001-ipam-backend/PLAN.md` (этот план) — до кода.
1. Каркас: docker-compose (postgres:16 + app), Dockerfile, config, venv, Alembic.
2. Модели + миграция 0001 + seed.
3. Auth (login/JWT/роли; viewer — только чтение).
4. Справочники: организации, VRF, операторы, типы, устройства.
5. Префиксы и адреса: вложенность, использование, next-free, проверка «адрес ∈ префикс», пересечения в VRF.
6. Обзор + audit.
7. UI SPA.
8. Тесты, обновить `README.md`, написать `SUMMARY.md`.
## Тесты (минимум, pytest + реальный Postgres из compose)
1. Логин → защищённый эндпоинт (401 без токена, 200 с токеном).
2. Префикс: дубль в VRF → 409; адрес вне префикса → 422.
3. Использование префикса и next-free считаются верно.
4. Удаление VRF/типа «в использовании» → 409.
## Проверка end-to-end
`docker compose up -d --build` → `alembic upgrade head` отрабатывает автоматически → `pytest` зелёный →
открыть `http://localhost:8000/` (UI), войти `admin`, пройти сценарий: организация → VRF → префикс →
назначить адрес → увидеть его в Обзоре и в audit. `http://localhost:8000/docs` — Swagger.
## Допущения (скажите, если не так)
- VRF принадлежит организации (в макете «общий список для организации»).
- Свободные адреса вычисляются, а не хранятся.
- Экран «Журнал» с ротацией/очисткой (страница ROS Manager) в этот этап не входит — только запись и чтение audit.
- Начальный пароль admin задаётся через `.env`, не хардкодится.
## Уточнения по итогам утверждения
- План утверждён пользователем; сохранён в этом файле до начала кода.
- Тесты выполняются против приложения, поднятого в контейнерах (docker compose). Учётные данные для тестов
генерируются автоматически (случайные пароль admin и секрет JWT в `.env`, файл в .gitignore). Контейнеры локальные, без внешнего доступа.
- Сборка и запуск вспомогательных инструментов (pytest, линтеры, alembic) — из `venv/` в корне проекта.
- Обязательная сверка UI собранного приложения с макетами (все экраны и диалоги страницы «IPAM Manager»);
расхождения устраняются до завершения работы, результат сверки фиксируется в SUMMARY.md.