Fly.io deploy config and /review service endpoint for AM Collective backend

adamwolfe2 ships a Dockerfile, fly.toml, and a new `POST /review` route that lets a sibling service call the backend for Claude-Haiku-powered document analysis without going through Supabase auth. The infrastructure setup is named for AmCollective, but the `/review` endpoint and its auth middleware are portable.

contract-reviewintegration

The Dockerfile is Node 22-slim with LibreOffice installed via apt, matching what upstream's nixpacks.toml produces. fly.toml targets shared-cpu-1x at 512MB in the iad region -- the comment notes that 256MB OOMs during LibreOffice DOCX-to-PDF conversion, which is consistent with reports from other forks running the same stack.

The /review route (backend/src/routes/review.ts, 171 lines) accepts a POST with a doc_url, fetches and extracts text using the same pdfjs/mammoth pipeline as chatTools.ts, then calls Claude Haiku and returns { summary, key_clauses, risks, recommendation } JSON. It's stateless: no database writes, no file uploads. Auth is handled by a new requireServiceAuth middleware that does a timing-safe Bearer token comparison against MIKE_SERVICE_TOKEN. The intended caller is a sibling service called Hermes, which exposes this as a legal.review MCP tool.

The middleware implementation is correct: it uses timingSafeEqual from Node's crypto module, pads to equal length before comparing to avoid leaking length via timing, and returns 401 with a generic message on failure. It's reusable without modification if you want a service-to-service auth pattern in your own fork -- just rename the env var.

One thing to flag: review.ts re-implements PDF and DOCX text extraction rather than calling a shared helper. If you pull this endpoint in, the duplication with chatTools.ts will need to be watched. Any future change to the extraction logic (new pdfjs version, changed DOCX handling) will need to be applied in two places.

So what Worth a look if you want a clean service-to-service review API or a reference for Fly.io deployment with LibreOffice. The Dockerfile and serviceAuth middleware are directly reusable; the fly.toml needs renaming and secret-layout adjustment for your own app. Skip the `/review` endpoint if you are happy using the existing chat interface for document analysis and don't have a Hermes-style caller.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

1 commit from adamwolfe2/mike-amcollective, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
cb876234 feat: add Fly deploy config, /review endpoint, and Supabase S3 support adamwolfe2 2026-04-30 ↗ GitHub
commit body
- Dockerfile: Node 22-slim + LibreOffice apt (mirrors nixpacks.toml config)
- fly.toml: mike-backend-amcollective, shared-cpu-1x @ 512MB, region iad
- routes/review.ts: POST /review - stateless doc review via Claude Haiku
  Fetches URL, extracts text (pdfjs/mammoth, same pattern as chatTools.ts),
  returns {summary, key_clauses, risks, recommendation} JSON
- middleware/serviceAuth.ts: timing-safe Bearer token auth (MIKE_SERVICE_TOKEN)
- index.ts: register /review route
- lib/storage.ts: R2_REGION env var instead of hardcoded 'auto'
  Set R2_REGION=us-east-1 for Supabase Storage S3, omit for Cloudflare R2

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-90.md from inside the repo you want the changes in.

⬇ Download capture-thread-90.md