Add /strip endpoint and web UI for metadata removal

- POST /strip: accepts any image, strips all metadata (EXIF, GPS, IPTC, XMP),
  returns clean anonymous JPEG at original dimensions (quality 92)
- GET / now serves a minimal web UI with drag-and-drop upload
- Token prompt on first use, saved to localStorage
- Add CLAUDE.md with project context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-13 17:22:58 -07:00
parent 6e6beb9f8e
commit ba9feacd48
2 changed files with 214 additions and 1 deletions

53
CLAUDE.md Normal file
View File

@@ -0,0 +1,53 @@
# 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 010 machines, 2 concurrent connection hard limit
## Environment Variables
- `PORT` (default 8080)
- `CONVERTER_TOKEN` (required)
- `REQ_TIMEOUT_MS` (default 120s, range 5600s)
- `REQ_TIMEOUT_PDF_MS` (default 5m, range 10s30m)
## 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`