# Isolated EventSnap test stack. Mirrors production layout (Caddy → frontend +
# backend) but on its own ports, its own volumes, with rate-limits disabled and
# `EVENTSNAP_TEST_MODE=1` so the `/admin/__truncate` reset endpoint is live.
#
# Bring it up once before running the suite:
#     npm run stack:up
# Tear it down (and wipe all volumes) after:
#     npm run stack:down
#
# Port 3101 is the only externally exposed port: Caddy fronts everything.

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: eventsnap_test
      POSTGRES_PASSWORD: eventsnap_test
      POSTGRES_DB: eventsnap_test
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U eventsnap_test -d eventsnap_test']
      interval: 3s
      timeout: 3s
      retries: 30
    ports:
      - '55432:5432' # exposed so the e2e harness can connect via pg for fixture setup

  app:
    build:
      context: ../backend
      dockerfile: Dockerfile
    depends_on:
      db:
        condition: service_healthy
    environment:
      DATABASE_URL: postgres://eventsnap_test:eventsnap_test@db:5432/eventsnap_test
      JWT_SECRET: 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff
      # bcrypt hash for the literal string "admin-test-pw" (cost 4 — fast for tests).
      # Generated once and committed. Verified with `bcrypt.compareSync`.
      # The $ characters are doubled to escape compose interpolation.
      ADMIN_PASSWORD_HASH: $$2b$$04$$XKJJkNX6BOi6y3S42DA5JOWwk4oxc8DHPL6.MrPfJI2vpnccZjP32
      EVENT_SLUG: e2e-test-event
      EVENT_NAME: E2E Test Event
      APP_PORT: '3000'
      MEDIA_PATH: /media
      # Exports MUST live outside MEDIA_PATH — see the note on the volume below and
      # config.rs::validate. Omitting this left exports on the container's writable
      # layer at the /exports default, so the test stack diverged from the prod layout
      # it claims to mirror, and export-leak/export-video wrote real archives into
      # ephemeral storage.
      EXPORT_PATH: /exports
      SESSION_EXPIRY_DAYS: '30'
      EVENTSNAP_TEST_MODE: '1' # ENABLES /admin/__truncate — never set in prod
      RUST_LOG: eventsnap_backend=info,tower_http=warn
    volumes:
      - media_data:/media
      # Separate volume, exactly as in production: a keepsake archive contains every
      # photo in the event, so it is kept off the media tree.
      - exports_data:/exports
    # Mirror production's cap (docker-compose.yml). The test stack having NO memory limit is
    # why an unbounded image decode was invisible here: a 99 MP upload that would OOM-kill the
    # 1 GiB production container simply succeeded in CI. A test environment more generous than
    # production cannot catch a resource bug — the same shape as WebKit being absent from CI
    # and /health existing only in Caddyfile.test.
    deploy:
      resources:
        limits:
          memory: 1G
    expose:
      - '3000'

  frontend:
    build:
      context: ../frontend
      dockerfile: Dockerfile
    depends_on:
      - app
    environment:
      PORT: '3001'
      HOST: '0.0.0.0'
      ORIGIN: 'http://localhost:3101'
    expose:
      - '3001'

  caddy:
    image: caddy:2-alpine
    depends_on:
      - app
      - frontend
    volumes:
      - ./Caddyfile.test:/etc/caddy/Caddyfile:ro
    ports:
      - '3101:3101'

volumes:
  media_data:
  exports_data:
