Сводный концепт модульной data-архитектуры. Применяется ко всем 6 сайтам портфеля. Один раз разработали — годы используем.
Принцип cross-fire: один API-ключ Supabase, один Looker аккаунт, одни правила — 6 проектов получают общую инфраструктуру.
| Слой | Технология | Зачем |
|---|---|---|
| База данных | Supabase (PostgreSQL) | Schemas per block, RLS, triggers, Realtime |
| Event bus | Postgres NOTIFY/LISTEN + Supabase Realtime | Блоки общаются без tight coupling |
| API | Supabase REST + Edge Functions | Auto-generated REST от схем + custom logic |
| Auth / RLS | Supabase Auth + Row Level Security | Безопасность per-role |
| Migrations | Supabase migrations в git | Версионирование схем |
| Dashboards | Looker Studio (connector PostgreSQL) | Визуализация метрик |
| CMS | WordPress + Bricks + ACF Pro | Менеджерская админка |
| Scripts | Python + Node.js | ETL, cron jobs, bulk operations |
| AI layer (future) | Claude API | Блок 9 — AI Analyst |
Что: все URL сайта с метаданными (шаблон, тир, статус, slug)
Exports: urls_master, templates, tags, redirects
Imports: ничего (фундамент)
Events: url_added, url_updated, url_deleted
Что: H1, title, meta, OG, Schema.org, блоки на странице
Exports: pages, blocks_config
Imports: CORE.urls_master.id
Events: content_updated, block_toggled
Что (специфично для проекта):
Схема универсальная, контент — проектный.
Что: данные GSC, GA4, Яндекс.Метрика, Яндекс.Вебмастер
Exports: gsc_daily, metrika_daily, ga4_daily, webmaster_queries
Imports: CORE.urls_master.id (чтобы привязать метрики к нашим URL)
Cron: ежедневный sync в 03:00 UTC
Events: traffic_spike, traffic_drop
Что: позиции в Google/Яндекс, ключевые слова, обратные ссылки (Ahrefs / Firehose / Keys.so)
Exports: positions, keywords_master, backlinks, indexation_status
Imports: CORE.urls_master.id
Events: position_dropped, deindexed, new_backlink
Что: заявки с сайта, бронирования, доходы
Exports: requests, bookings
Imports: CORE.urls_master.id (с какой страницы пришёл), HOTELS/PROGRAMS.id
Events: new_lead, booking_confirmed, revenue_recorded
Что: подписки на Web Push, email-лист, лог отправок
Exports: push_subscriptions, email_list, sent_log
Subscribes: price_updated, hot_tour, new_lead
Events: notification_sent, unsubscribed
Что: администраторы, роли, полный audit log
Exports: users, roles, audit_log
Subscribes: все события всех блоков (для audit)
Слой Claude API поверх 8 блоков. Не хранит данных — читает views других блоков, генерирует приоритизированные рекомендации и ловит аномалии.
Workflow (ежедневно, 04:00):
ai.recommendations → DashboardЭкономика: $150-450/мес vs SEO-специалист 100-200k ₽/мес. ROI ×5-10.
Когда делаем: после стабильной работы 8 блоков, примерно Q3 2026.
{
"name": "core",
"version": "1.0.0",
"status": "active",
"exports": {
"tables": ["urls_master", "templates", "tags", "redirects"],
"views": ["published_urls", "urls_by_template"],
"api": ["GET /urls", "POST /urls", "DELETE /urls/:id"]
},
"imports": {
"none": "ядро не зависит от других блоков"
},
"events_emitted": [
"url_added", "url_updated", "url_deleted", "template_changed"
],
"events_subscribed": [],
"health_check": "SELECT COUNT(*) > 0 FROM urls_master",
"can_disable": false,
"owners": ["system"],
"retention": "infinite"
}
Каждое ТЗ проходит 5 разных проверок:
| # | Pass | Вопросы |
|---|---|---|
| 1 | Полнота | Все поля / связи / edge-case описаны? |
| 2 | Связи | Все imports/exports/events учтены? |
| 3 | Обратная совместимость | Все старые запросы продолжат работать? |
| 4 | Безопасность | RLS / audit / sensitive поля защищены? |
| 5 | Масштабируемость | Выдержит ×10 нагрузку? |
Между passes — пауза (минимум 1 час). Чтобы увидеть свежим глазом.
| ❌ Запрещено | ✅ Разрешено |
|---|---|
| ALTER TABLE DROP COLUMN | ALTER TABLE ADD COLUMN DEFAULT NULL |
| DROP TABLE | CREATE TABLE новой |
| Переименовать поле | Создать новое + синоним/view |
| Удалить API endpoint | Пометить @deprecated + создать v2 |
| Удалить событие | Добавить новое опциональное поле |
Каждая посадочная страница = скелет (обязательный) + опциональные блоки. Менеджер в админке чекбоксами решает какие блоки показывать на конкретной странице.
Ключевое правило: нет контента → блок НЕ рендерится. Никаких «Coming soon» заглушек.
Страна «Турция»: ✓ курорты · ✓ погода · ✓ цены · ✓ достопримечательности · ✗ горнолыжка · ✗ свадебные
Страна «Мальдивы»: ✗ курорты (атоллы) · ✓ погода · ✓ цены · ✗ достопримечательности · ✗ горнолыжка · ✓ свадебные
Страна «Индия» (ayurtour): ✓ программы · ✓ аюрведа · ✓ йога · ✓ виза · ✓ погода · ✗ горнолыжка
Один шаблон — разные конфигурации per page.
| # | Шаблон | Пример (bestonline) | Эквивалент (ayurtour) |
|---|---|---|---|
| 1 | Homepage | / | / |
| 2 | Country landing | /turkey/ | /india/ |
| 3 | Region landing | /turkey/antalya/ | /india/kerala/ |
| 4 | Resort / City | /turkey/antalya/belek/ | /india/kerala/kovalam/ |
| 5 | Entity page | Hotel: /turkey/hotel-slug/ | Program: /panchakarma/weight-loss/ |
| 6 | City-from landing | /turkey/from-moscow/ | /india/from-moscow/ |
| 7 | Month landing | /turkey/june/ | /india/october/ |
| 8 | Brand landing | /brand/hilton/ | /program/kerala-panchakarma/ |
| 9 | Niche landing | /turkey/wedding/ | /ayurveda/anti-aging/ |
| 10 | Category listing | /turkey/hotels/5-stars/ | /ayurveda/all/ |
| 11 | Attraction | /turkey/attractions/pamukkale/ | /india/attractions/taj-mahal/ |
| 12 | Blog article | /blog/article-slug/ | /blog/article-slug/ |
| 13 | Blog hub / tag | /blog/ | /blog/ |
| 14 | Search results | /search?... | /quiz |
| 15 | Legal / Info | /about/ | /about/ |
Пересекается (cross-fire): архитектурная модель, паттерны, технический стек, правила, reference-скрипты
НЕ пересекается (строгая изоляция): конкретные данные каждого проекта — отели, программы, URL, контент, SEO-позиции, leads, подписчики
| Уровень | Общее | Отдельное на проект |
|---|---|---|
| Архитектурная модель (8 блоков, контракты) | ✅ | |
| Паттерны (Safe Evolution, 5-pass, block-toggle) | ✅ | |
| Технический стек (Supabase, Looker, WP+Bricks) | ✅ | |
| 15 типов шаблонов (концептуально) | ✅ | |
| Правила развития (backward compat) | ✅ | |
| Reference-скрипты (validators, check-brands) | ✅ (шаблон) | ⚠️ Конфигурируются per project |
| Данные HOTELS/PROGRAMS | ❌ Изолированы | |
| Конкретные URL, контент, тайтлы | ❌ Изолированы | |
| SEO-позиции, keywords, backlinks | ❌ Изолированы | |
| Leads, bookings, revenue | ❌ Изолированы | |
| Push-подписчики, email-листы | ❌ Изолированы | |
| Audit log, admin users | ❌ Изолированы (ФЗ-152) | |
| Supabase project / schemas | ❌ Свой на каждый сайт | |
| Api-токены, секреты | ❌ В SECRETS.local.md проекта |
Портфель = организм из 6 клеток.
В каждой клетке (сайте) — одна ДНК (архитектура, принципы, паттерны). Но клетки выполняют разные функции: одна отвечает за туры, другая за аюрведу, третья за визы.
Гены общие, выражение разное.
| Сайт | Supabase project | Статус |
|---|---|---|
| bestonline-tour.ru | bestonline-tour-db | ❌ Планируется |
| ayurtour.ru | ayurtour-workjet-analytics | ✅ Активен |
| evisa24.ru | evisa24 + AIproject | ⚠️ После restore, пустые |
| panchakarma-india.ru | panchakarma-india-db | ❌ Планируется |
| visa-russian.com | visa-russian-db | ❌ Планируется |
| viza-india.ru | viza-india-db | ❌ Планируется |
Каждый проект:
Вариант А (рекомендую): Отдельный Supabase project на каждый сайт
Вариант Б (не рекомендую): один Supabase с отдельными schemas per сайт
| Сайт | Тематика | HOTELS/PROGRAMS | Специфика |
|---|---|---|---|
| bestonline-tour.ru | Турагентство | 28k отелей из Tourvisor | Мета-агрегатор 150+ ТО |
| ayurtour.ru | Аюрведа-туры | Программы + отели-партнёры | E-E-A-T, экспертный контент |
| panchakarma-india.ru | Sister-site ayurtour | Программы панчакармы | Узкая медицинская ниша |
| evisa24.ru | Визы РФ/СНГ | Страны × типы виз | Supabase уже используется |
| visa-russian.com | Виза в РФ для иностранцев | 9 языков × визы | Cloudflare Pages |
| viza-india.ru | Визы в Индию | Типы виз × кейсы | Узкая ниша |
1 раз построили data-архитектуру → 6 сайтов работают по одной модели.
| Фаза | Время | Что |
|---|---|---|
| 0. Спека | 1-2 дня | ТЗ всех блоков × 5-pass review |
| 1. Foundation | 1-2 дня | Supabase schemas, CORE блок, migrations, health checks |
| 2. Первые 3 блока | 3-5 дней | CORE + CONTENT + HOTELS/PROGRAMS + master view + Looker MVP |
| 3. Analytics & SEO | 1 неделя | ANALYTICS + SEO + cron sync GSC/Метрика/Яндекс |
| 4. Event Bus | 1 неделя | Supabase Realtime + triggers + cross-block events |
| 5. Остальные блоки | 2 недели | LEADS + NOTIFICATIONS + ADMIN + полные dashboards |
| 6. AI Analyst (future) | 1 неделя | Claude API интеграция (Q3 2026) |
| Угроза | Защита |
|---|---|
| Блок X выключен — система падает | Graceful degradation (COALESCE, LEFT JOIN) |
| Схема изменилась — старые скрипты упали | Migrations only forward, backward compat |
| Человек случайно удалил поле | Migrations в git, RLS запрещает DELETE в prod |
| Данные не синхронизированы между блоками | Валидаторы консистентности + AI-аномалии |
| Cron упал — данные устарели | Health checks + alert если данные > 24h |
| API провайдер отвалился | Кеш последних данных + retry + fallback |
| Pump'ом миграция в прод | Canary deployment (5% → 20% → 100%) |
| Несовместимый deploy | Contract tests перед мерджем |
| Looker Studio | Свой дашборд (Custom) | |
|---|---|---|
| Для чего | Data exploration, аналитика | Operational cockpit, действия |
| Юзер | Менеджер (фильтры, отчёты) | Админ (решения, алерты) |
| Дизайн | Шаблоны Google | Наш стиль портфеля |
| Интеракция | View-only | Click → действие |
| AI-интеграция | ❌ | ✅ Встроенный помощник |
| Разработка | Быстро (drag-drop) | Медленнее (код) |
dashboard.{site}.ru (свой поддомен)
├── Frontend: Vanilla JS + Chart.js
├── Data: Supabase REST API + Realtime WebSocket
├── Auth: Supabase Auth (Basic Auth для MVP)
├── Hosting: Cloudflare Pages (бесплатно)
├── AI: Claude API через Supabase Edge Function
└── Style: единый дизайн с сайтом
Слой 10: CUSTOM DASHBOARD (UI для всех блоков) ↑ читает Слой 9: AI ANALYST (Claude API) ↑ анализирует Слои 1-8: 8 блоков данных (Supabase)
И Looker, и Custom читают одни и те же views — консистентность данных:
-- VIEW: master dashboard CREATE VIEW public.v_url_status AS SELECT u.url, u.tier, u.template_type, u.status, c.h1, c.title, c.blocks_enabled, a.clicks, a.impressions, a.position, s.indexation_status, l.requests_count FROM core.urls_master u LEFT JOIN content.pages c ON c.url_id = u.id LEFT JOIN analytics.v_gsc_last30 a ON a.url_id = u.id LEFT JOIN seo.indexation_status s ON s.url_id = u.id LEFT JOIN leads.v_requests_last30 l ON l.url_id = u.id;
Если какой-то блок не работает — в колонках NULL, dashboard не падает.
В дашборде https://dashboard.ayurtour.ru/tz/ :
Пароль дашборда: ayurtour2026
Архитектурное место: блок LEADS (слой 6) + дополнение для блока ANALYTICS (активность менеджеров).
Цель: автоматически тянуть из Битрикс24 всё что может помочь бизнесу и AI-аналитику.
| Сущность | API endpoint / event | Зачем нам | Приоритет |
|---|---|---|---|
| Сделки (deals) | crm.deal.list / ONCRMDEALADD, ONCRMDEALUPDATE | Воронка продаж, конверсия, средний чек | 🔴 P0 |
| Лиды | crm.lead.list / ONCRMLEADADD | Входящий поток, источники | 🔴 P0 |
| Контакты | crm.contact.list | База клиентов, сегментация | 🔴 P0 |
| Компании | crm.company.list | B2B-клиенты, корп-заказы | 🟡 P1 |
| Товары / прайсы | crm.product.list | Если в Битриксе заводятся пакеты туров | 🟡 P1 |
| Реквизиты | crm.requisite.list | Документооборот | 🟢 P2 |
| Кастомные поля | crm.deal.userfield.list | Страна тура, URL сайта, тур-параметры | 🔴 P0 |
| Сущность | API / event | Зачем нам | Приоритет |
|---|---|---|---|
| Звонки | voximplant.statistic.get / ONVOXIMPLANTCALLEND | Кто когда звонил, длительность, запись | 🔴 P0 |
| Записи звонков (mp3) | URL из VoxImplant | Транскрипция → AI анализ FAQ клиентов | 🔴 P0 (золото) |
| SMS | messageservice.message.list | Рассылки, уведомления | 🟡 P1 |
| Email активность | crm.activity.list (type=4) | История переписки с клиентом | 🟡 P1 |
| Чаты OpenLines (WhatsApp, Telegram) | imopenlines.* | Мессенджер-общение с клиентами | 🔴 P0 |
| Встречи | crm.activity.list (type=1) | Календарь менеджеров | 🟢 P2 |
| Сущность | API / event | Зачем нам | Приоритет |
|---|---|---|---|
| Задачи менеджеров | tasks.task.list | KPI, нагрузка, завершаемость | 🟡 P1 |
| Комментарии к задачам | tasks.commentitem.getlist | Нюансы сделок, коммуникация | 🟢 P2 |
| Трекер времени | tasks.task.history.list | Сколько ушло на клиента | 🟢 P2 |
| Пользователи (менеджеры) | user.get | Справочник, роли | 🟡 P1 |
| Отделы | department.get | Структура компании | 🟢 P2 |
| Бизнес-процессы | bizproc.* | Автоматизации, флоу | 🟢 P2 |
| Сущность | API | Зачем нам | Приоритет |
|---|---|---|---|
| Воронка продаж | crm.status.list | Стадии и конверсия между | 🔴 P0 |
| Источники лидов | crm.status.list (source) | Откуда приходят заявки | 🔴 P0 |
| История изменений сделки | crm.deal.history.list | Когда на какой стадии был | 🟡 P1 |
| Счета / оплаты | sale.payment.list | Фактическая выручка | 🟡 P1 |
Каждый звонок менеджера = запись mp3 + транскрипция (Whisper) + AI-анализ.
Это золотая жила для продуктовых решений. Ни один конкурент этого не делает.
-- Сырые события (аудит, всегда) leads.bitrix_events (event_type, payload jsonb, received_at) -- Нормализованные сущности leads.deals (bitrix_id, title, stage, amount, contact_id, ...) leads.leads (bitrix_id, source, status, ...) leads.contacts (bitrix_id, name, phone, email, ...) leads.companies (bitrix_id, name, inn, ...) -- Коммуникации leads.calls (bitrix_id, duration, record_url, contact_id, transcript) leads.messages (channel, from, to, text, timestamp) leads.activities (type, subject, contact_id, ...) -- Аналитика leads.pipeline_stages (bitrix_id, name, order, probability) leads.user_performance (user_id, deals_closed, revenue, avg_deal_size)
| Событие | Что ловим | P0/P1/P2 |
|---|---|---|
ONCRMDEALADD | Новая сделка | 🔴 P0 |
ONCRMDEALUPDATE | Изменение сделки (стадия, сумма) | 🔴 P0 |
ONCRMLEADADD | Новый лид | 🔴 P0 |
ONCRMCONTACTADD | Новый контакт | 🔴 P0 |
ONVOXIMPLANTCALLEND | Завершение звонка | 🔴 P0 |
ONIMBOTJOINCHAT | Чат с клиентом в мессенджере | 🟡 P1 |
ONCRMACTIVITYADD | Email, встреча, задача | 🟡 P1 |
ONTASKADD | Новая задача менеджеру | 🟢 P2 |
bitrix-webhook-receiver — принимает любые webhooksleads.bitrix_events — raw payload всех событийONCRMDEALADD, ONCRMDEALUPDATE, ONCRMLEADADDОстальные сущности (звонки, чаты, задачи) — добавляем по мере надобности, архитектура уже готова.
company.bitrix24.rucrm (сделки/лиды/контакты), telephony (звонки), imopenlines (чаты)
Обновлено 24.04.2026 · Cross-fire портфеля — единая data-архитектура для 6 сайтов
Применяется ко всем проектам WORKJET portfolio