name: PR Checks

# Required status checks — configure these in branch protection rules.
# PRs to preprod : lint + type-check + unit tests + integration tests
# PRs to main    : lint + type-check + unit tests only

on:
  pull_request:
    branches: [preprod, main]

concurrency:
  group: pr-${{ github.event.pull_request.number }}
  cancel-in-progress: true

env:
  NODE_VERSION: '20'

jobs:
  backend-quality:
    name: Backend — Lint
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: apps/backend
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: apps/backend/package-lock.json
      - run: npm install --legacy-peer-deps
      - run: npm run lint

  frontend-quality:
    name: Frontend — Lint & Type-check
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: apps/frontend
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: apps/frontend/package-lock.json
      - run: npm ci --legacy-peer-deps
      - run: npm run lint
      - run: npm run type-check

  backend-tests:
    name: Backend — Unit Tests
    runs-on: ubuntu-latest
    needs: backend-quality
    defaults:
      run:
        working-directory: apps/backend
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: apps/backend/package-lock.json
      - run: npm install --legacy-peer-deps
      - run: npm test -- --passWithNoTests

  frontend-tests:
    name: Frontend — Unit Tests
    runs-on: ubuntu-latest
    needs: frontend-quality
    defaults:
      run:
        working-directory: apps/frontend
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: apps/frontend/package-lock.json
      - run: npm ci --legacy-peer-deps
      - run: npm test -- --passWithNoTests

  # Integration tests — PRs to preprod only
  # Code going to main was already integration-tested when it passed through preprod
  integration-tests:
    name: Backend — Integration Tests
    runs-on: ubuntu-latest
    needs: backend-tests
    if: github.base_ref == 'preprod'
    defaults:
      run:
        working-directory: apps/backend

    services:
      postgres:
        image: postgres:15-alpine
        env:
          POSTGRES_USER: xpeditis_test
          POSTGRES_PASSWORD: xpeditis_test_password
          POSTGRES_DB: xpeditis_test
        options: >-
          --health-cmd pg_isready
          --health-interval 5s
          --health-timeout 5s
          --health-retries 10
        ports:
          - 5432:5432
      redis:
        image: redis:7-alpine
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 5s
          --health-timeout 5s
          --health-retries 10
        ports:
          - 6379:6379

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: apps/backend/package-lock.json
      - run: npm install --legacy-peer-deps
      - name: Run integration tests
        env:
          NODE_ENV: test
          DATABASE_HOST: localhost
          DATABASE_PORT: 5432
          DATABASE_USER: xpeditis_test
          DATABASE_PASSWORD: xpeditis_test_password
          DATABASE_NAME: xpeditis_test
          DATABASE_SYNCHRONIZE: 'false'
          REDIS_HOST: localhost
          REDIS_PORT: 6379
          REDIS_PASSWORD: ''
          JWT_SECRET: test-secret-key-ci
          SMTP_HOST: localhost
          SMTP_PORT: 1025
          SMTP_FROM: test@xpeditis.com
        run: npm run test:integration -- --passWithNoTests
