A walkthrough you can run cold against the preview URL. Each act is a beat that proves out one of the four pillars from the v2 plan. Every "watch this happen" line maps to a phase deliverable that is wired into the running app.
If you only have 90 seconds: run Act 4 (Investigation Agent). It carries the demo on its own.
Setup (do once before the demo):
- Open the preview URL.
- Append
?scenario=mixed&admin=1to the URL. The admin panel only renders when?admin=1is present (seesrc/features/earn/activity/admin/useAdminMode.ts) and is gated against production by default. - If you want to demo real Anthropic streaming, make sure
ANTHROPIC_API_KEYis set in the Vercel project. If it is missing, Act 4 still works — the drawer drops to a deterministic recorded response and shows aDemo modesubtitle in the footer.
URL: /earn/activity?scenario=mixed
"This is the v1 page, untouched. Four states — Continue earning, Tracking, Needs attention, Rewarded — derived from the same
deals.getActivityOfferPlacementstRPC procedure that ships in production. Snake_case on the wire, four derived statuses on the screen."
Point at:
- The hero card and lifetime earnings count-up.
- The four sections in production order.
- The "Refresh" button next to the header.
- The green
Livepill next to the page title.
"That
Livepill is new in v2. It's an SSE connection to/api/events/activity. One connection per browser, shared across tabs viaBroadcastChannelso we never hold more than one socket open."
Click the floating Partner Simulator panel in the bottom-right.
- Pick the Uber Eats offer in the dropdown.
- Pick
attribution_verifiedas the event. - Click Fire webhook.
Watch the Needs attention card morph: status pill animates amber → green, the card slides into the Continue earning section, the connection pill pulses once on the incoming event.
"That POST went to
/api/webhooks/partner— HMAC-signed, idempotent on(partner_slug, idempotency_key). The route turns it into anActivityEvent, appends it to the in-memory log, and broadcasts it over SSE. React Query patched the cache without a refetch."
Point at the network tab if anyone asks: there is no tRPC call after the
webhook fires — only the SSE frame.
Open a second tab to the same URL. Fire another webhook from the simulator
in tab one (any offer + attribution_verified works, or use
reward_paid on a Continue earning card to push it to Rewarded).
Both tabs update at the same time.
"One leader tab holds the SSE; followers receive events over
BroadcastChannel. If you killed the leader tab, a follower would auto-promote on the next leader-poll tick — there's alocalStoragelease so we never end up with two open sockets."
Optional flex: open the Network panel in DevTools on the follower tab.
There is no open EventSource. Only the leader holds the connection.
Reload ?scenario=needs-attention&admin=1 so we have fresh Needs attention
cards to investigate.
Pick the Hulu+ Live TV card. Click the small Why is this stuck?
link beneath the title.
The drawer opens. Narrate:
"This is
claude-sonnet-4-6running with three things stacked: prompt caching on the system prompt + tool definitions, extended thinking with a 2000-token budget, and tool use over a streaming connection. All three are live in this drawer."
Watch the streaming order:
- Reading the event log (
queryOfferEvents) appears with a spinner, then a check mark. - Checking partner attribution (
queryPartnerStatus) appears next. This is the tool that surfaces the seededios_attribution_lag_24hissue. - (Optional, depending on the agent's plan:) Reviewing your history with
this partner (
queryUserOfferHistory) for additional context. - The final answer streams in, paragraph by paragraph, naming the iOS attribution lag and explaining why the offer hasn't moved.
- The footer surfaces a Recommended next step card with a primary button: Re-check attribution.
Click Re-check attribution.
"That just fired the same partner webhook we used in Act 2 —
attribution_verified. The drawer closes, the card moves to Continue earning, the agent's recommendation became user action became a real webhook became an event in the log. Round-trip in one click."
If ANTHROPIC_API_KEY is unset, point at the Demo mode subtitle in the
footer:
"When the key is missing we fall back to a recorded streaming response from
src/server/ai/anthropic.ts. The demo never dies; it just runs deterministically."
Open DevTools → Network → EventStream filter. Show the open SSE
connection.
If you have it handy, hit /api/trpc/deals.getActivityEvents?input=... in
a new tab to show the audit log:
"Every state change you just watched — partner webhooks, status transitions, the investigation completing — is here in
deals.getActivityEvents. Same procedure that powers the time-travel stretch goal. The UI is a projection of this log."
Optional flex: kill the dev server (or rolling-restart the Vercel
deployment), wait three seconds, restart. The Live pill goes amber,
then green. Any partner webhooks fired while the server was down replay
via Last-Event-ID on reconnect — the
SSE resume Playwright spec
exercises this on every CI run.
"Three swaps and we're at production. One: the in-memory event log becomes Postgres or Vercel Queues — same
appendEventAPI, different backing store. Two: the admin panel goes away and the partner webhook route checks a real per-partner HMAC secret, rotated through Vercel env. Three: the three scripted agent tools become real attribution-service clients. Everything else — the SSE shape, the React Query cache patching, the drawer, the recommended-action button — stays exactly the same."
"Built and deployed in twelve hours. Four PRs, green CI. The v2 plan documents every cut and trade-off."
| Act | URL |
|---|---|
| 1 (baseline) | ?scenario=mixed |
| 2 (partner push) | ?scenario=mixed&admin=1 |
| 3 (multi-tab) | Same URL in two tabs |
| 4 (investigation) | ?scenario=needs-attention&admin=1 |
| 5 (audit log) | DevTools → Network → EventStream |
Livepill stays amber → red: SSE didn't open. Check/api/events/activityin DevTools Network — should be 200 withContent-Type: text/event-stream. Most common cause is a Vercel preview with a misconfigured runtime; the prod deployment uses Fluid Compute defaults and is reliable.- Drawer hangs on "Investigating…": the streaming connection didn't
open. Hard-refresh and re-click; if that still hangs, unset
ANTHROPIC_API_KEYto forceDemo mode(deterministic, never blocks). - Webhook returns 401: the simulator signs the body with the demo
secret. If you changed
PARTNER_HMAC_SECRETin env, restart the dev server. - Cards don't morph after a webhook: check the connection pill — if it's amber, SSE is reconnecting and events queue until it opens.