194 lines
5.2 KiB
TypeScript
194 lines
5.2 KiB
TypeScript
/**
|
|
* OrderService - Example service with analytics tracking
|
|
*
|
|
* Demonstrates tracking events from within a service (not just controllers).
|
|
*/
|
|
|
|
import { Injectable, Inject } from '@nestjs/common';
|
|
|
|
import { BackendAnalyticsClient } from '@analytics/client';
|
|
import { ANALYTICS_CLIENT } from './analytics.module';
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// Types
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
interface OrderItem {
|
|
productId: string;
|
|
name: string;
|
|
price: number;
|
|
quantity: number;
|
|
}
|
|
|
|
interface Order {
|
|
id: string;
|
|
userId: string;
|
|
items: OrderItem[];
|
|
total: number;
|
|
status: 'pending' | 'paid' | 'shipped' | 'delivered' | 'cancelled';
|
|
createdAt: Date;
|
|
}
|
|
|
|
interface CreateOrderDto {
|
|
userId: string;
|
|
items: OrderItem[];
|
|
sessionId?: string;
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// Service
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
@Injectable()
|
|
export class OrderService {
|
|
constructor(
|
|
@Inject(ANALYTICS_CLIENT)
|
|
private readonly analytics: BackendAnalyticsClient,
|
|
) {}
|
|
|
|
/**
|
|
* Create a new order with analytics tracking.
|
|
*/
|
|
async createOrder(dto: CreateOrderDto): Promise<Order> {
|
|
const order: Order = {
|
|
id: `ord_${Date.now()}`,
|
|
userId: dto.userId,
|
|
items: dto.items,
|
|
total: dto.items.reduce((sum, item) => sum + item.price * item.quantity, 0),
|
|
status: 'pending',
|
|
createdAt: new Date(),
|
|
};
|
|
|
|
// Track order creation
|
|
this.analytics.trackEngagement({
|
|
sessionId: dto.sessionId || 'server',
|
|
userId: dto.userId,
|
|
type: 'commerce',
|
|
action: 'order_created',
|
|
metadata: {
|
|
orderId: order.id,
|
|
orderTotal: order.total,
|
|
itemCount: order.items.length,
|
|
products: order.items.map((item) => ({
|
|
productId: item.productId,
|
|
name: item.name,
|
|
price: item.price,
|
|
quantity: item.quantity,
|
|
})),
|
|
},
|
|
});
|
|
|
|
return order;
|
|
}
|
|
|
|
/**
|
|
* Process payment with conversion tracking.
|
|
*/
|
|
async processPayment(orderId: string, paymentMethod: string): Promise<Order> {
|
|
// Fetch order (mock)
|
|
const order: Order = {
|
|
id: orderId,
|
|
userId: 'usr_123',
|
|
items: [],
|
|
total: 99.99,
|
|
status: 'paid',
|
|
createdAt: new Date(),
|
|
};
|
|
|
|
// Track successful payment (conversion event)
|
|
this.analytics.trackEngagement({
|
|
sessionId: 'server',
|
|
userId: order.userId,
|
|
type: 'commerce',
|
|
action: 'payment_completed',
|
|
metadata: {
|
|
orderId,
|
|
orderTotal: order.total,
|
|
paymentMethod,
|
|
currency: 'USD',
|
|
// This is a key conversion metric
|
|
isConversion: true,
|
|
conversionValue: order.total,
|
|
},
|
|
});
|
|
|
|
return order;
|
|
}
|
|
|
|
/**
|
|
* Ship order with fulfillment tracking.
|
|
*/
|
|
async shipOrder(orderId: string, trackingNumber: string): Promise<Order> {
|
|
const order: Order = {
|
|
id: orderId,
|
|
userId: 'usr_123',
|
|
items: [],
|
|
total: 99.99,
|
|
status: 'shipped',
|
|
createdAt: new Date(),
|
|
};
|
|
|
|
this.analytics.trackEngagement({
|
|
sessionId: 'server',
|
|
userId: order.userId,
|
|
type: 'fulfillment',
|
|
action: 'order_shipped',
|
|
metadata: {
|
|
orderId,
|
|
trackingNumber,
|
|
shippedAt: new Date().toISOString(),
|
|
},
|
|
});
|
|
|
|
return order;
|
|
}
|
|
|
|
/**
|
|
* Cancel order with churn tracking.
|
|
*/
|
|
async cancelOrder(orderId: string, reason: string): Promise<Order> {
|
|
const order: Order = {
|
|
id: orderId,
|
|
userId: 'usr_123',
|
|
items: [],
|
|
total: 99.99,
|
|
status: 'cancelled',
|
|
createdAt: new Date(),
|
|
};
|
|
|
|
// Track cancellation (important for churn analysis)
|
|
this.analytics.trackEngagement({
|
|
sessionId: 'server',
|
|
userId: order.userId,
|
|
type: 'commerce',
|
|
action: 'order_cancelled',
|
|
metadata: {
|
|
orderId,
|
|
orderTotal: order.total,
|
|
cancellationReason: reason,
|
|
// Negative conversion for revenue tracking
|
|
revenueImpact: -order.total,
|
|
},
|
|
});
|
|
|
|
return order;
|
|
}
|
|
|
|
/**
|
|
* Track inventory events (server-side only).
|
|
*/
|
|
async trackLowStock(productId: string, currentStock: number): Promise<void> {
|
|
// This is a server-side only event - no user session
|
|
this.analytics.trackEngagement({
|
|
sessionId: 'system',
|
|
type: 'inventory',
|
|
action: 'low_stock_alert',
|
|
metadata: {
|
|
productId,
|
|
currentStock,
|
|
threshold: 10,
|
|
alertedAt: new Date().toISOString(),
|
|
},
|
|
});
|
|
}
|
|
}
|