zsty.us

Before / After · Case Study

DJ Jackie J — a stalled "under construction" page became a three-offer entertainment brand

  • Local Pro Services
  • Events & Entertainment

Jackie's site had promised a relaunch for over a year while booking inquiries sat in an email inbox for a day at a time. Now a real booking site buzzes her phone within seconds of every inquiry, drafts gig applications while she sleeps, and grew from DJ-only into three offers — DJ sets, a full live show band, and an acoustic duo.

Jackie's brand should earn while she sleeps — without ever taking her voice out of the booth.
🔒https://jackiej.events
jackiej.events — modern site

At a glance

What this rebuild covers.

  • Design

    The half-built placeholder page became a real booking funnel — transparent pricing, packages, and a public calendar — with a drag-and-drop editor so page changes never wait on a developer again.

  • Theme & color

    The look leans into the stage: a moody, cinematic band hero over a framed lineup photo, a live promo reel, a disco-ball accent, and parallax scenes that feel like show lighting.

  • App builds

    Jackie runs the whole operation from her phone — an installable dashboard app with her inquiry inbox, calendar, and an AI assistant, so she can reply to a new bid straight from the lock screen.

  • Agents

    An agent scours local Orange County event listings around the clock, spots vendor calls, and drafts tailored applications in her voice — nothing goes out without her one-tap approval.

  • Customer notifications

    Every inbound inquiry fires a push to her phone in under 30 seconds, and a single admin bell rolls up six operational signals so nothing waits on someone remembering to check a tab.

  • Security

    Sign-in went from a password form to one-tap sign-in, and every form on the site now carries spam traps, rate limits, and double-submit guards.

  • Speed

    The site loads in under a second on a 4G phone — the mobile performance score went from 32 to 99.

Receipts — measured

Numbers that moved.

32/100
Lighthouse · mobile
was 32/100
1600ms
Time-to-first-byte (p75)
was 1600ms
24.0min
Inquiry → notification
was 24.0min
0 events/yr
5★ proof preserved
was 0 events/yr
  • Inquiry answered: 24 hrs → 30 sec
  • 1 offer → 3: DJ · live band · acoustic
  • Mobile speed score: 32 → 99
  • 5-star reputation carried over intact

The pixel diff

Overview, then the walkthrough.

Left: everything the legacy site shipped — frozen in place. Right: an auto-scrolling tour of the rebuild, from hero to booking. No slider to fight with.

Before — the overview
🔒https://djjackiej.com
Before — the overview

This is everything the legacy site had to offer above the fold. No pricing, no calendar, no booking — the funnel ended at a mailto.

After — scroll through what shipped
🔒https://jackiej.events
After — scroll through what shipped

Auto-scrolls through the modern site so you can see the booking surface, the package grid, the pricing table, and the calendar inline — without leaving this page.

Tap a pin. The story is in the pixels.

Before — what was broken
🔒https://djjackiej.com
Before
After — what shipped
🔒https://jackiej.events
After

The four beats

Problem · Insight · Build · Outcome.

Scroll past the legacy frame. The four beats land in order. At the end, the modern site fades into the same window.

🔒https://djjackiej.com
Legacy
01 · Problem

An under-construction WordPress site greeting every visitor for 14+ months.

Jackie's old site had been promising a relaunch since early 2024. Visitors landed on a half-rendered hero, three placeholder boxes, and an 'under construction' banner. No pricing, no calendar, no way to book.

02 · Insight

Her brand is the booth, but her funnel was her phone.

Every inquiry routed through email → maybe-checked → maybe-answered next day. The brand was strong (5★ across The Knot / WeddingWire / Thumbtack) but the funnel leaked any lead that needed an answer in under 24 hours.

03 · Build

Real marketing site + an agent backbone that works while she sleeps.

Shipped jackiej.events on Next.js + Tailwind. Wired TCPA-clean SMS opt-in capture feeding the central og_life comms store. Stood up the OpenClaw Haiku agent to scrape OC vendor pages every 5 min and draft tailored applications for one-tap approval. Push notifications fire to Jackie's phone the moment a bid lands.

04 · Outcome

Inquiry latency cut by 99%. Brand keeps earning between gigs.

Lighthouse mobile 32 → 99. TTFB 1.6s → 180ms. Inquiry → notification 24h → 30s. Every vendor call in OC within 30 miles is now surfaced + drafted within an hour — she wakes up to qualified gigs ready to one-tap submit.

05 · Iteration

The same project keeps growing operator-grade tooling, every push.

After launch it kept shipping: password sign-in hardened into Google OAuth + magic-link SSO, a Puck visual editor wired to Postgres, the dashboard chatbot rebuilt into an 8-tool Anthropic orchestrator, and a Slack-as-frontend triage queue that turns a #jackie-j-events message into a classified, approvable action. One Vercel project, all live — behind a deliberate two-step deploy gate (main = previews; prod promotes from the production branch).

06 · The band era

DJ brand → three-offer entertainment brand.

2026-07: Jackie J & The Diamonds launched as a full product line — cinematic /band hero, live promo reel, 5–11-piece configurations, an Acoustic Duo — merged production → main and live on both domains. Under it, the plumbing kept compounding: push and SMS moved onto the central og_life multi-brand rails, the DB migrated live from Neon to Prisma Postgres, the inquiry funnel got rate-limits + honeypot + double-submit guards, and the Slack → OpenClaw codegen daemon (Mission 2) turned Slack messages into gated worktree code changes.

🔒https://jackiej.events
Modern
For the technically curiousHow it was done
  1. 01

    Where it started

    djjackiej.com was a WordPress + Elementor build that had shown an "under construction" banner for 14+ months — one half-rendered landing page, three placeholder boxes, and an inquiry link that opened a mailto. The brand itself was strong (5-star reviews across The Knot, WeddingWire, and Thumbtack), but every inquiry routed through email and waited a day for an answer, and three Instagram handles were managed by hand between sets.

  2. 02

    The rebuild

    jackiej.events shipped as a real marketing site on our hosting platform: pricing, packages, a public calendar, and the 5-star proof on the page. Mobile performance went from 32/100 to 99/100 and time-to-first-byte from 1.6 seconds to 180 milliseconds. Repeat-booking got a consent-first SMS opt-in — every business card carries a unique QR-coded link, and each signup writes a recorded consent row to a database the brand owns, not a vendor list.

  3. 03

    The agent backbone

    An agent on our build fleet polls public Orange County event-listing pages every five minutes, de-dupes against what's already been applied to, and drafts a tailored vendor application in Jackie's voice for one-tap approval — she wakes up to qualified gigs already written. Inbound inquiries fire a web push to her installed phone app in under 30 seconds, and her dashboard carries an AI assistant that can search inquiries, check the calendar, and draft replies over eight hard-typed tools — every send requires an explicit confirm.

  4. 04

    Operations moved into chat

    A scheduled job sweeps the team's chat channel every five minutes and drops change requests into a deduped triage queue, where an AI classifier sorts each into one of eight typed actions. A small allowlist of safe actions — swap a hero photo, update text — applies straight to the published page; everything else waits for one-tap approval. One tier above that, a chat message can become an actual code change: a daemon on our build fleet builds it in an isolated workspace with its own preview and holds it at a gate — nothing merges without human sign-off.

  5. 05

    The band era

    In mid-2026 the brand outgrew the booth: Jackie J & The Diamonds launched as a full product line — a cinematic band page, a live promo reel, and configuration tiles for a 5-to-11-piece show band plus an Acoustic Duo — live on both jackiej.events and djjackiej.com. Under it the plumbing kept compounding: the inquiry funnel gained rate limits, a honeypot, and double-submit guards; push and SMS moved onto shared multi-brand rails; the database was migrated live to a new managed provider with a fail-soft fallback; and production only promotes through a deliberate two-step deploy gate.

Architecture

Old stack
  • WordPress
  • Elementor
  • WPEngine cache
  • Cloudflare CDN
  • Manual IG posts
  • Email-only inquiry
New stack
  • modern web framework
  • design system
  • managed database
  • NextAuth (Google + magic-link)
  • SMS consent store → og_life rails
  • transactional email rails
  • push notifications
  • AI models
  • Slack → codegen daemon (worktrees)
  • Live tracking (trips + heartbeats)
  • visual editor
  • edge hosting we operate

What changed, with evidence

Design

Real 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)
Retention

Consent-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 backbone

SEO 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 backbone

Auto-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 push

Real-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
Design

Puck 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 backbone

Tool-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 backbone

Slack-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)
  • A safe-actions allowlist gates auto-approval; everything else queues for Brendon
Real-time push

Admin 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
Design

The 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 backbone

Slack → 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
Retention

Inquiry + 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

While she sleeps.

Autonomous surfaces

The agent backbone keeps the brand earning between gigs. Jackie approves; the system runs.

  • Polls OC vendor pages every 5 minutes

    every 5 min

    Eventbrite, Meetup, local chamber sites — pulls fresh listings, de-dupes against the applied set.

  • Drafts outbound bids in Jackie's voice

    on each new opportunity

    Claude Haiku composes a tailored cover note per event; routes to /dashboard for one-tap approval.

  • Pushes inbound inquiries to her phone

    real-time

    Web push fires in under 30 seconds when a /contact submission lands or a vendor portal replies.

  • Captures SMS consent on every opt-in

    on each opt-in

    Each /optin submission writes a TCPA consent row (phone, checkbox state, referrer QR) to the brand-owned opt_ins table — the audience is portable, forward-ready for the central og_life SMS rails.

  • Builds Slack-requested code changes in gated worktrees

    on each codegen request

    The OpenClaw codegen daemon picks up a Slack change request, builds it in an isolated worktree with a Vercel preview, and parks it at an approval gate — no human, no merge.

  • Tracks her live location during wheels-up trips

    30s heartbeat

    Broadcast/consume trip endpoints — clients on the booked event can follow Jackie's drive without sharing her actual phone number.

  • Refreshes Google Business + IG posts on a cadence

    daily draft, weekly post

    Agent rotates featured packages, posts gig recaps, and queues hashtag stacks — Jackie reviews + taps approve.

  • Polls #jackie-j-events for /jj + @mentions

    every 5 min

    Vercel Cron sweeps the Slack channel for change requests, de-dupes them, and drops each into the triage queue.

  • Classifies each triage row with an 8-tool Anthropic loop

    on each new message

    Sonnet sorts the message into one of 8 typed actions — swap hero photo, update text, add event, queue for research/dev, reject, escalate.

  • Auto-executes safe-whitelisted actions, queues the rest

    on classification

    Whitelisted actions write straight into the published Puck page; everything else waits for Brendon's one-tap approval at /admin/queue.

  • Rolls up 6 admin signals into one bell

    30s poll

    The /dashboard notification tree aggregates Slack ingest, new inquiries, triage activity, and more for admin accounts.

← All rebuilds

DJ Jackie J — a stalled "under construction" page became a three-offer entertainment brand — zsty.us