Files
marketplaces/docs/backend/TRACK-A-ANALYTICS-CONTRACT.md
sdarbinyan 2e09369345
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
docs: Track A/S contracts + backend index tying the full v3.1 contract set together
- Track A: analytics event pipeline (traffic/catalog/commerce/operational/
  quality events), synthetic-traffic separation enforced server-side by
  environment/token, never a client-settable flag.
- Track S: 17-role/3-scope RBAC enforcement, audit log, secrets, rate
  limiting, step-up auth - closes this session's most serious finding
  (admin role model is decorative today, any authenticated admin has
  full access regardless of assigned role).
- docs/backend/README.md: index of all 12 contract docs (Phases 1-10 +
  2 tracks) in build order, plus what's deliberately excluded (namespace
  migration, per-connector adapters, extra payment providers) and the
  one thing still genuinely open across all of them - backend ownership.
- Cross-linked from BACKEND-API-REFERENCE.md and the delivery plan so the
  index is discoverable from either entry point.

This closes out documentation for every phase/track in
PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md that doesn't require a further business
decision. Nothing left undocumented on our side pending only implementation
and backend-ownership assignment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 23:09:04 +04:00

3.7 KiB

Track A Backend Contract — Analytics Event Pipeline

Companion to PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md Track A. Covers plan §3.1, §6.3, §13.3.

Status: ready to build. Start alongside Phase 1, not last — longest lead time in the programme, and it's a P0 in the plan's own §3.1. No tracking infrastructure exists at all today; this is missing infrastructure, not a missing endpoint.


1. Event logging spine

interface AnalyticsEvent {
  eventType: string;         // see §2-4 for the fixed vocabulary
  marketplaceId: string;
  sessionId: string;
  customerId?: string;
  timestamp: string;
  properties: Record<string, unknown>;
  isSynthetic: boolean;      // see §6 - mandatory, never inferred
}
POST /api/v2/storefront/analytics/events   { eventType, properties }   -- server-side batched ingest

Frontend fires events client-side; backend is the source of truth for sessionId and isSynthetic — never trust a client-asserted synthetic flag without a matching signed staging/test-environment token.

2. Traffic events

session_started, page_view, product_view (with source/utm/referrer), unique users/sessions rollups

3. Catalog events

search, category_view, product_view, seller_view

4. Commerce events

add_to_cart, cart_view, checkout_started, payment_started, payment_success, payment_failed, order_created

These map directly onto the Phase 1/2/6 contracts' own state transitions — emit them from the same backend code paths that already produce PaymentEvent/OrderEvent, not a separately-maintained tracking layer that can drift.

5. Operational + quality metrics

interface OperationalMetric {
  name: 'order_paid_to_notification_latency' | 'fulfillment_time' | 'connector_lag' | 'payment_webhook_lag';
  marketplaceId: string;
  value: number;
  unit: 'seconds' | 'minutes';
  measuredAt: string;
}

Quality events: frontend/backend errors, checkout validation failures, FX stale-rate blocks (Phase 1 §3.2).

6. Synthetic traffic separation (hard requirement, plan §3.1/§6.3/§10.2)

Synthetic/load-test traffic is permitted in staging and demo environments only, and must be technically inseparable-by-accident from production data — i.e. isSynthetic: true set server-side based on environment/token, never a client-settable flag that a real visit could accidentally or deliberately carry. Business reports must filter it out by construction, not by a manual exclusion query someone has to remember to add.

7. Endpoints

GET /api/admin/v2/analytics/funnel?marketplaceId=&period=
GET /api/admin/v2/analytics/operational?marketplaceId=&metric=
GET /api/admin/v2/analytics/quality?marketplaceId=
GET /api/v2/storefront/search/trending?marketplaceId=   -- top N queries over a recent window, closes the existing SearchTrendingService.loadTrending() stub (returns of(null) today)

8. Post-launch monitoring set (plan §13.3, reuses the same event stream)

checkout_conversion, payment_success_failure_rate, webhook_processing_lag,
order_notification_lag, external_connector_lag, fx_quote_age_errors,
unmatched_reconciliation_count, fulfillment_stuck_count

9. What the frontend will start doing once this ships

  • Replace the fully mock-composed AdminAnalyticsFacade with real funnel data.
  • Fire the event vocabulary above from the relevant storefront interaction points.
  • Bridge or replace the currently-always-zero AdminProduct.visits column with real tracking (see GAPS-AND-IMPROVEMENTS.md's admin-product-views item — already partially speced in this session's admin product views design).
  • Wire SearchTrendingService.loadTrending() to the real endpoint in §7.