services:
  # PostgreSQL - Base de datos core (app)
  postgres-a76:
    image: postgres:18-alpine
    container_name: anexo76-postgres-a76
    environment:
      POSTGRES_DB: anexo76_core
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${POSTGRES_APP_PASSWORD:-postgres}
      POSTGRES_INITDB_ARGS: "--encoding=UTF8"
    ports:
      - "5939:5432"
    volumes:
      - postgres_app_data:/var/lib/postgresql/data
    networks:
      - backend-net
    restart: unless-stopped
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U postgres -d anexo76_core || exit 1" ]
      interval: 5s
      timeout: 3s
      retries: 10
      start_period: 20s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M
    shm_size: 128mb

  # Backend - FastAPI
  backend:
    image: dev.aduanasoft.com/anexo76/backend:latest
    container_name: anexo76-backend
    environment:
      - DEBUG=${DEBUG:-True}
      - ENVIRONMENT=${ENVIRONMENT:-production}
      - PYTHONUNBUFFERED=1
      - PYTHONDONTWRITEBYTECODE=1
      - CORE_DB_HOST=${CORE_DB_HOST:-postgres-a76}
      - CORE_DB_PORT=${CORE_DB_PORT:-5432}
      - CORE_DB_NAME=${CORE_DB_NAME:-anexo76_core}
      - CORE_DB_USER=${CORE_DB_USER:-postgres}
      - CORE_DB_PASSWORD=${POSTGRES_APP_PASSWORD:-postgres}
      # Keycloak — fuente única de autenticación: Workspace (workspace.aduanasoft.com)
      - KEYCLOAK_SERVER_URL=${KEYCLOAK_SERVER_URL:-https://workspace.aduanasoft.com/kcauth}
      - KEYCLOAK_REALM=${KEYCLOAK_REALM:-master}
      - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID:-anexo76-frontend}
      - KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET:-}
      - CORS_ORIGINS=${CORS_ORIGINS:-https://anexo76-dev.aduanasoft.com,http://localhost:3000}
      - SITAR_API_URL=${SITAR_API_URL}
      - SITAR_API_USER=${SITAR_API_USER}
      - SITAR_API_PASSWORD=${SITAR_API_PASSWORD}
      - COVE_FIEL_HASH_KEY=${COVE_FIEL_HASH_KEY}
      - COVE_FIEL_HASH_IV=${COVE_FIEL_HASH_IV}
      - COVE_API_URL=${COVE_API_URL:-https://api.vu.aduanasoft.com}
      - COVE_API_VERIFY_SSL=${COVE_API_VERIFY_SSL:-False}
      - VALKEY_URL=${VALKEY_URL:-redis://valkey:6379/0}
      - CENTRAL_SERVER_URL=${CENTRAL_SERVER_URL:-""}
      - SYNC_SECRET_TOKEN=${SYNC_SECRET_TOKEN:-change-this-sync-token-in-production}
      - SPOKE_URLS=${SPOKE_URLS:-""}
      - HUB_URL=${HUB_URL:-https://workspace.aduanasoft.com}
      - HUB_ADMIN_EMAIL=${HUB_ADMIN_EMAIL:-}
      - HUB_ADMIN_PASSWORD=${HUB_ADMIN_PASSWORD:-}
      - APP_PUBLIC_URL=${APP_PUBLIC_URL:-https://anexo76-dev.aduanasoft.com}
      - SMTP_HOST=${SMTP_HOST:-smtp.gmail.com}
      - SMTP_PORT=${SMTP_PORT:-587}
      - SMTP_USER=${SMTP_USER:-}
      - SMTP_PASSWORD=${SMTP_PASSWORD:-}
      - SMTP_FROM_NAME=${SMTP_FROM_NAME:-Sistema Anexo76}
      - SMTP_USE_TLS=${SMTP_USE_TLS:-true}
      - CSV_IMPORT_STORAGE=${CSV_IMPORT_STORAGE:-minio}
      - S3_ENDPOINT_URL=${S3_ENDPOINT_URL:-http://minio:9000}
      - S3_ACCESS_KEY=${S3_ACCESS_KEY:-${MINIO_ROOT_USER:-minioadmin}}
      - S3_SECRET_KEY=${S3_SECRET_KEY:-${MINIO_ROOT_PASSWORD:-minioadmin}}
      - S3_BUCKET=${S3_BUCKET:-anexo76}
      - S3_REGION=${S3_REGION:-us-east-1}
      - S3_USE_SSL=${S3_USE_SSL:-false}
      - S3_FILE_STORAGE=${S3_FILE_STORAGE:-true}
      - S3_PRESIGNED_EXPIRES_SECONDS=${S3_PRESIGNED_EXPIRES_SECONDS:-3600}
    ports:
      - "3467:8000"
    depends_on:
      postgres-a76:
        condition: service_healthy
      minio:
        condition: service_healthy
    volumes:
      - backend_uploads:/app/uploads
      - backend_layouts:/app/layouts
    networks:
      - backend-net
      - frontend-net
    restart: unless-stopped
    command: [ "gunicorn", "main:app", "-k", "uvicorn.workers.UvicornWorker", "-w", "${WEB_CONCURRENCY:-1}", "-b", "0.0.0.0:8000", "--log-level", "info", "--forwarded-allow-ips", "*" ]
    healthcheck:
      test: [ "CMD-SHELL", "curl -f http://localhost:8000/api/health || exit 1" ]
      interval: 15s
      timeout: 5s
      retries: 5
      start_period: 60s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M

  # celery
  celery_worker:
    image: dev.aduanasoft.com/anexo76/backend:latest
    container_name: worker
    command: celery -A core.celery_app worker --loglevel=info
    environment:
      - VALKEY_URL=${VALKEY_URL:-redis://valkey:6379/0}
      - CENTRAL_SERVER_URL=${CENTRAL_SERVER_URL:-""}
      - SYNC_SECRET_TOKEN=${SYNC_SECRET_TOKEN:-change-this-sync-token-in-production}
      - SPOKE_URLS=${SPOKE_URLS:-""}
      - CORE_DB_HOST=${CORE_DB_HOST:-postgres-a76}
      - CORE_DB_PORT=${CORE_DB_PORT:-5432}
      - CORE_DB_NAME=${CORE_DB_NAME:-anexo76_core}
      - CORE_DB_USER=${CORE_DB_USER:-postgres}
      - CORE_DB_PASSWORD=${POSTGRES_APP_PASSWORD:-postgres}
      - SITAR_API_URL=${SITAR_API_URL}
      - SITAR_API_USER=${SITAR_API_USER}
      - SITAR_API_PASSWORD=${SITAR_API_PASSWORD}
      - COVE_FIEL_HASH_KEY=${COVE_FIEL_HASH_KEY}
      - COVE_FIEL_HASH_IV=${COVE_FIEL_HASH_IV}
      - COVE_API_URL=${COVE_API_URL:-https://api.vu.aduanasoft.com}
      - COVE_API_VERIFY_SSL=${COVE_API_VERIFY_SSL:-False}

      - CSV_IMPORT_STORAGE=${CSV_IMPORT_STORAGE:-minio}
      - S3_ENDPOINT_URL=${S3_ENDPOINT_URL:-http://minio:9000}
      - S3_ACCESS_KEY=${S3_ACCESS_KEY:-${MINIO_ROOT_USER:-minioadmin}}
      - S3_SECRET_KEY=${S3_SECRET_KEY:-${MINIO_ROOT_PASSWORD:-minioadmin}}
      - S3_BUCKET=${S3_BUCKET:-anexo76}
      - S3_REGION=${S3_REGION:-us-east-1}
      - S3_USE_SSL=${S3_USE_SSL:-false}
      - S3_FILE_STORAGE=${S3_FILE_STORAGE:-true}
    depends_on:
      - backend
      - valkey
    volumes:
      - backend_layouts:/app/layouts
    networks:
      - backend-net

  celery_beat:
    image: dev.aduanasoft.com/anexo76/backend:latest
    container_name: celery_beat
    command: celery -A core.celery_app beat --loglevel=info
    environment:
      - VALKEY_URL=${VALKEY_URL:-redis://valkey:6379/0}
      - CENTRAL_SERVER_URL=${CENTRAL_SERVER_URL:-""}
      - SYNC_SECRET_TOKEN=${SYNC_SECRET_TOKEN:-change-this-sync-token-in-production}
      - SPOKE_URLS=${SPOKE_URLS:-""}
      - CORE_DB_HOST=${CORE_DB_HOST:-postgres-a76}
      - CORE_DB_PORT=${CORE_DB_PORT:-5432}
      - CORE_DB_NAME=${CORE_DB_NAME:-anexo76_core}
      - CORE_DB_USER=${CORE_DB_USER:-postgres}
      - CORE_DB_PASSWORD=${POSTGRES_APP_PASSWORD:-postgres}
      - SITAR_API_URL=${SITAR_API_URL}
      - SITAR_API_USER=${SITAR_API_USER}
      - SITAR_API_PASSWORD=${SITAR_API_PASSWORD}
      - COVE_FIEL_HASH_KEY=${COVE_FIEL_HASH_KEY}
      - COVE_FIEL_HASH_IV=${COVE_FIEL_HASH_IV}
      - COVE_API_URL=${COVE_API_URL:-https://api.vu.aduanasoft.com}
      - COVE_API_VERIFY_SSL=${COVE_API_VERIFY_SSL:-False}

      - CSV_IMPORT_STORAGE=${CSV_IMPORT_STORAGE:-minio}
      - S3_ENDPOINT_URL=${S3_ENDPOINT_URL:-http://minio:9000}
      - S3_ACCESS_KEY=${S3_ACCESS_KEY:-${MINIO_ROOT_USER:-minioadmin}}
      - S3_SECRET_KEY=${S3_SECRET_KEY:-${MINIO_ROOT_PASSWORD:-minioadmin}}
      - S3_BUCKET=${S3_BUCKET:-anexo76}
      - S3_REGION=${S3_REGION:-us-east-1}
      - S3_USE_SSL=${S3_USE_SSL:-false}
      - S3_FILE_STORAGE=${S3_FILE_STORAGE:-true}
    depends_on:
      - backend
      - valkey
    volumes:
      - backend_layouts:/app/layouts
    networks:
      - backend-net
    restart: unless-stopped

  valkey:
    image: valkey/valkey:7.2
    container_name: valkey
    restart: always
    ports:
      - "6579:6379"
    networks:
      - backend-net

  minio:
    image: minio/minio:RELEASE.2025-09-07T16-13-09Z
    container_name: anexo76-minio
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
    ports:
      - "${MINIO_API_PORT:-9100}:9000"
      - "${MINIO_CONSOLE_PORT:-9101}:9001"
    volumes:
      - minio_data:/data
    networks:
      - backend-net
    restart: unless-stopped
    healthcheck:
      test: [ "CMD-SHELL", "curl -f http://127.0.0.1:9000/minio/health/live || exit 1" ]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 15s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # Frontend - SvelteKit
  frontend:
    image: dev.aduanasoft.com/anexo76/frontend:latest
    container_name: anexo76-frontend
    environment:
      - NODE_ENV=${NODE_ENV:-production}
      - VITE_API_URL=${VITE_API_URL:-https://anexo76-dev.aduanasoft.com/api}
      - INTERNAL_API_URL=${INTERNAL_API_URL:-http://backend:8000/api/}
      - INTERNAL_HUB_URL=https://workspace.aduanasoft.com
      - HUB_URL=https://workspace.aduanasoft.com
      # VITE_HUB_URL: URL pública del Hub para el browser (bakeada en build, pero también se lee
      # en runtime por $env/dynamic/private en workspace-auth.ts). El root .env puede tener
      # localhost; isDevOnlyUrl() lo descarta y cae a HUB_URL (correcto arriba).
      - VITE_HUB_URL=https://workspace.aduanasoft.com
      # Keycloak — fuente única de autenticación: Workspace (workspace.aduanasoft.com)
      # VITE_KEYCLOAK_URL: URL pública que el browser usa para el flujo OIDC.
      #   Debe ser el mismo Keycloak donde el usuario tiene su sesión de Workspace.
      - VITE_KEYCLOAK_URL=${VITE_KEYCLOAK_URL:-https://workspace.aduanasoft.com/kcauth}
      - VITE_KEYCLOAK_REALM=${VITE_KEYCLOAK_REALM:-master}
      - VITE_KEYCLOAK_CLIENT_ID=${VITE_KEYCLOAK_CLIENT_ID:-anexo76-frontend}
      # KEYCLOAK_URL: URL que usa SvelteKit server-side para intercambiar código por tokens.
      - KEYCLOAK_URL=${KEYCLOAK_URL:-https://workspace.aduanasoft.com/kcauth}
      - KEYCLOAK_REALM=${KEYCLOAK_REALM:-master}
      - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID:-anexo76-frontend}
      - KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET:-}
      # SvelteKit ORIGIN — determina url.origin en load functions y el flag secure de cookies.
      # ⚠️  Docker Compose carga el .env raíz automáticamente. Si ese .env tiene
      #     ORIGIN=http://localhost:5173 (valor dev), sobreescribe el default de abajo.
      #     SITE_URL es el fallback que usa el código cuando url.origin es localhost.
      - ORIGIN=${ORIGIN:-https://anexo76-dev.aduanasoft.com}
      # SITE_URL: hardcoded — no depende del .env raíz.
      # resolveSystemBaseUrl() lo usa cuando ORIGIN tiene localhost (root .env de dev en prod).
      - SITE_URL=https://anexo76-dev.aduanasoft.com
    ports:
      - "5111:5173"
    depends_on:
      backend:
        condition: service_healthy
    networks:
      - frontend-net
      - backend-net
    restart: unless-stopped
    command: [ "pnpm", "start" ]
    healthcheck:
      test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5173/ || exit 1" ]
      interval: 15s
      timeout: 5s
      retries: 5
      start_period: 45s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    deploy:
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 512M

volumes:
  postgres_app_data:
    driver: local
  frontend_node_modules:
    driver: local
  backend_cache:
    driver: local
  backend_uploads:
    driver: local
  backend_layouts:
    driver: local
  minio_data:
    driver: local

networks:
  backend-net:
    driver: bridge
  frontend-net:
    driver: bridge
