# Milestone 1 — Implementation Notes

## What's included
- Multi-tenant core: subdomain resolution (`ResolveTenant`), request-scoped
  `Tenancy` singleton, `BelongsToTenant` trait (global scope + auto-fill).
- Clinic signup: tenant + owner (clinic_owner role) + trialing subscription
  in one transaction; redirects to the new subdomain already signed in
  (session cookie spans `.central-domain`).
- Auth: Fortify (login, password reset, TOTP 2FA with recovery codes),
  tenant-scoped credential lookup, login history, rate limiting.
- RBAC: Spatie roles seeded (super_admin, clinic_owner, dentist,
  receptionist) with the M2+ permission vocabulary already defined.
- Subscription gate: `EnsureSubscriptionIsActive` middleware implementing
  trialing/active → grace (banner) → suspended (billing wall).
- Single plan seeded: $35.00 / 50,000 IQD, 14-day trial, limits JSON.
- Bilingual UI: ar (RTL) + en, session-persisted `?lang=` switch, dark mode.
- `php artisan medibook:install` — env checks, migrate, seed, super admin.
- Tests: tenancy isolation + signup lifecycle.

## Deliberate M1 boundaries
- Billing screen is read-only (gateways are M6). The subscription state
  machine and gate are final, so M6 only adds payment entry points.
- Spatie `teams` mode is off; roles are global names, assignments are
  per-user. Permission checks always run inside a resolved tenant, and the
  super-admin bypass lives in `Gate::before`.
- Email verification intentionally skipped at signup (regional reality:
  WhatsApp-first users); phone is captured for M5 messaging.

## Conventions the next milestones must follow
- Every tenant-owned model uses `BelongsToTenant`. Never query with
  `withoutGlobalScope('tenant')` outside admin/console contexts.
- All money in integer minor units; all timestamps UTC.
- New translatable strings: English literal as the key + `lang/ar.json` entry.
