docs: STATE.md — итоги ветки sonnet (edit, audit, admin, CIDR aggregation)

This commit is contained in:
“Naeel”
2026-05-30 09:17:05 +03:00
parent 3b46ad1a08
commit 9ad7eb9a8d
+96 -1
View File
@@ -1,4 +1,99 @@
# Состояние проекта на 2026-05-30 (коммит `2fb4548`)
# Состояние проекта на 2026-05-30 (ветка `sonnet`)
## Репозитории
| Репо | URL | Ветка | Локальный путь |
|---|---|---|---|
| Код приложения | `https://gitea.services.ngcloud.ru/Nail/ipwhitelist-app.git` | **sonnet** | `/home/naeel/ipwhitelist-app` |
| Документация | `https://gitea.services.ngcloud.ru/Nail/IPWhiteList.git` | main | `/home/naeel/IPWhiteList` |
## Стек
Node.js + Express + EJS + PostgreSQL + pg pool + jsonwebtoken
## Деплой
- URL: `https://white.nodejsk8s.dev.nubes.ru`
- DEV_MODE=true (мок-аутентификация)
- ⚠️ Нужен передеплой Nubes для ветки sonnet
## БД
- `write.bde8229b-1381-4330-b24b-727ad73fcb44.dev.nubes.ru`
- user: `super`, db: `ipwhitelist`
- Миграция от 2026-05-30 применена (CHECK, UNIQUE, индексы)
---
## Что сделано в ветке `sonnet` (4 коммита поверх master)
### 1. `src/validators.js` — CIDR агрегация
- `aggregateCIDRs(cidrs)` — суммаризация: merge пересекающихся + смежных диапазонов → минимальный набор CIDR
- Вспомогательные: `numToIP(n)`, `rangeToCIDRs(start, end)`
- Экспортируется и используется в `/export`
### 2. `src/auth.js` — admin-роль
- `ADMIN_CLIENT_ID` = `process.env.ADMIN_CLIENT_ID || 'WZ01112'`
- `req.user.isAdmin` — определяется по `clientId === ADMIN_CLIENT_ID`
- `DEV_ADMIN=true` в `.env` → admin-права в dev-режиме
- `requireAdmin` middleware — 403 для не-admin
### 3. `src/queries.js` — новые функции
- `getCompanyById(id)` — компания по числовому PK
- `getAllCompanies()` — все компании + `active_count` (LEFT JOIN)
- `setLimit(companyId, newLimit)` — установить/сбросить (null) индивидуальный лимит
- `getAudit()` — обновлён: JOIN с companies (поля `company_name`, `client_id`)
### 4. `server.js` — новые роуты
- `/export` — публичный (до auth.middleware), возвращает агрегированный список всех компаний
- `GET /` — admin: видит все компании с переключателем `?company=X`
- `POST /edit/:id` — редактирование записи (admin + user)
- `GET /audit` — журнал аудита (только admin)
- `GET /admin` — управление лимитами (только admin)
- `POST /admin/limit/:companyId` — изменить/сбросить лимит компании
- `backUrl()` — хелпер для редиректа обратно с учётом контекста admin/user
### 5. `views/index.ejs`
- Admin-панель выбора компании (dropdown + быстрые ссылки на Аудит/Лимиты)
- Кнопки Аудит/Лимиты/Выйти в header для admin
- Кнопка "Изменить" в таблице (открывает edit modal)
- Edit modal — overlay с формой, закрывается по Escape/backdrop
- Скрытый `company_id` в формах add/delete для корректной admin-ветки
### 6. `views/audit.ejs` — **новый**
- Таблица журнала аудита с фильтром по компании
- Цветные badges (CREATE/UPDATE/DELETE)
- old_value → new_value стрелочкой
### 7. `views/admin.ejs` — **новый**
- Таблица всех компаний: client_id, active_count, лимит
- Прогресс-бар использования (зелёный/янтарный/красный)
- Форма изменения лимита с подтверждением; кнопка ↺ сброс на дефолт
---
## Не сделано (production-hardening, не баги)
- helmet (X-Frame-Options, CSP, HSTS)
- rate-limit на POST /add, /delete, /export
- CSRF-токены в формах
- JWT-верификация через внешний JWKS (нужен URL от девопсов)
- Multi-company (нужен формат claims от платформы — массив clientId?)
## Мёртвый код (не критично)
- `isSubnetOf()` в validators.js — определена, не используется, не экспортируется
## Для прода
Выставить в `.env`:
```
NODE_ENV=production
JWKS_URL=<auth-api JWKS URL>
ADMIN_CLIENT_ID=<clientId администратора>
DEFAULT_LIMIT=15
```
## Репозитории