# PostConvert Image/PDF-to-JPEG conversion microservice. Single-file Node.js/Express app (`server.js`). ## Tech Stack - Node.js 18+ (ES modules), Express - Sharp (image processing), libheif-js (HEIC/HEIF via WASM) - pdftoppm from Poppler (PDF rendering), archiver (ZIP output) - Docker (node:20-bookworm-slim), deployed on Fly.io (sjc region) ## Endpoints - `GET /health` — health check - `POST /convert` — image or first PDF page → JPEG - `POST /convert/pdf` — all PDF pages → ZIP of JPEGs ## Auth Bearer token via `CONVERTER_TOKEN` env var on all endpoints. ## Key Design - Single-flight concurrency (1 conversion at a time, 429 if busy) - Resize/quality via headers: `x-jpeg-quality`, `x-max-dimension`, `x-pdf-dpi`, `x-without-enlargement` - Pixel limit 200M, bounded /tmp, no stack traces leaked, request timeouts - Fly.io auto-scaling 0–10 machines, 2 concurrent connection hard limit ## Environment Variables - `PORT` (default 8080) - `CONVERTER_TOKEN` (required) - `REQ_TIMEOUT_MS` (default 120s, range 5–600s) - `REQ_TIMEOUT_PDF_MS` (default 5m, range 10s–30m) ## Development ```sh npm install node server.js ``` Docker: ```sh docker build -t postconvert . docker run -e CONVERTER_TOKEN=secret -p 8080:8080 postconvert ``` ## Fly.io Deployment Tokens are in `.env` (gitignored). Load with `source .env` or use `dotenv`. Deploy: `FLY_API_TOKEN="$FLY_API_TOKEN" fly deploy`