# Docker Compose for Local Development
# Next.js + Neon Stack
#
# One compose project per worktree. The harness sets
# COMPOSE_PROJECT_NAME=morph-{feature}, which prefixes every container, network
# and volume — so two features running side by side never share a resource.
# Explicit `container_name:` entries are NOT prefixed, which is why this file
# declares none: a named container is a collision waiting for the second
# worktree.
#
# Host ports come from the feature's port block (see env-allocator.js):
#   PORT          block + 0   (web)
#   API_PORT      block + 1   (api)
#   POSTGRES_PORT block + 2   (postgres)
#   REDIS_PORT    block + 3   (redis)
# Every published port reads one of those variables with a single-stack
# default. A fixed host port here would defeat the block no matter what the
# harness injects — `morph-spec e2e up` and the verify e2e node refuse such a
# compose inside a worktree (`compose-not-isolable`).
#
# Named volumes are reclaimed by `morph-spec finish` when the feature closes
# (`--keep-volumes` opts out). Healthchecks are what make `up --wait`
# meaningful: without them Compose reports "started" the moment the process
# launches, and the e2e node would navigate an application not serving yet.
#
# The harness also exports PLAYWRIGHT_BASE_URL for the allocated port, so
# `playwright.config.ts` must read it instead of hardcoding a URL:
#   baseURL: process.env.PLAYWRIGHT_BASE_URL ?? `http://localhost:${process.env.PORT ?? 3000}`

services:
  # Next.js Application
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "${PORT:-3000}:3000"
    environment:
      - NODE_ENV=development
      - DATABASE_URL=${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/${POSTGRES_DB:-app}}
    volumes:
      - .:/app
      - /app/node_modules
      - /app/.next
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "node -e \"fetch('http://localhost:3000/').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 20s
    networks:
      - app-network

  # PostgreSQL Database (Local development)
  postgres:
    image: postgres:15-alpine
    restart: unless-stopped
    ports:
      - "${POSTGRES_PORT:-5432}:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: ${POSTGRES_DB:-app}
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./migrations:/docker-entrypoint-initdb.d
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d ${POSTGRES_DB:-app}"]
      interval: 5s
      timeout: 5s
      retries: 10
    networks:
      - app-network

volumes:
  postgres-data:
    driver: local

networks:
  app-network:
    driver: bridge
