From e09546f3e1eb35251937f939a6ac7a38e8b434e5 Mon Sep 17 00:00:00 2001 From: Magnus Root Date: Fri, 17 Apr 2026 10:31:18 +0300 Subject: [PATCH] Added database_schema --- DATABASE_SCHEMA.md | 230 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 DATABASE_SCHEMA.md diff --git a/DATABASE_SCHEMA.md b/DATABASE_SCHEMA.md new file mode 100644 index 0000000..8b5f77e --- /dev/null +++ b/DATABASE_SCHEMA.md @@ -0,0 +1,230 @@ +# grafana_gen — схема базы данных + +База данных PostgreSQL `waf_info`. Утилита работает в режиме **только чтение** — данные не изменяются. + +--- + +## Таблицы + +### `sp_info` + +Автоматически заполняемый список ресурсов из ServicePipe. + +| Колонка | Тип | Описание | +|---|---|---| +| `sid` | `text` | Идентификатор ресурса (SID). NULL-записи игнорируются | +| `domain_name` | `text` | Основной домен ресурса | +| `aliases` | `jsonb` | JSON-массив дополнительных доменов | + +**Пример:** +```sql +SELECT sid, domain_name, aliases FROM sp_info WHERE sid IS NOT NULL LIMIT 3; +``` +``` + sid | domain_name | aliases +--------+------------------------+---------------------------------- + 10307 | nationallottery.ru | ["www.nationallottery.ru"] + 11768 | fonbet-adapter.cloud.nationallottery.ru | [] + 14048 | self.nationallottery.ru | [] +``` + +--- + +### `manual_info` + +Ресурсы добавленные вручную (аналогична по структуре `sp_info`). + +| Колонка | Тип | Описание | +|---|---|---| +| `sid` | `text` | Идентификатор ресурса | +| `domain_name` | `text` | Основной домен | +| `aliases` | `jsonb` | JSON-массив дополнительных доменов | + +> Обе таблицы объединяются через `UNION` (без дублей). Если SID присутствует в обеих таблицах — берётся одна запись. + +--- + +### `apps_settings` + +Маппинг SID ресурса на клиента (тенанта). + +| Колонка | Тип | Описание | +|---|---|---| +| `l7resourceid` | `text` | SID ресурса (FK к `sp_info.sid` / `manual_info.sid`) | +| `client_title` | `text` | Название клиента — имя тенанта в дашборде | + +**Пример:** +```sql +SELECT l7resourceid, client_title FROM apps_settings LIMIT 5; +``` +``` + l7resourceid | client_title +--------------+-------------- + 10307 | nloto + 11768 | nloto + 14048 | nloto + 15363 | gorodpay + 12266 | gardia +``` + +> Один клиент может иметь несколько SID. Все SID одного клиента группируются в одну строку дашборда. + +--- + +### `client_info` + +Настройки мониторинга и пороги алертов для каждого клиента. + +| Колонка | Тип | По умолчанию | Описание | +|---|---|---|---| +| `client_title` | `text` | — | Название клиента (PK, совпадает с `apps_settings.client_title`) | +| `rps_limit` | `integer` | NULL | Порог RPS для алерта. NULL = алерт не создавать | +| `rps_commercial_limit` | `integer` | NULL | Коммерческий лимит RPS — синяя линия на графике. NULL → 100 | +| `four_hundred` | `integer` | NULL | Порог 4xx ошибок в процентах. NULL = алерт не создавать | +| `five_hundred` | `integer` | NULL | Порог 5xx ошибок в процентах. NULL = алерт не создавать | + +**Пример:** +```sql +SELECT client_title, rps_limit, rps_commercial_limit, four_hundred, five_hundred +FROM client_info +ORDER BY client_title; +``` +``` + client_title | rps_limit | rps_commercial_limit | four_hundred | five_hundred +--------------+-----------+----------------------+--------------+-------------- + gardia | 500 | 300 | 20 | 10 + gorodpay | 1000 | 800 | 20 | 10 + nloto | 7000 | 5000 | 20 | 10 + inferit | NULL | NULL | NULL | NULL +``` + +> Если `rps_limit = NULL` — алерт на RPS не создаётся, но клиент всё равно попадает в дашборд. +> Если `four_hundred = NULL` или `five_hundred = NULL` — соответствующий алерт не создаётся. + +--- + +## Основной запрос + +Утилита использует один объединённый запрос для получения всех данных: + +```sql +SELECT + s.sid, + s.domain_name, + s.aliases, + a.client_title, + ci.rps_limit, + ci.rps_commercial_limit, + ci.four_hundred, + ci.five_hundred +FROM ( + SELECT sid, domain_name, aliases FROM sp_info WHERE sid IS NOT NULL + UNION + SELECT sid, domain_name, aliases FROM manual_info WHERE sid IS NOT NULL +) s +LEFT JOIN apps_settings a ON s.sid = a.l7resourceid +LEFT JOIN client_info ci ON a.client_title = ci.client_title +ORDER BY a.client_title, s.sid; +``` + +Ресурсы без привязки к клиенту (`client_title IS NULL`) — **пропускаются**. + +--- + +## Управление данными + +### Добавление нового клиента + +```sql +-- Шаг 1: ресурс появится автоматически из sp_info (если интеграция настроена) +-- Или добавить вручную: +INSERT INTO manual_info (sid, domain_name, aliases) +VALUES ('99999', 'example.com', '["www.example.com"]'); + +-- Шаг 2: привязать ресурс к клиенту +INSERT INTO apps_settings (l7resourceid, client_title) +VALUES ('99999', 'Название клиента'); + +-- Шаг 3: задать пороги алертов +INSERT INTO client_info (client_title, rps_limit, rps_commercial_limit, four_hundred, five_hundred) +VALUES ('Название клиента', 1800, 1200, 20, 10); +``` + +### Добавление нового ресурса к существующему клиенту + +```sql +-- Только шаг 1 и 2: +INSERT INTO manual_info (sid, domain_name, aliases) +VALUES ('88888', 'new-domain.example.com', '[]'); + +INSERT INTO apps_settings (l7resourceid, client_title) +VALUES ('88888', 'Название клиента'); +-- Пороги алертов уже есть в client_info — добавлять не нужно +``` + +### Изменение порогов алертов + +```sql +UPDATE client_info +SET rps_limit = 2000, four_hundred = 30 +WHERE client_title = 'Название клиента'; +``` + +### Отключение алерта для клиента + +```sql +-- Отключить только RPS алерт +UPDATE client_info SET rps_limit = NULL WHERE client_title = 'Название клиента'; + +-- Отключить все алерты +UPDATE client_info +SET rps_limit = NULL, four_hundred = NULL, five_hundred = NULL +WHERE client_title = 'Название клиента'; +``` + +### Удаление клиента из дашборда + +```sql +-- Удалить привязку всех ресурсов клиента +DELETE FROM apps_settings WHERE client_title = 'Название клиента'; + +-- Удалить пороги (опционально) +DELETE FROM client_info WHERE client_title = 'Название клиента'; +``` + +### Просмотр всех клиентов с их ресурсами + +```sql +SELECT + a.client_title, + COUNT(s.sid) AS domain_count, + array_agg(s.sid ORDER BY s.sid) AS sids, + ci.rps_limit, + ci.four_hundred, + ci.five_hundred +FROM ( + SELECT sid FROM sp_info WHERE sid IS NOT NULL + UNION + SELECT sid FROM manual_info WHERE sid IS NOT NULL +) s +JOIN apps_settings a ON s.sid = a.l7resourceid +LEFT JOIN client_info ci ON a.client_title = ci.client_title +GROUP BY a.client_title, ci.rps_limit, ci.four_hundred, ci.five_hundred +ORDER BY a.client_title; +``` + +--- + +## Влияние данных на генерацию + +| Данные | Влияние | +|---|---| +| Новый SID в `sp_info`/`manual_info` + запись в `apps_settings` | Новый домен добавится в строку клиента | +| Новый `client_title` в `apps_settings` | Новая строка клиента в дашборде | +| Изменение `rps_limit` | Пересоздание алерта RPS, обновление красной линии на графике | +| Изменение `rps_commercial_limit` | Обновление синей линии на графике | +| Изменение `four_hundred` / `five_hundred` | Пересоздание алертов 4xx/5xx | +| NULL в `rps_limit` | Алерт RPS удаляется (или не создаётся) | +| Удаление из `apps_settings` | Клиент/домен исчезает из дашборда при следующем запуске | + +> Изменения в БД обнаруживаются через хэш (`alerts_hash` в `state.json`). При изменении любого порога — алерты пересоздаются автоматически при следующем запуске.