The problem
A new product needed a photo edited, a lab report pulled, inventory updated, then a page built by hand on the website, in the spreadsheet, and in the ERP. Three places, three chances to drift, one person's afternoon. And nobody noticed when a lab report expired.
What I built
One scheduled job that watches Drive for the photo, the report, and a stock quantity. When all three are there it builds the page, updates the ERP, mirrors the photo for customers, and emails whoever added the product what's still missing and which reports are about to expire.
What changed
The manual three-location update per product is gone. The expiring-report problem is gone. The person who used to spend the afternoon now spends it on customers, and the company kept the system after I moved on.
The mechanism
Every fifteen minutes one script walks its steps in order. On the left is what it reads. In the middle are the steps. On the right is what the company sees. A small local store in the middle is written once per tick and read by every later step, so the site, the sheet, and the customer folder never disagree with each other.
Each step is non-fatal. A failure is named in the log, and an email goes out only when the set of failing steps changes, so nobody gets paged for a known blip.
Step by step, in plain words
- Pull the latest code. The host updates itself from the repository before every run. Shipping a fix is a push; it's live within fifteen minutes.
- Mirror the Drive folders. Pending product photos and the lab-report folders are copied down so the rest of the run works on local files.
- Read the lab reports. Cannabinoid percentages and dates are extracted from each PDF into the store. Reports older than a year are flagged.
- Sync inventory. Stock, variants, and orders come from the ERP into the same store.
- Attach reports in the ERP. The newest report for each product is attached to its record, so the ERP is the source of truth for compliance too.
- Mirror media for customers. In-stock photos land in a shared folder the sales team sends to customers.
- Write descriptions. A new strain gets a short blurb from Claude, once. Existing blurbs are reused, so the API bill stays flat.
- Reconcile the website. Every in-stock product gets a page with photo, lab results, and description. Out-of-stock pages are hidden, not deleted.
- Push related products. The maintainer's picks from a spreadsheet become the "you might also like" strip.
- Notify. A morning digest and, only on change, a failure notice.
How it stays alive after I leave
The whole system is one repository with one Python package underneath it. Connecting to the ERP, authenticating to Google, knowing which sheet is which: each of those lives in exactly one place instead of being copied into every job. The production host pulls the repository at the top of every run, so a change moves from a developer's laptop to production without anyone logging into the server.
The one rule: never edit on the server. A hand edit makes the tree dirty and the self-update silently stops. The docs say so on page one.
The documentation is written for a reader who has never seen the system: what it is, how to install it, how to authenticate, what each job does, how to add a report, how to test end to end, what to do when something breaks. That's the part that makes it a handoff instead of a hostage situation.
Stack
The front of the pipeline is a small desktop app that cleans up the raw photos before they go in the folder. That one is open source: PhotoEditor. The back of it, the WooCommerce half, was worked out first on a spin-off's order portal, where a new product got its own product page and its photo from that same editor. Bringing that back to Elevated is what turned a photo tool into this pipeline.
Built in conversation
I'm not a career software engineer. This was designed, written, debugged, and documented through dialogue with Claude, one decision at a time, over about a year of evenings alongside a day job. The hard parts weren't the code. They were deciding what the source of truth is, what happens when a step fails at 2am, and how to hand the whole thing to someone else. Those are conversations, and in 2026 you can have them with a machine that never gets tired of the follow-up question.
Same approach behind everything on this site. The philosophy, or what I'm building right now.