diff --git a/db/CHANGELOG_schema.md b/db/CHANGELOG_schema.md index 04c15e84..28809983 100644 --- a/db/CHANGELOG_schema.md +++ b/db/CHANGELOG_schema.md @@ -6,6 +6,26 @@ **История записей:** +## v8.20 от 2026-05-14 (Plan 6 — Subject-level regions) + +**Изменения:** +- `projects` +1 колонка: `regions INT[] NOT NULL DEFAULT '{}'` +- `projects` +1 GIN-индекс: `idx_projects_regions` +- `projects` +1 COMMENT ON COLUMN на `regions` + +**Не изменено (deprecated, удаление в Plan 6.5):** +- `projects.region_mask` (помечен inline-комментарием DEPRECATED) +- `projects.region_mode` +- CHECK `chk_projects_region_mask_range` + +**Семантика:** +- `regions=[]` → «вся РФ» (паритет с legacy `region_mask=255 + region_mode='include'`) +- `regions=[77,82]` → проект принимает лиды только из Москвы (77) и Чукотки (82) + +**Schema baseline после v8.20:** 63 базовых таблиц / 12 партиций / **118 индексов** (+1) / 39 RLS / 5 функций / 13 триггеров. + +**Связано:** docs/superpowers/specs/2026-05-14-plan-6-regions-subject-level-design.md + ## v8.20 (11.05.2026 — Plan 5) **Added:** diff --git a/db/schema.sql b/db/schema.sql index f740c9a0..aab41cec 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -1,7 +1,8 @@ -- ============================================================================= -- schema.sql — единая схема БД для SaaS-аналога crm.bp-gr.ru («Лидерра») --- Версия: v8.20 (11.05.2026 — Plan 5 frontend projects UI: projects.archived_at TIMESTAMPTZ NULL для soft archive flow; tenants.limits JSONB NOT NULL DEFAULT '{}' для per-tenant project/user лимитов) --- Метрики: 63 базовые таблицы (61 regular + 2 partitioned parents: deals + supplier_lead_costs) + 12 партиций / 117 индексов / 39 RLS-политик / 5 функций / 13 триггеров +-- Версия: v8.20 от 2026-05-14 (Plan 6 — Subject-level regions array) +-- Метрики: 63 базовые таблицы (61 regular + 2 partitioned parents: deals + supplier_lead_costs) + 12 партиций / 118 индексов / 39 RLS-политик / 5 функций / 13 триггеров +-- Базовая версия: v8.20 (11.05.2026 — Plan 5 frontend projects UI: projects.archived_at TIMESTAMPTZ NULL для soft archive flow; tenants.limits JSONB NOT NULL DEFAULT '{}' для per-tenant project/user лимитов) -- Базовая версия: v8.19 (11.05.2026 — Plan 4 billing+csv+admin: tenants.delivered_in_month, lead_charges.charge_source + CHECK, supplier_leads.recovered_from_csv_at, supplier_csv_reconcile_log) -- Базовая версия: v8.18 (10.05.2026 — Plan 2/5 Task 1: supplier_leads SaaS-level + projects.delivered_today + 2 system_settings rows для supplier-webhook + IP allowlist defense-in-depth) -- Базовая версия: v8.17 (10.05.2026 — Plan 1/5 Task 2 fix: FK projects.supplier_b{1,2,3}_project_id → supplier_projects (ON DELETE SET NULL) + 3 partial index + CHECK chk_projects_b1_not_for_sms (defense-in-depth дублирует chk_supplier_projects_b1_not_for_sms на Project-уровне). Закрывает code-review BLOCKER#1 + WARNING#3 от 10.05.2026 поздний вечер) @@ -808,13 +809,18 @@ CREATE TABLE projects ( supplier_b3_project_id BIGINT, effective_limit_calculated_at TIMESTAMPTZ, -- РАСШИРЕНИЕ v8.2: регионы и дни (партия 10.3 секции 6, 7, 11) - region_mask INT NOT NULL DEFAULT 255, + region_mask INT NOT NULL DEFAULT 255, -- DEPRECATED Plan 6.5: см. regions INT[] -- битмаска 8 ФО РФ: бит 1=Центральный, 2=Северо-Западный, 4=Южный, -- 8=Северо-Кавказский, 16=Приволжский, 32=Уральский, 64=Сибирский, -- 128=Дальневосточный. 255 = все 8 округов. region_mode VARCHAR(10) NOT NULL DEFAULT 'include' CHECK (region_mode IN ('include','exclude')), -- 'include' = принимать только из выбранных, 'exclude' = принимать кроме выбранных + -- v8.20 (Plan 6): Subject-level regions array. 89 codes из resources/js/constants/regions.ts. + -- Пустой массив = «вся РФ» (паритет с legacy region_mask=255 + region_mode='include'). + -- region_mask/region_mode остаются для legacy reader'ов (PhonePrefixService, LeadRouter), + -- DEPRECATED — удаляются в Plan 6.5 после переключения читателей. + regions INT[] NOT NULL DEFAULT '{}'::INT[], delivery_days_mask INT NOT NULL DEFAULT 127, -- битмаска дней недели: бит 1=Пн, 2=Вт, 4=Ср, 8=Чт, 16=Пт, 32=Сб, 64=Вс. -- 127 = все 7 дней (паритет с формой создания нового проекта в оригинале). @@ -862,6 +868,8 @@ CREATE INDEX idx_projects_tag ON projects(tag); -- РАСШИРЕНИЕ v8.12: composite index для lookup по signal-полям (resolveSignalSource) CREATE INDEX idx_projects_tenant_signal ON projects(tenant_id, signal_type, signal_identifier); +-- v8.20 (Plan 6): GIN-индекс для outbound regions queries. +CREATE INDEX idx_projects_regions ON projects USING GIN (regions); COMMENT ON COLUMN projects.daily_limit_target IS 'Целевой дневной лимит лидов, заданный клиентом. Фактический лимит на ' @@ -873,6 +881,9 @@ COMMENT ON COLUMN projects.effective_daily_limit_today IS 'MIN(daily_limit_target, FLOOR(balance / lead_cost)). Пересчитывается cron ' 'limits:recalc в 00:00 МСК и при изменении баланса. NULL = не считалось.'; +COMMENT ON COLUMN projects.regions IS + 'Subject-level region filter (1..89 коды субъектов РФ). Пустой массив = вся РФ. Plan 6 (v8.20).'; + -- ----------------------------------------------------------------------------- -- supplier_projects — SaaS-level агрегатные проекты у поставщиков (v8.13, Plan 1/5 Task 2)