# =========================================================
# BreakPilot Core — Shared Infrastructure (Coolify)
# =========================================================
# Deployed via Coolify. SSL termination handled by Traefik.
# External services (managed separately in Coolify):
#   - PostgreSQL (PostGIS), Qdrant, S3-compatible storage
# Network: breakpilot-network (shared across all 3 repos)
# =========================================================

networks:
  breakpilot-network:
    name: breakpilot-network
    driver: bridge

volumes:
  valkey_data:
  embedding_models:
  paddleocr_models:

services:

  # =========================================================
  # CACHE
  # =========================================================
  valkey:
    image: valkey/valkey:8-alpine
    container_name: bp-core-valkey
    volumes:
      - valkey_data:/data
    command: valkey-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    healthcheck:
      test: ["CMD", "valkey-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
    restart: unless-stopped
    networks:
      - breakpilot-network

  # =========================================================
  # SHARED SERVICES
  # =========================================================
  consent-service:
    build:
      context: ./consent-service
      dockerfile: Dockerfile
    container_name: bp-core-consent-service
    expose:
      - "8081"
    environment:
      DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT:-5432}/${POSTGRES_DB}
      JWT_SECRET: ${JWT_SECRET}
      JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET}
      PORT: 8081
      ENVIRONMENT: production
      ALLOWED_ORIGINS: "*"
      VALKEY_URL: redis://valkey:6379/0
      SESSION_TTL_HOURS: ${SESSION_TTL_HOURS:-24}
      SMTP_HOST: ${SMTP_HOST}
      SMTP_PORT: ${SMTP_PORT:-587}
      SMTP_USERNAME: ${SMTP_USERNAME}
      SMTP_PASSWORD: ${SMTP_PASSWORD}
      SMTP_FROM_NAME: ${SMTP_FROM_NAME:-BreakPilot}
      SMTP_FROM_ADDR: ${SMTP_FROM_ADDR:-noreply@breakpilot.ai}
      FRONTEND_URL: ${FRONTEND_URL:-https://www.breakpilot.ai}
    depends_on:
      valkey:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8081/health"]
      interval: 30s
      timeout: 10s
      start_period: 15s
      retries: 3
    restart: unless-stopped
    networks:
      - breakpilot-network

  # =========================================================
  # RAG & EMBEDDING SERVICES
  # =========================================================
  rag-service:
    build:
      context: ./rag-service
      dockerfile: Dockerfile
    container_name: bp-core-rag-service
    expose:
      - "8097"
    environment:
      PORT: 8097
      QDRANT_URL: ${QDRANT_URL}
      QDRANT_API_KEY: ${QDRANT_API_KEY:-}
      MINIO_ENDPOINT: ${S3_ENDPOINT}
      MINIO_ACCESS_KEY: ${S3_ACCESS_KEY}
      MINIO_SECRET_KEY: ${S3_SECRET_KEY}
      MINIO_BUCKET: ${S3_BUCKET:-breakpilot-rag}
      MINIO_SECURE: ${S3_SECURE:-true}
      EMBEDDING_SERVICE_URL: http://embedding-service:8087
      OLLAMA_URL: ${OLLAMA_URL:-}
      OLLAMA_EMBED_MODEL: ${OLLAMA_EMBED_MODEL:-bge-m3}
      JWT_SECRET: ${JWT_SECRET}
      ENVIRONMENT: production
    depends_on:
      embedding-service:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:8097/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s
    restart: unless-stopped
    networks:
      - breakpilot-network

  embedding-service:
    build:
      context: ./embedding-service
      dockerfile: Dockerfile
    container_name: bp-core-embedding-service
    volumes:
      - embedding_models:/root/.cache/huggingface
    environment:
      EMBEDDING_BACKEND: ${EMBEDDING_BACKEND:-local}
      LOCAL_EMBEDDING_MODEL: ${LOCAL_EMBEDDING_MODEL:-BAAI/bge-m3}
      LOCAL_RERANKER_MODEL: ${LOCAL_RERANKER_MODEL:-cross-encoder/ms-marco-MiniLM-L-6-v2}
      PDF_EXTRACTION_BACKEND: ${PDF_EXTRACTION_BACKEND:-pymupdf}
      OPENAI_API_KEY: ${OPENAI_API_KEY:-}
      COHERE_API_KEY: ${COHERE_API_KEY:-}
      LOG_LEVEL: ${LOG_LEVEL:-INFO}
    deploy:
      resources:
        limits:
          memory: 8G
    healthcheck:
      test: ["CMD", "python", "-c", "import httpx; r=httpx.get('http://127.0.0.1:8087/health'); r.raise_for_status()"]
      interval: 30s
      timeout: 10s
      start_period: 120s
      retries: 3
    restart: unless-stopped
    networks:
      - breakpilot-network

  # =========================================================
  # OCR SERVICE (PaddleOCR PP-OCRv5)
  # =========================================================
  paddleocr-service:
    build:
      context: ./paddleocr-service
      dockerfile: Dockerfile
    container_name: bp-core-paddleocr
    expose:
      - "8095"
    environment:
      PADDLEOCR_API_KEY: ${PADDLEOCR_API_KEY:-}
      FLAGS_use_mkldnn: "0"
    volumes:
      - paddleocr_models:/root/.paddleocr
    labels:
      - "traefik.http.services.paddleocr.loadbalancer.server.port=8095"
    deploy:
      resources:
        limits:
          memory: 6G
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:8095/health"]
      interval: 30s
      timeout: 10s
      start_period: 300s
      retries: 5
    restart: unless-stopped
    networks:
      - breakpilot-network

  # =========================================================
  # PITCH DECK
  # =========================================================
  pitch-deck:
    build:
      context: ./pitch-deck
      dockerfile: Dockerfile
    container_name: bp-core-pitch-deck
    expose:
      - "3000"
    environment:
      DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT:-5432}/${POSTGRES_DB}
      PITCH_JWT_SECRET: ${PITCH_JWT_SECRET}
      PITCH_ADMIN_SECRET: ${PITCH_ADMIN_SECRET}
      PITCH_BASE_URL: ${PITCH_BASE_URL:-https://pitch.breakpilot.ai}
      MAGIC_LINK_TTL_HOURS: ${MAGIC_LINK_TTL_HOURS:-72}
      # Optional: bootstrap first admin via `npm run admin:create` inside the container.
      PITCH_ADMIN_BOOTSTRAP_EMAIL: ${PITCH_ADMIN_BOOTSTRAP_EMAIL:-}
      PITCH_ADMIN_BOOTSTRAP_NAME: ${PITCH_ADMIN_BOOTSTRAP_NAME:-}
      PITCH_ADMIN_BOOTSTRAP_PASSWORD: ${PITCH_ADMIN_BOOTSTRAP_PASSWORD:-}
      SMTP_HOST: ${SMTP_HOST}
      SMTP_PORT: ${SMTP_PORT:-587}
      SMTP_USERNAME: ${SMTP_USERNAME}
      SMTP_PASSWORD: ${SMTP_PASSWORD}
      SMTP_FROM_NAME: ${SMTP_FROM_NAME:-BreakPilot}
      SMTP_FROM_ADDR: ${SMTP_FROM_ADDR:-noreply@breakpilot.ai}
      NODE_ENV: production
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000/api/health"]
      interval: 30s
      timeout: 10s
      start_period: 15s
      retries: 3
    restart: unless-stopped
    networks:
      - breakpilot-network

  # =========================================================
  # HEALTH AGGREGATOR
  # =========================================================
  health-aggregator:
    build:
      context: ./scripts
      dockerfile: Dockerfile.health
    container_name: bp-core-health
    expose:
      - "8099"
    environment:
      PORT: 8099
      CHECK_SERVICES: "valkey:6379,consent-service:8081,rag-service:8097,embedding-service:8087,paddleocr-service:8095,pitch-deck:3000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:8099/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped
    networks:
      - breakpilot-network

