version: '3.8'

# =============================================================================
# GoodGo Platform - Local Development Environment
# =============================================================================
# 
# Prerequisites:
# 1. Copy env.local.example to .env.local and configure values
# 2. Ensure Docker and Docker Compose are installed
# 3. Get Neon PostgreSQL URL from https://console.neon.tech
#
# Start: docker-compose up -d
# Stop: docker-compose down
# Logs: docker-compose logs -f [service-name]
#
# Access Points:
# - Traefik Dashboard: http://localhost:8080
# - IAM Service: http://localhost/api/v1/auth (backward compatible)
# - IAM Service: http://localhost/api/v1/identity, /api/v1/access, /api/v1/governance
# - Web Admin: http://admin.localhost
# - Web Client: http://localhost
#
# =============================================================================

services:
  # ===========================================================================
  # SHARED INFRASTRUCTURE
  # ===========================================================================

  # Traefik - API Gateway and Reverse Proxy
  traefik:
    image: traefik:v3.3
    container_name: traefik-local
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=goodgo-network"
      - "--providers.file.directory=/etc/traefik/dynamic"
      - "--providers.file.watch=true"
      - "--entrypoints.web.address=:80"
      - "--log.level=${LOG_LEVEL:-INFO}"
      - "--accesslog=true"
    ports:
      - "80:80"       # HTTP
      - "8080:8080"   # Dashboard
    volumes:
      # EN: Use actual Docker Desktop socket path (not symlink)
      # VI: Sử dụng đường dẫn socket thực của Docker Desktop (không phải symlink)
      - ${HOME}/.docker/run/docker.sock:/var/run/docker.sock:ro
      - ../../infra/traefik:/etc/traefik:ro
    networks:
      - microservices-network
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.localhost`)"
      - "traefik.http.routers.traefik-dashboard.entrypoints=web"
      - "traefik.http.routers.traefik-dashboard.service=api@internal"

  # ===========================================================================
  # BACKEND SERVICES
  # ===========================================================================

  # Storage Service .NET - File Storage Management
  storage-service:
    build:
      context: ../../services/storage-service-net
      dockerfile: Dockerfile
    image: goodgo/storage-service-net:latest
    container_name: storage-service-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=storage_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: Storage - External MinIO
      # VI: Storage - MinIO bên ngoài
      - Storage__Provider=minio
      - Storage__DefaultBucket=goodgo
      - Storage__MinIO__Endpoint=167.114.174.113:9000
      - Storage__MinIO__AccessKey=minioadmin
      - Storage__MinIO__SecretKey=Velik@2026
      - Storage__MinIO__UseSSL=false
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=storage-service
      # EN: Redis Cache
      # VI: Cache Redis
      - Redis__Host=167.114.174.113
      - Redis__Port=6379
      - Redis__Password=Velik@2026
    ports:
      - "5002:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.storage-service.rule=PathPrefix(`/api/v1/files`) || PathPrefix(`/api/v1/quota`)"
      - "traefik.http.routers.storage-service.entrypoints=web"
      - "traefik.http.services.storage-service.loadbalancer.server.port=8080"
      - "traefik.http.services.storage-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.storage-service.loadbalancer.healthcheck.interval=10s"


  # Membership Service .NET - Membership Management
  membership-service-net:
    build:
      context: ../../services/membership-service-net
      dockerfile: Dockerfile
    image: goodgo/membership-service-net:latest
    container_name: membership-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=membership_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=membership-service
    ports:
      - "5003:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.membership-service.rule=PathPrefix(`/api/v1/members`) || PathPrefix(`/api/v1/levels`) || PathPrefix(`/api/v1/memberships`) || PathPrefix(`/api/v1/subscriptions`)"
      - "traefik.http.routers.membership-service.entrypoints=web"
      - "traefik.http.services.membership-service.loadbalancer.server.port=8080"
      - "traefik.http.services.membership-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.membership-service.loadbalancer.healthcheck.interval=10s"

  # Merchant Service .NET - Merchant & Shop Management
  merchant-service-net:
    build:
      context: ../../services/merchant-service-net
      dockerfile: Dockerfile
    image: goodgo/merchant-service-net:latest
    container_name: merchant-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=merchant_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=merchant-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
    ports:
      - "5005:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.merchant-service.rule=PathPrefix(`/api/v1/merchants`) || PathPrefix(`/api/v1/shops`)"
      - "traefik.http.routers.merchant-service.entrypoints=web"
      - "traefik.http.services.merchant-service.loadbalancer.server.port=8080"
      - "traefik.http.services.merchant-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.merchant-service.loadbalancer.healthcheck.interval=10s"

  # IAM Service .NET - Identity and Access Management (Duende IdentityServer)
  iam-service-net:
    build:
      context: ../../services/iam-service-net
      dockerfile: Dockerfile
    image: goodgo/iam-service-net:latest
    container_name: iam-service-net-local
    env_file:
      - .env
    environment:
      - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=${IAM_DATABASE_URL}
      # EN: Redis Cache (external)
      # VI: Cache Redis (bên ngoài)
      - Redis__Host=${REDIS_HOST}
      - Redis__Port=${REDIS_PORT}
      - Redis__Password=${REDIS_PASSWORD}
      - Redis__Database=${REDIS_DATABASE}
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Secret=${JWT_SECRET}
      - Jwt__Issuer=${JWT_ISSUER}
      - Jwt__Audience=${JWT_AUDIENCE}
      - Jwt__AccessTokenExpiryMinutes=${JWT_ACCESS_TOKEN_EXPIRY_MINUTES}
      - Jwt__RefreshTokenExpiryDays=${JWT_REFRESH_TOKEN_EXPIRY_DAYS}
      # EN: Features
      # VI: Tính năng
      - Features__SwaggerEnabled=${FEATURE_SWAGGER_ENABLED}
      - Features__DetailedErrors=${FEATURE_DETAILED_ERRORS}
      # EN: IdentityServer - Fixed issuer for inter-service communication
      # VI: IdentityServer - Issuer cố định cho giao tiếp giữa các service
      - IdentityServer__IssuerUri=http://iam-service
    ports:
      - "5001:8080"
    depends_on:
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.iam-service-net.rule=PathPrefix(`/api/v1/iam`) || PathPrefix(`/api/v1/auth`) || PathPrefix(`/api/v1/users`) || PathPrefix(`/api/v1/roles`)"
      - "traefik.http.routers.iam-service-net.entrypoints=web"
      - "traefik.http.services.iam-service-net.loadbalancer.server.port=8080"
      - "traefik.http.services.iam-service-net.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.iam-service-net.loadbalancer.healthcheck.interval=10s"

  # Wallet Service .NET - Wallet & PPoint Management
  wallet-service-net:
    build:
      context: ../../services/wallet-service-net
      dockerfile: Dockerfile
    image: goodgo/wallet-service-net:latest
    container_name: wallet-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=wallet_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=wallet-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
    ports:
      - "5004:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wallet-service.rule=PathPrefix(`/api/v1/wallets`) || PathPrefix(`/api/v1/points`) || PathPrefix(`/api/v1/admin/wallets`) || PathPrefix(`/api/v1/admin/points`)"
      - "traefik.http.routers.wallet-service.entrypoints=web"
      - "traefik.http.services.wallet-service.loadbalancer.server.port=8080"
      - "traefik.http.services.wallet-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.wallet-service.loadbalancer.healthcheck.interval=10s"

  # Chat Service .NET - Real-time Chat with SignalR
  chat-service-net:
    build:
      context: ../../services/chat-service-net
      dockerfile: Dockerfile
    image: goodgo/chat-service-net:latest
    container_name: chat-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=chat_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: Redis for SignalR Backplane
      # VI: Redis cho SignalR Backplane
      - ConnectionStrings__Redis=167.114.174.113:6379,password=Velik@2026
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=chat-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: SignalR Configuration
      # VI: Cấu hình SignalR
      - SignalR__EnableMessagePack=true
      - SignalR__StatefulReconnectBufferSize=32768
    ports:
      - "5010:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      # EN: HTTP API routes
      # VI: Routes cho HTTP API
      - "traefik.http.routers.chat-service.rule=PathPrefix(`/api/v1/conversations`) || PathPrefix(`/api/v1/messages`) || PathPrefix(`/api/v1/chat`)"
      - "traefik.http.routers.chat-service.entrypoints=web"
      - "traefik.http.services.chat-service.loadbalancer.server.port=8080"
      - "traefik.http.services.chat-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.chat-service.loadbalancer.healthcheck.interval=10s"
      # EN: SignalR Hub route with sticky sessions
      # VI: Route cho SignalR Hub với sticky sessions
      - "traefik.http.routers.chat-hub.rule=PathPrefix(`/hubs/chat`)"
      - "traefik.http.routers.chat-hub.entrypoints=web"
      - "traefik.http.routers.chat-hub.service=chat-service"
      - "traefik.http.services.chat-service.loadbalancer.sticky.cookie=true"
      - "traefik.http.services.chat-service.loadbalancer.sticky.cookie.name=chat_session"

  # Social Service .NET - Social Features (Profiles, Posts, Followers)
  social-service-net:
    build:
      context: ../../services/social-service-net
      dockerfile: Dockerfile
    image: goodgo/social-service-net:latest
    container_name: social-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=social_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=social-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: Redis Cache
      # VI: Cache Redis
      - Redis__Host=167.114.174.113
      - Redis__Port=6379
      - Redis__Password=Velik@2026
    ports:
      - "5009:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.social-service.rule=PathPrefix(`/api/v1/profiles`) || PathPrefix(`/api/v1/posts`) || PathPrefix(`/api/v1/followers`) || PathPrefix(`/api/v1/social`)"
      - "traefik.http.routers.social-service.entrypoints=web"
      - "traefik.http.services.social-service.loadbalancer.server.port=8080"
      - "traefik.http.services.social-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.social-service.loadbalancer.healthcheck.interval=10s"

  # Mining Service .NET - Pi Network-style Point Mining
  mining-service-net:
    build:
      context: ../../services/mining-service-net
      dockerfile: Dockerfile
    image: goodgo/mining-service-net:latest
    container_name: mining-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=mining_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=mining-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: Redis Cache
      # VI: Cache Redis
      - Redis__Host=167.114.174.113
      - Redis__Port=6379
      - Redis__Password=Velik@2026
    ports:
      - "5006:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mining-service.rule=PathPrefix(`/api/v1/mining`) || PathPrefix(`/api/v1/circles`) || PathPrefix(`/api/v1/referrals`)"
      - "traefik.http.routers.mining-service.entrypoints=web"
      - "traefik.http.services.mining-service.loadbalancer.server.port=8080"
      - "traefik.http.services.mining-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.mining-service.loadbalancer.healthcheck.interval=10s"
      # EN: SignalR Hub route with sticky sessions
      # VI: Route cho SignalR Hub với sticky sessions
      - "traefik.http.routers.mining-hub.rule=PathPrefix(`/hubs/mining`)"
      - "traefik.http.routers.mining-hub.entrypoints=web"
      - "traefik.http.routers.mining-hub.service=mining-service"
      - "traefik.http.services.mining-service.loadbalancer.sticky.cookie=true"
      - "traefik.http.services.mining-service.loadbalancer.sticky.cookie.name=mining_session"

  # Mission Service .NET - Gamification (Check-ins, Missions, Tasks)
  mission-service-net:
    build:
      context: ../../services/mission-service-net
      dockerfile: Dockerfile
    image: goodgo/mission-service-net:latest
    container_name: mission-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=mission_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=mission-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: Redis Cache
      # VI: Cache Redis
      - Redis__Host=167.114.174.113
      - Redis__Port=6379
      - Redis__Password=Velik@2026
    ports:
      - "5007:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mission-service.rule=PathPrefix(`/api/v1/checkins`) || PathPrefix(`/api/v1/missions`) || PathPrefix(`/api/v1/admin/missions`) || PathPrefix(`/api/v1/admin/checkins`) || PathPrefix(`/api/v1/admin/tasks`)"
      - "traefik.http.routers.mission-service.entrypoints=web"
      - "traefik.http.services.mission-service.loadbalancer.server.port=8080"
      - "traefik.http.services.mission-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.mission-service.loadbalancer.healthcheck.interval=10s"

  # Promotion Service .NET - Voucher, Gift Card, Campaign Management
  promotion-service-net:
    build:
      context: ../../services/promotion-service-net
      dockerfile: Dockerfile
    image: goodgo/promotion-service-net:latest
    container_name: promotion-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=promotion_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=promotion-service
      # EN: Wallet Service Communication
      # VI: Giao tiếp Wallet Service
      - WalletService__BaseUrl=http://wallet-service-net:8080
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
    ports:
      - "5008:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      wallet-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.promotion-service.rule=PathPrefix(`/api/v1/campaigns`) || PathPrefix(`/api/v1/vouchers`) || PathPrefix(`/api/v1/admin/campaigns`) || PathPrefix(`/api/v1/admin/vouchers`)"
      - "traefik.http.routers.promotion-service.entrypoints=web"
      - "traefik.http.services.promotion-service.loadbalancer.server.port=8080"
      - "traefik.http.services.promotion-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.promotion-service.loadbalancer.healthcheck.interval=10s"

  # ===========================================================================
  # MULTI-VERTICAL SERVICES - Product, Order, Inventory Management
  # ===========================================================================

  # Catalog Service .NET - Polymorphic Product Management
  catalog-service-net:
    build:
      context: ../../services/catalog-service-net
      dockerfile: Dockerfile
    image: goodgo/catalog-service-net:latest
    container_name: catalog-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Database=catalog_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=catalog-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
    ports:
      - "5016:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      merchant-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.catalog-service.rule=PathPrefix(`/api/v1/products`) || PathPrefix(`/api/v1/categories`)"
      - "traefik.http.routers.catalog-service.entrypoints=web"
      - "traefik.http.services.catalog-service.loadbalancer.server.port=8080"
      - "traefik.http.services.catalog-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.catalog-service.loadbalancer.healthcheck.interval=10s"

  # Order Service .NET - Order Orchestration with Strategy Pattern
  order-service-net:
    build:
      context: ../../services/order-service-net
      dockerfile: Dockerfile
    image: goodgo/order-service-net:latest
    container_name: order-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Database=order_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=order-service
      # EN: Service Communication
      # VI: Giao tiếp Service
      - CatalogService__BaseUrl=http://catalog-service-net:8080
      - InventoryService__BaseUrl=http://inventory-service-net:8080
      - WalletService__BaseUrl=http://wallet-service-net:8080
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
    ports:
      - "5017:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      catalog-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.order-service.rule=PathPrefix(`/api/v1/orders`)"
      - "traefik.http.routers.order-service.entrypoints=web"
      - "traefik.http.services.order-service.loadbalancer.server.port=8080"
      - "traefik.http.services.order-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.order-service.loadbalancer.healthcheck.interval=10s"

  # Inventory Service .NET - Stock Management (Retail + FnB)
  inventory-service-net:
    build:
      context: ../../services/inventory-service-net
      dockerfile: Dockerfile
    image: goodgo/inventory-service-net:latest
    container_name: inventory-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Database=inventory_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=inventory-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
    ports:
      - "5018:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      catalog-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.inventory-service.rule=PathPrefix(`/api/v1/inventory`) || PathPrefix(`/api/v1/stock`)"
      - "traefik.http.routers.inventory-service.entrypoints=web"
      - "traefik.http.services.inventory-service.loadbalancer.server.port=8080"
      - "traefik.http.services.inventory-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.inventory-service.loadbalancer.healthcheck.interval=10s"

  # FnB Engine .NET - Table, Session & Kitchen Management
  fnb-engine-net:
    build:
      context: ../../services/fnb-engine-net
      dockerfile: Dockerfile
    image: goodgo/fnb-engine-net:latest
    container_name: fnb-engine-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Database=fnb_engine;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=fnb-engine
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: Redis for SignalR (Kitchen Display)
      # VI: Redis cho SignalR (Màn hình bếp)
      - ConnectionStrings__Redis=167.114.174.113:6379,password=Velik@2026
    ports:
      - "5019:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      merchant-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.fnb-engine.rule=PathPrefix(`/api/v1/tables`) || PathPrefix(`/api/v1/sessions`) || PathPrefix(`/api/v1/kitchen`)"
      - "traefik.http.routers.fnb-engine.entrypoints=web"
      - "traefik.http.services.fnb-engine.loadbalancer.server.port=8080"
      - "traefik.http.services.fnb-engine.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.fnb-engine.loadbalancer.healthcheck.interval=10s"
      # EN: SignalR Hub route for Kitchen Display
      # VI: Route cho SignalR Hub màn hình bếp
      - "traefik.http.routers.fnb-hub.rule=PathPrefix(`/hubs/kitchen`)"
      - "traefik.http.routers.fnb-hub.entrypoints=web"
      - "traefik.http.routers.fnb-hub.service=fnb-engine"
      - "traefik.http.services.fnb-engine.loadbalancer.sticky.cookie=true"
      - "traefik.http.services.fnb-engine.loadbalancer.sticky.cookie.name=fnb_session"

  # Booking Service .NET - Appointment Scheduling (Services, Spa, Salon)
  booking-service-net:
    build:
      context: ../../services/booking-service-net
      dockerfile: Dockerfile
    image: goodgo/booking-service-net:latest
    container_name: booking-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Database=booking_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=booking-service
      # EN: Service Communication
      # VI: Giao tiếp Service
      - CatalogService__BaseUrl=http://catalog-service-net:8080
      - MerchantService__BaseUrl=http://merchant-service-net:8080
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
    ports:
      - "5020:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      catalog-service-net:
        condition: service_healthy
      merchant-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.booking-service.rule=PathPrefix(`/api/v1/appointments`) || PathPrefix(`/api/v1/resources`) || PathPrefix(`/api/v1/schedules`)"
      - "traefik.http.routers.booking-service.entrypoints=web"
      - "traefik.http.services.booking-service.loadbalancer.server.port=8080"
      - "traefik.http.services.booking-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.booking-service.loadbalancer.healthcheck.interval=10s"


  # Ads Manager Service .NET - Campaign & Ad Management
  ads-manager-service-net:
    build:
      context: ../../services/ads-manager-service-net
      dockerfile: Dockerfile
    image: goodgo/ads-manager-service-net:latest
    container_name: ads-manager-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=ads_manager_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=ads-manager-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: Redis Cache
      # VI: Cache Redis
      - Redis__Host=167.114.174.113
      - Redis__Port=6379
      - Redis__Password=Velik@2026
    ports:
      - "5011:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ads-manager-service.rule=PathPrefix(`/api/v1/ads-manager`)"
      - "traefik.http.routers.ads-manager-service.entrypoints=web"
      - "traefik.http.services.ads-manager-service.loadbalancer.server.port=8080"
      - "traefik.http.services.ads-manager-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.ads-manager-service.loadbalancer.healthcheck.interval=10s"

  # Ads Analytics Service .NET - Ad Performance Analytics & Reporting
  ads-analytics-service-net:
    build:
      context: ../../services/ads-analytics-service-net
      dockerfile: Dockerfile
    image: goodgo/ads-analytics-service-net:latest
    container_name: ads-analytics-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=ads_analytics_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=ads-analytics-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: Redis Cache
      # VI: Cache Redis
      - Redis__Host=167.114.174.113
      - Redis__Port=6379
      - Redis__Password=Velik@2026
    ports:
      - "5015:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ads-analytics-service.rule=PathPrefix(`/api/v1/ads-analytics`) || PathPrefix(`/api/v1/admin/ads-analytics`)"
      - "traefik.http.routers.ads-analytics-service.entrypoints=web"
      - "traefik.http.services.ads-analytics-service.loadbalancer.server.port=8080"
      - "traefik.http.services.ads-analytics-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.ads-analytics-service.loadbalancer.healthcheck.interval=10s"

  # Ads Serving Service .NET - Real-Time Bidding & Ad Serving (< 100ms)
  ads-serving-service-net:
    build:
      context: ../../services/ads-serving-service-net
      dockerfile: Dockerfile
    image: goodgo/ads-serving-service-net:latest
    container_name: ads-serving-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=ads_serving_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=ads-serving-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: Redis Cache (required for RTB)
      # VI: Cache Redis (bắt buộc cho RTB)
      - Redis__Host=167.114.174.113
      - Redis__Port=6379
      - Redis__Password=Velik@2026
      # EN: RabbitMQ for event publishing
      # VI: RabbitMQ để publish sự kiện
      - RabbitMQ__Host=rabbitmq
      - RabbitMQ__Port=5672
      - RabbitMQ__Username=guest
      - RabbitMQ__Password=guest
    ports:
      - "5012:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      # EN: Public API routes for ad serving
      # VI: Routes API công khai để serve quảng cáo
      - "traefik.http.routers.ads-serving-service.rule=PathPrefix(`/api/v1/ads/serve`) || PathPrefix(`/api/v1/ads/events`)"
      - "traefik.http.routers.ads-serving-service.entrypoints=web"
      - "traefik.http.services.ads-serving-service.loadbalancer.server.port=8080"
      - "traefik.http.services.ads-serving-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.ads-serving-service.loadbalancer.healthcheck.interval=10s"
      # EN: Admin API routes for monitoring
      # VI: Routes API Admin để giám sát
      - "traefik.http.routers.ads-serving-admin.rule=PathPrefix(`/api/v1/admin/auctions`) || PathPrefix(`/api/v1/admin/budget`) || PathPrefix(`/api/v1/admin/frequency`)"
      - "traefik.http.routers.ads-serving-admin.entrypoints=web"
      - "traefik.http.routers.ads-serving-admin.service=ads-serving-service"

  # Ads Billing Service .NET - Billing, Invoicing & Payment Management
  ads-billing-service-net:
    build:
      context: ../../services/ads-billing-service-net
      dockerfile: Dockerfile
    image: goodgo/ads-billing-service-net:latest
    container_name: ads-billing-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=ads_billing_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=ads-billing-service
      # EN: Wallet Service Communication
      # VI: Giao tiếp Wallet Service
      - WalletService__BaseUrl=http://wallet-service-net:8080
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
    ports:
      - "5013:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      wallet-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      # EN: Public API routes for billing, invoices, credit lines
      # VI: Routes API công khai cho billing, hóa đơn, tín dụng
      - "traefik.http.routers.ads-billing-service.rule=PathPrefix(`/api/v1/ads-billing/accounts`) || PathPrefix(`/api/v1/ads-billing/invoices`) || PathPrefix(`/api/v1/ads-billing/credit-lines`)"
      - "traefik.http.routers.ads-billing-service.entrypoints=web"
      - "traefik.http.services.ads-billing-service.loadbalancer.server.port=8080"
      - "traefik.http.services.ads-billing-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.ads-billing-service.loadbalancer.healthcheck.interval=10s"
      # EN: Admin API routes for billing management
      # VI: Routes API Admin để quản lý billing
      - "traefik.http.routers.ads-billing-admin.rule=PathPrefix(`/api/v1/admin/ads-billing`)"
      - "traefik.http.routers.ads-billing-admin.entrypoints=web"
      - "traefik.http.routers.ads-billing-admin.service=ads-billing-service"

  # Ads Tracking Service .NET - Pixel Tracking, Conversion Tracking & Attribution
  ads-tracking-service-net:
    build:
      context: ../../services/ads-tracking-service-net
      dockerfile: Dockerfile
    image: goodgo/ads-tracking-service-net:latest
    container_name: ads-tracking-service-net-local
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://+:8080
      # EN: Database - Neon PostgreSQL
      # VI: Cơ sở dữ liệu - Neon PostgreSQL
      - ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=ads_tracking_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
      # EN: IAM Service Communication
      # VI: Giao tiếp IAM Service
      - IamService__BaseUrl=http://iam-service-net:8080
      - IamService__ServiceName=ads-tracking-service
      # EN: JWT Configuration
      # VI: Cấu hình JWT
      - Jwt__Authority=http://iam-service-net:8080
      - Jwt__Audience=goodgo-api
      - Jwt__RequireHttpsMetadata=false
      # EN: Redis Cache (for high-volume event buffering)
      # VI: Cache Redis (cho buffering sự kiện lưu lượng cao)
      - Redis__Host=167.114.174.113
      - Redis__Port=6379
      - Redis__Password=Velik@2026
      # EN: RabbitMQ for event publishing
      # VI: RabbitMQ để publish sự kiện
      - RabbitMQ__Host=rabbitmq
      - RabbitMQ__Port=5672
      - RabbitMQ__Username=guest
      - RabbitMQ__Password=guest
    ports:
      - "5014:8080"
    depends_on:
      iam-service-net:
        condition: service_healthy
      traefik:
        condition: service_started
    networks:
      - microservices-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      # EN: Public API routes for pixel tracking (high traffic, no auth)
      # VI: Routes API công khai cho pixel tracking (lưu lượng cao, không auth)
      - "traefik.http.routers.ads-tracking-pixels.rule=PathPrefix(`/api/v1/pixels`)"
      - "traefik.http.routers.ads-tracking-pixels.entrypoints=web"
      - "traefik.http.services.ads-tracking-service.loadbalancer.server.port=8080"
      - "traefik.http.services.ads-tracking-service.loadbalancer.healthcheck.path=/health/live"
      - "traefik.http.services.ads-tracking-service.loadbalancer.healthcheck.interval=10s"
      # EN: Conversion tracking API routes
      # VI: Routes API cho conversion tracking
      - "traefik.http.routers.ads-tracking-conversions.rule=PathPrefix(`/api/v1/conversions`)"
      - "traefik.http.routers.ads-tracking-conversions.entrypoints=web"
      - "traefik.http.routers.ads-tracking-conversions.service=ads-tracking-service"
      # EN: Admin API routes for analytics and attribution
      # VI: Routes API Admin cho analytics và attribution
      - "traefik.http.routers.ads-tracking-admin.rule=PathPrefix(`/api/v1/admin/attribution`) || PathPrefix(`/api/v1/admin/tracking-stats`)"
      - "traefik.http.routers.ads-tracking-admin.entrypoints=web"
      - "traefik.http.routers.ads-tracking-admin.service=ads-tracking-service"


  # Jaeger - Distributed Tracing
  # jaeger:
  #   image: jaegertracing/all-in-one:1.47
  #   container_name: jaeger-local
  #   ports:
  #     - "16686:16686"  # UI
  #     - "14268:14268"  # Collector
  #   environment:
  #     - COLLECTOR_OTLP_ENABLED=true
  #   networks:
  #     - microservices-network
  #   restart: unless-stopped

  # Prometheus - Metrics Collection
  # prometheus:
  #   image: prom/prometheus:latest
  #   container_name: prometheus-local
  #   ports:
  #     - "9090:9090"
  #   volumes:
  #     - ../../infra/observability/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
  #     - prometheus_data:/prometheus
  #   networks:
  #     - microservices-network
  #   restart: unless-stopped

  # Grafana - Metrics Visualization
  # grafana:
  #   image: grafana/grafana:latest
  #   container_name: grafana-local
  #   ports:
  #     - "3001:3000"
  #   environment:
  #     - GF_SECURITY_ADMIN_PASSWORD=admin
  #   volumes:
  #     - grafana_data:/var/lib/grafana
  #   networks:
  #     - microservices-network
  #   restart: unless-stopped

# =============================================================================
# VOLUMES
# =============================================================================
volumes: {}
# =============================================================================
# NETWORKS
# =============================================================================
networks:
  microservices-network:
    driver: bridge
    name: goodgo-network
