Files
pos-system/services/ads-tracking-service-net/docs/vi/ARCHITECTURE.md

6.2 KiB

Ads Tracking Service Architecture / Kiến Trúc Dịch Vụ Theo Dõi Quảng Cáo

Tổng Quan / Overview

graph TB
    subgraph "Tracking Sources"
        PIX[Website Pixel]
        SDK[Mobile SDK]
        API[Server-side API]
    end
    
    subgraph "ads-tracking-service"
        EVT[Event Ingestion]
        ATTR[Attribution Engine]
        STORE[(TimescaleDB)]
    end
    
    subgraph "Output"
        ANAL[ads-analytics]
        BILL[ads-billing]
    end
    
    PIX --> EVT
    SDK --> EVT
    API --> EVT
    
    EVT --> STORE
    EVT --> ATTR
    ATTR --> ANAL
    ATTR --> BILL

Domain Aggregates

TrackingPixelAggregate

  • TrackingPixel (Root): Unique pixel per advertiser
  • PixelEvent: PageView, AddToCart, Purchase, Lead

ConversionAggregate

  • Conversion (Root): Actual conversion event
  • ConversionValue: Revenue amount
  • ConversionWindow: 1-day, 7-day, 28-day

AttributionAggregate

  • Attribution (Root): Links conversion to ad
  • AttributionModel: Last-click, First-click, Linear
  • TouchPoint: Each ad interaction in journey

Attribution Logic

┌─────────────────────────────────────────────────────────────────┐
│                     ATTRIBUTION FLOW                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  User Journey:                                                   │
│  ────────────                                                    │
│  Day 1: See Ad A (impression)                                    │
│  Day 3: Click Ad B                                               │
│  Day 5: Click Ad C                                               │
│  Day 6: Purchase $100                                            │
│                                                                  │
│  Attribution Models:                                             │
│  ──────────────────                                              │
│  Last-click:  Ad C = 100%                                        │
│  First-click: Ad B = 100%                                        │
│  Linear:      Ad B = 50%, Ad C = 50%                             │
│  Time-decay:  Ad B = 25%, Ad C = 75%                             │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Database Schema (TimescaleDB)

-- Pixels
CREATE TABLE tracking_pixels (
    id UUID PRIMARY KEY,
    advertiser_id UUID NOT NULL,
    pixel_code VARCHAR(50) UNIQUE,
    domain VARCHAR(255),
    created_at TIMESTAMP DEFAULT NOW()
);

-- Events (hypertable for time-series)
CREATE TABLE pixel_events (
    id UUID,
    pixel_id UUID REFERENCES tracking_pixels(id),
    event_type VARCHAR(50), -- 'PageView', 'AddToCart', 'Purchase'
    event_data JSONB,
    user_id VARCHAR(255),
    session_id VARCHAR(255),
    event_time TIMESTAMPTZ NOT NULL
);
SELECT create_hypertable('pixel_events', 'event_time');

-- Ad interactions (for attribution)
CREATE TABLE ad_interactions (
    id UUID PRIMARY KEY,
    user_id VARCHAR(255),
    ad_id UUID,
    campaign_id UUID,
    interaction_type VARCHAR(20), -- 'impression', 'click'
    interaction_time TIMESTAMPTZ NOT NULL
);

-- Conversions with attribution
CREATE TABLE conversions (
    id UUID PRIMARY KEY,
    pixel_event_id UUID,
    attributed_ad_id UUID,
    attributed_campaign_id UUID,
    attribution_model VARCHAR(50),
    conversion_value DECIMAL(18, 2),
    converted_at TIMESTAMPTZ
);

Attribution Window Settings

Setting Click Window View Window
7/1 (default) 7 days 1 day
7/0 7 days None
28/1 28 days 1 day
1/1 1 day 1 day

Pixel Integration Code

<!-- Website Pixel -->
<script>
!function(g,o,od,go){
  g.ggq=g.ggq||[];
  var n=o.createElement('script');
  n.async=1;
  n.src='https://tracking.goodgo.com/pixel.js';
  o.body.appendChild(n)
}(window,document);

ggq('init', 'PX-XXXXXX');
ggq('track', 'PageView');
</script>

<!-- Track Purchase -->
<script>
ggq('track', 'Purchase', {
  value: 99.99,
  currency: 'VND',
  order_id: 'ORD-12345'
});
</script>

Server-side Conversion API

/// <summary>
/// EN: Server-side conversion tracking.
/// VI: Tracking conversion phía server.
/// </summary>
[HttpPost("events/server")]
public async Task<ActionResult> TrackServerEvent(
    [FromBody] ServerEventRequest request)
{
    // EN: More reliable than pixel (no ad blockers)
    // VI: Đáng tin cậy hơn pixel (không bị ad blocker)
    var result = await _mediator.Send(new TrackServerEventCommand
    {
        PixelId = request.PixelId,
        EventType = request.EventType,
        EventData = request.EventData,
        UserId = request.UserId, // hashed
        EventTime = request.EventTime
    });
    
    return Ok(result);
}

Integration Events

// Consume from ads-serving
public record AdImpressionTrackedEvent(
    Guid AdId, string UserId, string Placement, DateTime TrackedAt);

public record AdClickTrackedEvent(
    Guid AdId, string UserId, string DestinationUrl, DateTime TrackedAt);

// Publish to ads-analytics
public record ConversionAttributedEvent(
    Guid ConversionId, Guid AdId, Guid CampaignId,
    decimal ConversionValue, string AttributionModel);

API Endpoints

Method Endpoint Description
GET /api/v1/ads-tracking/pixels/{advertiserId} Get pixel code
POST /api/v1/ads-tracking/events Track pixel event
POST /api/v1/ads-tracking/events/server Server-side event
GET /api/v1/ads-tracking/conversions List conversions