Architecture
This section is for developers who host, customise or extend WhatsMine. It assumes familiarity with Laravel.
High-level design
WhatsMine is a monolithic Laravel 12 application that uses Inertia.js to render a React single-page interface — so there's no separate API layer for the web UI; controllers return Inertia pages that hydrate React components.
Browser ── Inertia (React) ── Laravel Controllers ── Eloquent ── MySQL
├── Queue Jobs ── Redis/DB
└── REST API v1 ── Sanctum
Authentication guards
Two separate guards keep platform staff and customers completely isolated:
| Guard | Model | Table | Login |
|---|---|---|---|
web | User | users | /login |
admin | AdminUser | admin_users | /admin/login |
The admin guard only reaches /admin/* routes; customers never share a session with admins.
Multi-tenancy model
AdminUser (platform staff)
└── manages Clients (businesses)
├── owns a Subscription → Plan
└── has Users (team members)
└── belong to Workspaces
└── Contacts · Conversations · Campaigns · …
- A Client is the billable B2B organisation. The subscription belongs to the Client, not a User.
- Users are individuals; they can belong to multiple Workspaces.
- Most product data is scoped by
workspace_id, keeping tenants separate.
Request lifecycle (customer area)
- Request hits Laravel.
webmiddleware: session, CSRF, locale, Inertia, secure headers.auth(web guard) +verified.client.scope— loads the Client and active Subscription onto the request.- Controller returns
Inertia::render(...). - React hydrates on the client.
Key middleware
| Middleware | Purpose |
|---|---|
EnsureClientScope | Attaches the client + subscription. |
HandleInertiaRequests | Shares CSRF, locale, theme, branding, auth & permissions to every page. |
EnsureAdminRole / RequirePermission | Admin RBAC gates. |
SetLocale | Applies the active language (and RTL direction). |
SecureHeaders | CSP, HSTS, X-Frame-Options. |
EnsureNotDemoMode | Blocks writes in demo mode. |
Billing architecture
BillingGatewayInterface
├── StripeGateway
├── PayPalGateway
└── PaddleGateway
BillingGatewayRegistry — discovers enabled gateways
CheckoutController — starts checkout
WebhookController — verifies & persists gateway events (billing_events)
Gateway webhooks are signature-verified, and raw payloads are stored to billing_events for idempotency, replay and audit. Renewals are webhook-driven, with an hourly billing:sync safety net.
Queues & real-time
Background work runs on named queues: whatsapp, broadcast, ai, social, leads, automation, default. Real-time events (new message, status update, typing, assignment) broadcast on private conversation.{id} and workspace.{id} channels via Pusher/Reverb and Laravel Echo.
Service providers
bootstrap/providers.php registers AppServiceProvider, ModuleServiceProvider (auto-discovers every product module), PusherSettingsServiceProvider and BroadcastChannelsServiceProvider.
Directory map
app/
├── Console/Commands/ ← saas:install, billing:sync, db:backup, …
├── Http/
│ ├── Controllers/{Admin,Api/V1,Client}/
│ └── Middleware/
├── Models/
├── Modules/ ← the product modules (see Module System)
└── Services/Billing/ ← Stripe / PayPal / Paddle gateways
resources/js/
├── Components/ ← shared UI + design system (ui/)
├── Layouts/ ← AdminLayout, ClientLayout, InboxLayout, …
└── Pages/ ← Inertia pages (Admin, Auth, client, Inbox, …)
routes/
├── web.php admin.php client.php api.php reports.php
├── channels.php console.php webhooks.php
➡️ Next: Module System.