# TeleCart Pulse ## Назначение Связка модуля с внешним SaaS `pulse.telecart.pro`. Включает две концептуально разные части: - **События кампаний** (`WEBAPP_OPEN`, `ORDER_CREATED`, …) — аналитика маркетинговых кампаний и Telegram-рассылок. Завязана на действия продавца: событие сохраняется и отправляется только если в `start_param` пришли `campaign_id` и `tracking_id`, и только при заданном `pulse.api_key`. - **Heartbeat** — раз в час отправляет технические сведения об установке (домен, имя бота, версии PHP/модуля/OpenCart). Используется для статистики установок и техподдержки. Управляется **отдельным** переключателем `pulse.heartbeat_enabled` (по умолчанию **выключен**, opt-in), независимым от `pulse.api_key`. В коде обе части живут в namespace `Openguru\OpenCartFramework\TeleCartPulse`. ## Точки входа | action | Метод | Где объявлен | |-------------|------------------------------|------------------| | `ingest` | `TelemetryHandler::ingest` | `src/routes.php` | | `heartbeat` | `TelemetryHandler::heartbeat`| `src/routes.php` | Триггерятся из SPA (`frontend/spa/src/stores/Pulse.js`, вызов при инициализации WebApp в `frontend/spa/src/main.js`). Heartbeat кэшируется на 1 час (`telecart_pulse_heartbeat`). ## Ключевые файлы по слоям - **Handler:** `module/.../src/Handlers/TelemetryHandler.php` — `ingest()` (события) и `heartbeat()` (телеметрия окружения); оба делегируют в `TeleCartPulseService`. - **Сервис:** `module/.../framework/TeleCartPulse/TeleCartPulseService.php` — `handleIngest()` (валидация campaign/tracking, сохранение события в БД) и `handleHeartbeat()` (сбор окружения, подпись, POST). В начале `handleHeartbeat()` — гейт `if (! $this->heartbeatEnabled) return;`. - **Отправка событий:** `module/.../framework/TeleCartPulse/TeleCartPulseEventsSender.php` — POST накопленных событий на `/events` с `Authorization: Bearer `. - **Регистрация в DI:** `module/.../framework/TeleCartPulse/TeleCartPulseServiceProvider.php` — читает `pulse.api_key`, секрет подписи (`pulse.heartbeat_secret` / env `PULSE_HEARTBEAT_SECRET`) и `pulse.heartbeat_enabled`, инжектит в сервисы. - **Модель/данные:** `module/.../framework/TeleCartPulse/TeleCartEvent.php`, таблица `telecart_events` (миграция `database/migrations/20260101000010_create_telecart_events_table.php`). - **Расписание:** `configs/schedule.php` — `TeleCartPulseSendEventsTask` каждые 10 минут; CLI-аналог — `console/Commands/PulseSendEventsCommand.php` (`pulse:send`). - **Конфиг/дефолты:** `configs/app.php`, секция `pulse` (`api_key`, `heartbeat_enabled`, `batch_size`, `max_attempts`). - **Фронтенд (админка):** `frontend/admin/src/views/TeleCartPulseView.vue` — поля настроек, включая переключатель heartbeat (`ItemBool`) с раскрытием состава отправляемых данных; дефолты в `frontend/admin/src/stores/settings.js` (секция `pulse`). ## Поток данных **События:** SPA `ingest` → `handleIngest()` → проверка `api_key` + наличия `campaign_id`/`tracking_id` → запись в `telecart_events` (status `pending`) → каждые 10 мин `TeleCartPulseSendEventsTask` → `TeleCartPulseEventsSender::sendEvent()` → POST `/events`. **Heartbeat:** SPA `heartbeat` → `handleHeartbeat()` → гейт `heartbeat_enabled` → кэш-чек (1 ч) → `getMe()` → payload окружения → подпись (если есть signer) → POST `/heartbeat`. ## Связанные фичи - [settings](../settings/CLAUDE.md) — переключатель heartbeat и `api_key` проходят через общий каркас настроек. ## Нюансы и подводные камни - **PHP 7.4** в backend-коде. - **Heartbeat и Pulse — независимы.** `pulse.heartbeat_enabled` НЕ завязан на `api_key`. Heartbeat реально уходит только при `heartbeat_enabled = true` **и** наличии signer (секрет настроен). Выключенный тумблер → ранний `return`, даже кэш не ставится. - **События гейтятся `api_key`:** при пустом `pulse.api_key` `handleIngest()` выходит сразу, ничего не сохраняется и не отправляется. - **Прозрачность heartbeat — обязательна.** Состав отправляемых данных раскрыт покупателю в `TeleCartPulseView.vue`; при изменении полей payload в `handleHeartbeat()` синхронизируй текст раскрытия. - Дефолт `heartbeat_enabled = false` (opt-in): без явного включения покупателем heartbeat не отправляется; существующие установки без сохранённого значения тоже ничего не шлют. - Тест гейта: `tests/Unit/Framework/TeleCartPulse/TeleCartPulseServiceHeartbeatTest.php`.