# ZeTa-AI Crawler — includes Playwright + Chromium
# Playwright needs a real Linux environment with system deps.
# This service CANNOT run on Vercel serverless — use Railway/Render.
# IMPORTANT: ECS Fargate task definition must set sharedMemorySize: 2048 (MB) for Chromium stability
FROM mcr.microsoft.com/playwright:v1.55.0-jammy AS runner
WORKDIR /app
ENV NODE_ENV=production
# Install browsers to a fixed path — base image ships browsers here and
# we override after npm ci to match the exact installed playwright revision.
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright

# Install Node.js 20 (Playwright base image ships with 18)
RUN apt-get update && apt-get install -y curl build-essential python3 && \
    curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
    apt-get install -y nodejs && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

# Workspace manifests (layer cache)
# Copy all workspace package.json files so npm ci can resolve the full lockfile.
# Packages not used by the crawler (api, web, etc.) are stubs; their source is not copied later.
COPY package.json package-lock.json ./
COPY packages/agent-cli/package.json    packages/agent-cli/
COPY packages/agents/package.json       packages/agents/
COPY packages/api/package.json          packages/api/
COPY packages/app-brain/package.json    packages/app-brain/
COPY packages/chrome-extension/package.json packages/chrome-extension/
COPY packages/connectors/package.json   packages/connectors/
COPY packages/core/package.json         packages/core/
COPY packages/crawler/package.json      packages/crawler/
COPY packages/database/package.json     packages/database/
COPY packages/github-action/package.json packages/github-action/
COPY packages/reranker/package.json     packages/reranker/
COPY packages/sdk/package.json          packages/sdk/
COPY packages/session-receiver/package.json packages/session-receiver/
COPY packages/vscode-extension/package.json packages/vscode-extension/
COPY packages/web/package.json          packages/web/
RUN npm ci --include=dev

# Patch Stagehand's act() schema to add `additionalProperties: false` on the
# inner anyOf[0] object. OpenAI strict mode (v1/responses) requires it on every
# nested object; Stagehand ≤3.6 omits it, causing a 400 "invalid_json_schema".
RUN node -e "const fs=require('fs');['packages/crawler/node_modules/@browserbasehq/stagehand/dist/cjs/lib/inference.js','packages/crawler/node_modules/@browserbasehq/stagehand/dist/esm/lib/inference.js'].forEach(f=>{if(!fs.existsSync(f)){console.log('skip',f);return;}let c=fs.readFileSync(f,'utf8');if(c.includes('.strict()')){console.log('already patched',f);return;}c=c.replace(/\\.nullable\\(\\)\\n(\\s+)\\.describe\\(\"The element to act on/g,'\.strict()\n\$1.nullable()\n\$1.describe(\"The element to act on');fs.writeFileSync(f,c);console.log('patched',f);});"

# Re-install chromium after npm ci so the browser revision matches the
# exact playwright version resolved by the lockfile (not the base image's
# bundled version, which may differ if the lockfile was updated).
RUN npx playwright install chromium

# Source
COPY tsconfig.base.json ./
COPY packages/database        packages/database
COPY packages/reranker        packages/reranker
COPY packages/core            packages/core
COPY packages/connectors      packages/connectors
COPY packages/app-brain       packages/app-brain
COPY packages/agents          packages/agents
COPY packages/crawler         packages/crawler

# Build order: database → reranker → core → connectors → app-brain → agents → crawler
RUN npx prisma generate --schema packages/database/prisma/schema.prisma && \
    npm run -w @detiq/database build && \
    npm run -w @detiq/reranker build && \
    npm run -w @detiq/core build && \
    npm run -w @detiq/connectors build && \
    npm run -w @detiq/app-brain build && \
    npm run -w @detiq/agents build && \
    npm run -w @detiq/crawler build

# Screenshot cache dir
RUN mkdir -p /app/.screenshots-cache

RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
RUN chown -R appuser:appgroup /app
USER appuser

EXPOSE 4001
# index.js is a side-effect-free library barrel (also imported by @detiq/api) — it holds
# no listener/timer, so running it directly starts the process, finishes its imports,
# and exits immediately with nothing ever consuming the job queue. worker.js is the
# actual long-running entrypoint: it starts the durable job-poll loop (and the SQS
# consumer when JOB_QUEUE_BACKEND=sqs) and keeps the process alive.
CMD ["node", "packages/crawler/dist/worker.js"]
