feat: Introduce a multi-vertical architecture implementation plan and a new ads documentation file.
This commit is contained in:
408
Multi-vertical.md
Normal file
408
Multi-vertical.md
Normal file
@@ -0,0 +1,408 @@
|
||||
Multi-vertical Architecture Implementation Plan
|
||||
Problem Statement / Vấn Đề
|
||||
Hệ thống hiện tại có Merchant Service đang làm tốt vai trò quản trị/định danh, nhưng cần mở rộng để hỗ trợ đa ngành hàng (Multi-vertical) bao gồm:
|
||||
|
||||
Retail: Bán lẻ hàng hóa vật lý (Áo, Mũ, Điện thoại...)
|
||||
F&B: Food & Beverage (Quán cafe, Nhà hàng, Quán ăn...)
|
||||
Services: Dịch vụ (Spa, Salon, Phòng khám...)
|
||||
Hybrid: Kết hợp nhiều ngành (Quán cafe bán kèm merchandise)
|
||||
Nguyên tắc thiết kế:
|
||||
|
||||
Merchant Service chỉ quản lý "Ai" (Identity) và "Luật chơi" (Configuration), còn "Chơi thế nào" (Execution) phải đẩy ra các Service vệ tinh.
|
||||
|
||||
Architecture Overview / Tổng Quan Kiến Trúc
|
||||
🔵 Vertical Engines - Logic Ngành
|
||||
🔴 Orchestration Layer
|
||||
🟡 Core Services - Configuration & Identity
|
||||
Client
|
||||
Retail Item
|
||||
Service Item
|
||||
F&B Item
|
||||
Ref
|
||||
Get Config
|
||||
⚡ Traefik Gateway
|
||||
💳 Smart POS / Web
|
||||
🔐 IAM Service(User/Role)
|
||||
🏪 Merchant Service(Shop DNA, Settings, Staff)
|
||||
💰 Wallet Service(Payment)
|
||||
📦 Catalog Service(Polymorphic Products)
|
||||
📝 Order Service(The Brain - Strategy Pattern)
|
||||
🏭 Inventory Service(Retail Logic)
|
||||
📅 Booking Service(Spa/Service Logic)
|
||||
🍳 F&B Engine(Table/Session/KDS)
|
||||
User Review Required
|
||||
IMPORTANT
|
||||
|
||||
Quyết định Scope: Plan này bao gồm 4 phases. User cần xác nhận muốn triển khai tất cả hay chỉ một số phases cụ thể.
|
||||
|
||||
WARNING
|
||||
|
||||
Breaking Changes trong Phase 1: Thay đổi database schema của Shop entity sẽ yêu cầu migration và có thể ảnh hưởng đến các service đang sử dụng Merchant Service API.
|
||||
|
||||
Phase 1: Foundation Refactoring
|
||||
Mục tiêu
|
||||
Chuẩn bị Merchant Service làm nền tảng cho multi-vertical, không triển khai logic nghiệp vụ ngành.
|
||||
|
||||
1.1 Database Changes
|
||||
[MODIFY] Add JSONB columns to shops table
|
||||
Migration SQL:
|
||||
|
||||
-- Migration: Add multi-vertical support columns
|
||||
ALTER TABLE shops
|
||||
ADD COLUMN features_config JSONB DEFAULT '{}',
|
||||
ADD COLUMN vertical_settings JSONB DEFAULT '{}',
|
||||
ADD COLUMN business_category VARCHAR(50) DEFAULT 'Other';
|
||||
-- Index for performance
|
||||
CREATE INDEX idx_shops_business_category ON shops(business_category);
|
||||
CREATE INDEX idx_shops_features_config ON shops USING GIN (features_config);
|
||||
-- Comment documentation
|
||||
COMMENT ON COLUMN shops.features_config IS 'Feature flags: HasInventory, HasBooking, HasTables, HasKitchen...';
|
||||
COMMENT ON COLUMN shops.vertical_settings IS 'Business-specific settings as JSON document';
|
||||
COMMENT ON COLUMN shops.business_category IS 'Primary business type: Retail, FoodBeverage, Services, Other';
|
||||
1.2 Domain Model Changes
|
||||
[MODIFY]
|
||||
|
||||
Shop.cs
|
||||
New Properties:
|
||||
|
||||
public class Shop : Entity, IAggregateRoot
|
||||
{
|
||||
// ... existing properties ...
|
||||
|
||||
// NEW: Business category enum
|
||||
public BusinessCategory Category { get; private set; }
|
||||
|
||||
// NEW: Feature configuration (maps to JSONB)
|
||||
public ShopFeatures Features { get; private set; }
|
||||
|
||||
// NEW: Dynamic settings (maps to JSONB)
|
||||
public JsonDocument? Settings { get; private set; }
|
||||
|
||||
// Factory method with category-based defaults
|
||||
public static Shop Create(Guid merchantId, string name, BusinessCategory category)
|
||||
{
|
||||
var shop = new Shop(merchantId, name, category);
|
||||
shop.Features = GetDefaultFeatures(category);
|
||||
return shop;
|
||||
}
|
||||
|
||||
private static ShopFeatures GetDefaultFeatures(BusinessCategory category) => category switch
|
||||
{
|
||||
BusinessCategory.Retail => new ShopFeatures(HasInventory: true, HasShipping: true),
|
||||
BusinessCategory.FoodBeverage => new ShopFeatures(HasTables: true, HasKitchen: true, HasInventory: true),
|
||||
BusinessCategory.Services => new ShopFeatures(HasBooking: true),
|
||||
_ => new ShopFeatures(HasInventory: true, HasBooking: true) // Hybrid
|
||||
};
|
||||
}
|
||||
[NEW] BusinessCategory.cs
|
||||
// Path: MerchantService.Domain/AggregatesModel/ShopAggregate/BusinessCategory.cs
|
||||
public enum BusinessCategory
|
||||
{
|
||||
Retail = 1, // Bán lẻ
|
||||
FoodBeverage = 2, // F&B
|
||||
Services = 3, // Dịch vụ (Spa, Salon)
|
||||
Other = 99 // Hybrid/Other
|
||||
}
|
||||
[NEW] ShopFeatures.cs (Value Object)
|
||||
// Path: MerchantService.Domain/AggregatesModel/ShopAggregate/ShopFeatures.cs
|
||||
public record ShopFeatures(
|
||||
bool HasInventory = false,
|
||||
bool HasBooking = false,
|
||||
bool HasTables = false,
|
||||
bool HasKitchen = false,
|
||||
bool HasShipping = false,
|
||||
bool HasDelivery = false
|
||||
);
|
||||
1.3 API Changes
|
||||
[MODIFY] Shop DTOs
|
||||
CreateShopRequest:
|
||||
|
||||
public record CreateShopRequest(
|
||||
string Name,
|
||||
string? Description,
|
||||
+ BusinessCategory Category = BusinessCategory.Other,
|
||||
+ ShopFeaturesDto? Features = null
|
||||
);
|
||||
ShopResponse:
|
||||
|
||||
public record ShopResponse(
|
||||
Guid Id,
|
||||
string Name,
|
||||
string? Description,
|
||||
+ BusinessCategory Category,
|
||||
+ ShopFeaturesDto Features,
|
||||
...
|
||||
);
|
||||
[NEW] ShopFeaturesDto
|
||||
public record ShopFeaturesDto(
|
||||
bool HasInventory = false,
|
||||
bool HasBooking = false,
|
||||
bool HasTables = false,
|
||||
bool HasKitchen = false,
|
||||
bool HasShipping = false,
|
||||
bool HasDelivery = false
|
||||
);
|
||||
Phase 2: Retail MVP
|
||||
Mục tiêu
|
||||
Xây dựng luồng bán hàng cơ bản cho ngành Retail.
|
||||
|
||||
2.1 Catalog Service (NEW)
|
||||
Trách nhiệm: Quản lý sản phẩm đa hình (Polymorphic Products)
|
||||
|
||||
Database Schema
|
||||
CREATE TABLE products (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
shop_id UUID NOT NULL REFERENCES shops(id),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
price DECIMAL(18,2) NOT NULL,
|
||||
product_type VARCHAR(50) NOT NULL, -- Physical, Service, PreparedFood
|
||||
attributes JSONB DEFAULT '{}', -- Type-specific attributes
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX idx_products_shop ON products(shop_id);
|
||||
CREATE INDEX idx_products_type ON products(product_type);
|
||||
Core Entities
|
||||
Product (Aggregate Root)
|
||||
ProductType (Enum: Physical, Service, PreparedFood)
|
||||
ProductVariant (Size, Color...)
|
||||
ProductCategory
|
||||
2.2 Inventory Service (NEW)
|
||||
Trách nhiệm: Quản lý tồn kho cho Retail
|
||||
|
||||
Database Schema
|
||||
CREATE TABLE inventory_items (
|
||||
id UUID PRIMARY KEY,
|
||||
product_id UUID NOT NULL,
|
||||
shop_id UUID NOT NULL,
|
||||
quantity INT NOT NULL DEFAULT 0,
|
||||
reserved_quantity INT NOT NULL DEFAULT 0,
|
||||
reorder_level INT DEFAULT 10,
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
CREATE TABLE inventory_transactions (
|
||||
id UUID PRIMARY KEY,
|
||||
inventory_item_id UUID NOT NULL,
|
||||
transaction_type VARCHAR(50) NOT NULL, -- IN, OUT, ADJUSTMENT
|
||||
quantity INT NOT NULL,
|
||||
reference_id UUID, -- Order ID, PO ID...
|
||||
notes TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
Core Features
|
||||
Stock in/out operations
|
||||
Stock reservation for orders
|
||||
Low stock alerts
|
||||
Inventory audit trail
|
||||
2.3 Order Service (NEW) - The Brain
|
||||
Trách nhiệm: Điều phối đơn hàng, sử dụng Strategy Pattern
|
||||
|
||||
Strategy Pattern Design
|
||||
// Interface for line item processing
|
||||
public interface ILineItemStrategy
|
||||
{
|
||||
ProductType SupportedType { get; }
|
||||
Task ValidateAsync(OrderItem item, Guid shopId);
|
||||
Task ExecuteAsync(OrderItem item, Guid shopId);
|
||||
}
|
||||
// Strategy implementations
|
||||
public class RetailStrategy : ILineItemStrategy
|
||||
{
|
||||
public ProductType SupportedType => ProductType.Physical;
|
||||
|
||||
public async Task ValidateAsync(OrderItem item, Guid shopId)
|
||||
{
|
||||
// Call Inventory Service: Check stock availability
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(OrderItem item, Guid shopId)
|
||||
{
|
||||
// Call Inventory Service: Reserve/Deduct stock
|
||||
}
|
||||
}
|
||||
Order Flow
|
||||
WalletService
|
||||
InventoryService
|
||||
MerchantService
|
||||
OrderService
|
||||
POS
|
||||
WalletService
|
||||
InventoryService
|
||||
MerchantService
|
||||
OrderService
|
||||
POS
|
||||
loop
|
||||
[For each LineItem]
|
||||
loop
|
||||
[For each LineItem]
|
||||
Create Order
|
||||
Get Shop Features
|
||||
ShopFeatures
|
||||
Select Strategy by ProductType
|
||||
Validate (Check Stock)
|
||||
OK/Error
|
||||
Process Payment
|
||||
Payment OK
|
||||
Execute (Deduct Stock)
|
||||
Order Completed
|
||||
Phase 3: F&B Vertical
|
||||
Mục tiêu
|
||||
Mở rộng hỗ trợ ngành F&B (Food & Beverage)
|
||||
|
||||
3.1 F&B Engine (NEW)
|
||||
Trách nhiệm: Quản lý phiên ăn uống và bếp
|
||||
|
||||
Core Entities
|
||||
Table - Sơ đồ bàn
|
||||
Session - Phiên ăn (khách ngồi tại bàn)
|
||||
KitchenTicket - Phiếu bếp
|
||||
Recipe - Định lượng nguyên liệu
|
||||
Database Schema
|
||||
CREATE TABLE tables (
|
||||
id UUID PRIMARY KEY,
|
||||
shop_id UUID NOT NULL,
|
||||
table_number VARCHAR(50) NOT NULL,
|
||||
capacity INT DEFAULT 4,
|
||||
zone VARCHAR(100),
|
||||
status VARCHAR(50) DEFAULT 'Available'
|
||||
);
|
||||
CREATE TABLE sessions (
|
||||
id UUID PRIMARY KEY,
|
||||
table_id UUID NOT NULL,
|
||||
started_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
closed_at TIMESTAMPTZ,
|
||||
guest_count INT DEFAULT 1,
|
||||
status VARCHAR(50) DEFAULT 'Active'
|
||||
);
|
||||
CREATE TABLE kitchen_tickets (
|
||||
id UUID PRIMARY KEY,
|
||||
session_id UUID NOT NULL,
|
||||
order_item_id UUID NOT NULL,
|
||||
station VARCHAR(50), -- Bar, Kitchen, Grill...
|
||||
priority INT DEFAULT 0,
|
||||
status VARCHAR(50) DEFAULT 'Pending',
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
3.2 F&B Strategy
|
||||
public class FnbStrategy : ILineItemStrategy
|
||||
{
|
||||
public ProductType SupportedType => ProductType.PreparedFood;
|
||||
|
||||
public async Task ExecuteAsync(OrderItem item, Guid shopId)
|
||||
{
|
||||
// 1. Publish KitchenTicketCreated event
|
||||
// 2. F&B Engine receives and displays on KDS
|
||||
// 3. Optionally: Deduct ingredients from Inventory
|
||||
}
|
||||
}
|
||||
Phase 4: Services Vertical (Spa/Salon)
|
||||
Mục tiêu
|
||||
Mở rộng hỗ trợ ngành Dịch vụ (Spa, Salon, Clinic)
|
||||
|
||||
4.1 Booking Service (NEW)
|
||||
Trách nhiệm: Quản lý "tồn kho thời gian"
|
||||
|
||||
Core Entities
|
||||
StaffSchedule - Lịch làm việc nhân viên
|
||||
Resource - Tài nguyên (Giường, Phòng)
|
||||
Appointment - Cuộc hẹn
|
||||
TimeSlot - Slot thời gian khả dụng
|
||||
Database Schema
|
||||
CREATE TABLE staff_schedules (
|
||||
id UUID PRIMARY KEY,
|
||||
staff_id UUID NOT NULL,
|
||||
shop_id UUID NOT NULL,
|
||||
day_of_week INT NOT NULL,
|
||||
start_time TIME NOT NULL,
|
||||
end_time TIME NOT NULL
|
||||
);
|
||||
CREATE TABLE resources (
|
||||
id UUID PRIMARY KEY,
|
||||
shop_id UUID NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
resource_type VARCHAR(50) NOT NULL, -- Room, Bed, Equipment
|
||||
capacity INT DEFAULT 1
|
||||
);
|
||||
CREATE TABLE appointments (
|
||||
id UUID PRIMARY KEY,
|
||||
shop_id UUID NOT NULL,
|
||||
customer_id UUID,
|
||||
staff_id UUID,
|
||||
resource_id UUID,
|
||||
service_id UUID NOT NULL,
|
||||
start_time TIMESTAMPTZ NOT NULL,
|
||||
end_time TIMESTAMPTZ NOT NULL,
|
||||
status VARCHAR(50) DEFAULT 'Scheduled'
|
||||
);
|
||||
4.2 Booking Strategy
|
||||
public class ServiceStrategy : ILineItemStrategy
|
||||
{
|
||||
public ProductType SupportedType => ProductType.Service;
|
||||
|
||||
public async Task ValidateAsync(OrderItem item, Guid shopId)
|
||||
{
|
||||
// Call Booking Service: Check slot availability
|
||||
// Check staff + resource availability intersection
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(OrderItem item, Guid shopId)
|
||||
{
|
||||
// Call Booking Service: Create Appointment
|
||||
}
|
||||
}
|
||||
New Microservices Summary
|
||||
Service Trách nhiệm Phase
|
||||
Catalog Service Quản lý sản phẩm đa hình Phase 2
|
||||
Inventory Service Quản lý tồn kho Retail + F&B ingredients Phase 2
|
||||
Order Service Orchestrator với Strategy Pattern Phase 2
|
||||
F&B Engine Table management, KDS, Sessions Phase 3
|
||||
Booking Service Appointment scheduling Phase 4
|
||||
File Changes Summary
|
||||
Phase 1 (Merchant Service Updates)
|
||||
Action File
|
||||
MODIFY MerchantService.Domain/AggregatesModel/ShopAggregate/Shop.cs
|
||||
NEW MerchantService.Domain/AggregatesModel/ShopAggregate/BusinessCategory.cs
|
||||
NEW MerchantService.Domain/AggregatesModel/ShopAggregate/ShopFeatures.cs
|
||||
MODIFY MerchantService.Infrastructure/EntityConfigurations/ShopConfiguration.cs
|
||||
NEW Migration file for JSONB columns
|
||||
MODIFY API DTOs (CreateShopRequest, ShopResponse)
|
||||
Phase 2-4 (New Services)
|
||||
Action Project
|
||||
NEW catalog-service-net/
|
||||
NEW inventory-service-net/
|
||||
NEW order-service-net/
|
||||
NEW fnb-engine-net/
|
||||
NEW booking-service-net/
|
||||
Verification Plan
|
||||
Documentation Review
|
||||
Technical Documentation reviewed by team
|
||||
Architecture diagrams validated
|
||||
API specifications approved
|
||||
Phase 1 Verification
|
||||
Migration runs successfully on test database
|
||||
Existing Merchant Service APIs unchanged (backward compatible)
|
||||
New ShopFeatures returned in API responses
|
||||
Unit tests for new Value Objects pass
|
||||
Phase 2+ Verification
|
||||
Integration tests between services pass
|
||||
End-to-end order flow works for Retail
|
||||
Strategy Pattern correctly routes line items
|
||||
Notes
|
||||
NOTE
|
||||
|
||||
Scope: User yêu cầu chỉ tạo documentation và planning, KHÔNG triển khai code trong phase này.
|
||||
|
||||
TIP
|
||||
|
||||
Phụ thuộc Skills: Khi triển khai code, tham khảo các skills:
|
||||
|
||||
|
||||
domain-driven-design
|
||||
|
||||
repository-pattern
|
||||
|
||||
cqrs-mediatr
|
||||
|
||||
inter-service-communication
|
||||
411
ads.md
Normal file
411
ads.md
Normal file
@@ -0,0 +1,411 @@
|
||||
Ads Service - Đề Xuất Giải Pháp / Solution Proposal
|
||||
Mục tiêu / Goal: Xây dựng hệ thống quảng cáo (Ads Service) tương tự Meta Ads, tích hợp vào kiến trúc microservices GoodGo hiện tại.
|
||||
|
||||
1. Phân Tích Kiến Trúc Hiện Tại / Current Architecture Analysis
|
||||
1.1 Điểm Mạnh Có Thể Tái Sử Dụng / Reusable Strengths
|
||||
Component Hiện Có / Available Tái Sử Dụng Cho Ads / Reuse for Ads
|
||||
IAM Service ✅ User, Organization, Group management Advertiser accounts, permissions
|
||||
Wallet Service ✅ Wallet, PointAccount, Transactions Prepaid/Postpaid billing
|
||||
Merchant Service ✅ Merchant, Shop management Advertiser business profiles
|
||||
Promotion Service ✅ Campaign, Voucher, Redemption Campaign structure inspiration
|
||||
Storage Service ✅ File storage Ad creatives (images, videos)
|
||||
RabbitMQ/MassTransit ✅ Async messaging Real-time bidding events
|
||||
Redis ✅ Caching, Rate limiting Ad serving cache, frequency capping
|
||||
1.2 Patterns Hiện Có / Existing Patterns
|
||||
✅ Clean Architecture (API/Domain/Infrastructure)
|
||||
✅ CQRS với MediatR
|
||||
✅ SAGA Pattern cho distributed transactions
|
||||
✅ Outbox Pattern cho reliable messaging
|
||||
✅ Repository Pattern với EF Core
|
||||
✅ Resilient HTTP với Polly
|
||||
2. Đề Xuất Kiến Trúc Ads Service / Proposed Ads Service Architecture
|
||||
2.1 Phân Chia Microservices / Microservices Breakdown
|
||||
Để đáp ứng yêu cầu scale và separation of concerns, đề xuất chia thành 5 microservices:
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ADS SERVICES ECOSYSTEM │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ ads-manager │ │ ads-serving │ │ ads-billing │ │
|
||||
│ │ service │ │ service │ │ service │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ • Campaigns │ │ • RTB Engine │ │ • Prepaid │ │
|
||||
│ │ • Ad Sets │ │ • Ad Selection │ │ • Credit Lines │ │
|
||||
│ │ • Ads │ │ • Pacing │ │ • Invoicing │ │
|
||||
│ │ • Targeting │ │ • Frequency │ │ • Thresholds │ │
|
||||
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
|
||||
│ │ │ │ │
|
||||
│ └──────────────┬─────┴────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌─────▼─────┐ │
|
||||
│ │ RabbitMQ │ │
|
||||
│ │ Event Bus │ │
|
||||
│ └─────┬─────┘ │
|
||||
│ │ │
|
||||
│ ┌─────────────────┐ │ ┌─────────────────┐ │
|
||||
│ │ ads-tracking │◄────┴────►│ ads-analytics │ │
|
||||
│ │ service │ │ service │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ • Pixel/SDK │ │ • Reporting │ │
|
||||
│ │ • Attribution │ │ • Dashboard │ │
|
||||
│ │ • Conversions │ │ • ROAS │ │
|
||||
│ └─────────────────┘ └─────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
2.2 Tích Hợp Với Services Hiện Có / Integration with Existing Services
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ INTEGRATION ARCHITECTURE │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ EXISTING SERVICES ADS SERVICES │
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ IAM Service │◄─────────────►│ ads-manager │ Advertiser Auth │
|
||||
│ └─────────────┘ └─────────────┘ │
|
||||
│ │ │
|
||||
│ ┌─────────────┐ │ │
|
||||
│ │ Merchant │◄─────────────────────┤ Business Profile │
|
||||
│ │ Service │ │ │
|
||||
│ └─────────────┘ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Wallet │◄─────────────►│ ads-billing │ Payment Processing │
|
||||
│ │ Service │ └─────────────┘ │
|
||||
│ └─────────────┘ │ │
|
||||
│ │ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Storage │◄─────────────►│ ads-manager │ Creative Assets │
|
||||
│ │ Service │ └─────────────┘ │
|
||||
│ └─────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Social │◄─────────────►│ ads-serving │ User Interest Data │
|
||||
│ │ Service │ └─────────────┘ │
|
||||
│ └─────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
3. Domain Model Chi Tiết / Detailed Domain Model
|
||||
3.1 Ads Manager Service - Campaign Aggregates
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ads-manager-service │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ AggregatesModel/ │
|
||||
│ ├── AdvertiserAggregate/ │
|
||||
│ │ ├── Advertiser.cs (Root - links to IAM User) │
|
||||
│ │ ├── AdvertiserSettings.cs (Timezone, Currency, etc.) │
|
||||
│ │ └── AdvertiserStatus.cs (Active, Suspended, etc.) │
|
||||
│ │ │
|
||||
│ ├── CampaignAggregate/ │
|
||||
│ │ ├── Campaign.cs (Root) │
|
||||
│ │ ├── CampaignObjective.cs (ValueObject: Awareness, Traffic...) │
|
||||
│ │ ├── CampaignStatus.cs (Draft, Active, Paused, Completed) │
|
||||
│ │ └── CampaignBudget.cs (Daily/Lifetime, Amount) │
|
||||
│ │ │
|
||||
│ ├── AdSetAggregate/ │
|
||||
│ │ ├── AdSet.cs (Root) │
|
||||
│ │ ├── Targeting.cs (Core + Interest + Custom) │
|
||||
│ │ ├── Placement.cs (ValueObject: Feed, Story, etc.) │
|
||||
│ │ ├── Schedule.cs (Start/End dates, dayparting) │
|
||||
│ │ ├── BidStrategy.cs (CPC, CPM, OCPM, Target Cost) │
|
||||
│ │ └── AdSetBudget.cs (Daily/Lifetime, Pacing) │
|
||||
│ │ │
|
||||
│ ├── AdAggregate/ │
|
||||
│ │ ├── Ad.cs (Root) │
|
||||
│ │ ├── AdFormat.cs (Image, Video, Carousel, etc.) │
|
||||
│ │ ├── AdCreative.cs (Media, Headline, CTA) │
|
||||
│ │ ├── AdReviewStatus.cs (Pending, Approved, Rejected) │
|
||||
│ │ └── AdDestination.cs (URL, App Deep Link) │
|
||||
│ │ │
|
||||
│ └── AudienceAggregate/ │
|
||||
│ ├── CustomAudience.cs (Uploaded lists, Retargeting) │
|
||||
│ ├── LookalikeAudience.cs (Similarity %, Source audience) │
|
||||
│ └── SavedAudience.cs (Reusable targeting templates) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
3.2 Ads Serving Service - RTB Aggregates
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ads-serving-service │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ AggregatesModel/ │
|
||||
│ ├── AdRequestAggregate/ │
|
||||
│ │ ├── AdRequest.cs (User context, placement, etc.) │
|
||||
│ │ └── UserContext.cs (Demographics, interests, device) │
|
||||
│ │ │
|
||||
│ ├── AuctionAggregate/ │
|
||||
│ │ ├── Auction.cs (Root - single ad auction) │
|
||||
│ │ ├── Bid.cs (Entity - each candidate ad) │
|
||||
│ │ ├── AuctionResult.cs (Winner, final price) │
|
||||
│ │ └── eCPMCalculator.cs (Bid × Predicted CTR + Quality) │
|
||||
│ │ │
|
||||
│ ├── PacingAggregate/ │
|
||||
│ │ ├── BudgetPacer.cs (Smooth vs Accelerated spending) │
|
||||
│ │ └── SpendTracker.cs (Real-time budget consumption) │
|
||||
│ │ │
|
||||
│ └── FrequencyAggregate/ │
|
||||
│ ├── FrequencyCap.cs (Max impressions per user/day) │
|
||||
│ └── UserAdHistory.cs (Redis-backed user ad views) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
3.3 Ads Billing Service - Financial Aggregates
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ads-billing-service │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ AggregatesModel/ │
|
||||
│ ├── BillingAccountAggregate/ │
|
||||
│ │ ├── BillingAccount.cs (Root - links to Wallet) │
|
||||
│ │ ├── PaymentMethod.cs (Credit Card, Bank, Wallet) │
|
||||
│ │ └── BillingThreshold.cs (Auto-charge at $25, $50, etc.) │
|
||||
│ │ │
|
||||
│ ├── CreditLineAggregate/ │
|
||||
│ │ ├── CreditLine.cs (Postpaid limit) │
|
||||
│ │ ├── CreditEvaluation.cs (Trust score calculation) │
|
||||
│ │ └── PaymentHistory.cs (Track payment reliability) │
|
||||
│ │ │
|
||||
│ ├── InvoiceAggregate/ │
|
||||
│ │ ├── Invoice.cs (Root) │
|
||||
│ │ ├── InvoiceLineItem.cs (Per-campaign charges) │
|
||||
│ │ └── TaxCalculation.cs (VAT by region) │
|
||||
│ │ │
|
||||
│ └── ChargeAggregate/ │
|
||||
│ ├── AdCharge.cs (Individual impression/click cost) │
|
||||
│ └── DailySpendSummary.cs (Aggregated daily charges) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
3.4 Ads Tracking Service - Attribution Aggregates
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ads-tracking-service │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ AggregatesModel/ │
|
||||
│ ├── TrackingPixelAggregate/ │
|
||||
│ │ ├── TrackingPixel.cs (Root - unique pixel per advertiser)│
|
||||
│ │ └── PixelEvent.cs (PageView, AddToCart, Purchase) │
|
||||
│ │ │
|
||||
│ ├── ConversionAggregate/ │
|
||||
│ │ ├── Conversion.cs (Root - actual conversion event) │
|
||||
│ │ ├── ConversionValue.cs (Revenue amount) │
|
||||
│ │ └── ConversionWindow.cs (1-day, 7-day, 28-day) │
|
||||
│ │ │
|
||||
│ └── AttributionAggregate/ │
|
||||
│ ├── Attribution.cs (Links conversion to ad) │
|
||||
│ ├── AttributionModel.cs (Last-click, First-click, Linear) │
|
||||
│ └── TouchPoint.cs (Each ad interaction in journey) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
3.5 Ads Analytics Service - Reporting Aggregates
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ads-analytics-service │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ AggregatesModel/ │
|
||||
│ ├── MetricsAggregate/ │
|
||||
│ │ ├── CampaignMetrics.cs (Impressions, Clicks, CTR, etc.) │
|
||||
│ │ ├── AdSetMetrics.cs (Per-targeting performance) │
|
||||
│ │ └── AdMetrics.cs (Per-creative performance) │
|
||||
│ │ │
|
||||
│ ├── ReportAggregate/ │
|
||||
│ │ ├── Report.cs (Root - scheduled/custom reports) │
|
||||
│ │ ├── ReportSchedule.cs (Daily, Weekly, Monthly) │
|
||||
│ │ └── ReportExport.cs (CSV, Excel, PDF) │
|
||||
│ │ │
|
||||
│ └── InsightAggregate/ │
|
||||
│ ├── AudienceInsight.cs (Demographics of reached users) │
|
||||
│ └── PerformanceInsight.cs (Recommendations, trends) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
4. Data Flow & Communication Patterns
|
||||
4.1 Ad Serving Flow (< 100ms target)
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ AD SERVING FLOW (< 100ms) │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ User App/Web │
|
||||
│ │ │
|
||||
│ │ 1. Request ad slot │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────┐ │
|
||||
│ │ Traefik Gateway │ │
|
||||
│ └────────┬────────┘ │
|
||||
│ │ 2. Route to ads-serving │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────┐ 3. Check cache ┌─────────────────┐ │
|
||||
│ │ ads-serving │◄────────────────────►│ Redis │ │
|
||||
│ │ service │ (user freq, ads) │ (< 5ms cache) │ │
|
||||
│ └────────┬────────┘ └─────────────────┘ │
|
||||
│ │ │
|
||||
│ │ 4. Run RTB auction (in-memory) │
|
||||
│ │ • Filter by targeting │
|
||||
│ │ • Calculate eCPM for each candidate │
|
||||
│ │ • Apply pacing & frequency caps │
|
||||
│ │ • Select winner │
|
||||
│ │ │
|
||||
│ │ 5. Return winning ad │
|
||||
│ ▼ │
|
||||
│ User sees ad │
|
||||
│ │ │
|
||||
│ │ 6. Fire impression/click events (async) │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────┐ │
|
||||
│ │ RabbitMQ │ │
|
||||
│ └────────┬────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────┴────────┬─────────────────┐ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ads-tracking ads-billing ads-analytics │
|
||||
│ (attribution) (charge $) (metrics) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
4.2 Integration Events
|
||||
// ads-serving → ads-billing
|
||||
public record AdImpressionChargedEvent(
|
||||
Guid AdId, Guid CampaignId, Guid AdvertiserId,
|
||||
decimal Cost, DateTime ChargedAt);
|
||||
// ads-serving → ads-tracking
|
||||
public record AdImpressionTrackedEvent(
|
||||
Guid AdId, Guid UserId, string Placement,
|
||||
Dictionary<string, string> UserContext, DateTime TrackedAt);
|
||||
// ads-tracking → ads-analytics
|
||||
public record ConversionAttributedEvent(
|
||||
Guid ConversionId, Guid AdId, Guid CampaignId,
|
||||
decimal ConversionValue, string AttributionModel);
|
||||
// ads-billing → wallet-service (existing)
|
||||
public record WalletDebitRequestedEvent(
|
||||
Guid WalletId, decimal Amount, string Description,
|
||||
Guid ReferenceId, string ReferenceType);
|
||||
5. Phân Giai Đoạn Triển Khai / Implementation Phases
|
||||
Phase 1: MVP (4-6 tuần / weeks)
|
||||
Domain Features
|
||||
ads-manager Campaign/AdSet/Ad CRUD, Basic targeting (location, age, gender)
|
||||
ads-billing Prepaid only, Simple charge per impression/click
|
||||
ads-serving Basic ad selection, CPC/CPM fixed bidding, No RTB
|
||||
ads-tracking Click tracking only, Simple attribution
|
||||
ads-analytics Basic metrics (impressions, clicks, CTR)
|
||||
Tech Focus:
|
||||
|
||||
Clean Architecture như services hiện có
|
||||
MediatR commands/queries
|
||||
EF Core với PostgreSQL
|
||||
Basic Redis caching
|
||||
Phase 2: Core Features (6-8 tuần / weeks)
|
||||
Domain Features
|
||||
ads-manager Interest targeting, Custom Audiences, Lookalike (basic)
|
||||
ads-billing Postpaid với Credit Lines, Threshold billing
|
||||
ads-serving Real-time bidding engine, Pacing algorithm, Frequency capping
|
||||
ads-tracking Pixel tracking, Server-side conversions, Multi-touch attribution
|
||||
ads-analytics Real-time dashboard, Campaign insights
|
||||
Tech Focus:
|
||||
|
||||
MassTransit/RabbitMQ cho async events
|
||||
Redis Sorted Sets cho frequency tracking
|
||||
SAGA pattern cho billing flows
|
||||
Grafana dashboards
|
||||
Phase 3: Advanced Meta-like (8-12 tuần / weeks)
|
||||
Domain Features
|
||||
ads-manager AI-based Lookalike, Dynamic Ads, A/B testing
|
||||
ads-billing Multi-currency, Tax compliance, Invoice automation
|
||||
ads-serving OCPM optimization, Predictive CTR models, ML ranking
|
||||
ads-tracking Cross-device tracking, SKAdNetwork integration
|
||||
ads-analytics Audience insights, Lift studies, Attribution modeling
|
||||
Tech Focus:
|
||||
|
||||
ML pipeline (recommendation, CTR prediction)
|
||||
Event Sourcing cho audit trails
|
||||
ClickHouse/TimescaleDB cho analytics
|
||||
Kubernetes auto-scaling
|
||||
6. Database Strategy
|
||||
6.1 Database Per Service
|
||||
Service Database Reason
|
||||
ads-manager PostgreSQL (Neon) ACID for campaign management
|
||||
ads-serving Redis (primary) + PostgreSQL (backup) Speed for real-time bidding
|
||||
ads-billing PostgreSQL (Neon) Financial accuracy, ACID
|
||||
ads-tracking TimescaleDB Time-series data for events
|
||||
ads-analytics ClickHouse OLAP for aggregations
|
||||
6.2 Caching Strategy
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ REDIS CACHING LAYERS │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Layer 1: Hot Ads Cache │
|
||||
│ Key: "ads:active:{placementType}" │
|
||||
│ TTL: 5 minutes │
|
||||
│ Type: Sorted Set (by eCPM score) │
|
||||
│ │
|
||||
│ Layer 2: User Frequency │
|
||||
│ Key: "freq:{userId}:{date}" │
|
||||
│ TTL: 24 hours │
|
||||
│ Type: Hash (adId → impressionCount) │
|
||||
│ │
|
||||
│ Layer 3: Budget Tracker │
|
||||
│ Key: "budget:{campaignId}:{date}" │
|
||||
│ TTL: 24 hours │
|
||||
│ Type: String (atomic increment) │
|
||||
│ │
|
||||
│ Layer 4: Targeting Index │
|
||||
│ Key: "target:{targetingCriteria}" │
|
||||
│ TTL: 1 hour │
|
||||
│ Type: Set (eligible adSetIds) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
7. API Design Overview
|
||||
7.1 Ads Manager API
|
||||
# Campaigns
|
||||
POST /api/v1/ads-manager/campaigns
|
||||
GET /api/v1/ads-manager/campaigns
|
||||
GET /api/v1/ads-manager/campaigns/{id}
|
||||
PATCH /api/v1/ads-manager/campaigns/{id}
|
||||
DELETE /api/v1/ads-manager/campaigns/{id}
|
||||
POST /api/v1/ads-manager/campaigns/{id}/duplicate
|
||||
# Ad Sets
|
||||
POST /api/v1/ads-manager/campaigns/{campaignId}/adsets
|
||||
GET /api/v1/ads-manager/adsets/{id}
|
||||
PATCH /api/v1/ads-manager/adsets/{id}
|
||||
# Ads
|
||||
POST /api/v1/ads-manager/adsets/{adSetId}/ads
|
||||
GET /api/v1/ads-manager/ads/{id}
|
||||
PATCH /api/v1/ads-manager/ads/{id}
|
||||
# Audiences
|
||||
POST /api/v1/ads-manager/audiences/custom
|
||||
POST /api/v1/ads-manager/audiences/lookalike
|
||||
GET /api/v1/ads-manager/audiences
|
||||
7.2 Ads Serving API
|
||||
# Real-time ad request (optimized for speed)
|
||||
POST /api/v1/ads/serve # Returns selected ad for placement
|
||||
# Event tracking (async, fire-and-forget)
|
||||
POST /api/v1/ads/events/impression
|
||||
POST /api/v1/ads/events/click
|
||||
7.3 Ads Analytics API
|
||||
# Reporting
|
||||
GET /api/v1/ads-analytics/campaigns/{id}/metrics
|
||||
GET /api/v1/ads-analytics/campaigns/{id}/breakdown?by=age,gender
|
||||
GET /api/v1/ads-analytics/insights/audience
|
||||
POST /api/v1/ads-analytics/reports/schedule
|
||||
8. Tóm Tắt Đề Xuất / Summary
|
||||
8.1 Key Decisions
|
||||
Decision Choice Rationale
|
||||
Architecture 5 separate microservices Separation of concerns, independent scaling
|
||||
Ad Selection eCPM-based RTB Industry standard, balances revenue & relevance
|
||||
Billing Wallet Service integration Reuse existing payment infrastructure
|
||||
Storage Multi-DB (PostgreSQL + Redis + Time-series) Optimal for each workload
|
||||
Events MassTransit/RabbitMQ Existing pattern, reliable async processing
|
||||
8.2 Lợi Ích / Benefits
|
||||
Tái sử dụng tối đa / Maximum Reuse: Tích hợp với IAM, Wallet, Merchant, Storage đã có
|
||||
Scale độc lập / Independent Scaling: ads-serving có thể scale riêng cho traffic cao
|
||||
Nhất quán patterns / Consistent Patterns: Giữ Clean Architecture, CQRS, MediatR như dự án hiện có
|
||||
Phân giai đoạn rõ ràng / Clear Phases: MVP → Core → Advanced theo lộ trình
|
||||
8.3 Rủi Ro & Giải Pháp / Risks & Mitigations
|
||||
Risk Impact Mitigation
|
||||
Ad serving latency > 100ms Poor UX Aggressive Redis caching, precomputed scores
|
||||
Budget overspend Financial loss Atomic Redis counters, pessimistic locking
|
||||
Invalid ad charges Billing disputes Event sourcing, comprehensive audit trail
|
||||
Ad review bottleneck Slow go-live AI-first review with human escalation
|
||||
9. Câu Hỏi Cần Làm Rõ / Questions to Clarify
|
||||
Targeting data source: Dữ liệu Interest/Behavior sẽ lấy từ đâu? (Social Service, external data providers?)
|
||||
Payment methods: Ngoài Wallet hiện có, cần hỗ trợ Credit Card, Bank transfer?
|
||||
Ad placements: Quảng cáo sẽ hiển thị ở đâu? (GoodGo app, partner apps, websites?)
|
||||
MVV (Minimum Viable Version): MVP nên tập trung vào segment nào? (SMB advertisers, Enterprise?)
|
||||
Compliance: Có yêu cầu đặc biệt về data privacy (GDPR, local laws)?
|
||||
Next Step: Sau khi được approve, sẽ tạo implementation plan chi tiết cho Phase 1 (MVP) với task breakdown, domain models, và API specifications cụ thể.
|
||||
Reference in New Issue
Block a user