Files
pos-system/microservices/.agent/skills/multi-vertical-architecture/SKILL.md
Ho Ngoc Hai 76d75c753b Migrate
2026-05-23 18:37:02 +07:00

12 KiB

name, description, compatibility, metadata
name description compatibility metadata
multi-vertical-architecture Multi-vertical Architecture patterns cho đa ngành hàng (Retail, F&B, Services). Use for Order Service orchestration, Strategy Pattern, Satellite Services, và Shop feature configuration. .NET 10, PostgreSQL, JSONB
author version references
Velik Ho 1.0 Clean Architecture, Domain-Driven Design

Multi-vertical Architecture / Kiến Trúc Đa Ngành Hàng

When to Use This Skill / Khi Nào Sử Dụng

Use this skill when:

  • Thiết kế hệ thống hỗ trợ nhiều ngành kinh doanh (Retail, F&B, Services)
  • Tạo Order Service với Strategy Pattern để xử lý đơn hàng đa loại
  • Thêm Vertical Engine mới (Inventory, Booking, F&B Engine...)
  • Cấu hình Shop features và business settings động

Core Principle / Nguyên Tắc Cốt Lõi

Merchant Service quản lý "AI" (Identity) và "LUẬT" (Configuration), còn "CÁCH" (Execution) được ủy quyền cho các service vệ tinh.

Architecture Layers / Các Tầng Kiến Trúc

┌─────────────────────────────────────────────────────────┐
│                   📱 Client Layer                        │
│              (POS, Web Dashboard, Mobile App)            │
└─────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────┐
│                   ⚡ API Gateway (Traefik)               │
└─────────────────────────────────────────────────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        ▼                   ▼                   ▼
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│ 🟡 Core Layer │   │ 🔴 Orchestration│   │ 🔵 Vertical   │
│               │   │     Layer      │   │   Engines     │
│ • IAM         │   │ • Catalog      │   │ • Inventory   │
│ • Merchant    │   │ • Order        │   │ • Booking     │
│ • Wallet      │   │                │   │ • F&B Engine  │
└───────────────┘   └───────────────┘   └───────────────┘

Layer Responsibilities

Layer Trách Nhiệm Services
Core Identity & Configuration IAM, Merchant, Wallet
Orchestration Business logic coordination Catalog, Order
Vertical Engines Domain-specific execution Inventory, Booking, F&B

Key Patterns / Mẫu Chính

1. Shop Feature Flags

Sử dụng JSONB để lưu cấu hình động:

// Value Object mapping với JSONB
public record ShopFeatures(
    bool HasInventory = false,  // Bật Inventory Service
    bool HasBooking = false,    // Bật Booking Service
    bool HasTables = false,     // Bật quản lý bàn
    bool HasKitchen = false,    // Bật KDS
    bool HasShipping = false,   // Bật vận chuyển
    bool HasDelivery = false    // Bật giao hàng
);

// Entity sử dụng
public class Shop : Entity, IAggregateRoot
{
    public BusinessCategory Category { get; private set; }
    public ShopFeatures Features { get; private set; }
    public JsonDocument? Settings { get; private set; }
}

2. Business Category

public enum BusinessCategory
{
    Retail = 1,       // Bán lẻ hàng hóa
    FoodBeverage = 2, // Nhà hàng, quán cafe
    Services = 3,     // Spa, salon, phòng khám
    Other = 99        // Hybrid
}

3. Strategy Pattern for Order Processing

Interface:

public interface ILineItemStrategy
{
    ProductType SupportedType { get; }
    Task ValidateAsync(OrderItem item, Guid shopId);
    Task ExecuteAsync(OrderItem item, Guid shopId);
}

Retail Strategy:

public class RetailStrategy : ILineItemStrategy
{
    private readonly IInventoryService _inventory;
    
    public ProductType SupportedType => ProductType.Physical;
    
    public async Task ValidateAsync(OrderItem item, Guid shopId)
    {
        // Gọi Inventory Service: Kiểm tra tồn kho
        var stock = await _inventory.CheckStockAsync(item.ProductId, shopId);
        if (stock.Available < item.Quantity)
            throw new InsufficientStockException(item.ProductId);
    }
    
    public async Task ExecuteAsync(OrderItem item, Guid shopId)
    {
        // Gọi Inventory Service: Trừ tồn kho
        await _inventory.DeductStockAsync(item.ProductId, item.Quantity, shopId);
    }
}

Service Strategy (Spa/Salon):

public class ServiceStrategy : ILineItemStrategy
{
    private readonly IBookingService _booking;
    
    public ProductType SupportedType => ProductType.Service;
    
    public async Task ValidateAsync(OrderItem item, Guid shopId)
    {
        // Kiểm tra slot + nhân viên khả dụng
        var available = await _booking.CheckAvailabilityAsync(
            item.ServiceId, 
            item.RequestedTime, 
            shopId);
        if (!available)
            throw new SlotNotAvailableException(item.RequestedTime);
    }
    
    public async Task ExecuteAsync(OrderItem item, Guid shopId)
    {
        // Tạo appointment
        await _booking.CreateAppointmentAsync(item, shopId);
    }
}

F&B Strategy:

public class FnbStrategy : ILineItemStrategy
{
    private readonly IEventBus _eventBus;
    
    public ProductType SupportedType => ProductType.PreparedFood;
    
    public async Task ExecuteAsync(OrderItem item, Guid shopId)
    {
        // Bắn event xuống bếp
        await _eventBus.PublishAsync(new KitchenTicketCreated
        {
            OrderItemId = item.Id,
            ProductName = item.ProductName,
            Quantity = item.Quantity,
            Notes = item.Notes,
            Station = item.KitchenStation
        });
    }
}

4. Order Handler with Strategy Factory

public class CreateOrderHandler : IRequestHandler<CreateOrderCommand, OrderResponse>
{
    private readonly IEnumerable<ILineItemStrategy> _strategies;
    
    public async Task<OrderResponse> Handle(CreateOrderCommand request, CancellationToken ct)
    {
        var order = Order.Create(request.ShopId, request.CustomerId);
        
        // Phase 1: Validate all items
        foreach (var item in request.Items)
        {
            var strategy = _strategies.First(s => s.SupportedType == item.ProductType);
            await strategy.ValidateAsync(item, request.ShopId);
            order.AddItem(item);
        }
        
        // Phase 2: Process payment
        await ProcessPaymentAsync(order);
        
        // Phase 3: Execute all items
        foreach (var item in order.Items)
        {
            var strategy = _strategies.First(s => s.SupportedType == item.ProductType);
            await strategy.ExecuteAsync(item, request.ShopId);
        }
        
        return order.ToResponse();
    }
}

Database Patterns / Mẫu Database

JSONB Columns for Dynamic Config

ALTER TABLE shops 
ADD COLUMN features_config JSONB DEFAULT '{}',
ADD COLUMN vertical_settings JSONB DEFAULT '{}',
ADD COLUMN business_category VARCHAR(50) DEFAULT 'Other';

-- GIN index for JSONB queries
CREATE INDEX idx_shops_features ON shops USING GIN (features_config);

EF Core JSONB Configuration

public class ShopConfiguration : IEntityTypeConfiguration<Shop>
{
    public void Configure(EntityTypeBuilder<Shop> builder)
    {
        builder.Property(s => s.Features)
            .HasColumnName("features_config")
            .HasColumnType("jsonb")
            .HasConversion(
                v => JsonSerializer.Serialize(v, JsonSerializerOptions.Default),
                v => JsonSerializer.Deserialize<ShopFeatures>(v, JsonSerializerOptions.Default)!
            );
            
        builder.Property(s => s.Settings)
            .HasColumnName("vertical_settings")
            .HasColumnType("jsonb");
    }
}

Vertical Engines Overview / Tổng Quan Engines

Inventory Service

Feature Retail F&B
Stock tracking Thành phẩm Nguyên liệu
Deduction logic 1:1 (Bán 1 trừ 1) Recipe-based (Định lượng)
Low stock alerts

Booking Service

Entity Mô Tả
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

F&B Engine

Entity Mô Tả
Table Sơ đồ bàn
Session Phiên ăn (khách ngồi tại bàn)
KitchenTicket Phiếu bếp cho KDS
Recipe Định lượng nguyên liệu

Common Mistakes / Lỗi Thường Gặp

1. Đặt logic nghiệp vụ trong Core Layer

// ❌ BAD: Logic inventory trong Merchant Service
public class ShopService
{
    public async Task<bool> ProcessSale(Guid productId, int quantity)
    {
        // Logic tồn kho không thuộc về Merchant Service!
        var stock = await _db.Stocks.FindAsync(productId);
        stock.Quantity -= quantity;
    }
}

// ✅ GOOD: Merchant Service chỉ trả về cấu hình
public class ShopService
{
    public async Task<ShopFeatures> GetShopFeaturesAsync(Guid shopId)
    {
        var shop = await _shopRepository.GetByIdAsync(shopId);
        return shop.Features; // Order Service sẽ gọi Inventory Service
    }
}

2. Dùng if-else thay vì Strategy Pattern

// ❌ BAD: If-else spaghetti
public async Task ProcessOrder(Order order)
{
    foreach (var item in order.Items)
    {
        if (item.Type == "Physical")
            await _inventory.DeductStock(item);
        else if (item.Type == "Service")
            await _booking.CreateAppointment(item);
        else if (item.Type == "PreparedFood")
            await _kitchen.CreateTicket(item);
        // Thêm ngành mới = thêm else if
    }
}

// ✅ GOOD: Strategy Pattern
public async Task ProcessOrder(Order order)
{
    foreach (var item in order.Items)
    {
        var strategy = _strategies.First(s => s.SupportedType == item.ProductType);
        await strategy.ExecuteAsync(item, order.ShopId);
        // Thêm ngành mới = thêm Strategy class mới
    }
}

3. Không sử dụng Feature Flags

// ❌ BAD: Gọi service không kiểm tra feature
public async Task ProcessOrder(Order order)
{
    await _inventory.DeductStock(order); // Sẽ lỗi nếu shop không có Inventory!
}

// ✅ GOOD: Kiểm tra feature trước
public async Task ProcessOrder(Order order)
{
    var features = await _merchantService.GetShopFeaturesAsync(order.ShopId);
    
    if (features.HasInventory)
        await _inventory.DeductStock(order);
}

Quick Reference / Tham Chiếu Nhanh

Concept Pattern Áp Dụng
Cấu hình động JSONB + Value Object ShopFeatures, Settings
Xử lý đa loại Strategy Pattern ILineItemStrategy
Giao tiếp service Integration Events KitchenTicketCreated
Mở rộng ngành Satellite Architecture Vertical Engines

Resources / Tài Nguyên