name: haixun-app

x-backend-env: &backend-env
  HAIXUN_MONGO_URI: ${HAIXUN_MONGO_URI:?HAIXUN_MONGO_URI is required}
  HAIXUN_MONGO_DB: ${HAIXUN_MONGO_DB:-haixun}
  HAIXUN_REDIS_ADDR: ${HAIXUN_REDIS_ADDR:-redis:6379}
  HAIXUN_REDIS_PASSWORD: ${HAIXUN_REDIS_PASSWORD:?HAIXUN_REDIS_PASSWORD is required}
  HAIXUN_JWT_ACCESS_SECRET: ${HAIXUN_JWT_ACCESS_SECRET:?HAIXUN_JWT_ACCESS_SECRET is required}
  HAIXUN_JWT_REFRESH_SECRET: ${HAIXUN_JWT_REFRESH_SECRET:?HAIXUN_JWT_REFRESH_SECRET is required}
  HAIXUN_WORKER_SECRET: ${HAIXUN_WORKER_SECRET:?HAIXUN_WORKER_SECRET is required}
  HAIXUN_SECRETS_KEY: ${HAIXUN_SECRETS_KEY:?HAIXUN_SECRETS_KEY is required}
  THREADS_APP_ID: ${THREADS_APP_ID:-}
  THREADS_APP_SECRET: ${THREADS_APP_SECRET:-}
  THREADS_REDIRECT_URI: ${THREADS_REDIRECT_URI:-}
  THREADS_OAUTH_SUCCESS_REDIRECT: ${THREADS_OAUTH_SUCCESS_REDIRECT:-}
  HAIXUN_KEYWORD_SEARCH_URL: http://node-tool-keyword-search:9101
  HAIXUN_RESOLVE_MEDIA_URL: http://node-tool-resolve-media:9102

x-worker-env: &worker-env
  <<: *backend-env
  HAIXUN_JOB_WORKER_ENABLED: "true"
  HAIXUN_JOB_SCHEDULER_ENABLED: "${HAIXUN_JOB_SCHEDULER_ENABLED:-false}"
  HAIXUN_JOB_SCHEDULER_INTERVAL_SECONDS: "${HAIXUN_JOB_SCHEDULER_INTERVAL_SECONDS:-60}"
  HAIXUN_JOB_REAPER_ENABLED: "${HAIXUN_JOB_REAPER_ENABLED:-false}"
  HAIXUN_JOB_REAPER_INTERVAL_SECONDS: "${HAIXUN_JOB_REAPER_INTERVAL_SECONDS:-30}"
  HAIXUN_THREADS_TOKEN_REFRESH_ENABLED: "${HAIXUN_THREADS_TOKEN_REFRESH_ENABLED:-false}"
  HAIXUN_THREADS_TOKEN_REFRESH_INTERVAL_SECONDS: "${HAIXUN_THREADS_TOKEN_REFRESH_INTERVAL_SECONDS:-3600}"
  HAIXUN_THREADS_TOKEN_REFRESH_LEAD_DAYS: "${HAIXUN_THREADS_TOKEN_REFRESH_LEAD_DAYS:-7}"
  HAIXUN_THREADS_PUBLISH_QUEUE_ENABLED: "${HAIXUN_THREADS_PUBLISH_QUEUE_ENABLED:-false}"
  HAIXUN_THREADS_PUBLISH_QUEUE_INTERVAL_SECONDS: "${HAIXUN_THREADS_PUBLISH_QUEUE_INTERVAL_SECONDS:-60}"
  HAIXUN_THREADS_PUBLISH_QUEUE_BATCH_SIZE: "${HAIXUN_THREADS_PUBLISH_QUEUE_BATCH_SIZE:-20}"

x-worker-service: &worker-service
  image: ${BACKEND_IMAGE:-ghcr.io/kupi-cat/haixun-backend}:${BACKEND_TAG:-v0.0.1}
  restart: unless-stopped
  command: ["/app/worker", "-f", "/app/etc/gateway.worker.prod.yaml"]
  networks:
    - app
    - haixun-infra

services:
  web:
    build:
      context: ..
      dockerfile: backend/web/Dockerfile
    image: ${WEB_IMAGE:-ghcr.io/kupi-cat/haixun-web}:${WEB_TAG:-v0.0.1}
    restart: unless-stopped
    ports:
      - "${WEB_PORT:-80}:80"
    depends_on:
      - gateway
    networks:
      - app

  gateway:
    build:
      context: ..
      dockerfile: backend/Dockerfile
    image: ${BACKEND_IMAGE:-ghcr.io/kupi-cat/haixun-backend}:${BACKEND_TAG:-v0.0.1}
    restart: unless-stopped
    command: ["/app/gateway", "-f", "/app/etc/gateway.prod.yaml"]
    environment:
      <<: *backend-env
    expose:
      - "8890"
    networks:
      - app
      - haixun-infra

  worker-scheduler:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_ENABLED: "false"
      HAIXUN_JOB_WORKER_TYPE: disabled
      HAIXUN_JOB_WORKER_ID: scheduler
      HAIXUN_JOB_SCHEDULER_ENABLED: "true"

  worker-reaper:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_ENABLED: "false"
      HAIXUN_JOB_WORKER_TYPE: disabled
      HAIXUN_JOB_WORKER_ID: reaper
      HAIXUN_JOB_REAPER_ENABLED: "true"

  worker-token-sweeper:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_ENABLED: "false"
      HAIXUN_JOB_WORKER_TYPE: disabled
      HAIXUN_JOB_WORKER_ID: token-sweeper
      HAIXUN_THREADS_TOKEN_REFRESH_ENABLED: "true"

  worker-publish-queue-sweeper:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_ENABLED: "false"
      HAIXUN_JOB_WORKER_TYPE: disabled
      HAIXUN_JOB_WORKER_ID: publish-queue-sweeper
      HAIXUN_THREADS_PUBLISH_QUEUE_ENABLED: "true"

  worker-expand-graph:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-expand-graph
      HAIXUN_JOB_WORKER_ID: go-expand-graph

  worker-placement-scan:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-placement-scan
      HAIXUN_JOB_WORKER_ID: go-placement-scan

  worker-scan-viral:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-scan-viral
      HAIXUN_JOB_WORKER_ID: go-scan-viral

  worker-copy-mission-analyze:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-analyze-copy-mission
      HAIXUN_JOB_WORKER_ID: go-analyze-copy-mission

  worker-copy-mission-expand-graph:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-expand-copy-mission-graph
      HAIXUN_JOB_WORKER_ID: go-expand-copy-mission-graph

  worker-copy-matrix:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-generate-copy-matrix
      HAIXUN_JOB_WORKER_ID: go-generate-copy-matrix

  worker-copy-draft:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-generate-copy-draft
      HAIXUN_JOB_WORKER_ID: go-generate-copy-draft

  worker-outreach-draft:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-generate-outreach-draft
      HAIXUN_JOB_WORKER_ID: go-generate-outreach-draft

  worker-refresh-threads-token:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-refresh-threads-token
      HAIXUN_JOB_WORKER_ID: go-refresh-threads-token

  worker-publish-analytics:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-publish-analytics
      HAIXUN_JOB_WORKER_ID: go-publish-analytics

  worker-refill-publish-inventory:
    <<: *worker-service
    environment:
      <<: *worker-env
      HAIXUN_JOB_WORKER_TYPE: go-refill-publish-inventory
      HAIXUN_JOB_WORKER_ID: go-refill-publish-inventory

  node-worker-style-8d:
    build:
      context: ..
      dockerfile: backend/worker/Dockerfile
    image: ${NODE_WORKER_IMAGE:-ghcr.io/kupi-cat/haixun-node-worker}:${NODE_WORKER_TAG:-v0.0.1}
    restart: unless-stopped
    command: ["npm", "run", "style-8d"]
    environment:
      HAIXUN_BACKEND_URL: http://gateway:8890
      HAIXUN_WORKER_SECRET: ${HAIXUN_WORKER_SECRET:?HAIXUN_WORKER_SECRET is required}
      HAIXUN_NODE_WORKER_TYPE: node-style-8d
      HAIXUN_NODE_WORKER_ID: node-style-8d
      HAIXUN_WORKER_POLL_MS: ${HAIXUN_WORKER_POLL_MS:-3000}
      HAIXUN_8D_TARGET_SAMPLES: ${HAIXUN_8D_TARGET_SAMPLES:-4}
      PLAYWRIGHT_HEADLESS: "true"
    depends_on:
      - gateway
    networks:
      - app

  node-tool-keyword-search:
    image: ${NODE_WORKER_IMAGE:-ghcr.io/kupi-cat/haixun-node-worker}:${NODE_WORKER_TAG:-v0.0.1}
    restart: unless-stopped
    command: ["npm", "run", "keyword-search-server"]
    environment:
      PORT: "9101"
      PLAYWRIGHT_HEADLESS: "true"
    expose:
      - "9101"
    networks:
      - app

  node-tool-resolve-media:
    image: ${NODE_WORKER_IMAGE:-ghcr.io/kupi-cat/haixun-node-worker}:${NODE_WORKER_TAG:-v0.0.1}
    restart: unless-stopped
    command: ["npm", "run", "resolve-media-server"]
    environment:
      PORT: "9102"
      PLAYWRIGHT_HEADLESS: "true"
    expose:
      - "9102"
    networks:
      - app

  init:
    image: ${BACKEND_IMAGE:-ghcr.io/kupi-cat/haixun-backend}:${BACKEND_TAG:-v0.0.1}
    profiles: ["init"]
    command: ["/app/tool", "init", "-f", "/app/etc/gateway.prod.yaml"]
    environment:
      <<: *backend-env
      INIT_TENANT_ID: ${INIT_TENANT_ID:-default}
      INIT_ADMIN_EMAIL: ${INIT_ADMIN_EMAIL:?INIT_ADMIN_EMAIL is required}
      INIT_ADMIN_PASSWORD: ${INIT_ADMIN_PASSWORD:?INIT_ADMIN_PASSWORD is required}
      INIT_ADMIN_DISPLAY_NAME: ${INIT_ADMIN_DISPLAY_NAME:-Admin}
    networks:
      - haixun-infra

networks:
  app:
  haixun-infra:
    external: true
