db(schema): v8.20 — add projects.regions INT[] for subject-level filtering
Adds INT[] column + GIN index to support 89-code regions (Plan 6). region_mask/region_mode kept for backward-compat (DEPRECATED, removal in Plan 6.5). Empty array semantically equivalent to legacy region_mask=255 (all of Russia). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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:**
|
||||
|
||||
+14
-3
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user