Files
ipam_control/docs/changes/001-ipam-backend/PLAN.md
T

96 lines
8.7 KiB
Markdown
Raw Normal View History

# 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.