My wife’s reaction to this week’s work:

“So you built… nothing I can see?”
“Well, I built CI/CD pipelines and—”
“Can I use it during tomorrow’s show?”
“Not exactly, but—”
“Cool. I sold 147 pieces this week. You?”

Welcome to infrastructure week, where the only visible progress was discovering I’ve been publishing iOS apps under “OldClientName LLC” since 2016. Permanently. Forever. No takebacks.

What My Wife Sees:
├── 🎯 Sales data lookup (saves 1 min/customer)
└── 📦 Bundle automation (saves 3 min/customer)

What Actually Happened This Week:
├── 🔧 CI/CD pipelines for 6+ systems
├── 🌐 4 browser extensions
├── 🔐 Workload identity federation
├── 📱 iOS automated deployments
├── 🖨️ Print style overhaul
├── 🔑 Secret management system
├── 🤖 Event-driven AI generation & data workflows
└── 💔 8-year Apple identity crisis

Here’s what actually happened in Week 3 of being my wife’s CTO.

The Infrastructure Nobody Sees

After two weeks of rapid features and our massive 3x growth (1 → 3 users), I spent this week making sure we don’t die when we hit 4 users. Or when I push code during a live show. Or when secrets leak. You know, the fun stuff.

The full list of “invisible” wins:

  • CI/CD for EVERYTHING (bookmarklet site, web app, iOS via Fastlane, Cloud Run functions, Cloud Run reverse proxy routing, firestore/firebase storage rules, etc.)
  • Release automation with release-please (because manual versioning is for people with time)
  • Multi-browser extension support (Chrome → Chrome + Firefox + Safari + Edge)
  • Workload identity federation (goodbye service account key files, well, mostly)
  • Vaultwarden for secrets (no more .env files in Slack DMs to myself)
  • Print styles that don’t look like 1995. Or at least not 1995 in a bad way.
  • SwiftLint for iOS code (because my Swift was… not great)

That Apple thing though. While setting up Fastlane and moving wife to TestFlight from Xcode WiFi builds, I discovered my Developer account is eternally bound to a client from 8 years ago. Apple’s response: “Yeah, that’s permanent.” My wife’s response: “So our app is published by… who exactly?”

When you make your first iOS app, you don’t think about the long-term consequences of naming your Apple Developer account after a client. You just want to ship. Now, I have to live with “OldClientName LLC” forever. Whoops.

2016: "Quick client project" → 2025: "Wait, what that email say?" → Apple: "¯\_(ツ)_/¯"

The marriage survives another week.

Why This Matters for Live Selling

When your wife is speed-talking through 50 vintage pieces while tracking inventory, calculating bundle discounts, and thanking buyers BY NAME, your code better work.

This week’s boring infrastructure means:

  • My React Native code for voice-described inventory items has been migrated over
  • Photo uploads are now handled by Firebase Storage iOS SDK directly, are minutes faster, and generation happens in parallel on the backend based on all photos for an item being uploaded
  • I now have a third party sanity check for my iOS code (thank you GitHub Actions, Fastlane, and SwiftLint)
  • Automated TestFlight builds are pretty slick
    • Wife needs to use an actual stable build, our motto is to eject to prior-process at the first sign of failure. So TestFlight became our staging environment
  • Secrets that are actually… secret
  • While I’m on my 10k steps a day streak I can now dip into the code

The Technical Reality Check

Look, I could have built features. And I did. But here is the real business impact from this week’s work:

  • Sales bookmarklet now fetches prior sales data for the purchaser, so we save a minute per user for order complimentary card lookup
  • We also added custom bundle setup for the bookmarklet from the purchaser data, so specific items now require no manual lookup. This saves 2-3 minutes per user for bundle setup

These may not sound like much, but when you’re selling 100+ items in a live show, every second counts. And when your wife is the one selling, you better believe those seconds add up to more sales. And when you’re the one helping pack and ship those sales, you care about every second too.

BEFORE THIS WEEK:
87 customers × 3 minutes each = 261 minutes = 4.35 hours

AFTER THIS WEEK:
87 customers × 0 minutes = 0 minutes = 🎉

Weekly Time Saved: ~4 hours
Annual Time Saved: 225+ hours (Almost 6 work weeks!)

What Actually Happened

Here’s the technical breakdown for anyone who cares about the details:

CI/CD Everywhere

  • Bookmarklet website: Simple GitHub Actions → Vercel
  • Web app/Marketing site: Same stack, different pipelines
  • iOS app: Fastlane + Match for signing, TestFlight for distribution
  • Cloud Run functions: Automated deployments with proper API subdirectory redirects

The Browser Extension Evolution

Week 1: Chrome only (me)
Week 2: "Why doesn't it work here?" - Wife shows me Edge
Week 3: "What about Firefox?" - Me
Also Week 3: "... we're only supporting iOS. What about Safari?" - also me

Current Status: ✅ All browsers (even Safari)

Started with Chrome-only because that’s what I use. Turns out resellers and wives are browser agnostic:

  • Leaned out of chrome specific APIs and into WXTs cross-browser APIs
  • Added Edge support (because why not, it’s just Chrome with a different icon)
  • Added Firefox support (minor manifest changes)
  • Added Safari support (why is this so different, Apple?)
  • Sales data fetching now works across all platforms

Infrastructure-as-Code

  • OpenTofu (because we’re not paying for Terraform Cloud)
  • Workload identity federation for Firebase and Cloud Run, because I figured out how to do it last year
  • No more service account keys floating around

The Print Revolution

You know what matters during fulfillment? Print styles. Updated everything:

  • Pick lists that actually fit on paper, grouped by user, bigger pictures
  • Purchase history that’s readable
  • Shipping labels that work

SwiftLint Discovery

Found out about SwiftLint this week. My Swift code was… not idiomatic. It is now. And my dangling commas are gone.

The Research

Here is some of the research I had generated this week:

Next Week

With CI/CD humming and secrets actually secret, we’re back to features:

  • The magical ‘process items from 150 photos’ button
    • The prior process included manually selecting which photos were items, but we have -bunch of items- and -how to tell them apart- prompt tweaks that could save the time of selecting photos, paired with a new manual photo-reorganization flow
    • We hit 95% accuracy last week, which means we’re about to eliminate a 45-minute pre-show ritual. She’s running 7 shows a week.
  • Show analytics (spoiler: she already tracks this in 4 spreadsheets)
  • Maybe fixing that Apple Developer name (narrator: he won’t)
Photo Batch Processing Progress:
Week 1: ▓░░░░░░░░░ 10% (manual everything)
Week 2: ▓▓▓▓▓▓▓░░░ 70% (basic AI integration)
Week 3: ▓▓▓▓▓▓▓▓▓░ 95% (parallel processing, retries)
Goal:   ▓▓▓▓▓▓▓▓▓▓ 100% (let the server do it)

Impact: 45 minutes per show
        × 7 shows/week = 5.25 hours saved

… but once we’re part of the show item generation process, we can add a lot of metadata to manage custom bundles and provide hooks on various Poshmark pages for getting the latest show data without much overhead. This part opens up a lot of possibilities for future features.

P.S.

If you’re building tools for your spouse’s business, infrastructure week is still marriage week. Every pipeline failure is dinner conversation. Every successful deployment is… also dinner conversation. Plan accordingly.

Also, if anyone knows how to change an Apple Developer organization name after 8 years, my DMs are open. Otherwise, “OldClientName LLC” will be shipping Poshmark tools forever.


Building tools for resellers, one crisis at a time.