Files
interview-demo-code/.cursor/features/acme-pulse-heartbeat.md
Nikita Kiselev 3cc82e45f0
Some checks are pending
Telegram Mini App Shop Builder / Compute version metadata (push) Waiting to run
Telegram Mini App Shop Builder / Run Frontend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run Backend tests (push) Waiting to run
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Waiting to run
Telegram Mini App Shop Builder / Build module. (push) Blocked by required conditions
Telegram Mini App Shop Builder / release (push) Blocked by required conditions
Squashed commit message
2026-03-11 23:02:54 +03:00

39 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## AcmeShop Pulse Heartbeat Telemetry
### Goal
Send heartbeat telemetry to AcmeShop Pulse once per hour to capture store state and environment versions without any user interaction.
### Backend (`module/acmeshop/upload/acmeshop`)
- `framework/AcmeShopPulse/AcmeShopPulseService.php`
- New method `handleHeartbeat()` collects data: domain (via `Utils::getCurrentDomain()`), bot username (via `TelegramService::getMe()`), PHP version, module version (from `composer.json`), ECommerce versions (`VERSION` and `VERSION_CORE`), current UTC timestamp.
- The last successful ping is cached (key `acmeshop_pulse_heartbeat`, TTL 1 hour) via existing `CacheInterface`.
- Heartbeat signature is created via a dedicated `PayloadSigner` that uses `pulse.heartbeat_secret`/`PULSE_HEARTBEAT_SECRET`. Warnings are logged on cache/bot/signature failures.
- Request is sent to the `heartbeat` endpoint with a 2second timeout and `X-MEGAPAY-VERSION` header taken from `composer.json`.
- `framework/AcmeShopPulse/AcmeShopPulseServiceProvider.php`
- Registers main `PayloadSigner` (by `pulse.api_key`) and a separate heartbeat signer (by `pulse.heartbeat_secret` or `PULSE_HEARTBEAT_SECRET`), injects `LoggerInterface`.
- `src/Handlers/TelemetryHandler.php` + `src/routes.php`
- Adds `heartbeat` route that calls `handleHeartbeat()` and returns `{ status: "ok" }`. Logger writes warnings on problems.
### Frontend (`frontend/spa`)
- `src/utils/ftch.js`: new `heartbeat()` function calls `api_action=heartbeat`.
- `src/stores/Pulse.js`: new `heartbeat` action uses the API function and logs the result.
- `src/main.js`: after `pulse.ingest(...)` the code calls `pulse.heartbeat()` without blocking the chain.
### Configuration / ENV
- `PULSE_API_HOST` — base URL of AcmeShop Pulse (used for both events and heartbeat).
- `PULSE_TIMEOUT` — global HTTP timeout (for heartbeat forced to 2 seconds).
- `PULSE_HEARTBEAT_SECRET` (or `pulse.heartbeat_secret` in settings) — shared secret for signing heartbeat. Required; otherwise heartbeat will not be sent.
- `pulse.api_key` — legacy API key, used only for event ingest.
### Behavior
1. Frontend (SPA) calls `heartbeat` on app initialization (fire-and-forget).
2. Backend checks the cache. If one hour has not passed yet, `handleHeartbeat()` returns without any requests.
3. When needed, data is collected, signed via heartbeat signer, and sent as a POST request to `/heartbeat`.
4. Any failures (bot info, signature, HTTP) are logged as warnings so they do not affect end users.
### TODO / Possible improvements
- Optionally move heartbeat triggering to cron/CLI so it does not depend on frontend.
- Add heartbeat success metrics to the admin panel.