version: '3.8'

services:
  # PostgreSQL Database with PostGIS
  db:
    image: postgis/postgis:16-3.4-alpine
    container_name: schoolcompare_db
    environment:
      POSTGRES_USER: schoolcompare
      POSTGRES_PASSWORD: schoolcompare
      POSTGRES_DB: schoolcompare
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    networks:
      - schoolcompare-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U schoolcompare"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s

  # FastAPI Backend
  backend:
    image: privaterepo.sitaru.org/tudor/school_compare-backend:latest
    container_name: schoolcompare_backend
    ports:
      - "8000:80"
    environment:
      DATABASE_URL: postgresql://schoolcompare:schoolcompare@db:5432/schoolcompare
      PYTHONUNBUFFERED: 1
      ADMIN_API_KEY: ${ADMIN_API_KEY:-changeme}
      TYPESENSE_URL: http://typesense:8108
      TYPESENSE_API_KEY: ${TYPESENSE_API_KEY:-changeme}
    volumes:
      - ./data:/app/data:ro
    depends_on:
      db:
        condition: service_healthy
    networks:
      - schoolcompare-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/api/data-info"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s

  # Next.js Frontend
  nextjs:
    image: privaterepo.sitaru.org/tudor/school_compare-frontend:latest
    container_name: schoolcompare_nextjs
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production
      NEXT_PUBLIC_API_URL: http://localhost:8000/api
      FASTAPI_URL: http://backend:80/api
      TYPESENSE_URL: http://typesense:8108
      TYPESENSE_API_KEY: ${TYPESENSE_SEARCH_KEY:-changeme}
    depends_on:
      backend:
        condition: service_healthy
    networks:
      - schoolcompare-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # Typesense — search engine
  typesense:
    image: typesense/typesense:30.1
    container_name: schoolcompare_typesense
    ports:
      - "8108:8108"
    environment:
      TYPESENSE_API_KEY: ${TYPESENSE_API_KEY:-changeme}
      TYPESENSE_DATA_DIR: /data
    volumes:
      - typesense_data:/data
    networks:
      - schoolcompare-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "cat < /dev/tcp/localhost/8108"]
      interval: 15s
      timeout: 5s
      retries: 5
      start_period: 10s

  # Apache Airflow — API server + UI (http://localhost:8080)
  airflow-api-server:
    image: privaterepo.sitaru.org/tudor/school_compare-pipeline:latest
    container_name: schoolcompare_airflow_api
    command: airflow api-server --port 8080
    ports:
      - "8080:8080"
    environment: &airflow-env
      AIRFLOW__CORE__EXECUTOR: LocalExecutor
      AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://schoolcompare:schoolcompare@db:5432/schoolcompare
      AIRFLOW__CORE__DAGS_FOLDER: /opt/pipeline/dags
      AIRFLOW__CORE__LOAD_EXAMPLES: "false"
      AIRFLOW__CORE__EXECUTION_API_SERVER_URL: http://airflow-api-server:8080/execution/
      AIRFLOW__API_AUTH__JWT_SECRET: "school-compare-airflow-jwt-secret-key-long-enough-for-sha512"
      AIRFLOW__API_AUTH__JWT_ISSUER: airflow
      AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_USERS: "admin:admin"
      PG_HOST: db
      PG_PORT: "5432"
      PG_USER: schoolcompare
      PG_PASSWORD: schoolcompare
      PG_DATABASE: schoolcompare
      TYPESENSE_URL: http://typesense:8108
      TYPESENSE_API_KEY: ${TYPESENSE_API_KEY:-changeme}
    volumes:

    depends_on:
      db:
        condition: service_healthy
    networks:
      - schoolcompare-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/v2/monitor/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s

  airflow-scheduler:
    image: privaterepo.sitaru.org/tudor/school_compare-pipeline:latest
    container_name: schoolcompare_airflow_scheduler
    command: airflow scheduler
    environment: *airflow-env
    volumes:

    depends_on:
      db:
        condition: service_healthy
    networks:
      - schoolcompare-network
    restart: unless-stopped

  # One-shot: initialise Airflow metadata DB
  airflow-init:
    image: privaterepo.sitaru.org/tudor/school_compare-pipeline:latest
    container_name: schoolcompare_airflow_init
    command: bash -c "airflow db migrate && airflow dags delete school_data_daily -y 2>/dev/null; airflow dags delete school_data_monthly_ofsted -y 2>/dev/null; airflow dags delete school_data_annual_ees -y 2>/dev/null; airflow dags reserialize"
    environment: *airflow-env
    depends_on:
      db:
        condition: service_healthy
    networks:
      - schoolcompare-network
    restart: "no"

networks:
  schoolcompare-network:
    driver: bridge

volumes:
  postgres_data:
  typesense_data:
