Путь данных
Кабинет устроен по стандартной схеме хранилищ данных «загрузить, потом преобразовать» (ELT), как сервисы приёма данных Airbyte и Fivetran: сначала данные сохраняются как пришли, потом раскладываются по столбцам.
Три канала — одни сырые данные
Заголовок раздела «Три канала — одни сырые данные»У источника три канала:
- адрес приёма — сайт, форма или сервис присылают данные сами;
- файл — история из CSV, Excel или буфера обмена;
- опрос по адресу — платформа сама по расписанию забирает JSON или CSV.
Что бы ни пришло, оно ложится событием в сырые данные — таблицу
raw.events: тело, разобранное из JSON или формы в jsonb без столбцов
и типов, плюс канал, время и пометки. Приём не предъявляет к данным
требований: нет обязательных полей, нет типов, нет схемы. Заявка ложится
всегда — даже пустая или с битым JSON, служебными ключами: потерять
обращение хуже, чем принять его с дырой.
Дальше канал никого не интересует: таблица, вебхуки и API различают его
только меткой (_channel в таблице, channel в API).
Таблица источника — за доли секунды
Заголовок раздела «Таблица источника — за доли секунды»Следом платформа раскладывает событие строкой в таблицу источника
sources.<имя>: поле верхнего уровня — столбец, новое поле — новый столбец,
у прежних строк в нём пусто. Вложенный объект или массив — значением
столбца jsonb: разбирать структуру за вас платформа не берётся,
но и не теряет — достанете своим SQL:
select a->>'q' as vopros, (a->>'points')::int as bally from sources.kviz, lateral jsonb_array_elements(result -> 'answers') a;Если вы держите таблицу своим долгим запросом, строка дождётся и ляжет позже — заявка уже в сырых данных и не теряется.
Один раз
Заголовок раздела «Один раз»Строка рождается из события один раз и дальше принадлежит вам. Платформа не строит таблицу заново из сырых данных — ни сама, ни кнопкой. Поэтому:
- ваша правка (
UPDATE) живёт, но необратима: прежнее значение остаётся только в событии вraw.events; - удалённую строку не воскресит новое событие — её возвращают из корзины;
- смена типа столбца идёт по значениям таблицы, а не по сырым данным.
Повторная отправка
Заголовок раздела «Повторная отправка»Двойной щелчок по кнопке формы шлёт два одинаковых события. Кабинет
сохраняет оба — события не выбрасываются, — но второе, пришедшее в течение
5 минут с тем же телом, помечает повторной отправкой (repeat_of). Это
тот же факт: строкой оно не становится, вебхук по нему не уходит,
а в корзину, обратно и насовсем оно идёт вслед за своим событием.
История и новые обращения
Заголовок раздела «История и новые обращения»Загрузка файла и первый запуск опроса — история: прошлое, а не новые обращения. Строки таблицы они дают как обычно, а вебхуки по ним молчат — ваша CRM не получит тысячу «новых заявок» из старой выгрузки. Следующее живое событие уйдёт вебхуком, как всегда.
Ваши объекты
Заголовок раздела «Ваши объекты»Всё, что вы строите на данных, — обычные объекты Postgres в вашей схеме
public: представления, таблицы, материализованные представления, функции.
Реестра у платформы нет — зависимости между объектами ведёт сам Postgres.
Кнопка «Дедупликация» создаёт такое же обычное представление.