Files
IPWhiteList/docs/plan-gemini.md
T

86 lines
6.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.
# План разработки — IP WhiteList Microservice
> **Автор:** GitHub Copilot (Gemini 3.1 Pro Preview)
> **Дата:** 2026-05-29
---
## 1. Анализ предыдущих планов и моё видение
Я изучил ТЗ и варианты коллег (DeepSeek, Claude, GPT-5.4).
- **DeepSeek** предложил избыточный Async/ORM подход.
- **Claude** упростил до psycopg2 и HTMX, но оставил много "белых пятен" в работе с Keycloak.
- **GPT-5.4** дал отличный продуктовый разбор рисков (гонки, лимиты, нормализация), но оставил проект заблокированным до "уточнения с командой Keycloak".
**Мой подход (Gemini 3.1 Pro):**
Мы не будем блокировать разработку в ожидании ответов от админов Keycloak. Разночтения с форматами claims (как выглядит админ, как выглядит мульти-аккаунт) мы вынесем в **гибкую конфигурацию (.env)**. Если формат токена изменится, нам не придется править код, мы просто поменяем переменные окружения.
Также мы откажемся от сторонней библиотеки `netaddr`, так как встроенный модуль Python `ipaddress` имеет встроенную функцию `collapse_addresses()`, которая идеально решает задачу агрегации по ТЗ.
---
## 2. Технологический стек
* **Бэкенд:** FastAPI (Python 3.11+). Обеспечивает Pydantic-валидацию (используем встроенный `IPv4Network`).
* **СУБД:** PostgreSQL.
* **Доступ к данным:** SQLModel (надстройка над SQLAlchemy). Дает удобство ORM без избыточной сложности, синхронный режим.
* **Суммаризация (Агрегация):** Standard Library Python `ipaddress.collapse_addresses`.
* **Фронтенд:** Jinja2 + HTMX + TailwindCSS (через CDN или standalone cli для простоты).
* **Авторизация:** Dependency injection в FastAPI для OIDC/JWT. Заглушка (MockOIDC) для локальной разработки.
---
## 3. Решение узких мест (Архитектурные решения)
**Проблема 1: Как определять администратора и принадлежность к компаниям из токена?**
*Решение:* Выносим структуру токена в `Config`.
```env
OIDC_COMPANY_CLAIM="client_id" # Может быть списком или строкой, обработаем оба варианта
OIDC_ADMIN_CLAIM_KEY="roles"
OIDC_ADMIN_CLAIM_VALUE="whitelist-admin"
```
Код будет динамически проверять, совпали ли значения, указанные в конфиге, с данными из токена.
**Проблема 2: Гонки при записи и лимиты**
*Решение:*
1. Проверка лимита делается запросом `SELECT count(*) FROM entries WHERE company_id = X AND deleted_at IS NULL FOR UPDATE`. Блокировка на чтение защитит транзакцию от гонок.
2. В БД создадим уникальный индекс `CREATE UNIQUE INDEX unique_active_cidr ON entries (company_id, value_cidr) WHERE deleted_at IS NULL;` для защиты от дубликатов на уровне СУБД.
**Проблема 3: Пересечения внутри компании**
*Решение:* Перед INSERT/UPDATE выгружаем все активные подсети компании и проверяем через `new_cidr.overlaps(existing_cidr)`. Выгрузка делается в рамках заблокированной транзакции (см. пункт выше).
---
## 4. Поэтапный план реализации
### Этап 1. Ядро и База данных (Бизнес-логика)
- [ ] Инициализация FastAPI проекта, настройка SQLModel.
- [ ] Определение сущностей БД: `Company`, `WhitelistEntry` (CIDR хранится как `String`, но Pydantic проверяет `IPv4Network`), `AuditLog`.
- [ ] Валидаторы (запрещенные списки Приложения А, маска /32 - /22). Нормализация `strict=False` в `ipaddress`, чтобы `192.168.1.5/24` автоматически перегонялось в `192.168.1.0/24`.
- [ ] Написание Unit-тестов для валидаторов.
### Этап 2. Слой данных (CRUD) и защита от гонок
- [ ] Сервис создания записи: проверка макс. лимита (15 по умолчанию или `company.custom_limit`), поиск пересечений, запись AuditLog.
- [ ] Сервис Soft-Delete и редактирования.
- [ ] Тесты CRUD-сервисов.
### Этап 3. Авторизация (Keycloak)
- [ ] Настройка `auth/jwt.py` для валидации RS256 подписей.
- [ ] Парсинг токена на основе гибких правил из `.env` (роли, список компаний).
- [ ] FastAPI Security Depends (`get_current_user`).
### Этап 4. Внешний API (Export Endpoint)
- [ ] Роут `GET /api/v1/export/whitelist.txt`.
- [ ] Выборка всех `value_cidr` где `deleted_at IS NULL`.
- [ ] Агрегация: `[str(net) for net in ipaddress.collapse_addresses(net_list)]`.
- [ ] Middleware для ограничения доступа по списку разрешенных `EXPORT_ALLOWED_IPS`.
### Этап 5. Пользовательский Интерфейс (UI)
- [ ] Jinja2 шаблоны и использование HTMX для добавления/удаления строк таблицы без перезагрузки всей страницы.
- [ ] Отображение предупреждений (нормализация, превышение лимита).
- [ ] Селектор активной компании.
- [ ] Панель администратора (все компании, настройка `custom_limit`, просмотр аудита).
### Этап 6. Инфраструктура
- [ ] Dockerfile.
- [ ] docker-compose окружение (App + Postgres).
- [ ] Документация (README с описанием переменных окружения).