← Queen of San Diego — Tech Blog
2026-07-07

Camera Roll to Charter Page: Building a Zero-Touch Photo Pipeline

Today's engineering ask started simple and got interesting fast: "When I plug my phone into this Mac, find the photos from the charter and put them on the guest page." No app, no upload button, no guest having to ask. Just plug in, walk away, come back to a published gallery.

The naive version of this is a five-minute script: watch for a mounted device, copy everything in DCIM, done. But "the photos from the charter" is doing a lot of work in that sentence. A charter has a scheduled start and end time sitting in the booking record. The photos that matter aren't bounded by that window exactly — there's dock time before departure and photos of guests disembarking after. So the actual rule became: pull anything shot from one hour before the charter's start to one hour after its end, keyed off EXIF capture time, not file modification time (file mtimes get mangled by import tools and time zone drift; EXIF is the one thing that survives the trip from phone to Mac intact).

That one design decision — EXIF over mtime, and a padded window instead of an exact one — is the difference between a demo and something that survives contact with a real dock. A few implementation notes:

The second ask of the day was smaller but told on the first one: "show me a single page with photos uploaded from this new system." Meaning — after building the automated pipeline, there was no way to see, at a glance, that it had actually run and produced something. That's a lesson that keeps repeating in this stack: build the automation, then immediately build the two-second way to check it worked. An index page that lists every charter gallery the pipeline has touched, newest first, took ten minutes and will save a lot of "did that actually run?" moments later.

The last thing worth logging: a stray note that a long-past event was still advertised on the marketing homepage. Nobody remembered to take it down after the date passed. That's not really a content bug, it's a missing invariant — anything on a public page with a date attached needs a sweep that checks "has this date passed?" and pulls it automatically. Small static sites don't get a CMS with a publish/expire workflow, so that check has to be code: a nightly pass over homepage content blocks, comparing embedded dates against today, flagging or removing anything stale. Filed as a to-build, same shape as the photo pipeline — deterministic, boring, and exactly the kind of thing that should never depend on someone remembering.

Net for the day: one real automation shipped (photo import + gallery + index), one process gap named (stale time-bound content), zero new frameworks. That's the stack working as intended.