feat: Track A frontend - analytics event pipeline core + real call sites
core/analytics (AnalyticsEvent model, gateway/token/mock, AnalyticsService wrapper) against docs/backend/TRACK-A-ANALYTICS-CONTRACT.md §1. isSynthetic is derived from the build environment at the service layer, never client-settable at a call site - matches the contract's §6 requirement that synthetic traffic be inseparable-by-accident from production data once a real backend exists. Wired into real, live interaction points (additive only, no existing logic touched): product_view + add_to_cart in product-details-container.component.ts, checkout_started + payment_started in pages/cart/cart.component.ts. This is the actual event-firing infrastructure the plan calls "the single largest remaining backend effort" (§3.1) - the frontend side (call sites) is real now; the mock gateway just doesn't persist anywhere yet. Not wired: search/category_view/seller_view/cart_view/payment_success/ payment_failed/order_created - follow-up call sites once this pattern is reviewed, to avoid a much larger unreviewed diff in one push. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@ import { IconComponent } from '../../shared/ui/icon/icon.component';
|
||||
import { EmptyStateComponent } from '../../shared/ui/empty-state/empty-state.component';
|
||||
import { ButtonComponent } from '../../shared/ui/button/button.component';
|
||||
import { ConfigService } from '../../core/config/config.service';
|
||||
import { AnalyticsService } from '../../core/analytics/services/analytics.service';
|
||||
import { TenantResolverService } from '../../core/config/tenant-resolver.service';
|
||||
import { UserNotificationService } from '../../features/website/user-experience/services/user-notification.service';
|
||||
import { ConfirmDialogComponent } from '../../shared/ui/confirm-dialog/confirm-dialog.component';
|
||||
@@ -83,6 +84,7 @@ export class CartComponent implements OnDestroy {
|
||||
private configService = inject(ConfigService);
|
||||
private tenantResolver = inject(TenantResolverService);
|
||||
private currencyRates = inject(CurrencyRatesService);
|
||||
private readonly analytics = inject(AnalyticsService);
|
||||
|
||||
constructor(
|
||||
private cartService: CartService,
|
||||
@@ -206,10 +208,12 @@ export class CartComponent implements OnDestroy {
|
||||
this.notifications.show(this.i18n.t('cart.acceptTerms'), 'warning');
|
||||
return;
|
||||
}
|
||||
this.analytics.track('checkout_started', { itemCount: this.items().length });
|
||||
this.openPaymentPopup(paymentMethod);
|
||||
}
|
||||
|
||||
openPaymentPopup(paymentMethod: PaymentMethod): void {
|
||||
this.analytics.track('payment_started', { paymentMethod });
|
||||
this.showPaymentPopup.set(true);
|
||||
this.selectedPaymentMethod.set(paymentMethod);
|
||||
this.paymentStatus.set('creating');
|
||||
|
||||
Reference in New Issue
Block a user