ℹ️
Note: The hosted demo at specialoffer-demo.fly.dev runs on a shared Fly.io instance with an in-memory event store. Data resets on server restart. Performance may vary slightly from a local instance — projections may take a moment longer to update. If an action doesn't reflect immediately, wait 1–2 seconds and refresh.
Opening — 30 seconds
“SpecialOffer.com is a membership platform for verified professionals. Think of it as the intersection of LinkedIn's trust layer and a premium marketplace — doctors, lawyers, and high-net-worth individuals get curated offers from partners who want to reach exactly these audiences. Partners pay for access. Members get value. Everyone wins.”
“I'm going to walk you through three stories that show what this platform does. Everything you're about to see is a working proof of concept — real code, real data flows, real-time.”
Story 1
“The Velvet Rope”
How a verified professional discovers, applies to, and enters the platform
~3.5 minutes
Before we bring a member in, let me show you the operations center — this is what powers everything behind the scenes.
- Open Admin UI at
https://specialoffer-demo.fly.dev/admin (or http://localhost:3000/admin)
- Dashboard: point out Platform Overview (active members, offers, partners), Recent Activity feed showing live events
- Click Domains — three configured domains: Medical, Legal, HNW. Point out domain types (PROFESSIONAL vs LIFESTYLE), specialties, career stages, completeness %
- Click Offers — 16 offers from 12 partners, each targeted to specific domains and tiers
Career stages, life moments, verification methods — these all drive personalization downstream. Adding a new domain is configuration, not code.
Now let's bring a member in →
The application form is domain-aware. Every dropdown, every option comes from the domain configuration we just saw in admin.
- Click “Accept Invitation”
- Application form loads — point out domain-aware dropdowns: specialties, practice types, career stages all populated from the Medical domain config
- Show geography fields (country → state → city cascade)
- Show tier selection: Free Vetted (default) vs Founders Club (premium)
- Fill in the form and submit
If this were the Legal domain, the specialties would be “Corporate Law”, “Litigation”, etc. The platform adapts automatically.
Now the admin takes over →
Story 2
“The Platform Learns”
How behavioral intelligence transforms a blank profile into personalized recommendations
~5 minutes
Story 3
“One Platform, Many Worlds”
How domain architecture creates distinct experiences and how partners see their ROI
~4 minutes
Three domains, three different worlds. Adding Accounting is configuration — specialties, career stages, verification methods, partner categories. No code changes.
- Switch to Admin → Domains page
- Show three domains side by side: Medical (PROFESSIONAL), Legal (PROFESSIONAL), HNW (LIFESTYLE)
- Click into Medical — show specialties, career stages, verification methods, completeness
- Point out domain type: PROFESSIONAL vs LIFESTYLE
- Note: “Want to add Accounting? Create a domain, configure its specialties and career stages, activate it. The platform handles offer targeting, personalization, and partner matching automatically.”
Now let's see how domain types control visibility →
Professional domains are walled — doctors don't see lawyers' offers. But lifestyle offers like HNW are visible across boundaries. Everyone can see them; Founders Club members can unlock them.
- Return to Dr. Priya Sharma's dashboard — she sees Medical offers AND HNW lifestyle offers (gold “Premium Lifestyle” badge)
- Point out: Founders Club offers show as “Founders Club Exclusive” and are locked for Free Vetted members
- Compare: Victoria (HNW member) saw only HNW offers — no Medical, no Legal
Professional offers are walled by domain. Lifestyle offers cross boundaries. Tier gates control premium access. Three rules, infinite flexibility.
Finally, the partner's perspective →
Epilogue
“Under the Hood”
The architecture that makes it all work — and the path forward
~2 minutes
Anticipated Questions
How is this different from just a marketplace? ▶
Two things: the velvet rope and the intelligence layer. Members are verified professionals — you can't just sign up. And every interaction teaches the platform, so partners get increasingly precise targeting over time. It's not a billboard. It's a concierge.
How do you make money? ▶
Three streams: partner commissions on conversions, Founders Club membership fees, and strategic data monetization — aggregated, anonymized insights on professional behavior and spending patterns. The verified membership base makes that data uniquely valuable.
How does the personalization work? ▶
Behavioral signals (clicks, dwell time, partner visits) are recorded with consent and fed into an affinity scoring engine. Each offer category gets a 0-100 affinity score based on weighted, time-decayed signals. The offer feed sorts by affinity, and “Recommended” badges appear on categories with high scores. No ML models — it's a transparent, rule-based system that adapts in real-time.
What about privacy? ▶
Full consent lifecycle — grant, manage preferences, withdraw. Tracking is consent-gated at the domain layer — no signals are recorded until the member explicitly opts in. Three separate toggles: behavioral, geographic, and third-party sharing. Members can withdraw consent at any time via the “Privacy” link in the nav, which anonymizes all behavioral signals (memberId replaced with a deterministic hash — aggregate analytics preserved), resets the behavioral profile to zero, and stops personalization immediately. Members can re-consent and start fresh at any time. The ConsentWithdrawn event is immutable and auditable. Server-authoritative consent (not localStorage). Architecture supports PIPEDA (Canada), GDPR (Europe), and CCPA (US) consent models.
How fast can new domains be added? ▶
Configuration, not development. A new domain — specialties, career stages, verification methods, partner categories — can be stood up in the admin console. The platform handles offer targeting, personalization, and partner matching automatically.
How does partner tracking work? ▶
Two mechanisms: (1) outbound redirects through https://specialoffer-demo.fly.dev/go/{offerId} record a PARTNER_VISIT signal before redirecting to the partner site, and (2) a 1x1 tracking pixel at https://specialoffer-demo.fly.dev/api/track/pixel.gif embedded on partner pages fires a PARTNER_PIXEL signal on load. No cookies, no JavaScript — just HTTP requests. These are high-weight signals (7 and 4 respectively) because they indicate strong purchase intent.
How does this scale? ▶
The CQRS pattern means reads and writes scale independently. Read models are denormalized PostgreSQL — fast queries with no joins. The event store handles append-only writes. In production, EventStoreDB handles millions of events, and read models can be rebuilt from the event stream at any time. The in-process event bus swaps to SNS/SQS for distributed processing.
What about the other modules? ▶
The Blueprint specifies 9 modules. This PoC implements the 5 core modules (Domain Config, Membership, Offers, Partners, Member Profile & Career Journey) plus Tiering, the member portal, partner portal, and admin UI. The remaining modules (Rewards, Analytics, Content, Affiliates) follow the exact same patterns — the architecture is proven.
How long to production? ▶
Three phases: Day 1–60 (core modules — largely proven here), Day 60–90 (growth enablers), Day 120–180 (scale and differentiation). The PoC de-risks the hardest part — proving the architecture works end-to-end with real event sourcing, CQRS projections, and multi-domain configuration.
Troubleshooting
Page loads slowly or shows error (Fly.io)
The Fly.io instance may be waking up from sleep (auto-stop is enabled). Wait 10–15 seconds and refresh. The first request after idle wakes the machine.
Data seems stale or members are missing (Fly.io)
The in-memory event store resets on server restart. The hosted instance is re-seeded on each deployment. If data looks wrong, it may have been reset — start fresh from the Member Directory.
Signals or affinities not updating (Fly.io)
On the hosted instance, projection timing may be slightly slower than local. Wait 2–3 seconds after an action before checking results. Refresh the page if needed.
Member Directory empty
Seed hasn't run or server restarted without re-seeding. Run npm run restart to rebuild and re-seed locally. On Fly.io, the instance re-seeds automatically on deploy.
No “Recommended” badges or personalization on offers
Member hasn't granted behavioral consent yet, or no signals have been recorded. Accept the consent banner first, then browse some offers. Wait 5 seconds for signal batching to flush.
Consent banner doesn't appear
Only shows for ACTIVE members. Ensure the member is fully activated (not just approved). If consent has already been granted, use the “Privacy” nav link to manage preferences, or withdraw consent to see the banner again. Consent is server-authoritative — clearing browser data does not affect consent status.
Partner mock page doesn't load
Ensure you're clicking the “Visit [Partner]” link from an offer detail page. The /partner-demo/{slug} routes require offer and member query params.
Status page stuck on “Under Review”
Admin needs to both Approve AND Activate the member. Check the Members tab → Review Queue in admin.
Events not appearing in stream
SSE connection may have dropped. Refresh the Event Stream page. Check that the backend is running.
Build or deploy issues
Run npm run restart for a clean local rebuild. For Fly.io, use npm run deploy:fly which handles the full pipeline.
“Privacy” link not visible in nav
Member must be active (ACTIVE status). The link doesn't appear on the directory, invitation, application, or status pages. Switch to a pre-seeded member to see it.
Consent withdrawal doesn't seem to work
Check that the member has active consent first — you can't withdraw what isn't granted. After withdrawal, hard-refresh the page (Ctrl+Shift+R) if the dashboard still shows old personalization.