From 8f4a67e476895bc1763fb043dffd9ce3d8ab7e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Sat, 30 May 2026 07:14:26 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=B0=D0=BA=D1=82=D1=83=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BF=D0=BB=D0=B0=D0=BD=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B5=20=D0=A2=D0=97=20?= =?UTF-8?q?=D0=B8=20=D1=80=D0=B5=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/plan-actual.md | 131 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 docs/plan-actual.md diff --git a/docs/plan-actual.md b/docs/plan-actual.md new file mode 100644 index 0000000..42444fb --- /dev/null +++ b/docs/plan-actual.md @@ -0,0 +1,131 @@ +# План разработки IP WhiteList — актуальный (30.05.2026) + +> Основан на ТЗ (`WhiteIPlist.txt`) и реальном состоянии кода. +> Все предыдущие планы (plan.md, plan-v2.md, plan-working.md, plan-gemini.md, plan-gpt54.md) устарели. + +--- + +## Что уже работает (не трогать) + +| Компонент | Файл | Состояние | +|---|---|---| +| Валидатор IPv4/CIDR | `src/validators.js` | ✅ Полный — все 14 диапазонов Приложения А | +| CRUD функции | `src/queries.js` | ✅ `createEntry`, `updateEntry`, `deleteEntry`, `listEntries`, `getExportCIDRs`, `getAudit` | +| Soft delete | `src/queries.js` + `sql/schema.sql` | ✅ `deleted_at`, `deleted_by` | +| Схема БД | `sql/schema.sql` | ✅ Все таблицы и индексы | +| Аудит-лог запись | `src/queries.js` | ✅ Пишется при CREATE/UPDATE/DELETE | +| UI главная страница | `views/index.ejs` | ✅ Стиль Nubes | +| Экспорт txt | `server.js GET /export` | ✅ Работает (без суммаризации) | +| Лимит + custom_limit | `src/queries.js` | ✅ | + +--- + +## Что есть в queries.js, но не подключено к роутам + +- `updateEntry` — написана, роута `POST /update/:id` нет, UI-кнопки нет +- `getAudit` — написана, роута и страницы нет +- `listEntries(companyId, includeDeleted=true)` — параметр есть, но нигде не вызывается с `true` + +--- + +## Что отсутствует полностью + +### A. Роуты (server.js) +- `POST /update/:id` — редактирование записи +- `GET /admin` — страница администратора +- `POST /admin/limit/:companyId` — изменение лимита компании +- `GET /admin/audit` — журнал аудита (только для admin) + +### B. UI (views/) +- Кнопка и inline-форма редактирования в таблице +- Страница admin (`views/admin.ejs`): + - Список всех компаний + - Записи с фильтром по компании + - Переключатель "показать удалённые" + - Журнал аудита + - Изменение лимита компании + +### C. Авторизация +- Текущий код: наивный base64 decode JWT — не проверяет подпись, не Keycloak +- Нужно: `openid-client` (OIDC), интеграция с Keycloak, проверка `clientID` и `email` из claims +- Admin-роль: `clientId === 'WZ01112'` — определяется из claim + +### D. Суммаризация CIDR в экспорте +- ТЗ требует агрегацию в минимальный набор CIDR +- Нужна библиотека: `npm install cidr-tools` или `ip-range-check` +- Или самописный merge (sorted ranges → contiguous merge) + +### E. Клиентская валидация +- ТЗ: валидация на клиенте обязательна, серверная — авторитетная +- Сейчас: только серверная +- Нужно: JS в index.ejs — проверить формат CIDR, маску /22–/32, не RFC1918 + +### F. Переключатель компаний +- ТЗ: пользователь может быть в нескольких компаниях (несколько `clientId` в токене) +- Нужно: UI-dropdown, переключение активного `clientId`, хранение выбора в сессии + +--- + +## Обнаруженные баги + +### overlaps() в validators.js — логическая ошибка + +```js +// Текущий код (неверно): +return a.start <= b.end && b.start <= a.start || + b.start <= a.end && a.start <= b.start; + +// Правильно: +return a.start <= b.end && b.start <= a.end; +``` + +Стандартное условие пересечения отрезков. Текущий код даёт false positive для некоторых смежных диапазонов. +**Приоритет: высокий** — влияет на корректность проверки пересечений. + +--- + +## Порядок реализации + +### Этап 1 — Критические фиксы (не ломают работу) +1. Исправить `overlaps()` в `validators.js` +2. Добавить `POST /update/:id` в `server.js` +3. Добавить кнопку редактирования + inline-форму в `views/index.ejs` + +### Этап 2 — Полнота ТЗ +4. Клиентская валидация (JS в index.ejs) +5. Суммаризация CIDR в `GET /export` (cidr-tools или ручной merge) +6. Определение admin-роли (`clientId === 'WZ01112'`) +7. Страница `/admin` + роут `GET /admin` +8. Роут `POST /admin/limit/:companyId` +9. Журнал аудита для admin (`GET /admin/audit`) + +### Этап 3 — Авторизация (блокирующая для продакшена) +10. `npm install openid-client` — OIDC Keycloak +11. Заменить auth middleware на реальную проверку токена +12. Убрать `DEV_MODE` (или оставить только для локальной разработки) + +### Этап 4 — Опционально +13. Переключатель компаний (multi-company claim) +14. Автотесты: `npm install --save-dev jest supertest` +15. Пагинация (только если лимит вырастет > 50) +16. Audit UI для клиента (не только admin) + +--- + +## Зависимости + +``` +openid-client — OIDC / Keycloak +cidr-tools — суммаризация CIDR в экспорте +``` + +Всё остальное — в рамках существующего стека (Express, EJS, pg). + +--- + +## Что НЕ нужно делать + +- Переписывать validators.js (только исправить overlaps) +- Переписывать queries.js — всё уже написано +- Менять схему БД — она полная +- Пересобирать стек — Express + EJS достаточно для ТЗ