Each claim ships with concrete evidence — env vars, table names, cadence chips. No marketing fluff.
◆DesignReal marketing site, mobile-first
Cut the under-construction WordPress and shipped a Next.js + Tailwind site with real sections: pricing, packages, calendar, booking. The Knot / WeddingWire / Thumbtack 5★ proof is on the page. Loads in under a second on a 4G phone.
- Before
- Single landing page with a hero, three placeholder boxes, and an under-construction banner.
- After
- Full booking funnel with a public calendar, transparent packages, and direct SMS opt-in.
- ▸Lighthouse 99/100 mobile (was 32/100 on the WP site)
- ▸TTFB 1.6s → 180ms p75
- ▸Real /pricing, /packages, /calendar surfaces (legacy had none)
◉RetentionConsent-first SMS opt-in + per-referrer QR codes
Every business card carries a unique /optin?ref=… link backed by a printable QR. Subscribers go through a TCPA-clean opt-in with an explicit consent checkbox; consent rows persist to the site's own opt_ins table — owned data, not a vendor list. The forward path is the central og_life SMS store (same multi-brand rails the push path already rides), with AWS 10DLC registration filed for the sending number.
- Before
- Repeat clients had to text Jackie's personal cell.
- After
- Subscribers opt in once, with recorded consent, into a store the brand owns.
- ▸/api/sms/subscribe writes consent rows (phone, consent state, source ref) to opt_ins
- ▸Per-card QR tracking — Jackie can see which gig drove which signups
- ▸Central-store proxy wired (brand jackiejevents, same ingest secret as push); AWS 10DLC registration Step 1 filed
△Agent backboneSEO agent backbone — posts ads while she sleeps
Python agent on the OpenClaw machine polls every 5 minutes via launchd. Queued tasks flow through Claude Haiku: scour local OC event-vendor pages, draft applications, draft outbound DM replies, refresh Google Business posts. Every outbound is a draft — Jackie approves before anything goes live (her explicit choice).
- Before
- Jackie scrolled IG hashtags between sets to find vendor calls.
- After
- Agent surfaces ranked opportunities each morning with pre-drafted applications.
- ▸5-min polling cadence, launchd-managed (no Cron drift)
- ▸Targets: Eventbrite OC vendor calls, Meetup events, IG hashtag scans
- ▸Draft-for-review — never auto-posts without Jackie's tap
△Agent backboneAuto-applies to be a vendor on scraped OC event pages
Same agent watches public Orange County event-listing surfaces — fairs, weddings expos, local-business mixers — extracts vendor application links, and queues a tailored application for Jackie to one-tap approve. She wakes up to a list of qualified gigs already drafted.
- Before
- Vendor opportunities slipped past during peak season — too many sites, no time.
- After
- Every public OC vendor call within 30 miles is surfaced + pre-drafted within an hour.
- ▸Per-event tailored cover note (uses Jackie's voice, not boilerplate)
- ▸De-dupes against already-applied events automatically
- ▸Surfaces in /dashboard with a single Approve → Submit button
▲Real-time pushReal-time inquiry push (PWA), not email
Every inbound — bid request, calendar question, review reply — fires a Web Push to Jackie's phone via her installed PWA. She taps the notification, the app opens straight to the relevant inbox thread. Push now rides the central og_life push store (brand jackiejevents): the site route is a thin proxy, and the same multi-brand rails serve every property in the portfolio — one keypair, one ingest secret, zero new infra per brand.
- Before
- Inquiries arrived as email; replies came hours or days later, if at all.
- After
- Phone buzzes the moment a bid lands; Jackie can reply from the lock screen.
- ▸PR #7 merged: standalone VAPID keys retired; /api/push proxies the central og_life push store
- ▸Average inquiry → notification: <30 seconds end-to-end
- ▸Tap-through deep-links to the exact inbox thread
◆DesignPuck visual editor wired to Postgres
/admin/edit is a real drag-and-drop editor (Puck) with 15 typed blocks — hero, services, calendar, reviews, the disco-ball accent, the parallax scene, the Instagram embeds row. Edits save as drafts and publish per page; every version is kept in Neon so a change can be rolled back.
- Before
- Copy changes meant a code edit + redeploy, every time.
- After
- Jackie (or Brendon) edits the live page visually; drafts publish without touching the repo.
- ▸15 Puck blocks in src/puck/config.tsx
- ▸puck_pages + puck_page_versions tables (draft/published per page)
- ▸Auth-gated — redirects to /dashboard/sign-in if not an owner
△Agent backboneTool-using chatbot for Jackie's dashboard
/dashboard/ai runs a real Anthropic tool-use loop (Sonnet, 6-iteration cap) over 8 hard-typed tools — it can search inquiries, pull a full client record, check the calendar for open weekends, draft a reply in Jackie's voice, and send it. Every send needs an explicit confirm and is audit-tagged in the messages table.
- Before
- Jackie re-read threads and hand-wrote every reply on her phone.
- After
- She asks for an inquiry in plain English; the bot finds it, drafts the reply, and sends only on her confirm.
- ▸8 tools: search_inquiries, get_inquiry, search_clients, draft_message, send_message, queue_long_task, check_calendar, generate_brochure
- ▸Sends require confirm:true and are tagged ai:chat:<email>
- ▸Errored tools return is_error so Claude can recover mid-loop
△Agent backboneSlack-as-frontend triage queue
A Vercel Cron polls #jackie-j-events every 5 minutes for /jj or @JACKIEBOT messages and pushes them into a deduped triage queue. An Anthropic classifier sorts each into one of 8 typed actions — swap a hero photo, update text, add an event, queue for research/dev — and a whitelisted few execute straight into the published Puck page; the rest wait for one-tap approval at /admin/queue.
- Before
- Quick-change requests lived in scattered texts and got lost.
- After
- A Slack message becomes a classified, approvable action — some apply themselves, the rest are one tap away.
- ▸triage_queue table with unique (source, source_ref) dedup index
- ▸8 typed action kinds → executor framework (swap_hero_photo + update_text write puck_pages.home.published)
- ▸LIVE_SAFE_WHITELIST gates auto-approval; everything else queues for Brendon
▲Real-time pushAdmin notification tree across 6 sources
The /dashboard sidebar carries an admin-only bell that aggregates six signals — Slack ingest, new inquiries, triage-queue activity, and more — on a 30-second poll, so nothing waits on someone remembering to check a tab.
- Before
- Status lived in N separate places; you found out when you looked.
- After
- One bell rolls up every operational signal the moment it lands.
- ▸6 aggregated sources, 30s poll, admin-only
- ▸Surfaces alongside the Web Push path, not in place of it
- ▸Built on the same Auth.js owner/allowlist role layer
◆DesignThe band era — Jackie J & The Diamonds ships as a product line
2026-07: the site stopped being DJ-only. A cinematic /band page (framed lineup photo over a moody backdrop), a live promo reel with non-teardown unmute, and configuration tiles for a 5–11-piece show band plus an Acoustic Duo — the brand now sells three offers from one homepage: DJ · live band · MC. Band content merged production → main and confirmed live on both domains.
- Before
- One offer: DJ sets.
- After
- Three offers — DJ, a configurable 5–11-piece band, an acoustic duo — one funnel.
- ▸BandHero rewrite (149 lines) + BandCinema promo reel + band configuration tiles
- ▸Lineup photo optimized 424 KB → 127 KB in the same merge
- ▸Live title: “Wedding & Event DJ · Live Band · MC | LA + OC” — verified on jackiej.events
△Agent backboneSlack → OpenClaw codegen daemon (Mission 2)
One tier above the triage queue: a Slack message can now become an actual code change. The codegen daemon picks up a request, builds it in an isolated git worktree with its own Vercel preview, and holds at a gate — nothing merges or ships without human approval. Gates 1–2 proven on this repo, with hardening follow-ups (worktree .vercel sharing, stale-job cleanup, Slack webhook guard).
- Before
- Slack messages could reclassify content; code changes still meant a dev session.
- After
- A Slack request becomes a gated, previewable code change awaiting one approval.
- ▸Mission 2 Gates 1 & 2 landed (PR #4/#3 + hardening commits)
- ▸Isolated worktree builds — the daemon never touches main directly
- ▸Same human-gated promotion contract as the triage queue
◉RetentionInquiry + forms hardening — the funnel stopped trusting the internet
The inquiry pipeline grew a DB-backed rate limit, a honeypot, a double-submit guard, and real date validation. Every form on the site now goes through a shared useFormSubmit hook with stale-bundle auto-reload (a deploy can't strand an open tab on dead JS) and a CI guard that keeps new forms on the same rails.
- Before
- One unguarded form endpoint; two pollers kept the DB billing 24/7.
- After
- Hardened funnel, uniform form rails, and a DB that sleeps when Jackie does.
- ▸DB-backed rate-limit + honeypot + double-submit guard + date validation on /contact
- ▸Shared useFormSubmit hook + stale-bundle auto-reload + CI guard
- ▸Live DB migration Neon → Prisma Postgres executed with a fail-soft env fallback; the two 24/7 pollers that pinned the DB awake were killed