# Milestone 6 — SaaS Billing (Implementation Notes)

The monetization layer: trials, demo, soft limits, multi-channel expiry
notices, a fully audited manual-payment workflow, and the super-admin
financial console.

## Subscription lifecycle
`SubscriptionService` owns trialing → active → grace → suspended (and cancel),
keeping `tenants.status` in lockstep with `subscriptions.status`. A daily sweep
(`medibook:subscriptions --lifecycle`, 00:30) moves expired subs to a
configurable grace window, then to suspended. Paying early **stacks** from the
later of now / current period end. MRR is normalized to a single monthly-IQD
column per active sub so the dashboard sums one field.

## 1 · 14-day trial, no card
Signup creates a `trialing` subscription with `current_period_ends_at = now +
trial_days`; no payment method is collected. A `trial.started` activity event
is logged.

## 2 · Demo clinic
`php artisan medibook:demo [--fresh]` builds a self-contained, `is_demo`
evaluation clinic (2 dentists + schedules, 3 patients, chart records,
procedures + templates, 5-year trial). Demo data is excluded from all metrics.
Login: demo@medibookai.com / demo12345.

## 3 · Soft usage limits
`UsageService` tracks monthly WhatsApp messages (counter) and computes live
storage (MB from `patient_files.size`), staff seats, and dentist seats against
plan limits. Levels: ok / warn (≥80%) / over (≥100%). **Never hard-blocks** —
banners in the app shell and meters on the billing page nudge an upgrade.

## 4 · Multi-channel expiry notifications
`ExpiryNotifier` fires a ladder (7/3/1 days before end), each milestone once
per subscription (tracked in `subscriptions.expiry_notified`), across three
channels simultaneously: in-app (database notifications + bell badge), email
(`SubscriptionExpiringNotification`), and WhatsApp (system message to the
owner). Copy is trial-aware. Runs daily at 09:00 (`--notify`).

## 5 · Manual payment workflow + audit trail
Owners upload a Zain Cash / SuperQi receipt (`billing.proof`); a
`subscription_payments` row is created (pending). Super-admins work an approval
queue (filter by status), open a payment to view the proof image/PDF, and
approve / reject / request-info. **Two complementary trails:**
`payment_proof_reviews` (per-payment: who, when, from→to, note, IP) and the
unified `activity_logs` stream. Approval extends the period and reactivates
access in one transaction.

## 6 · Super-admin financial dashboard
MRR, ARR, active/trial/grace/suspended/cancelled counts, **expiring-within-7-
days** (count + action table), monthly churn, trial→paid conversion, a 6-month
revenue chart, **MRR by gateway**, and **revenue by payment method**. Pending-
proof alert links into the queue. A dedicated super-admin layout (not the
tenant sidebar).

## 7 · MRR tracking
`subscriptions.mrr_iqd` is set on activation and zeroed on suspend/cancel;
`recalcAllMrr()` runs after any plan price edit so the figure never drifts.

## 8 · Churn & active metrics
`MetricsService::churnRate()` = cancellations this month / (active +
cancelled-this-month). `trialFunnel()` reports started / converted / expired +
rate, backed by `tenants.subscription_converted_at`.

## Activity log (every billing action)
`ActivityLogger` writes an append-only `activity_logs` entry for
trial.started, trial.converted, trial.expired, subscription.activated/grace/
cancelled, and payment.submitted/approved/rejected/info_requested — viewable
under Admin → Activity, filterable by category.

## Plan management
Super-admins edit the single plan's USD + IQD price and trial days; saving
recalculates MRR across active subscriptions.

## Scheduler (add to cron)
```
medibook:subscriptions --lifecycle   daily 00:30
medibook:subscriptions --notify      daily 09:00
```
(plus the M5 whatsapp:dispatch entries). Run `php artisan queue:work`.

## Tests (33 new)
Lifecycle (grace/suspend/stack/reactivate), payment approval (audit trail +
endpoints + double-approve guard), usage (levels, never-blocks), metrics
(MRR/counts/churn/revenue/gateway), expiry ladder (fires once, multi-channel),
demo (build/exclude/rebuild), activity log (events + conversion), owner usage
panel (staff/dentist/storage meters + billing page KPIs).
