# BEEB BEEB (بيب بيب) — Complete Feature List & Cursor Execution Plan

> **Project:** BEEB BEEB — Electric scooter sharing platform (Saudi Arabia)
> **Source:** SRS v1.2 (92 pages) + Figma screens (Rider app + Investor dashboard)
> **Products:** Rider Mobile App · Investor Dashboard (web) · Admin Panel (web) · Shared Backend/API
> **Identity:** Yellow + dark theme · duck mascot · Arabic (RTL)
> **Document purpose:** (1) a complete, structured feature inventory, and (2) a fully detailed, sequenced build plan written to be executed task-by-task inside **Cursor**.
> **Repo baseline:** Forked from team **`codebase`** (Laravel 9 marketplace starter). BEEB domain (scooters, rides, settlements) is **not built yet** — reuse auth, wallet, admin shell, then refactor away marketplace-specific code.

---

## How to use this document in Cursor

1. **Repo:** `beeb` — **Laravel 9** monolith: Blade admin at `/admin/*`, JSON API at **`/api/client/*`** and **`/api/provider/*`** (no `/api/v1` prefix today). Do **not** use Turborepo/NestJS or greenfield a second backend.
2. Start at **Part 4 → Phase 0** (including **`T-0.0` legacy cleanup**) and work top to bottom. Phases are ordered by dependency.
3. Each task has: **Goal**, **Reuses**, **Files/Folders**, **Acceptance criteria**, and a **Ready-to-paste Cursor prompt** (`🟡 Cursor:`).
4. Prefer existing patterns: `app/Services/Entity/*`, `app/Services/Auth/AuthenticationService`, `routes/api.php` + `routes/api/client.php`, admin routes in `routes/dashboard/*.php`.
5. Mark `[x]` / `[~]` / `[ ]` on checklist items as you complete them. Don't skip acceptance criteria.
6. Add `docs/SRS.md` when you have the SRS file; reference it and this doc in prompts. Add `.cursor/context/domain-context.md` when you set up Cursor rules (not in repo yet).
7. **Actor mapping (SRS product name → Laravel model):**

| SRS / Figma | Laravel model | API prefix (current) | Admin module (current) |
|---|---|---|---|
| **Rider** (rider app) | **`Client`** | `/api/client/*` | `admin/clients` (`A-RIDER-*`) |
| **Investor** (investor dashboard) | **`Provider`** | `/api/provider/*` | `admin/providers` (`A-INV-*`) |
| Staff | **`Admin`** | session `/admin` | Admins + RBAC |
| Scooter | **`Scooter`** *(to add)* | — | Fleet *(to add)* |
| Ride | **`Ride`** *(to add)* | — | Rides *(to add)* |

Use **Client** / **Provider** in all code, migrations, services, and routes. Keep **Rider** / **Investor** only when referencing SRS feature IDs (`R-*`, `I-*`) or product/UI copy.

### Implementation snapshot (repo audit — 2026-06-03)

| Area | Status | Notes |
|---|---|---|
| Client OTP auth + profile | **[~]** | `routes/api.php` + `Api\Client\AuthController`, `AuthenticationService`, `AuthOtp` |
| Client wallet API | **[~]** | Morph wallet on `Client`; `GET/POST /api/client/wallet*` — extend types for rides |
| Provider KYC register | **[~]** | `POST /api/provider/register` multipart (`RegisterRequest`, `ProviderRegistrationService`) → `is_approved: null`; no register OTP |
| Provider login | **[x]** | `POST /api/provider/login` — **email + password** (`I-AUTH-01` / `provider-login.png`); no `verify-login` for provider |
| Provider forgot password | **[~]** | `Api\Provider\ForgetPasswordController` + **email** OTP (`password/*` in `api.php`) |
| Provider profile / phone / email / notifications | **[x]** | Shared `routes/api.php` provider group (Sanctum + `is-active`) |
| Admin clients / providers CRUD | **[x]** | `Admin\ClientController`, `Admin\ProviderController` — adapt columns/workflows for KYC |
| Wallet + transactions (DB) | **[x]** | `wallets`, `wallet_transactions`, `WalletTransactionType` enum (marketplace types) |
| App onboarding slides | **[x]** | `AppIntro` + `GET /api/client/app-intro` → reuse for `R-AUTH-02` |
| FAQ / pages / settings | **[x]** | `fqs`, `pages`, `SettingService` |
| Notifications + FCM | **[~]** | `NotificationService`, `nodeServer/` (Socket.IO + FCM) |
| Payments | **[~]** | `HyperpayService`, `PaymentService`, `payment_transactions` — wire to wallet top-up |
| Scooters, rides, billing, settlements | **[ ]** | Core BEEB domain — Phase 0–4 |
| Provider investor dashboard API | **[x]** | `routes/api/provider.php` — home, vehicles, earnings, transactions, CSV export |
| Provider KYC columns | **[x]** | `national_id`, `iban`, `vehicle_count`, KYC images, `profit_rate`; approval via `is_approved` |
| BEEB enums (full set) | **[ ]** | Phase 0 |
| `docs/SRS.md`, Cursor context | **[ ]** | Phase 0 |
| Admin BEEB theme (yellow/dark) | **[ ]** | Phase 0 |
| Postman Provider folder | **[~]** | `scripts/postman/definitions.php` — sync via `php scripts/build-and-sync-postman.php --sync` |

---

# PART 1 — Project Overview

BEEB BEEB is a self-service electric-scooter rental system. A rider opens the app, finds the nearest available scooter on a map, scans its QR code to unlock, rides, then ends the trip and parks. Billing is **prepaid-wallet first**: a ride can only start if the wallet has sufficient balance (or an active subscription), and the fare is auto-deducted when the trip ends.

The platform has **three front-end products on one shared backend**:

| Product | Users | Platform | Auth | Core mode |
|---|---|---|---|---|
| **Rider App** | End riders | iOS + Android (mobile) | Phone OTP | Action-heavy, on-the-go |
| **Investor Dashboard** | Fleet investors | Responsive web | Email + password | Read-heavy analytics |
| **Admin Panel** | BEEB BEEB staff | Desktop-first web | Email + password + 2FA | Full operational control |

**Core principles (from SRS):** Status-Driven system · Real-time tracking · Wallet-first · Auto-charge & auto-lock · Full audit trail · RBAC.

---

# PART 2 — Complete Feature List

Each feature has a stable ID so tasks in Part 4 can reference it (e.g. `R-RIDE-03`).

## 2.1 Rider Mobile App (prefix `R-`) — *implemented as **`Client`** API*

### Onboarding & Auth (`R-AUTH`)
- `R-AUTH-01` Splash screen (logo + scooter, 2–3s auto-advance).
- `R-AUTH-02` Onboarding carousel (3 slides with dot indicators).
- `R-AUTH-03` Phone login: Saudi number input, country-code dropdown (default +966), privacy/terms links.
- `R-AUTH-04` OTP screen: 6-digit code, resend countdown (e.g. 01:57), confirm enabled on completion.
- `R-AUTH-05` Complete profile (2-step stepper): optional photo + required full name → "Start your ride".
- `R-AUTH-06` Session management via **Sanctum** tokens; OTP session expiry handling → return to login.

### Account states (`R-STATE`)
- `R-STATE-01` Account states: `NEW`, `ACTIVE`, `IN_RIDE`, `BALANCE_LOW`, `BLOCKED` with allowed actions per state.
- `R-STATE-02` Ride preconditions: account ACTIVE, balance ≥ minimum or active subscription, camera+GPS permissions, no other active ride, internet during scan.

### Home & Map (`R-HOME`)
- `R-HOME-01` Bottom navigation (4 tabs): Home, My Rides, Wallet, Account.
- `R-HOME-02` Greeting bar + notifications bell (yellow dot when unread) + map search.
- `R-HOME-03` Balance card ("Available balance: 85.50 SAR") + Top-up button.
- `R-HOME-04` Interactive Google Map: user location (blue dot), available scooters as yellow icons, "Available" badge.
- `R-HOME-05` Auto-refresh scooter positions every 10–15s; hide out-of-service scooters and scooters <5% battery.
- `R-HOME-06` Primary CTA: "Scan code to start" (yellow, QR icon).
- `R-HOME-07` Scooter bottom sheet on marker tap: code, model, status badge, photo, price/min, range (km), distance (m), battery % bar, "Scan code" CTA.

### Ride flow (`R-RIDE`)
- `R-RIDE-01` Select scooter (map tap or direct scan CTA).
- `R-RIDE-02` QR scan screen: camera viewfinder, animated scan line, "Scanning…" badge, manual-entry fallback, help (i).
- `R-RIDE-03` Manual code entry (`SCT-XXXX`) fallback.
- `R-RIDE-04` Pre-ride verification photo (full scooter in frame, auto-verify).
- `R-RIDE-05` Auto-unlock on valid QR + sufficient balance.
- `R-RIDE-06` Active ride screen: status badge + pulse, live timer (MM:SS), current street (GPS), remaining balance (decrements), speed, distance, scooter battery %, approx remaining range, mini-map, red "Stop ride" button.
- `R-RIDE-07` End-ride confirmation modal: duration, distance, computed cost, balance after deduction, "Continue ride" / "Yes, end".
- `R-RIDE-08` Post-ride parking photo (proof of proper parking).
- `R-RIDE-09` "Ride ended successfully" screen: summary (duration, distance, total cost, remaining balance, ride code) + optional 5-star rating + return-to-home.
- `R-RIDE-10` Ride lifecycle state machine: `SCANNING → ACTIVE → ENDING → COMPLETED` (+ `CANCELLED`).
- `R-RIDE-11` Edge cases: insufficient balance pre-ride (block scan), balance runs out mid-ride (alert + grace period then auto-stop), internet loss (cache + resync), QR read fail (retry + manual), scooter fault after unlock (report + cancel), camera/GPS disabled (permission prompts), low-battery scooter hidden.

### Wallet & Subscriptions (`R-WALLET`)
- `R-WALLET-01` Wallet screen with top tabs: Wallet / Subscriptions.
- `R-WALLET-02` Wallet tab: active-wallet badge, current balance, top-up (+) CTA, total-spent card, total-topped-up card, transactions list + "View all".
- `R-WALLET-03` Transaction types: top-up, scooter ride, package purchase, admin refund/adjustment — each with amount, date, time, details.
- `R-WALLET-04` Top-up screen: quick amounts (25/50/100/200 + custom), payment methods (Apple Pay, Visa/Mastercard, Mada, STC Pay), confirm.
- `R-WALLET-05` Subscriptions: Day (15 SAR), Week (79 SAR), Month (249 SAR), 2-Month (399 SAR) with per-ride minute caps & benefits.
- `R-WALLET-06` Active package badge: name, "active" badge, expiry date, progress bar (days elapsed/remaining).
- `R-WALLET-07` Subscription confirmation screen: package summary, payment method, confirm.

### My Rides & Stats (`R-TRIPS`)
- `R-TRIPS-01` Stats card (4 metrics): total spent, riding hours, km ridden, completed rides.
- `R-TRIPS-02` Time filters: All / This month / Last month / month-year selector.
- `R-TRIPS-03` Rides list (newest first): model, status badge (completed/cancelled/ongoing), start time + duration + distance, start→end location, cost, chevron to detail.
- `R-TRIPS-04` Ride detail bottom sheet: ride #, date, status, start/end points, distance, cost, model, start/end times.

### Account & Settings (`R-ACC`)
- `R-ACC-01` Account screen: Account / App / Support sections + logout + settings icon.
- `R-ACC-02` Edit profile: photo, full name, save, delete-account card (irreversible warning).
- `R-ACC-03` Delete-account flow: confirm modal warning (loses balance + all ride history).
- `R-ACC-04` Change phone number (2-step: new number → OTP verify).
- `R-ACC-05` Notification toggle, language (Arabic default).
- `R-ACC-06` Contact us: 3 channels (email 24h, phone 9–21, WhatsApp live) + message form (topic chips, 10–500 char body, counter, send).
- `R-ACC-07` FAQ (accordion categories: Rides / Wallet & Payment / Account).
- `R-ACC-08` Help Center alt: search + topic list with view counts.
- `R-ACC-09` Rate app / Share app.

### Notifications (`R-NOTIF`)
- `R-NOTIF-01` Notification types: OTP (SMS), ride confirmation, ride end, low balance (<10 SAR), balance depleted mid-ride, package reminder (3 days before), package expired, top-up success, payment failure, promo.
- `R-NOTIF-02` Master toggle + (later) per-type controls (promo/rides/wallet).
- `R-NOTIF-03` Push delivery (FCM/APNs) + in-app inbox.

### Permissions & Geo (`R-PERM`)
- `R-PERM-01` Location (mandatory), Camera (mandatory), Notifications (optional), Storage/Photos (optional, temporary).
- `R-PERM-02` Map default zoom showing scooters within ~500m; per-second GPS during ride.
- `R-PERM-03` QR validation only for valid BEEB BEEB codes (`SCT-XXXX`).
- `R-PERM-04` Verification photos uploaded with ride id; retained 30 days then auto-deleted; internal-only.

## 2.2 Investor Dashboard (prefix `I-`) — *implemented as **`Provider`** API + portal*

### Auth & Verification (`I-AUTH`)
- `I-AUTH-01` Split-screen login (left: brand + marketing stats "124 rides today / 18% your share / +7 active vehicles"; right: form). Email + password + remember-me + forgot-password.
- `I-AUTH-02` Sign-up step 1: first/last name, email, phone (+966), password (8+ with strength meter).
- `I-AUTH-03` Sign-up step 2: national ID (10 digits, starts 1/2), IBAN (SA + 22), vehicle count radio (1-2/3-5/6-10/10+), **uncategorized** document upload (`documents[]`, 1–10 files, drag&drop, PDF/JPG/PNG ≤10MB — no attachment type), read-only 18% profit display, terms checkbox.
- `I-AUTH-04` Forgot-password flow (separate screen — flagged missing in Figma, must design).
- `I-AUTH-05` Verification flow: submit → `REVIEW_PENDING` → admin review → `ACTIVE`/`REJECTED` (+ reason) → email+SMS notice → admin assigns vehicles.
- `I-AUTH-06` Account states: `PENDING_REVIEW`, `ACTIVE`, `NO_VEHICLES`, `SUSPENDED`, `REJECTED`.

### Home Dashboard (`I-HOME`)
- `I-HOME-01` RTL sidebar (4 sections: Home, My Vehicles, Earnings, Account) + top bar (logo, investor name, notifications, active-section highlight, logout).
- `I-HOME-02` KPI cards (4): profit share % (18%), expected profit this month, rides today + avg/vehicle, total earnings + MoM %.
- `I-HOME-03` Monthly earnings bar chart (last 6 months, tooltip, current-month highlight, range dropdown).
- `I-HOME-04` Today summary card (revenue today + vs-yesterday %).
- `I-HOME-05` Vehicles summary (total/active/maintenance + mini bar chart).
- `I-HOME-06` Recent transactions table (last 5 + "View all"): vehicle code, area, rides, relative time, amount; row click → detail modal; empty state.

### My Vehicles (`I-VEH`)
- `I-VEH-01` Header + fleet summary ("My Vehicles (7)"), filter chips (All/Active/Maintenance/Stopped — later), search (later).
- `I-VEH-02` Vehicle card grid: status badge, code (yellow), location, today's rides, today's revenue, details button.
- `I-VEH-03` Status colors: Active (green), In-Ride (yellow+pulse), Maintenance (orange), Inactive (gray), Out-of-service (red).
- `I-VEH-04` Vehicle detail (modal/page — flagged to design): photo+model, code+status, day/week/month revenue, utilization %, total rides + avg duration, avg rating, recent ops log, mini-map of recent rides.
- `I-VEH-05` Empty state: "Awaiting your first vehicle assignment".

### Earnings / Analytics (`I-EARN`)
- `I-EARN-01` KPI cards (4): profit share %, avg daily profit (30d), this-month profit, total profit + %.
- `I-EARN-02` Monthly earnings distribution bar chart (6 months, values above bars).
- `I-EARN-03` Year-over-year comparison chart (area+line, 12 months, legend, bars/area toggle).
- `I-EARN-04` Per-vehicle earnings table: code, status, area, rides today, daily revenue, your share (18%, auto-computed), monthly revenue, your monthly share + % bar; sortable columns; top performer highlighted; **Excel/CSV export**.

### Account & Settings (`I-ACC`)
- `I-ACC-01` Profile card (right): avatar, name, "investor since", verified badge, share %, vehicle count, membership months, account status.
- `I-ACC-02` Personal info form (left): name (editable), phone (editable w/ OTP), email (read-only), national ID (masked, read-only), IBAN (masked, editable w/ verify), save.
- `I-ACC-03` Change password screen: current/new/confirm + live requirement validation (8+, uppercase, number, special char); last-changed timestamp.
- `I-ACC-04` Actions: logout, (proposed) active sessions, GDPR data export, account deletion.

### Investor financials (`I-FIN`)
- `I-FIN-01` Profit formula: `investor share = sum(vehicle revenue in period) × profit rate (18% default)`.
- `I-FIN-02` Settlement cycle: real-time accrual → period close (monthly) → invoice gen (day 1-3) → investor review (5 days) → bank transfer (day 7-10) → transfer notice (push+email+sms).
- `I-FIN-03` Invoices (PDF): invoice #, date, period, investor info, per-vehicle table, totals, bank ref, VAT, digital signature/stamp.
- `I-FIN-04` Disputes/objections window (5 days) — later in-panel form.
- `I-FIN-05` Read-only dashboard (investor cannot change pricing/operation).

## 2.3 Admin Panel (prefix `A-`)

### Auth & RBAC (`A-AUTH`)
- `A-AUTH-01` Staff login: `@beebbeep.sa` email only, 12+ char password, captcha after 3 fails, mandatory 2FA (TOTP/SMS), (later) IP whitelist.
- `A-AUTH-02` Password policy: 12+ mixed, 90-day rotation, no reuse of last 5, lockout 30min after 5 fails.
- `A-AUTH-03` Two roles: **Super Admin** (full) and **Operator** (operational, no sensitive actions).
- `A-AUTH-04` RBAC enforcement on every section + every action.

### Dashboard (`A-DASH`)
- `A-DASH-01` Top KPI bar (6 cards): total users (+new today), rides today (+%), revenue today (vs yesterday), active vehicles (X/150), open support tickets (red badge if critical), avg ride rating.
- `A-DASH-02` Charts: rides (line, 30d), monthly revenue (bar, 12m), rides-by-city (donut), peak hours (heatmap), live vehicle map (Riyadh).
- `A-DASH-03` Quick actions: add scooter, send broadcast, review new investor requests (badge), open tickets, run monthly settlement.
- `A-DASH-04` Recent activity feed (live events).

### Rider management (`A-RIDER`) — *admin: **`clients`** module*
- `A-RIDER-01` Riders table: ID, name+avatar, phone (WhatsApp link), reg date (sortable), status badge, ride count (sortable), total spend (sortable), current balance, last activity (sortable), actions menu.
- `A-RIDER-02` Filters: reg-date range, status, ride-count range, balance range, city, search (name/phone/ID).
- `A-RIDER-03` Rider detail tabs: Profile, Rides, Financial transactions, Support tickets.
- `A-RIDER-04` Admin actions (with RBAC + audit + confirm): view, edit, block/unblock (+reason), refund <100 (Operator) / ≥100 (Super Admin), permanent delete (Super Admin + password), gift balance (Super Admin + daily cap), reset OTP (Operator).
- `A-RIDER-05` Edge cases: blocked-login message, auto-ticket on ride objection, inactive-6mo tag, account-deletion request flow, data-theft report → immediate block + investigation.

### Fleet management (`A-FLEET`)
- `A-FLEET-01` Vehicles list (List + Map view toggle): code, model, owner (BEEB BEEB/investor), status, battery % bar, location, last used, today revenue, actions.
- `A-FLEET-02` Map view: Riyadh map, color-coded markers, popup, filters (model/status/battery/area), optional usage heatmap.
- `A-FLEET-03` Add vehicle: auto-gen code (`SCT-XXXX`), model dropdown, serial #, purchase date, purchase price, owner dropdown, initial status (default stock), **auto-generate QR + printable sticker**, tech specs (battery/speed/range), photo upload.
- `A-FLEET-04` Vehicle detail tabs: Overview (stats, utilization, last location), Ride log, Maintenance log (+ add record, periodic alerts), Current technical state (battery, self-check, sensor warnings, 24h GPS log).
- `A-FLEET-05` Vehicle actions: change status (Operator+), assign to investor (Super Admin), unassign (Super Admin), remote lock (Operator+), OTA firmware update (Super Admin), retire (Super Admin), relocate/geofence (Operator+).
- `A-FLEET-06` Maintenance subpanel: current maintenance list, periodic scheduling (every 500 rides / 1000 km, calendar), full maintenance history + cost reports.

### Ride management (`A-RIDE`)
- `A-RIDE-01` Rides list: ride #, rider, vehicle, start (time+loc), end (time+loc/ongoing), duration, distance, cost, status, actions. Filters: date, status, vehicle, rider, area, duration range, cost range, problem-only.
- `A-RIDE-02` Live Rides view (map of active rides, counter, click→live track, red alert >1h, orange alert geofence violation).
- `A-RIDE-03` Ride detail: map replay (path, start/end markers, minute slider, speed heatmap), detailed timeline (scan/photo/unlock/move/stops/stop/parking photo/lock), full invoice breakdown.
- `A-RIDE-04` Ride actions: manual end (Operator+), cancel + full refund (Operator+), partial refund (Operator+, cap), cost adjustment down (Super Admin), open ticket from ride (Both), flag suspicious (Operator+).
- `A-RIDE-05` Disputes panel: open disputes list + priority, full evidence (messages, photos, GPS), decisions (accept/refund, reject, request info), audit trail.

### Investor management (`A-INV`) — *admin: **`providers`** module*
- `A-INV-01` Investors list: ID, name+avatar, email, phone, reg date, status, vehicle count, total profit, profit %, actions.
- `A-INV-02` Approval flow (Super Admin): review screen (personal data, ID image w/ zoom, IBAN image, commercial reg, vehicle count, proposed 18%) → Approve / Reject (+reason) / Request changes / Hold.
- `A-INV-03` Investor detail tabs: Profile (+ID images, masked IBAN editable, profit % editable), Assigned vehicles (+assign/unassign), Invoices & settlements (+manual invoice), Communications (emails/calls/internal notes).
- `A-INV-04` Vehicle assignment modal: select investor, multi-select unassigned vehicles, profit %, start date, notes, confirm → audit + notify.

### Finance (`A-FIN`)
- `A-FIN-01` Revenue dashboard KPIs: revenue today/month/year (with comparisons), avg ride value, total wallet balances, package revenue, minute revenue, total investor payables.
- `A-FIN-02` Finance charts: daily revenue line (90d), stacked bar (minutes+packages monthly), revenue-by-package pie, day/hour heatmap.
- `A-FIN-03` Transactions ledger: top-up, ride deduction, package purchase, refund, investor transfer, commission, fees/VAT.
- `A-FIN-04` Refunds management: list + status (Pending/Approved/Rejected), type, amount, method; approval policy by amount (<50 Operator, 50-200 Operator+reason, 200-500 Super Admin, >500 Super Admin + extra approval).
- `A-FIN-05` **Investor settlements panel** (critical): month dropdown, table of investors + monthly revenue + share + settlement status, bulk actions (generate all invoices / execute all transfers). 8-step monthly settlement workflow.
- `A-FIN-06` Invoices management: all issued invoices, filters, reissue, periodic VAT reports for ZATCA, e-invoicing integration.
- `A-FIN-07` Financial settings (Super Admin): investor % (18%), price/min (0.45), package prices (15/79/249/399), min top-up (10), min ride balance (5), VAT (15%), settlement day (7).

### Content & Support (`A-CONTENT`)
- `A-CONTENT-01` Cities & geofencing: add city (polygon on map), neighborhoods, no-ride zones, preferred parking zones, out-of-zone alerts, per-city pricing.
- `A-CONTENT-02` FAQ CMS: tree view, add/edit (rich text + order), drag-drop reorder, hide/show, view counters.
- `A-CONTENT-03` Banners: add (image/title/link/dates), targeting (all/city/segment), display order, stats (views/clicks/conversion), scheduling.
- `A-CONTENT-04` Notification center: create campaign (name, audience incl. multi-select, type push/sms/email/in-app, title/body+preview, scheduling), campaign stats (open/click/conversion).
- `A-CONTENT-05` Support tickets: inbox (open + counter, priority order, assignment, tags), ticket detail (owner data + linked ride, chat thread, internal notes, attachments, quick actions: refund/credit/link/escalate), SLAs (critical 15m/2h, high 1h/8h, medium 4h/24h, low 24h/72h).

### Reports & Analytics (`A-REPORT`)
- `A-REPORT-01` Operational reports: daily rides, fleet, top-10 vehicles, top areas, peak hours, monthly maintenance.
- `A-REPORT-02` Financial reports: monthly revenue, VAT (ZATCA), investors, transactions, refunds, P&L.
- `A-REPORT-03` User reports: user growth (DAU+new), retention, churn, active users (DAU/WAU/MAU), user segments, signup sources.
- `A-REPORT-04` Custom report builder (Super Admin): data source, date range, columns, filters, view type, save + schedule + auto-email.
- `A-REPORT-05` Executive dashboard: MRR, ARR, CAC, LTV, burn rate, runway, fleet utilization.
- `A-REPORT-06` Export: PDF, Excel, CSV, (later) API/JSON.

### Settings & Audit (`A-SET`)
- `A-SET-01` Staff management (Super Admin): list, add (email @beebbeep.sa, role, department, temp password + email, force change on first login, mandatory 2FA), edit/suspend/delete.
- `A-SET-02` System settings: platform/legal, financial, operational hours, security (password policy, session timeout, 2FA), notifications defaults, language/formats, external API keys (Maps/SMS/Payment).
- `A-SET-03` **Audit logs**: log all sensitive ops (login/logout w/ IP+device, setting edits, investor approve/reject, transfers, refunds, block/unblock, deletions, role edits, staff CRUD); each entry: who, action type, second-precise timestamp, before/after diff, IP+user-agent, reason; advanced search/filter, export, fully read-only (even Super Admin can't edit/delete), 5-year retention (legal).
- `A-SET-04` Empty states for all lists + error pages (404/500/403).
- `A-SET-05` UX: desktop-first, density mode (comfortable/compact), dark mode optional, in-page help docs, staff onboarding, i18n-ready.

## 2.4 Shared Backend / Platform (prefix `S-`)

- `S-API-01` Unified backend + single database; product-specific endpoints.
- `S-AUTH-01` Separate auth actors: **`Client`** (rider app), **`Provider`** (investor dashboard), **`Admin`** (staff); Sanctum tokens + `check-auth-type` middleware — no cross-use.
- `S-AUTH-02` Sanctum sessions; OTP for **clients**; password+2FA for staff; password for **providers**.
- `S-DOMAIN-01` Separation: `app.beebbeep.sa` (client/rider app) / `investor.beebbeep.sa` (provider portal) / `admin.beebbeep.sa`; separate audit logs.
- `S-RT-01` Real-time tracking engine (WebSocket for clients; MQTT for scooter IoT telemetry: GPS/speed/battery/lock state).
- `S-RT-02` Per-second ride telemetry persistence + replay data.
- `S-PAY-01` Payment gateway integration: Apple Pay, Visa/Mastercard/Amex, Mada, STC Pay; wallet top-up; webhook handling; >500 SAR extra verification.
- `S-PAY-02` Billing engine: per-minute pricing + subscription caps + auto-deduction + refunds + investor settlement computation.
- `S-PAY-03` E-invoicing + VAT (ZATCA-compliant); PDF generation.
- `S-NOTIF-01` Notification service (push/sms/email/in-app) shared across products.
- `S-GEO-01` Geofencing service (PostGIS): operating polygons, no-ride zones, parking zones, violation detection.
- `S-STORE-01` S3-compatible storage for verification photos (30-day TTL, internal-only) + documents.
- `S-MAP-01` Google Maps integration (mobile + web).

## 2.5 Non-functional & Compliance (prefix `N-`)

- `N-SEC-01` Security: Sanctum, RBAC, 2FA/TOTP for staff, CSP (XSS), CSRF protection, data masking (ID/IBAN), rate limiting, captcha.
- `N-PRIV-01` Saudi PDPL compliance; verification-photo retention (30d) auto-delete; GDPR-style data export & deletion.
- `N-FIN-01` ZATCA e-invoicing + 15% VAT.
- `N-AUDIT-01` Immutable audit logs, 5-year retention.
- `N-I18N-01` Arabic-first RTL across all products; i18n-ready for English later.
- `N-PERF-01` Real-time updates ≤1s during rides; map scooter refresh 10–15s.
- `N-AVAIL-01` Offline cache + resync on mobile (ride continuity).
- `N-UX-01` Empty states, skeleton loaders, toasts, confirm modals for critical actions; consistent yellow/dark design system.

---

# PART 3 — Tech Stack & Architecture (Laravel `beeb` repo)

Stack matches the **current `beeb` repo** (Laravel 9 fork of team `codebase`) — refactor marketplace leftovers, then add BEEB domain. Do not greenfield a second backend.

| Layer | Choice | Notes |
|---|---|---|
| Backend + Admin | **Laravel 9** (`laravel/framework ^9.19`, PHP ^8.0) | `app/Services/Entity/*`, Form Requests, Blade admin, Sanctum ^2.12 |
| Admin UI | **Blade + Bootstrap/Admin theme (Vite)** | `resources/views/admin/` — add BEEB tokens; not Tailwind v4 today |
| Client API (rider app) | **`/api/client/*`** (Sanctum) | Shared auth in `routes/api.php`; BEEB routes in `routes/api/client.php` |
| Provider API (investor dashboard) | **`/api/provider/*`** (Sanctum) | Refactor **`Provider`** off clinic/category model; add KYC + analytics |
| Staff | **Session `/admin`** | `Admin`, `Role`, `Permission`; add 2FA + Operator role (SRS) |
| Database | **MySQL** (+ **PostGIS** later) | New BEEB tables under `database/migrations/beeb/` (recommended) |
| Realtime | **`nodeServer/`** (Socket.IO + FCM) + optional Laravel broadcasting | Extend for ride telemetry; MQTT bridge TBD |
| Queue / cache | **Redis** in production | Jobs: settlements, photo TTL, notifications |
| Storage | **Model image paths** (`ModelTrait`, `IMAGEPATH`) + S3 disk optional | Verification/KYC uploads; consider Spatie Media later |
| Auth | **Sanctum** + `check-auth-type` middleware | `AuthenticationService`, `AuthOtp` morph on `Client`/`Provider` |
| Payments | **`app/Services/PaymentGateway/*`** (HyperPay, Myfatoorah, …) | Consolidate behind `PaymentService`; webhook → wallet credit |
| Maps | Google Maps (clients) | API returns geo JSON |
| Charts (admin/investor web) | Admin theme chart assets | KPI views in Blade |
| Rider mobile app | **Expo React Native** (separate repo) | Consumes **`/api/client/*`** only |
| Investor web | **Phase 7:** Blade `/provider` or SPA | **`/api/provider/*`** |
| i18n | **`lang/ar` + `lang/en`** + Spatie Translatable on models | Arabic-first RTL |
| Testing | **PHPUnit ^8.5** | Feature tests + Postman (`Client` / `Provider` / `General`) — skill `@.cursor/skills/postman-beeb-api` |
| CI/CD | **GitHub Actions** (to add) | pint, phpunit on PR |

### Repo layout (actual — 2026-06-02)
```
beeb/
├─ app/
│  ├─ Enums/                    # WalletTransactionType, OTPType, … (+ BEEB enums in Phase 0)
│  ├─ Http/Controllers/
│  │  ├─ Admin/                 # Client, Provider, Setting, Complain, AppIntro, …
│  │  └─ Api/
│  │     ├─ Client/             # Auth, Profile, Wallet, Complain, Favorite, …
│  │     └─ Provider/           # Auth, WorkDays, … (refactor for investor)
│  ├─ Models/                   # Client, Provider, Wallet, WalletTransaction, …
│  ├─ Services/
│  │  ├─ Auth/                  # AuthenticationService, ProfileBaseService
│  │  ├─ Entity/                # *Service extends BaseService (admin CRUD)
│  │  ├─ PaymentGateway/        # HyperpayService, PaymentService, …
│  │  └─ SettingService.php
│  └─ Events/Listeners/         # OtpRequested → SendOtp
├─ database/migrations/         # Flat today; add beeb/ subfolder for new domain
├─ resources/views/admin/
├─ routes/
│  ├─ api.php                   # Shared client/provider auth + profile
│  ├─ api/client.php            # Client-specific (wallet, complains, …)
│  ├─ api/provider.php
│  └─ dashboard/                # Admin modules (timestamp-prefixed PHP files)
├─ nodeServer/                  # Socket.IO + FCM push bridge
├─ docs/                        # Add SRS.md, RUNBOOK.md, postman/
└─ # BEEB BEEB … Complete Feature.md   # This file
```

### Legacy marketplace code (refactor or remove in `T-0.0`)

These exist from the **`codebase`** template and are **not** in the BEEB SRS — hide from rider API or delete once BEEB modules exist:

| Legacy | Location | Action |
|---|---|---|
| Provider browse / favorites | `Api\Client\ProviderController`, `FavoriteController` | Remove or gate behind feature flag |
| Provider categories, work days | Models + `routes/api/provider.php` | Replace with fleet/earnings APIs |
| `Provider.clinic_name`, `category_id` | `providers` migration | Migrate to investor KYC fields (`I-AUTH-03`) |
| Legacy wallet transaction types | `WalletTransactionType` | Add `ride`, `top_up`, `package`, `refund` |

### Base platform reuse (already in repo — do not rebuild)

| BEEB need | Base feature | Status |
|---|---|---|
| Staff login + RBAC | `Admin`, `Role`, `Permission` | ✅ Reuse |
| OTP auth | `AuthenticationService`, `AuthOtp`, `OtpRequested` event | ✅ Reuse for **Client** |
| Settings (pricing, VAT, limits) | `SettingService` + `site_settings` | ✅ Extend keys (Appendix C) |
| FAQ / static pages | `Faq`, `Page`, `StaticController` | ✅ Reuse for `R-ACC-07` |
| App onboarding slides | `AppIntro`, `GET /api/client/app-intro` | ✅ Reuse for `R-AUTH-02` |
| Push + in-app notifications | `NotificationService`, `nodeServer` FCM | ✅ Extend templates |
| Geography | `Country`, `City` | ✅ Extend → geofence zones later |
| Contact / support | `Contact`, `Complain` | ✅ Adapt → `SupportTicket` |
| File upload | `ModelTrait` image paths | ✅ Reuse; optional Spatie Media later |
| Excel export | Maatwebsite Excel, `Admin\ExcelController` | ✅ Reuse for reports |
| Wallet + transactions | `Wallet`, `WalletTransaction`, morph on `Client` | ✅ Extend types + ride debit |
| Client / Provider admin CRUD | `Admin\ClientController`, `ProviderController` | ✅ Adapt UI + actions |
| HyperPay / payment gateways | `PaymentGateway\HyperpayService`, etc. | ✅ Wire top-up webhooks |
| Scooter / Ride / settlements | — | ❌ Build (Phase 0–4) |
| Provider investor fields & dashboard API | — | ❌ Refactor **Provider** + Phase 4/7 |

---

# PART 4 — Detailed Cursor Execution Tasks (Laravel)

> Conventions: `[ ]` = todo · `[~]` = partial (base exists, needs BEEB domain) · `[x]` = done in base.  
> Workflow per task: analysis → migration/model → `app/Services/Entity` or domain service → API/admin routes → PHPUnit → Postman.

---

## Phase 0 — Domain setup & documentation

### `T-0.0` Legacy marketplace cleanup
- [x] **Goal:** Stop new BEEB work from inheriting wrong domain (clinics, favorites, provider catalog).
- **Reuses:** `routes/api/client.php`, `Provider` model, admin provider views
- **Acceptance:** Rider-facing API has no provider-catalog/favorite endpoints (or they return 410); `Provider` fillable documented as “investor-only” target schema; README names BEEB BEEB.

> 🟡 Cursor: Audit `routes/api/client.php` and remove or disable marketplace routes (`providers`, `favorites`, `main-categories`). Document deprecated models (`Favorite`, `ProviderCategory`) in `docs/LEGACY.md`. Update root `README.md` for BEEB BEEB. Do not delete admin modules until investor CRUD replaces them — mark sidebar items hidden if needed.

### `T-0.1` SRS + domain context
- [x] **Goal:** Pin SRS and rewrite Cursor context files for BEEB terminology.
- **Reuses:** `.cursor/context/project-context.md`, `domain-context.md`
- **Files:** `docs/SRS.md`, `.cursor/context/domain-context.md`, `.cursor/context/project-context.md`
- **Acceptance:** `domain-context.md` lists **Client**, **Provider**, Scooter, Ride, Wallet, Settlement entities and state enums; `project-context.md` names BEEB BEEB (not "Base Laravel Starter").

> 🟡 Cursor: Copy the SRS into `docs/SRS.md`. Rewrite `@.cursor/context/domain-context.md` for BEEB BEEB: **Client** (= SRS rider), **Provider** (= SRS investor), Scooter, Ride, etc. Map account states (`R-STATE-01` → `ClientAccountState`, `I-AUTH-06` → `ProviderAccountState`), ride state machine (`R-RIDE-10`), scooter statuses (`I-VEH-03`). Update `@.cursor/context/project-context.md` — products: rider mobile app (Client API), investor dashboard (Provider API), admin. Reference Part 2 feature IDs and the SRS↔Laravel naming table in this doc.

### `T-0.2` Domain enums
- [~] **Goal:** All BEEB status/type enums in `app/Enums/`.
- **Covers:** `R-RIDE-10`, `R-STATE-01`, `I-AUTH-06`, `I-VEH-03`, `S-PAY-*`, wallet transaction types
- **Reuses:** `app/Enums/Base.php`, existing `WalletTransactionType` (extend, don't duplicate)
- **Acceptance:** Enums used in migrations and Form Requests; no magic strings in services.

> 🟡 Cursor: Create enums: `RideStatus`, `ClientAccountState`, `ScooterStatus`, `ProviderAccountState`, `SubscriptionPackageType`, `SettlementStatus`, `RefundStatus`, `SupportTicketPriority`, `AuditActionType`. **Extend** `WalletTransactionType` with BEEB values (`ride`, `top_up`, `package`, `refund`, `admin_adjustment`) and deprecate marketplace-only constants when unused. Follow `app/Enums/Base.php` style. Match @docs/SRS.md and Appendix C.

### `T-0.3` Core database migrations
- [ ] **Goal:** Migrations for BEEB domain tables under `database/migrations/beeb/`.
- **Files:** `database/migrations/beeb/*.php`
- **Acceptance:** `php artisan migrate` succeeds; foreign keys and indexes on `scooter_id`, `client_id`, `provider_id`, `ride.status`.

> 🟡 Cursor: Add migrations (beeb subfolder): extend **`clients`** (`account_state`, BEEB rider fields), extend **`providers`** (KYC, IBAN, `profit_rate` default 18, `account_state`), `scooters` (`code` SCT-XXXX, `provider_id` nullable), `rides` (`client_id`, state machine, cost, photos via Spatie), `wallets` + `wallet_transactions` (morph **`Client`**), `subscription_packages` + `client_subscriptions`, `settlements` + `settlement_lines` + `invoices`, `ride_telemetry`, `audit_logs`, `geofence_zones`. Port wallet morph from team `codebase` (`Wallet` → `Client`). Do not create separate `riders`/`investors` tables.

### `T-0.4` Demo seeders
- [ ] **Goal:** One `php artisan db:seed --class=BeebDemoSeeder` populates charts and lists.
- **Acceptance:** 30 scooters, 50 clients, 1 active provider with 7 scooters, 1 month of completed rides, wallet balances, settings keys from Appendix C.

> 🟡 Cursor: Create `BeebDemoSeeder`: **clients** with wallets, scooters in Riyadh, **provider** `ACTIVE` with assignments, completed/cancelled rides, financial settings via `SettingService`. Document in `docs/RUNBOOK.md`.

### `T-0.5` Admin branding (yellow/dark)
- [~] **Goal:** BEEB yellow + dark theme tokens in Tailwind / admin layout.
- **Reuses:** `resources/views/admin/layouts/`, Vite CSS
- **Acceptance:** Primary CTA yellow; status badge colors match SRS; RTL unchanged.

> 🟡 Cursor: Add BEEB design tokens to Tailwind config and admin CSS variables (primary `#F5C518`, dark surfaces, status colors per `I-VEH-03` / ride statuses). Update admin login and sidebar logo placeholders. Do not rebuild layout — only theme tokens.

---

## Phase 1 — Authentication & account states

### `T-1.1` Client OTP API (`R-AUTH`) — *SRS “Rider”*
- [~] **Goal:** *(completeProfile + account_state added)* `/api/client/*` auth — phone OTP register/login, profile completion, Sanctum tokens aligned with SRS.
- **Reuses:** `routes/api.php` (register, login, verify-login, profile/complete), `Api\Client\AuthController`, `AuthenticationService`, `AuthOtp`
- **Covers:** `R-AUTH-03`–`06`, `S-AUTH-02`
- **Acceptance:** 6-digit OTP, resend cooldown, verify issues token; `profile/complete` matches `R-AUTH-05`; `ClientAccountState` wired; Feature tests + Postman.

> 🟡 Cursor: **Extend** existing client auth (do not duplicate): add `account_state` on **Client**, map `is_blocked` → `BLOCKED`, enforce `R-STATE-02` on ride routes when they exist. Confirm `POST /api/client/profile/complete` and delete-account. Rate-limit OTP in `RouteServiceProvider`. Document endpoints in `docs/postman/client.json`.

### `T-1.2` Provider auth + KYC signup (`I-AUTH`) — *SRS “Investor”*
- [~] **Goal:** `/api/provider/*` — investor signup + auth aligned with SRS (replace clinic schema).
- **Reuses:** `routes/api.php` provider group, `Api\Provider\AuthController`, `ProviderRegistrationService`, `is_approved` / `rejection_reason`
- **Covers:** `I-AUTH-01`–`05`, `S-AUTH-02`
- **Screens:** `ai helper/provider/provider-login.png` (login), `provider-register step 1/2.png` (register), `provider-change password.png` (forgot password)
- **Done:** `POST /api/provider/register` (multipart KYC, `is_approved: null`, no OTP); `POST /api/provider/login` (**email + password**, returns token); provider `verify-login` removed; forgot-password uses **email** OTP; KYC columns on `providers`; Postman **Provider → 01–06**; seeded login `ahmed.investor@beeb.test` / `TestPass123!`
- **Remaining:** Admin KYC approve/reject UX; notify on new application; dashboard route middleware (`is_approved`); legacy admin provider forms cleanup.

> 🟡 Cursor: Extend admin **providers** show for KYC approve/reject (`is_approved`). Add investor dashboard routes in `T-4.4`. Run `php scripts/build-and-sync-postman.php --sync` after auth changes.

### `T-1.3` Staff 2FA + Operator role (`A-AUTH`)
- [~] **Goal:** Extend admin auth: `@beebbeep.sa` emails, 12+ password policy, TOTP 2FA, Super Admin vs Operator.
- **Reuses:** `Admin`, `Role`, `Permission`, `CheckRolePermission`
- **Covers:** `A-AUTH-01`–`04`
- **Acceptance:** Operator denied on Super-Admin-only routes; lockout after 5 fails; captcha after 3 fails (session flag).

> 🟡 Cursor: Add `AdminType` values `SUPER_ADMIN` and `OPERATOR`. Implement TOTP setup/verify on login, password policy validation, failed-login counter + 30min lockout. Gate routes via existing `Role`/`Permission` checks and `MenuTrait` (super-admin-only menu items).

### `T-1.4` Client account state middleware (`R-STATE`)
- [ ] **Goal:** Middleware enforces `ClientAccountState` on **`Client`** routes.
- **Covers:** `R-STATE-01`, `R-STATE-02`
- **Acceptance:** `BLOCKED` cannot start ride; `IN_RIDE` cannot start second ride; `BALANCE_LOW` allows top-up only.

> 🟡 Cursor: `EnsureClientAccountState` middleware + `ClientStateService` on **`Client`** (ride start → `IN_RIDE`, ride end → `ACTIVE`, balance → `BALANCE_LOW`). Document allowed actions matrix in `domain-context.md`.

---

## Phase 2 — Wallet, billing & payments

### `T-2.1` Wallet module (extend)
- [~] **Goal:** Morph wallet on **`Client`**; BEEB transaction types; admin client wallet tab.
- **Reuses:** `Wallet`, `WalletTransaction`, `WalletService`, `Api\WalletController`, `GET/POST /api/client/wallet*`
- **Covers:** `R-WALLET-01`–`03`, `S-PAY-02`
- **Acceptance:** Transaction list API; types include ride/top-up/package; admin client show displays balance + ledger.

> 🟡 Cursor: **Extend** `WalletService` and `WalletTransactionType` for BEEB. Add `GET /api/client/wallet/transactions` if missing. Admin `clients/{id}/show`: wallet tab with transactions. Debit helper used later by `BillingService`.

### `T-2.2` Billing engine
- [ ] **Goal:** Fare computation from settings; subscription minute caps; auto-deduct on ride end.
- **Covers:** `R-RIDE-07`, `S-PAY-02`, Appendix C constants
- **Acceptance:** Unit tests: per-minute 0.45 SAR, package cap overage, min balance 5 SAR before ride start, low-balance event at 10 SAR.

> 🟡 Cursor: `BillingService` + `SettingService` keys. `computeFare(Ride)`, `canStartRide(Client)`, `deductOnRideEnd` in DB transaction. Emit `WalletLowBalance` / `WalletDepleted` for **`Client`** notifications.

### `T-2.3` Payment gateway (top-up)
- [~] **Goal:** Top-up initiate + webhook; idempotent wallet credit.
- **Reuses:** `PaymentService`, `HyperpayService`, `payment_transactions`, existing `POST /api/client/wallet/charge`
- **Covers:** `R-WALLET-04`, `S-PAY-01`
- **Acceptance:** Sandbox session URL returned; webhook credits wallet once; >500 SAR sets `requires_extra_verification`.

> 🟡 Cursor: Wrap existing gateways behind a single `PaymentGatewayInterface`. Extend `wallet/charge` for Apple Pay / Mada / STC Pay per SRS. Webhook route with signature verify → `WalletService::credit`. Feature test with HTTP fake.

### `T-2.4` Subscriptions / packages
- [ ] **Goal:** Package purchase debits wallet or gateway; active subscription affects billing.
- **Covers:** `R-WALLET-05`–`07`
- **Acceptance:** Four packages seeded; purchase creates `client_subscriptions` row; API returns active package + progress.

> 🟡 Cursor: `SubscriptionService` + admin package CRUD. **Client** API: list packages, purchase, `GET active-subscription`.

---

## Phase 3 — Fleet & rides (core domain)

### `T-3.1` Scooter fleet admin + API
- [ ] **Goal:** Admin fleet CRUD; auto `SCT-XXXX` code; QR sticker; **client** available-scooters endpoint.
- **Covers:** `A-FLEET-01`–`03`, `R-HOME-04`–`05`, `S-RT-01`
- **Acceptance:** Admin add-scooter generates QR image; `GET /api/client/scooters/available?lat&lng` excludes <5% battery and out-of-service.

> 🟡 Cursor: Admin `ScooterController` + `Entity\ScooterService` (match `ClientService` / `ProviderService` patterns): list/map/filter, store with auto code + `simplesoftwareio/simple-qrcode`, image upload via `ModelTrait`. API `ScooterController@available` with haversine distance, cache hint headers. Register `routes/dashboard/*_scooters.php`.

### `T-3.2` Ride state machine + client API
- [ ] **Goal:** Full ride lifecycle API with guarded transitions.
- **Covers:** `R-RIDE-01`–`11`, `A-RIDE-01`
- **Acceptance:** Feature tests for each transition; invalid transition returns 422; pre-ride balance/permission checks enforced.

> 🟡 Cursor: `RideService` state machine: scan → verification photo → active → ending → completed (+ cancelled). Endpoints: start-scan, submit-verification-photo, activate, end (with confirmation payload), submit-parking-photo, rate. Spatie collections `verification_photo`, `parking_photo`. Enforce `R-STATE-02` and `R-RIDE-11` edge cases in service.

### `T-3.3` Real-time telemetry
- [ ] **Goal:** Broadcast ride updates to **client**; ingest scooter MQTT (or simulated).
- **Covers:** `R-RIDE-06`, `A-RIDE-02`, `S-RT-01`–`02`, `N-PERF-01`
- **Acceptance:** Active ride channel pushes timer/balance/battery each second; `ride_telemetry` rows for replay; grace-period auto-stop job on depletion.

> 🟡 Cursor: Extend **`nodeServer/`** Socket.IO for ride channels + FCM alerts. Optional Laravel broadcasting later. Artisan command or MQTT bridge updating `Scooter` location/battery. Job `AutoStopRideOnDepletion` after grace period. Admin live-rides page consumes same socket namespace.

### `T-3.4` Geofencing (v1)
- [ ] **Goal:** Zone CRUD in admin; violation detection on ride GPS updates.
- **Covers:** `A-CONTENT-01`, `S-GEO-01`, `A-RIDE-02`
- **Acceptance:** Point-in-polygon check on telemetry; `geofence_violation` logged; no-ride zone blocks ride start.

> 🟡 Cursor: `GeofenceZone` model (GeoJSON polygon in JSON column for v1). Admin CRUD + map drawing (Google Maps JS in Blade). `GeofenceService::contains`, `::violation`. Hook into ride telemetry listener. Plan PostGIS migration as `T-3.4b` later.

---

## Phase 4 — Provider domain (backend + admin) — *SRS “Investor”*

### `T-4.1` Provider admin — list & approval (`A-INV`)
- [ ] **Goal:** Admin **providers** module with approval workflow.
- **Covers:** `A-INV-01`–`02`, `I-AUTH-05`
- **Acceptance:** Super Admin can Approve/Reject(+reason)/Hold; audit log entry; email/SMS to **provider**.

> 🟡 Cursor: Admin **`ProviderController`** (extend `codebase` `Admin\ProviderController`): index filters, show KYC media, approve/reject/hold + `AuditLogService`. Sidebar + permissions (`admin.providers.*`).

### `T-4.2` Vehicle assignment (`A-INV-04`)
- [ ] **Goal:** Assign/unassign scooters to **providers** from admin.
- **Covers:** `I-VEH`, `A-INV-04`
- **Acceptance:** Multi-select unassigned scooters; `profit_rate` + `assigned_at`; provider `NO_VEHICLES` → `ACTIVE` when first assigned.

> 🟡 Cursor: Modal + `ProviderAssignmentService`: sync `scooters.provider_id`, update **`Provider`** state, notify provider push/email.

### `T-4.3` Settlement & invoices (`A-FIN-05`, `I-FIN`)
- [ ] **Goal:** Monthly settlement computation + PDF invoices + bulk admin actions.
- **Reuses:** Maatwebsite Excel; add `mpdf` or `barryvdh/laravel-dompdf` if needed
- **Covers:** `A-FIN-05`–`06`, `I-FIN-01`–`03`, `N-FIN-01`
- **Acceptance:** `computeSettlement(YYYY-MM)` correct 18% share; PDF has ZATCA fields + 15% VAT; queued bulk generate; 8-step status enum on settlement batch.

> 🟡 Cursor: `SettlementService`, `InvoicePdfService`, admin Finance → Settlements panel (month picker, table, bulk actions). Queue `GenerateSettlementInvoicesJob`. Unit tests for share math. **Provider** API read-only: `GET settlements`, `GET invoices/{id}/pdf`.

### `T-4.4` Provider dashboard API (read-only analytics) — *SRS “Investor dashboard”*
- [x] **Goal:** `/api/provider/*` analytics: KPIs, vehicles, earnings, transactions.
- **Covers:** `I-HOME`, `I-VEH`, `I-EARN`, `I-ACC`
- **Acceptance:** Dashboard routes require approved provider (`is_approved` + `provider.approved` middleware); CSV export on `GET provider/earnings/export`; legacy branch `HomeController` removed.

> **Done:** `routes/api/provider.php`, `ProviderDashboardService`, `DashboardController`, Postman `07 — Dashboard`. Profile/IBAN remain in shared `routes/api.php` profile group.

---

## Phase 5 — Admin panel modules (Blade)

> Match existing admin modules (`routes/dashboard/`, `MenuTrait`, permission slugs in lang files). Add sidebar entries + permissions per module.

### `T-5.1` Admin dashboard (`A-DASH`)
- [~] **Goal:** BEEB KPI dashboard replacing generic admin home.
- **Reuses:** `HomeController`, chart assets
- **Acceptance:** 6 KPI cards + 5 charts + quick actions + activity feed (live or seeded).

> 🟡 Cursor: `Admin\DashboardController` + service aggregating **clients**, rides today, revenue, active scooters, tickets, avg rating. Blade view with ApexCharts. Quick actions (add scooter, review **providers** badge count, settlements).

### `T-5.2` Client management (`A-RIDER`) — *SRS “Riders”*
- [ ] **Goal:** Admin **clients** table, filters, detail tabs, RBAC actions with audit.
- **Covers:** `A-RIDER-01`–`05`
- **Acceptance:** Block/refund/delete follow tier rules; each action writes `audit_logs`; confirm modals in Blade.

> 🟡 Cursor: Admin **`ClientController`** (from `codebase` `Admin\ClientController` pattern): index DataTable, show tabs Profile/Rides/Wallet/Transactions/Tickets, block, refund tiers, gift balance (Super Admin), delete, reset OTP.

### `T-5.3` Fleet management (`A-FLEET`)
- [ ] **Goal:** List + map view, vehicle detail tabs, maintenance log, actions by role.
- **Covers:** `A-FLEET-01`–`06`
- **Acceptance:** Map toggle works; maintenance subpanel CRUD; remote lock sets scooter flag (IoT command stub).

> 🟡 Cursor: Extend `T-3.1` admin: map view, detail tabs Overview/Rides/Maintenance/Technical, maintenance scheduling fields, role-gated action buttons.

### `T-5.4` Ride management (`A-RIDE`)
- [ ] **Goal:** Rides list, live map, detail replay, disputes panel.
- **Covers:** `A-RIDE-01`–`05`
- **Acceptance:** Live rides page uses broadcasting; ride detail shows timeline + telemetry replay; dispute resolve updates ride + refund optional.

> 🟡 Cursor: Admin `RideController`: filters, live view (Echo), show with map replay JS + timeline partial, dispute list + resolve form linked to `SupportTicket` or `Complaint` adaptation.

### `T-5.5` Finance admin (`A-FIN`)
- [ ] **Goal:** Revenue dashboard, ledger, refunds tier policy, financial settings.
- **Covers:** `A-FIN-01`–`04`, `A-FIN-07`
- **Acceptance:** Refund approval routes check amount tiers; settings keys editable Super Admin only.

> 🟡 Cursor: Finance section: revenue KPIs, `wallet_transactions` ledger, refunds workflow, link to settlements (`T-4.3`), extend `SettingService` for Appendix C keys.

### `T-5.6` Content & support (`A-CONTENT`)
- [~] **Goal:** Extend base FAQ/banners/notifications; add tickets SLAs; geofence UI from `T-3.4`.
- **Reuses:** `Faq`, `Slider`, `Notification`, `Complaint`/`ContactMessage`
- **Covers:** `A-CONTENT-01`–`05`, `R-ACC-06`–`08`
- **Acceptance:** Campaign builder targets rider segments; ticket detail shows linked ride; SLA badges on inbox.

> 🟡 Cursor: Adapt Complaint → `SupportTicket` (priority, SLA enums, link `ride_id`). Banner CRUD if not present. Notification campaign: audience = **clients** in city / segment. FAQ types for Rides/Wallet/Account (`R-ACC-07`).

### `T-5.7` Reports, audit, settings (`A-REPORT`, `A-SET`)
- [ ] **Goal:** Export reports, immutable audit viewer, staff CRUD with 2FA flag.
- **Covers:** `A-REPORT-01`–`06`, `A-SET-01`–`03`
- **Acceptance:** Audit log UI read-only; CSV export; Operator cannot access audit export.

> 🟡 Cursor: `AuditLog` admin index (filters: actor, action, date range). Reports: rides/fleet/revenue Excel exports via Maatwebsite. Staff management: force password change on first login checkbox.

---

## Phase 6 — Rider mobile app (separate repo — after API stable)

> **Prerequisite:** Phase 1–3 **client** API complete + Postman collection. Mobile app is the SRS “rider” product; all calls go to **`/api/client/*`**.

### `T-6.1` Expo shell + auth
- [ ] **Covers:** `R-AUTH-01`–`06`, `R-HOME-01`
- **Acceptance:** Consumes `/api/client/*`; SecureStore tokens; RTL + yellow theme.

> 🟡 Cursor: New Expo app: 4-tab navigation, splash, IntroPage content from API, phone OTP flow, profile completion. Base URL from env. No duplicate business logic — API only.

### `T-6.2` Map, ride flow, wallet, account
- [ ] **Covers:** `R-HOME`–`R-ACC`, `R-NOTIF`, `R-PERM`
- **Acceptance:** End-to-end ride against staging API; FCM push; offline queue for end-ride sync (`N-AVAIL-01`).

> 🟡 Cursor: Implement remaining rider-app screens per @docs/SRS.md Part 2 (`R-HOME` through `R-NOTIF`) against **`/api/client/*`**. Socket client to `nodeServer` for active ride. Google Maps markers from available endpoint.

---

## Phase 7 — Provider portal (Blade) — *SRS "Investor dashboard"*

> **Decision:** Laravel Blade portal at `/provider` prefix (same monolith, separate session guard). Dark + yellow RTL theme. Consumes `ProviderDashboardService` directly (no HTTP round-trip). Figma screens: `ai helper/provider/*.png`.
>
> **API ready (T-4.4):** home, vehicles, vehicle-detail, earnings, earnings/export, transactions — `ProviderDashboardService` reused directly in Blade controllers.

---

### `T-7.1.1` Layout foundation & auth guard
- [ ] **Goal:** Blade master layout + `provider` session guard + route group + theme.
- **Covers:** `I-HOME-01` (sidebar + topbar shell)
- **Files to create/edit:**
  - `config/auth.php` — add `providers.providers` (Eloquent `Provider`) + `guards.provider` (session)
  - `app/Http/Middleware/ProviderSessionMiddleware.php` — unauthenticated -> `/provider/login`; not-approved -> `/provider/pending`
  - `routes/provider.php` — prefix `/provider`, loaded in `RouteServiceProvider` with `['web', 'provider-session']`
  - `resources/views/provider/layouts/app.blade.php` — dark sidebar + topbar
  - `resources/views/provider/layouts/auth.blade.php` — split-screen: brand panel (right) + form (left)
  - `public/css/provider.css` — dark theme `#16161E` bg, `#FFD700` yellow, `#1F1F2A` card surface, RTL
- **Acceptance:**
  - Unauthenticated -> `/provider/login`; approved=false -> `/provider/pending`
  - Sidebar: BEEB duck logo (top), 4 nav items (الرئيسية, مركباتي, الأرباح, حسابي), "تسجيل الخروج" bottom-red
  - Topbar: investor name + yellow avatar-initials circle + notification bell
  - Active nav item highlighted (dark yellow `#3a3200` background)
  - `<html dir="rtl" lang="ar">` on all provider pages

> 🟡 Cursor: Add `provider` guard in `config/auth.php` (driver: session, provider: providers using `App\Models\Provider`). Register `routes/provider.php` in `RouteServiceProvider::boot()`. Middleware `ProviderSessionMiddleware` checks `Auth::guard('provider')->check()`. Build `layouts/app.blade.php` from `provider-vehicles.png` (sidebar, 4 nav items, logout). `layouts/auth.blade.php` from `provider-login.png` (brand panel right with duck logo + "استثمارك الذكي" + 3 bullets + 3 stats).

---

### `T-7.1.2` Auth pages — Login, Register, Forgot password, Pending
- [ ] **Goal:** Full investor auth flow in Blade (session-based, delegates to existing services).
- **Covers:** `I-AUTH-01`--`I-AUTH-05`
- **Files:**
  - `app/Http/Controllers/Provider/AuthController.php`
  - `resources/views/provider/auth/login.blade.php`
  - `resources/views/provider/auth/register.blade.php` (2-step with JS stepper)
  - `resources/views/provider/auth/forgot-password.blade.php`
  - `resources/views/provider/auth/reset-password.blade.php`
  - `resources/views/provider/auth/pending.blade.php`
- **Acceptance:**
  - **Login** (from `provider-login.png`): tab pair تسجيل الدخول / إنشاء حساب. Fields: email, password (show/hide eye), "تذكرني", "نسيت كلمة المرور؟" link. CTA yellow full-width. `needApproval` -> pending page.
  - **Register step 1** (from `provider-register step 1.png`): stepper 2 steps. Fields: first_name, last_name, email, phone (+966), password (strength meter). "التالي ←" = JS advance (no page reload). Client-side validation before step 2.
  - **Register step 2** (from `provider-register step 2.png`): national ID (10 digits), IBAN (SA+22), vehicle count toggle-buttons (1-2 / 3-5 / 6-10 / 10+, yellow when selected), document drag-drop upload (PDF/JPG/PNG <= 10MB), 18% profit badge read-only, terms checkbox. "إنشاء الحساب" CTA. Calls `ProviderRegistrationService`.
  - **Pending page:** duck icon + "جارٍ مراجعة طلبك" + logout link.
  - **Forgot password:** email -> OTP -> new password (calls `Provider\ForgetPasswordController` logic).

> 🟡 Cursor: `AuthController@login` uses `Auth::guard('provider')->attempt(...)`. On `needApproval` redirect to `/provider/pending`. Register POSTs multipart to `AuthController@register` which calls `ProviderRegistrationService`. Stepper = two `<fieldset>` blocks toggled by JS. Match exact Figma layout for both screens.

---

### `T-7.1.3` Home dashboard (I-HOME)
- [ ] **Goal:** Main dashboard page -- KPIs, charts, today summary, vehicles mini, last-5 transactions.
- **Covers:** `I-HOME-02`--`I-HOME-06`
- **Files:**
  - `app/Http/Controllers/Provider/HomeController.php`
  - `resources/views/provider/home/index.blade.php`
- **Data source:** `ProviderDashboardService::forAuthenticated()->home()`
- **Acceptance (from `provider-home statistics.png`):**
  - **4 KPI cards** (dark surface, yellow numbers): نسبة أرباحك 18%, الربح المتوقع هذا الشهر, رحلات اليوم + متوسط/مركبة, إجمالي الأرباح + MoM % badge
  - **Monthly earnings bar chart** (ApexCharts CDN): last 6 months, current month yellow, others dark-yellow, tooltip. Range select dropdown (3/6/12 months) updates chart via AJAX.
  - **Today summary card:** إيراد اليوم, حصتك, vs-yesterday % with up/down arrow.
  - **Vehicles mini-summary:** total / نشط / صيانة as colored segment bar.
  - **Recent transactions table:** 5 rows -- كود المركبة, المنطقة, رحلات, الوقت (relative), المبلغ. "عرض الكل" link. Empty state card.
  - Single service call, < 500ms page load.

> 🟡 Cursor: `HomeController@index` calls `$service->home()`. JSON-encode chart data into `<script>` variable. ApexCharts bar init in `@push('scripts')`. AJAX months selector: `HomeController@chart` returns JSON. Match `provider-home statistics.png` precisely.

---

### `T-7.1.4` My Vehicles page (I-VEH)
- [ ] **Goal:** Fleet card grid with status filters + vehicle detail modal.
- **Covers:** `I-VEH-01`--`I-VEH-05`
- **Files:**
  - `app/Http/Controllers/Provider/VehicleController.php`
  - `resources/views/provider/vehicles/index.blade.php`
  - `resources/views/provider/vehicles/partials/card.blade.php`
  - `resources/views/provider/vehicles/partials/detail-modal.blade.php`
- **Data source:** `ProviderDashboardService::vehicles()` + `vehicleDetail($id)`
- **Acceptance (from `provider-vehicles.png`):**
  - **Header:** "مركباتي (N)" + "إدارة ومتابعة مركباتك"
  - **Filter chips:** الكل / نشط / في رحلة / صيانة / متوقف -- yellow selected, JS client-side filter by `data-status`.
  - **Vehicle card:** status badge (نشط green dot, في رحلة pulsing yellow, صيانة orange, متوقف gray), lock icon + code (yellow bold), إيراد اليوم (SAR yellow), رحلات اليوم, المنطقة (pin icon). Hover: lighter surface.
  - **Empty state:** duck + "في انتظار تعيين أول مركبة لك"
  - **Detail modal** (click card -> AJAX): photo, code, status, revenue (day/week/month), حصتك, total rides, avg duration, utilization %, last 5 rides. Close (x) button.

> 🟡 Cursor: `VehicleController@index` view, `VehicleController@show` JSON. Each card `<div data-status="...">`. JS chips toggle `hidden`. Modal = `<dialog>` filled from AJAX. Match `provider-vehicles.png` exactly.

---

### `T-7.1.5` Earnings & profit stats page (I-EARN)
- [ ] **Goal:** Full earnings analytics -- 2 charts + per-vehicle table + CSV export.
- **Covers:** `I-EARN-01`--`I-EARN-04`
- **Files:**
  - `app/Http/Controllers/Provider/EarningsController.php`
  - `resources/views/provider/earnings/index.blade.php`
- **Data source:** `ProviderDashboardService::earnings()` + `perVehicleEarningsTable()`
- **Acceptance (from `provider-profit statistiscs.png`):**
  - **4 KPI cards:** نسبة أرباحك, متوسط ربح يومي (30 يوم), ربح هذا الشهر, إجمالي الأرباح
  - **Monthly bar chart** (ApexCharts): range picker (3/6/12 months) AJAX update via `EarningsController@chart`
  - **YoY comparison** (ApexCharts line/area): 12 months, 2 series (هذا العام / العام الماضي), toggle area/line button
  - **Per-vehicle table:** الكود, الحالة, المنطقة, رحلات اليوم, إيراد اليوم, نسبة أرباحك%, حصتك اليومية, إيراد الشهر, حصتك الشهرية. Top performer: yellow border + star icon. JS sortable headers.
  - **Export CSV button** (yellow-outlined): `<a href="/provider/earnings/export">` -- `EarningsController@export` delegates to `ProviderDashboardService::perVehicleEarningsTable()` + streams CSV.

> 🟡 Cursor: Two chart divs `#chart-monthly` + `#chart-yoy`. `@push('scripts')` inits both. Per-vehicle table: yellow ring on `is_top_performer` row. Export = plain anchor. Match `provider-profit statistiscs.png`.

---

### `T-7.1.6` Account & profile page (I-ACC)
- [ ] **Goal:** Profile card + personal info form + change-password sub-page.
- **Covers:** `I-ACC-01`--`I-ACC-04`
- **Files:**
  - `app/Http/Controllers/Provider/AccountController.php`
  - `resources/views/provider/account/index.blade.php`
  - `resources/views/provider/account/change-password.blade.php`
- **Acceptance (from `provider-update profile.png` + `provider-change password.png`):**
  - **Profile card (right):** avatar initials yellow circle, full name, "مستثمر منذ {month year}", "حساب موثق ✓" green badge. Rows: مركبات / نسبة الأرباح / عضوية نشطة (months). Actions: "تغيير كلمة المرور" button, "تسجيل الخروج" red link.
  - **Personal info form (left):** الاسم الكامل (editable), رقم الجوال (editable + OTP modal), البريد الإلكتروني (read-only), رقم الهوية (masked xxxxxxxx12, read-only), رقم الإيبان (masked SAxxxxxxxx1234, editable). "حفظ التغييرات" yellow button.
  - **Change password page** (`/provider/account/password`): 3 password inputs, live requirements checklist (4 rows: 8 chars / uppercase / number / special char -- green check or red X on input), "آخر تغيير منذ N أشهر", CTA + "إلغاء والعودة" link.

> 🟡 Cursor: `AccountController@index` passes `$provider = Auth::guard('provider')->user()`. Avatar initials = mb_substr first letters. Change-password: Alpine `x-data` computes `hasUpper`, `hasNumber`, `hasSpecial`, `hasLength` live. Save profile POSTs to `AccountController@update` using `ProfileBaseService`. Match both Figma screens.

## Phase 8 — Cross-cutting, QA & release

### `T-8.1` Security (`N-SEC-01`)
- [ ] **Acceptance:** Rate limits on OTP/payment; CSRF on admin; national ID / IBAN masking helpers; `@beebbeep.sa` admin email validation.

> 🟡 Cursor: `RouteServiceProvider` or middleware rate limiting; `MaskingHelper` for Blade/API resources; security headers middleware; PHPUnit test Operator cannot hit super-admin routes.

### `T-8.2` Compliance (`N-PRIV-01`, `N-FIN-01`, `N-AUDIT-01`)
- [ ] **Acceptance:** Scheduled command deletes ride photos >30 days; **client** data export/delete endpoints; audit retention policy in `docs/COMPLIANCE.md`.

> 🟡 Cursor: `DeleteExpiredRidePhotosCommand` daily schedule; **`ClientDataExportController`**; verify invoice PDF ZATCA fields; document 5-year audit retention (no delete in `AuditLogService`).

### `T-8.3` Testing & CI
- [ ] **Acceptance:** `php artisan test` green; GitHub Actions: pint + phpunit on PR; critical path Feature tests listed in `docs/TEST_PLAN.md`.

> 🟡 Cursor: Feature tests: **client** OTP, ride happy path, billing edge cases, settlement math, **provider** approve. GitHub Actions workflow. Postman: `client` + `provider` collections under `docs/postman/`.

### `T-8.4` Runbook & handoff
- [ ] **Acceptance:** `docs/RUNBOOK.md` covers local setup, queue worker, MQTT bridge, env vars, demo seed.

> 🟡 Cursor: Write RUNBOOK + update root README for BEEB BEEB (not generic Laravel). List all env vars (FCM, Moyasar, Google Maps, Reverb, MQTT).

---

## Appendix A — Build order summary (dependency-sorted)

1. **Phase 0** — Legacy cleanup, SRS, domain context, enums, migrations, seeders, admin theme.
2. **Phase 1** — **Client** OTP auth, **Provider** auth + KYC, staff 2FA, client account-state middleware.
3. **Phase 2** — Wallet (on `Client`), billing, payments, subscriptions.
4. **Phase 3** — Scooters, ride state machine, realtime, geofencing v1.
5. **Phase 4** — Provider approval, assignment, settlements, provider analytics API.
6. **Phase 5** — Admin Blade (dashboard → **clients** → fleet → rides → finance → content → audit).
7. **Phase 6** — Rider mobile app (Expo; consumes **client** API).
8. **Phase 7** — Provider portal (Blade `/provider` or external SPA).
9. **Phase 8** — Security, compliance, CI, runbook.

**Parallelization tip:** After Phase 3, admin fleet/rides (`T-5.3`–`5.4`) can proceed alongside Phase 4 **provider** APIs.

## Appendix B — Screens flagged in SRS as "missing / must design"

These were marked not-yet-in-Figma and must be designed during build:
- Investor: **Forgot Password** screen, **Vehicle Detail** screen, **Notifications panel**, **Invoices/Settlements** screen, **Transaction detail modal**, **Empty states**.
- Admin: all screens (no Figma) — design from the SRS specs, plus **Empty states** and **404/500/403** error pages.

## Appendix C — Key business constants (from SRS, keep in SettingsService — never hardcode)

| Constant | Default |
|---|---|
| Price per minute | 0.45 SAR |
| Min balance to start ride | 5 SAR |
| Min wallet top-up | 10 SAR |
| Low-balance alert threshold | 10 SAR |
| Packages | 15 / 79 / 249 / 399 SAR (day/week/month/2-month) |
| Investor profit share | 18% |
| VAT | 15% |
| Settlement transfer day | 7th of month |
| Verification photo retention | 30 days |
| Audit log retention | 5 years |
| Scooter map refresh | 10–15 s |
| Ride telemetry update | 1 s |
| Investor verification time | 24–72 h |
| Staff password | 12+ chars, 90-day rotation, no last-5 reuse, 5-fail lockout 30min |

---

*Generated from BEEB BEEB SRS v1.2 (92 pages) + Figma screens. **Tasks aligned to actual `beeb` repo** (Laravel 9 `codebase` fork): `/api/client/*`, `/api/provider/*`, `/admin/*`, existing wallet/auth, marketplace legacy called out. Part 2 feature IDs unchanged. Keep this file in the repo root and reference it from Cursor prompts.*

*Last revised: 2026-06-03 — Provider `T-1.2` progress (KYC register, forgot-password controller, Postman Provider folder), snapshot table*
