Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ DIRECT_DATABASE_URL=

# Clerk
# Required in production
# For local development, use Clerk test/dev keys that allow localhost redirects.
# Production-domain-restricted keys can trigger browser console origin errors on http://localhost:3000.
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
Expand Down Expand Up @@ -46,8 +48,8 @@ FOUNDER_CLERK_USER_ID=
RESEND_API_KEY=
CALLBACKCLOSER_FROM_EMAIL=

# Optional public simulator
# Keep these disabled in production unless the public simulator is intentionally enabled.
# Optional legacy backend simulator tooling
# The current public /simulator page is self-contained and does not require these values.
ENABLE_PUBLIC_MISSED_CALL_SIMULATOR=
SIMULATOR_BUSINESS_ID=
ENABLE_PUBLIC_SIMULATOR_REAL_SMS=
Expand Down
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ When a customer calls a business's Twilio number and the forwarded call is misse
- Twilio SMS webhook (`/api/twilio/sms`) with lead qualification steps
- Qualified-lead delivery with idempotent SMS/email/in-app owner notifications
- Lead dashboard + filters + lead detail transcript + status updates
- Public missed-call simulator (`/simulator`) with isolated demo lead runs
- Public missed-call simulator (`/simulator`) with a self-contained interactive preview flow
- Stripe billing page + checkout + billing portal
- Public purchase entry route (`/buy`) for external marketing-site links
- Stripe webhook sync for subscription status gating
Expand Down Expand Up @@ -74,10 +74,14 @@ Required categories:
- Stripe keys + price IDs + webhook secret
- Twilio credentials + webhook auth token
- Optional owner email delivery (`RESEND_API_KEY`, `CALLBACKCLOSER_FROM_EMAIL`)
- Optional public simulator config (`ENABLE_PUBLIC_MISSED_CALL_SIMULATOR`, `SIMULATOR_BUSINESS_ID`, `ENABLE_PUBLIC_SIMULATOR_REAL_SMS`)
- Database URL
- Optional rate-limit tuning vars (defaults are built in)

Local note:

- Use Clerk test/dev keys for localhost work.
- If you point `.env.local` at production-domain-restricted Clerk keys, public pages can still render, but Clerk will log browser origin errors on `http://localhost:3000`.

### 4. Run Prisma migrations / generate client

This repo includes a Prisma migration at `prisma/migrations/20260222000000_init/migration.sql`.
Expand Down Expand Up @@ -150,6 +154,7 @@ Turn it off after smoke testing by unsetting `ALLOW_FOUNDER_BILLING_BYPASS` or s
- `https://YOUR_DOMAIN/sign-in`
- `https://YOUR_DOMAIN/sign-up`
4. Ensure your app origin(s) are allowed in Clerk.
5. For localhost development, prefer Clerk test/dev keys. Production keys that are locked to `callbackcloser.com` will reject browser requests from `http://localhost:3000`.

## Stripe Setup (Required)

Expand Down Expand Up @@ -374,11 +379,15 @@ What it demonstrates:

Simulator safety:

- The simulator is enabled only when `ENABLE_PUBLIC_MISSED_CALL_SIMULATOR=true`
- It uses the business identified by `SIMULATOR_BUSINESS_ID`
- Simulator records are isolated with `Lead.isSimulator`, `Call.isSimulator`, `Message.isSimulator`, and `SimulatorRun`
- Owner notifications for simulator runs are stored as preview records and do not send to real customer destinations
- If `ENABLE_PUBLIC_SIMULATOR_REAL_SMS=true`, the simulator can send the caller-side SMS to the supplied demo number, but owner delivery remains simulated
- The public `/simulator` page is self-contained and does not require Twilio, login, or backend simulator config
- No real SMS is sent and no Twilio calls are made
- Public visitor input stays inside the browser demo and does not create customer-facing records
- Caller numbers are masked in the UI before the owner-alert preview is shown

Legacy internal simulator backend:

- The repo still includes isolated simulator-record models and env flags for internal/admin demo tooling
- Those flags are not required for the current public `/simulator` experience

Creating a dedicated simulator workspace:

Expand Down Expand Up @@ -474,7 +483,7 @@ Use this checklist before sending paid traffic to `callbackcloser.com` or allowi
- `/privacy` - privacy policy
- `/refund` - refund policy
- `/contact` - public support/contact page
- `/simulator` - public missed-call simulator
- `/simulator` - public interactive missed-call simulator
- `/sign-in` - Clerk sign-in
- `/sign-up` - Clerk sign-up
- `/app/onboarding` - create business record
Expand Down
30 changes: 16 additions & 14 deletions app/demo/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ export default function DemoPage() {
</p>
</div>
<div className="flex flex-wrap gap-3">
<Link className={buttonVariants({ size: 'lg' })} href="/contact">
Want this running on your number?
<Link className={buttonVariants({ size: 'lg' })} href="/simulator">
Try the interactive simulator
</Link>
<Link className={buttonVariants({ size: 'lg', variant: 'outline' })} href="#demo-workspace">
See it in action
See the quick overview
</Link>
</div>
<p className="text-sm text-muted-foreground">Get this live on your number fast, without changing how your team already works.</p>
<p className="text-sm text-muted-foreground">
This page is the fast visual walkthrough. The simulator lets you reply like the caller and see the full handoff yourself.
</p>
<p className="text-xs text-muted-foreground">Demo only: fake business, fake callers, and no live customer or Twilio data.</p>
</div>

Expand Down Expand Up @@ -103,7 +105,7 @@ export default function DemoPage() {

<section className="container space-y-8 py-12" id="demo-workspace">
<div className="max-w-2xl space-y-3">
<Badge variant="outline">Live-looking product view</Badge>
<Badge variant="outline">Quick overview</Badge>
<h2 className="text-3xl font-semibold tracking-tight">Here&apos;s what happens after a missed HVAC call</h2>
<p className="text-muted-foreground">
They call. You miss it. We text them right away, ask what they need, and send you the lead while they&apos;re still ready to book.
Expand Down Expand Up @@ -220,11 +222,11 @@ export default function DemoPage() {
<p className="mt-4 text-sm text-muted-foreground">{demoOwnerAlert.summary}</p>
</div>
<div className="flex flex-wrap gap-3">
<Link className={buttonVariants()} href="/contact">
Want this on your business?
<Link className={buttonVariants()} href="/simulator">
Try the interactive simulator
</Link>
<Link className={buttonVariants({ variant: 'outline' })} href={PUBLIC_START_FREE_PILOT_PATH}>
See it on your number
Start 14-Day Pilot
</Link>
</div>
</CardContent>
Expand Down Expand Up @@ -257,17 +259,17 @@ export default function DemoPage() {
<div className="container space-y-6 py-16 text-center">
<Badge variant="outline">Close with a demo, not a long explanation</Badge>
<div className="space-y-3">
<h2 className="text-3xl font-semibold tracking-tight sm:text-4xl">Want this on your business?</h2>
<h2 className="text-3xl font-semibold tracking-tight sm:text-4xl">Ready to try the missed-call flow yourself?</h2>
<p className="mx-auto max-w-2xl text-muted-foreground">
We can set it up on your number and get you live fast.
Use the simulator for the hands-on experience, then start a pilot when you&apos;re ready to put it on your number.
</p>
</div>
<div className="flex flex-wrap items-center justify-center gap-3">
<Link className={buttonVariants({ size: 'lg' })} href={PUBLIC_START_FREE_PILOT_PATH}>
See it on your number
<Link className={buttonVariants({ size: 'lg' })} href="/simulator">
Try the interactive simulator
</Link>
<Link className={buttonVariants({ size: 'lg', variant: 'outline' })} href="/contact">
Book a quick setup call
<Link className={buttonVariants({ size: 'lg', variant: 'outline' })} href={PUBLIC_START_FREE_PILOT_PATH}>
Start 14-Day Pilot
</Link>
</div>
</div>
Expand Down
6 changes: 6 additions & 0 deletions app/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 0 additions & 115 deletions app/simulator/actions.ts

This file was deleted.

Loading
Loading