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