# PRD: Real-Time Shift Backfill — SMS-First Emergency Coverage

> **Version:** v1
> **Generated:** 2026-05-14
> **Direction:** employee-scheduling-automation
> **Top Score:** 31/40 — BUILD

---

## 1. Problem & User

**Target User:** Restaurant, retail, and hourly workforce managers at single-location or small multi-location businesses (1–5 sites, 10–80 employees).

**Core Problem:** When an employee calls out sick 30 minutes before a shift, managers must personally phone or text a list of eligible workers, track who replied, handle overtime risks, and confirm coverage — all under time pressure. This takes 20–60 minutes of manager attention per incident and frequently results in understaffing. Broader workforce suites (HotSchedules, Deputy, 7shifts) require full platform adoption and monthly seats, which is too heavy for managers who only need urgent backfill solved.

**User Quote:** "员工临时请假无人顶替" — employees call out and no one covers the shift.

---

## 2. Target Outcome & KPIs

- Time to confirm shift coverage after call-out: **< 10 minutes** (vs. 20–60 min manual)
- Manager actions required per backfill event: **< 3 taps**
- Aha Moment timeline: first backfill offer sent within **3 minutes** of registration
- Free-to-paid conversion: **> 8%** within 14-day trial
- SMS reply-to-confirm rate: **> 40%** per broadcast (vs. phone tree ~20%)

---

## 3. MVP Scope (In)

- Web app (mobile-responsive, works in phone browser)
- Manager creates locations + employee roster (name, phone, role, availability flags)
- One-tap "Create Open Shift": date, time, role, short description
- System ranks eligible employees: availability match, no overtime risk, fair rotation
- Sends SMS offers to top N employees simultaneously
- Employee replies YES/NO via SMS; first YES confirms, others receive "Position filled" message
- Manager sees live dashboard: who was texted, who responded, coverage status
- Paywall: first 3 backfill events free, then $39/location/month
- Stripe subscription + 14-day trial after paywall

---

## 4. Out of Scope

- Native iOS/Android apps
- Full scheduling / shift-building (weekly schedule creation)
- Payroll or time-tracking integration
- Employee self-scheduling or swap requests
- Compliance rules (breaks, overtime calc) — v2
- Multi-location cross-transfer offers — v2
- AI schedule optimization — v2

---

## 5. User Flow (Happy Path)

1. Manager registers → onboarding: "Add your location and first 3 employees (name + phone + role)"
2. Employee calls out → manager taps "New Open Shift" → fills role + date/time + optional note
3. System calculates ranked list of eligible employees (role match, available, lowest recent backfill count)
4. Manager taps "Send Offers" → SMS blasts to top 5 eligible workers: "Open shift [time] at [location]. Reply YES to take it."
5. First employee replies YES → system replies "You're confirmed. See you at [time]!" → others get "Position filled, thanks!"
6. Manager dashboard flips to "Covered ✅" — incident closed
7. After 3rd free backfill → modal: "Upgrade for unlimited shift backfill at $39/location/month"

**Aha Moment:** Manager creates first open shift → taps Send Offers → within 60 seconds sees "Offers sent to 5 employees" on the live status board. The phone stops being the tool.

**Paywall Trigger:** 4th backfill event created → upgrade modal appears before Send Offers.

---

## 6. Functional Requirements (P0 Only)

### Auth & Onboarding
- Email/password registration (Supabase Auth)
- Onboarding wizard: create location → add ≥3 employees → create first open shift
- Free plan: 3 backfill events per location (no credit card)

### Employee Roster
- Add employee: name, phone (E.164), role (tag), availability (days of week checkboxes)
- Edit / deactivate employees
- Track backfill history count per employee (for fairness ranking)

### Open Shift Creation
- Fields: role (select from roster roles), date, start time, end time, optional note
- Auto-rank eligible employees: role match + available day + lowest `backfill_count`
- Show ranked list to manager before sending

### SMS Backfill Flow
- Send SMS via Twilio to top 5 (configurable N) ranked employees simultaneously
- Parse inbound Twilio webhook: if `Body = "YES"` and shift still open → confirm that employee, send filled messages to others, update shift `status = covered`
- If no YES within 60 min → manager notified via email to try next batch

### Live Dashboard
- Open Shifts list: status (Pending / Covered / Expired), role, time, who confirmed
- Per-shift detail: who was texted, response status (Sent / Yes / No / No-Response)
- Employee roster view with backfill count

### Subscription
- Stripe Checkout ($39/location/month, 14-day trial)
- Block 4th event: show upgrade modal
- Webhook: `customer.subscription.created` → unlock location

---

## 7. Data Model (Minimal)

```
users (id, email, stripe_customer_id, created_at)
locations (id, user_id, name, plan, trial_ends_at, backfill_count)
employees (id, location_id, name, phone, role, availability jsonb, backfill_count, active)
open_shifts (id, location_id, role, shift_date, start_time, end_time, note, status, confirmed_employee_id, created_at)
backfill_offers (id, open_shift_id, employee_id, status, sent_at, responded_at)
```

---

## 8. API / Integration Notes

- **Twilio**: Send SMS via REST API; receive inbound replies via webhook `POST /api/twilio/inbound`
- **Supabase**: Auth, Postgres, real-time subscriptions for live dashboard updates
- **Stripe**: Subscription with 14-day trial; webhook `customer.subscription.created`
- **Email (Resend)**: Manager notification if no coverage after 60 min
- **Cron**: Check open shifts older than 60 min with no confirmation → trigger email alert

---

## 9. Acceptance Criteria

- [ ] `POST /api/open-shifts` creates shift, returns ranked eligible employee list
- [ ] `POST /api/open-shifts/[id]/send` triggers Twilio SMS to top 5 employees
- [ ] Twilio inbound webhook `POST /api/twilio/inbound` with `Body=YES` confirms shift, sends "filled" SMS to others
- [ ] Dashboard reflects `status = covered` within 5 seconds of YES receipt (Supabase real-time)
- [ ] 4th open shift blocked with upgrade modal for free-plan locations
- [ ] Stripe trial subscription purchase → `locations.plan = pro`, event limit removed
- [ ] 60-min no-response cron → manager receives email notification

---

## 10. Delivery Plan

### Milestone 1 — Auth + Roster + Open Shift (Day 1–2)
**Files to create:**
- `app/api/auth/` — Supabase Auth setup
- `app/api/locations/route.ts` — create, get
- `app/api/employees/route.ts` — CRUD, availability
- `app/api/open-shifts/route.ts` — create, list, rank algorithm
- `app/onboarding/page.tsx` — wizard (location → employees → first shift)
- `prisma/schema.prisma` — all tables

**Exit criteria:** `POST /api/open-shifts` returns ranked employee list; dashboard shows open shift card.

### Milestone 2 — SMS Flow + Live Dashboard (Day 3–4)
**Files to create:**
- `app/api/open-shifts/[id]/send/route.ts` — Twilio blast
- `app/api/twilio/inbound/route.ts` — YES/NO parse + confirm logic
- `app/dashboard/page.tsx` — open shifts + offer status table (Supabase real-time)
- `lib/twilio.ts` — SMS send + inbound parse helpers

**Exit criteria:** SMS sent to test numbers; replying YES updates shift to Covered; dashboard updates in real-time without reload.

### Milestone 3 — Paywall + Cron + Deploy (Day 5–6)
**Files to create:**
- `app/upgrade/page.tsx` — Stripe Checkout for subscription
- `app/api/webhooks/stripe/route.ts` — subscription activation
- `app/api/open-shifts/route.ts` (update) — free plan gate at 4th event
- `app/api/cron/no-response-alert/route.ts` — 60-min timeout email
- `vercel.json` — cron schedule

**Exit criteria:** 4th shift blocked with modal; Stripe purchase removes limit; no-response email arrives at test address 60 min after unanswered shift.

---

## 11. Risks & Mitigations

| Risk | Mitigation |
|------|-----------|
| Twilio SMS costs erode margin | Include $5/mo SMS bundle in base price; show usage meter in dashboard |
| Employees reply in non-standard format (e.g. "yes please") | Normalize: lowercase, trim, match `yes`/`y`/`1`; fallback to manager confirmation |
| Spam filter blocks SMS from unknown number | Use Twilio verified sender + pre-register as A2P 10DLC |
| Real-time updates fail on poor mobile connection | Supabase real-time + 30s polling fallback |

---

## 12. Chargeability Rationale

Each prevented understaffed shift saves a restaurant or retail location an estimated $200–500 in lost sales and overtime — the $39/month subscription pays for itself in the first covered shift of the month.

**Free tier:** 3 backfill events — enough to experience the full SMS workflow and see the dashboard before paying.
**Paid tier:** Unlimited events + 60-min alert + team access. Paywall triggers at the 4th event, when the manager has already lived through the Aha Moment.
**PLG flywheel:** Every SMS an employee receives says "Sent via ShiftFill" — organic brand exposure to every worker on the roster.
