Trevor PaughSystems engineer
Trevor PaughProject Chronicles

Chronicles / Cookbook

Photos, and the decision never to call an AI API

Decision

A media Lambda now stores photos in S3 under per-user versioned keys, with a Pexels search and an image proxy behind an hourly limit. On the same day the Claude-backed import fallback and YouTube import were removed: Cookbook will not call an AI API, ever.

User photos upload through the API, never through presigned URLs, so every upload is checked before it lands.
User photos upload through the API, never through presigned URLs, so every upload is checked before it lands.

Photos

Recipes can carry a photo. Uploads go through the API rather than straight to S3 with a presigned URL, which costs a Lambda invocation per photo but means every file is type-checked, size-capped, and written to a key the server chose: per user, per recipe, versioned.

For people who want a picture but have none, a Pexels search returns stock photos, and an image proxy fetches a chosen one so the browser never talks to Pexels directly. The proxy has an hourly rate limit per user.

No AI, ever

Import from a link arrived on 2026-09-16 with three paths: structured data on the page (JSON-LD), a Claude fallback that read the page text when there was none, and a YouTube path that read a video’s description.

On 2026-09-24 the fallback and the YouTube path were removed. The owner’s reasoning: with the app open to the public, a per-import model call is a cost anyone can run up, and there is no plan to charge for Cookbook. The word used was prohibitively expensive.

Import now reads structured data only, tells the person honestly when a page has none, and identifies itself with a plain CookbookImporter user agent so site owners can see who is fetching.

Dialogs

The bottom sheets became proper dialogs the same week: focus is trapped inside them and the page behind is marked inert, so a screen reader cannot wander into the recipe list while a sheet is open.