Adds a GET /api/csv/shots/[jobId] endpoint with two modes:
?detail=shots (default) - one row per shot, with rolled-up task
count, hours, days, subtotal and total.
?detail=tasks - one row per line item, adding artist role, rate
card, rates and the markup/discount/tax/total split.
Totals run through the existing calcLineItem/sumLineItems helpers so
they match the editor and the PDF. Amounts are emitted as plain 2dp
numbers with the currency named in the header, so spreadsheets can sum
them. Rows follow the editor's display order (grouped by episode or
shot group, Ungrouped last, then alphabetical by shot code) and the
group column header adapts to the job type.
Shotlist column headers deliberately match the CSV importer's aliases
so an export can be edited and re-imported. Free text is flattened to a
single line to keep one shot per row: the importer's parser splits on
newlines before handling quotes, so multi-line quoted fields would
otherwise corrupt a re-import.
Exposed as an "Export CSV" dropdown in the shots editor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
puppeteer was declared in package.json but never imported anywhere in
the codebase -- PDF generation goes through @react-pdf/renderer. Its
postinstall step downloaded a ~150-200MB Chrome build on every clean
`npm ci`, which exhausted the disk on the deploy host and failed the
build with ENOSPC.
That download was wasted work even when it succeeded: the runner stage
never copies /root/.cache/puppeteer out of the builder, so the browser
was discarded when the builder stage ended.
Also drops 633 lines of transitive dependencies from the lockfile.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The import-shots feature calls review.twotalesvfx.com from a server
action that reads process.env.SHOTS_API_KEY. That variable existed only
in the local gitignored .env, and the compose file passed just
DATABASE_URL, NEXTAUTH_SECRET and NEXTAUTH_URL to the app service. In
production the key was therefore undefined, so the action threw before
issuing any request -- and because Next.js masks server-action errors in
production, the UI showed a generic failure that looked like a network
or CDN problem rather than missing configuration.
Interpolate SHOTS_API_KEY from the deploy environment instead of
hardcoding it, so the secret stays out of the repo. The :? guard makes
compose abort with an explanatory message when the variable is missing,
rather than silently starting an app that cannot import shots.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The CLI create-user scripts hit environment issues on the VPS (missing
ts-node, missing node_modules on the host). A /signup page sidesteps
that entirely since it runs inside the already-working Next.js server.
It's a one-time-use setup form: the server action refuses to run once
any user already exists, so it's safe to leave in place, though it can
be deleted after the first account is created.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ts-node is a devDependency and isn't available after a production
install; scripts/create-user.js only needs packages already in
dependencies so it runs on the deployed server.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>