social-reporting-tool/v2/Dockerfile.v2
DJP aeb1675554 Per-report dashboard SPA (V3 §10a) — 9 interactive views
Closes the last big spec gap: a single bundled React+Vite+Tailwind+Recharts
SPA that renders any report's dataset_v2.json under /api/reports/:id/dashboard/.

Spec deviation (intentional): rather than per-brief Vite builds (Netlify-
portable case), one bundle serves every report and fetches its dataset at
runtime. The portable HTML bundle (§10b) still ships per-report for offline
upload to claude.ai.

Dashboard template (v2/templates/dashboard_template):
- React 18 + Vite + TypeScript + Tailwind + Recharts. Same dark theme tokens
  as the operator app.
- 9 views: Overview, Categories, Trends explorer (filters + sort + drilldown),
  Lenses (4 sub-tabs for Hooks Library / Visual Vernacular / Audio Atlas /
  Sentiment Map), Charts (engagement-vs-reach scatter, category treemap,
  paid-vs-organic stacked bar), Compare (MoM new/returning/faded + category
  momentum), Paid creators appendix, Methodology.
- Tab-based navigation with hash-stable URLs so deep links work.

Server:
- GET /api/reports/:id/dataset returns the on-disk dataset_v2.json (auth-
  gated; 404 if Stage 10 hasn't built it yet).
- handleDashboardServe rewrite: serves (1) the explicit dashboard.html bundle,
  (2) per-report on-disk static (covers, dataset_v2.json), (3) the bundled
  SPA's assets/* and index.html with SPA fallback.

Build:
- v2/package.json workspaces re-includes templates/dashboard_template (was
  excluded after earlier cutover-prep).
- Dockerfile.v2 builds the dashboard template alongside operator-app and
  copies dist/ into the runtime image.

Local build: 838 modules transformed, 580 kB / 166 kB gzipped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 20:06:12 -04:00

54 lines
1.8 KiB
Text

# V2 image: builds operator-app SPA, copies server + pipeline + templates, runs Node.
FROM node:20-slim AS ui-build
WORKDIR /build
COPY v2/package.json v2/package-lock.json* ./
COPY v2/operator-app/package.json operator-app/package.json
COPY v2/templates/dashboard_template/package.json templates/dashboard_template/package.json
RUN npm install --include=dev --no-audit --no-fund
COPY v2/operator-app ./operator-app
COPY v2/templates ./templates
COPY v2/tsconfig.base.json ./tsconfig.base.json
# Vite reads VITE_* vars at build time (they're inlined into the bundle), not runtime.
# Pass these from compose `build.args` so the SPA knows the Azure tenant/client IDs.
ARG VITE_AZURE_TENANT_ID=""
ARG VITE_AZURE_CLIENT_ID=""
ARG VITE_BASE="/social-reports/"
ENV VITE_AZURE_TENANT_ID=$VITE_AZURE_TENANT_ID
ENV VITE_AZURE_CLIENT_ID=$VITE_AZURE_CLIENT_ID
ENV VITE_BASE=$VITE_BASE
RUN npm run build --workspace operator-app
# Per-report dashboard SPA (V3 §10a). Built once; same dist serves any report id.
RUN npm run build --workspace v2-dashboard-template
FROM node:20-slim AS runtime
# ffmpeg for Stage 4 frame extraction
RUN apt-get update \
&& apt-get install -y --no-install-recommends ffmpeg ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
ENV NODE_ENV=production
COPY v2/package.json v2/package-lock.json* ./
RUN npm install --omit=dev --no-audit --no-fund
COPY v2/tsconfig.base.json v2/tsconfig.json ./
COPY v2/server ./server
COPY v2/pipeline ./pipeline
COPY v2/templates ./templates
COPY v2/db ./db
# UI build artifacts
COPY --from=ui-build /build/operator-app/dist ./operator-app/dist
COPY --from=ui-build /build/templates/dashboard_template/dist ./templates/dashboard_template/dist
RUN mkdir -p briefs && useradd -u 1000 -m -s /bin/bash node-v2 || true
RUN chown -R 1000:1000 /app
USER 1000
EXPOSE 3457
CMD ["npx", "tsx", "server/index.ts"]