Owner: Growth / Sales Ops (eng: Platform team) | Review: Quarterly
This is the ongoing operating procedure — for go-live instructions see the Runbook.
Pipeline overview
A visitor books a 30-minute demo on Cal.com → Cal fires a webhook → SmartPRO creates a DB row and starts the automated lifecycle:
- Booking created → sales notification email, row in admin console
- Reminder job (every 30 min) → sends RSVP email before each demo
- No response → chaser emails up to
DEMO_REMINDER_MAX (default 2)
- RSVP clicked →
confirmation_status recorded (confirmed / declined)
- Meeting starts → Cal
MEETING_STARTED webhook sets attended_at
- Meeting ends → recap email (attended) or reschedule email (no-show)
- Cancelled → re-engage / reschedule email
Admin console
Route: /admin/demo-bookings (admin role required)
| Column |
What it shows |
| Lead |
Name, email, UTM source, lifecycle chips |
| Slot |
Date/time, duration, "Today" chip if same day |
| Status |
Booking status from Cal (active / cancelled / rescheduled) |
| Disposition |
Sales pipeline stage (New → Contacted → Attended → Qualified → Converted / Lost) |
| Meeting |
Join link, recording link (once available) |
Disposition values
| Value |
Meaning |
| New |
Just booked, no contact yet |
| Contacted |
Sales has reached out |
| Attended |
Showed up to the demo |
| No-show |
Missed the meeting |
| Qualified |
Fit confirmed, moving forward |
| Converted |
Signed up / became a customer |
| Lost |
Not moving forward |
Update disposition inline from the dropdown in each row. Notes expand below the row (red dot = notes exist).
Lifecycle email map
| Trigger |
Email |
Recipient |
| Booking created |
Sales notification |
SALES_NOTIFICATION_EMAIL |
| ~24 h before meeting |
Reminder + RSVP |
Lead |
| No RSVP after gap |
Chaser |
Lead |
| Post-meeting (attended) |
Recap + recording |
Lead |
| Post-meeting (no-show) |
"Sorry we missed you" + reschedule |
Lead |
| Cancelled |
Re-engage / reschedule |
Lead |
Failure modes
| Symptom |
Likely cause |
Fix |
| Booking doesn't appear |
Webhook not reaching server / wrong secret |
Check CAL_WEBHOOK_SECRET, Cal webhook logs |
| No reminder emails |
RESEND_API_KEY missing or job disabled |
Check env + DISABLE_DEMO_LIFECYCLE_JOBS |
| RSVP link broken |
PUBLIC_APP_URL not set |
Set env var to https://www.thesmartpro.io |
| Everyone shows "No-show" |
MEETING_STARTED trigger not enabled in Cal |
Enable in Cal dashboard |
| Recap not sending |
recap_sent_at already set (idempotent) |
Check DB row directly |
Key files
| File |
Purpose |
server/demoWebhooks.ts |
Webhook handler (POST /api/webhooks/cal) + Cal event parsing |
server/jobs/demoLifecycle.ts |
Reminder + recap/no-show jobs |
server/demoBookingPublicRoutes.ts |
Tokened RSVP confirm/decline route |
server/routers/platformOps.ts |
listDemoBookings + updateDemoBooking tRPC procedures |
client/src/pages/admin/DemoBookingsPage.tsx |
Admin console UI |
| Demo Booking Runbook |
Go-live checklist |