init: ТЗ, правила copilot, планы от моделей (DeepSeek, Claude, GPT-5.4, Gemini)

This commit is contained in:
“Naeel”
2026-05-29 19:54:41 +03:00
commit 65de34ba4a
6 changed files with 948 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
# План разработки — 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 с описанием переменных окружения).