Дашборд за 500 тысяч тенге: Как Скауту собрать сквозную аналитику для селлера, используя Looker Studio и Cloud Functions
Пятница, 23:00. Офис крупного селлера на барахолке в Алматы. Менеджер с красными глазами скачивает пятый за сегодня CSV-отчет из кабинета Kaspi Pay, выгружает расходы из Facebook Ads, тянет остатки из МойСклад и пытается свести это всё в гигантской Google Таблице с помощью ВПР (VLOOKUP). Таблица виснет, браузер просит пощады, а собственник бизнеса рвет на себе волосы: «Мы сделали оборот 25 миллионов тенге за месяц, где наши деньги?!». Знакомая боль? Именно в этот момент на сцену выходит выпускник Академии Скаутов OZAT, который продает решение этой проблемы за 500 000 тенге. И самое смешное — облачная инфраструктура для этого решения будет стоить бизнесу около двух долларов в месяц.
В чём заключалась реальная бизнес-проблема?
E-commerce в Казахстане, будь то продажа чехлов на Kaspi, выход на Wildberries или собственный интернет-магазин в Instagram, страдает от одной системной болезни — фрагментации данных. Селлер видит общую выручку (Gross Revenue), но абсолютно слеп в отношении юнит-экономики (Unit Economics) и чистой маржинальности (Net Profit Margin).
Почему так происходит?
- Разрозненные источники (Data Silos): Заказы падают в CRM (AmoCRM или Bitrix24), транзакции идут через Kaspi Pay или интернет-эквайринг, реклама крутится в Meta (Instagram) и Google Ads, а складской учет ведется в 1С или МойСклад.
- Скрытые комиссии: Маркетплейсы удерживают комиссии, стоимость логистики, возвраты и штрафы. В интерфейсе банка селлер видит только итоговое поступление (Payout), а не детализацию по каждому SKU.
- Слепой маркетинг: Без сквозной аналитики невозможно понять, что рекламная кампания "Smartphones_Sale" сожрала 300 000 тенге бюджета, но принесла только убыточные заказы с высокой долей возвратов.
Бизнес живет «по ощущениям». Деньги на счету есть — значит, всё хорошо. Кассовый разрыв — значит, где-то просчитались. Для Скаута OZAT такой селлер — идеальный клиент. Боль огромная, а техническое решение, если владеть правильным стеком Google Cloud, собирается за пару выходных.
Почему очевидные решения (Google Sheets и готовые коннекторы) не работают?
Когда селлер осознает проблему, он обычно идет по одному из двух тупиковых путей:
Тупик №1: Google Таблицы + Ручной труд (или Make/Zapier)
Казалось бы, зачем база данных? Давайте просто через Make (ex-Integromat) лить все вебхуки в Google Таблицу и строить графики там.
Проблема в том, что Google Sheets — это не база данных. Официальный лимит — 10 миллионов ячеек, но по факту таблица начинает невыносимо тормозить уже на 50 тысячах строк, если там есть формулы вроде SUMIFS или QUERY. Дашборд в Looker Studio, подключенный напрямую к такой таблице, будет грузиться по 40 секунд. Руководитель просто перестанет им пользоваться.
Тупик №2: Платные ETL-коннекторы (Supermetrics, OWOX, Power My Analytics)
Второй путь — купить готовые коннекторы, которые будут тянуть данные из рекламных кабинетов и CRM прямо в Looker Studio. Минусы: Во-первых, это дорого. Подписка на 3-4 коннектора обойдется минимум в $150-300 ежемесячно. Для малого бизнеса это ощутимый OpEx. Во-вторых, коннекторы часто работают в режиме Direct Query. Каждый раз, когда вы меняете фильтр по дате в дашборде, коннектор делает API-запрос к источнику. Вы ловите Rate Limits, и дашборд ломается с ошибкой «Quota Exceeded». Вы не владеете своими историческими данными.
«Гадание на кофейной гуще vs BigQuery ML»: Как кофейне перестать выкидывать круассаны и предсказывать спрос
Правильная архитектура: Сквозная аналитика на Google Cloud
Чтобы построить масштабируемое, отказоустойчивое и практически бесплатное решение, мы будем использовать подход ELT (Extract, Load, Transform) и современный облачный стек: Cloud Scheduler + Cloud Functions + BigQuery + Looker Studio.
Именно за такую архитектуру селлеры готовы платить чек от 500 000 до 1 500 000 тенге за внедрение. Скаут выступает как архитектор, который один раз настраивает пайплайн, а дальше система работает автономно.
┌────────────────┐ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Источники │ │ Cloud Scheduler │ │ BigQuery │ │ Looker Studio │
│ (Kaspi, 1C, │ ──> │ + │ ──> │ (Data Warehouse) │ ──> │ (Dashboard) │
│ Meta, CRM) │ │ Cloud Functions │ │ Raw -> Staging │ │ (BI Engine Cache)│
└────────────────┘ └──────────────────┘ └──────────────────┘ └──────────────────┘Рис 1. Серверлесс пайплайн для E-commerce аналитики
Как это работает по шагам:
- Оркестрация: Cloud Scheduler по cron-расписанию (например, каждые 15 минут для заказов и раз в сутки для рекламных расходов) дергает HTTP-триггеры наших Cloud Functions.
- Экстракция (Extract & Load): Node.js Cloud Functions обращаются к API Kaspi, МойСклад или Facebook, забирают свежие данные (инкрементальная загрузка по
updated_at) и сбрасывают их как есть (Raw Data) в таблицы BigQuery через Streaming Inserts (или Load Jobs для больших батчей). - Трансформация (Transform): С помощью SQL-представлений (Views) или Scheduled Queries внутри BigQuery сырые JSON-данные очищаются, джойнятся по ID заказа и превращаются в красивую витрину данных (Data Mart) для юнит-экономики.
- Визуализация: Looker Studio подключается к готовой витрине в BigQuery. Благодаря технологии BI Engine (in-memory кэш), дашборды летают, загружаясь за миллисекунды.
Инженерная реализация: Код и SQL
Давайте посмотрим, как выглядит базовая Cloud Function на Node.js (TypeScript), которая стягивает заказы из условной CRM (например, AmoCRM или МойСклад) и кладет их в BigQuery. Мы пишем production-ready код с обработкой ошибок и идемпотентностью.
import { BigQuery } from '@google-cloud/bigquery';
import axios from 'axios';
import { Request, Response } from 'express';
const bigquery = new BigQuery();
const datasetId = 'ecommerce_raw';
const tableId = 'crm_orders';
// Пример инкрементальной загрузки заказов
export const fetchOrdersToBQ = async (req: Request, res: Response) => {
try {
// 1. Получаем дату последнего обновления из BQ (High-water mark)
const [lastSyncRows] = await bigquery.query(`
SELECT MAX(updated_at) as last_sync
FROM \`ozatkz-project.${datasetId}.${tableId}\`
`);
const lastSyncDate = lastSyncRows[0]?.last_sync?.value
? new Date(lastSyncRows[0].last_sync.value).toISOString()
: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(); // Fallback: 7 days
console.log(`Fetching orders updated since: ${lastSyncDate}`);
// 2. Делаем запрос к API источника (например, CRM)
const response = await axios.get('https://api.example-crm.com/v1/orders', {
headers: { 'Authorization': `Bearer ${process.env.CRM_API_KEY}` },
params: { updated_after: lastSyncDate, limit: 1000 }
});
const orders = response.data.items;
if (orders.length === 0) {
return res.status(200).send('No new orders to sync.');
}
// 3. Форматируем данные для BigQuery
const rowsToInsert = orders.map((order: any) => ({
order_id: order.id,
status: order.status,
total_amount: order.price,
created_at: bigquery.datetime(order.created_at),
updated_at: bigquery.datetime(order.updated_at),
raw_json: JSON.stringify(order) // Сохраняем сырой JSON на всякий случай
}));
// 4. Стримим данные в BigQuery
await bigquery
.dataset(datasetId)
.table(tableId)
.insert(rowsToInsert);
res.status(200).send(`Successfully synced ${orders.length} orders.`);
} catch (error) {
console.error('Error syncing orders:', error);
res.status(500).send('Internal Server Error');
}
};Смотреть код на GitHub (OZAT-kz)
Заметьте важную деталь: мы используем поле raw_json. Это паттерн проектирования хранилищ данных (Data Lakehouse). Если завтра бизнес решит, что ему нужен еще и номер телефона клиента, который мы изначально не выделили в отдельную колонку, нам не придется перекачивать всю базу за год по API. Мы просто обновим SQL-запрос в BigQuery, извлекая телефон через функцию JSON_EXTRACT_SCALAR(raw_json, '$.customer.phone'). Это экономит недели времени на дебаг.
После того как данные из CRM, рекламных кабинетов и складов оказались в BigQuery, мы пишем SQL-витрину, которая собирает всё воедино:
-- Витрина данных для сквозной аналитики (Юнит-экономика)
CREATE OR REPLACE VIEW `ozatkz-project.ecommerce_mart.unit_economics` AS
SELECT
o.order_id,
o.created_at AS order_date,
o.status,
o.total_amount AS revenue,
COALESCE(c.cogs_amount, 0) AS cogs, -- Себестоимость товара из складской системы
(o.total_amount * 0.12) AS marketplace_commission, -- 12% комиссия маркетплейса (пример)
COALESCE(a.ad_spend_attributed, 0) AS ad_spend, -- Атрибутированные рекламные расходы
-- Считаем валовую и чистую прибыль
(o.total_amount - COALESCE(c.cogs_amount, 0)) AS gross_profit,
(o.total_amount - COALESCE(c.cogs_amount, 0) - (o.total_amount * 0.12) - COALESCE(a.ad_spend_attributed, 0)) AS net_profit
FROM
`ozatkz-project.ecommerce_raw.crm_orders` o
LEFT JOIN
`ozatkz-project.ecommerce_raw.inventory_cogs` c ON o.sku_id = c.sku_id
LEFT JOIN
`ozatkz-project.ecommerce_raw.marketing_attribution` a ON o.order_id = a.order_id
WHERE
o.status IN ('DELIVERED', 'COMPLETED');Смотреть код на GitHub (OZAT-kz)
Метрики и FinOps: Инженерный профит
А теперь поговорим о самом приятном — деньгах. Почему Скаут может смело брать 500 000 ₸ за такую работу, и почему бизнесу это выгодно?
- ROI для бизнеса: Селлер, внедряющий дашборд, обычно в первый же месяц находит «дыры» в бюджете (например, рекламные кампании с ROMI -50%, или товары, которые продаются в минус из-за логистики). Экономия составляет миллионы тенге. Дашборд окупается за пару недель.
- Скорость отчетов: Менеджер больше не тратит 3 часа в день на сведение таблиц. Данные обновляются автоматически каждые 15 минут.
Сравнение затрат на аналитику в год (тыс. ₸)
FinOps (Стоимость владения облаком): Для малого и среднего бизнеса (до 10 000 заказов в месяц) инфраструктура Google Cloud работает практически бесплатно. Cloud Functions предоставляет 2 миллиона бесплатных вызовов в месяц. Cloud Scheduler дает 3 бесплатных джоба. BigQuery предлагает 10 ГБ бесплатного хранения и 1 ТБ запросов в месяц.
Итоговый ежемесячный счет от Google Cloud (OpEx) для такого проекта составит примерно $1.50 - $2.00 (в основном за хранение секретов в Secret Manager или небольшие превышения по логам). Сравните это с подписками на готовые коннекторы за $200 в месяц. Выгода очевидна.
Реальные ограничения и компромиссы
- API Rate Limits: Маркетплейсы могут жестко лимитировать количество запросов (например, не более 5 запросов в секунду). Ваш код в Cloud Function должен уметь делать exponential backoff и корректно обрабатывать статусы 429 (Too Many Requests).
- Поддержка инфраструктуры: Если источник изменит структуру API (например, переименует поле
total_priceвamount), загрузка может сломаться. Скаут должен настроить алерты в Cloud Monitoring, чтобы вовремя чинить парсер. Обязательно продавайте бизнесу SLA на техподдержку за фикс в месяц. - Не настоящий Real-Time: Данные загружаются микробатчами (раз в 15 минут или час). Если бизнесу нужен хардкорный реалтайм до секунды, придется внедрять Pub/Sub и Dataflow, что сложнее и выведет вас из Free Tier. Но для 99% e-commerce задержка в 15 минут — это более чем ок.
Сборка хранилищ данных (Data Warehousing) — это уже давно не привилегия банков и корпораций. Благодаря Serverless технологиям, любой малый бизнес в Казахстане может получить аналитику уровня Enterprise, а талантливый инженер — заработать на этом отличные деньги, собрав решение один раз и масштабируя его на других клиентов.
Если вы хотите научиться строить такие архитектуры и продавать их бизнесу, добро пожаловать в Академию Скаутов. Мы учим не просто писать код, а решать бизнес-боли с помощью облака.
💡 Совет OZAT: Готовы к внедрению? Рассчитайте архитектуру и бюджет через Scope Builder или пройдите бесплатный ИИ-аудит.

Рустам Шарафутдинов
Эксперт в области архитектуры Google Cloud и Senior Full-Stack разработчик с более чем 15-летним опытом. Специализируется на отказоустойчивых архитектурах, оптимизации высоконагруженных проектов и интеграции AI (Vertex AI).