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