# syntax=docker/dockerfile:1
#
# Three stages, so the TypeScript API client is generated from the REAL schema
# without a running server and without anything generated being committed
# (react.md). Node exists only in stage 2 — never at runtime.

# ---- Stage 1: emit the OpenAPI document from the real FastAPI app -----------
# app/db.py builds its engine lazily, so importing the app here needs no
# database and no DATABASE_URL.
FROM python:3.12-slim AS schema
WORKDIR /src
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY app ./app
COPY scripts ./scripts
COPY VERSION ./
RUN python scripts/gen_openapi.py /src/openapi.json

# ---- Stage 2: generate the TS client, then build the SPA -------------------
FROM node:22-slim AS frontend
WORKDIR /fe
COPY frontend/package.json frontend/package-lock.json* ./
RUN npm install --no-audit --no-fund
COPY frontend/ ./
# vite.config.ts reads ../VERSION to bake the version into the bundle.
COPY VERSION /VERSION
COPY --from=schema /src/openapi.json ./openapi.json
RUN npx openapi-typescript ./openapi.json -o ./src/api/schema.d.ts \
    && npm run build

# ---- Stage 3: the runtime — one Python process -----------------------------
FROM python:3.12-slim AS runtime
ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
WORKDIR /app

# Non-root. Nothing is bind-mounted from the host (Postgres uses a named
# volume), so there is no host uid to match — an unprivileged app user is
# simply the smaller blast radius.
RUN groupadd --system dailysplice \
    && useradd --system --gid dailysplice --no-create-home \
    --shell /usr/sbin/nologin dailysplice

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY app ./app
COPY alembic ./alembic
COPY alembic.ini ./
COPY scripts ./scripts
COPY VERSION ./
COPY entrypoint.sh ./
# vite.config.ts sets outDir "../static", which from WORKDIR /fe is /static.
COPY --from=frontend /static ./static

RUN chmod +x entrypoint.sh && chown -R dailysplice:dailysplice /app
USER dailysplice

EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=25s --retries=3 \
  CMD python -c "import urllib.request;urllib.request.urlopen('http://127.0.0.1:3000/api/health',timeout=3)"

ENTRYPOINT ["./entrypoint.sh"]
