Module System
WhatsMine's product features live in self-contained modules under app/Modules/. Each module registers its own routes, migrations, models and services, and is auto-discovered at boot — so adding a feature doesn't require touching the core.
The modules
| Module | Responsibility |
|---|---|
| Shared | Core messaging models: Contact, Conversation, Message, ChannelAccount, Segment, tags. Services: ChannelManager, ContactService, SegmentResolver. |
WhatsApp Business: accounts, phone numbers, templates, auto-replies, widget. CloudApiClient, WhatsappDriver. | |
| Inbox | Unified team inbox + Messenger/Instagram drivers, canned replies, labels, notes. |
| Social | Social media posting (Facebook/IG/LinkedIn/X/YouTube/TikTok). |
| Integrations | Credential storage & resolution (CredentialResolver). |
| AI | Chatbots, knowledge bases (RAG), LLM provider abstraction. |
| Automation | Visual no-code workflow engine. |
| Broadcasting | Bulk WhatsApp/SMS/Email campaigns. |
| Leads | Google Places lead scraping. |
| Ecommerce | Shopify/WooCommerce/BigCommerce sync. |
How a module is structured
app/Modules/{Name}/
├── {Name}ServiceProvider.php ← registers routes + migrations
├── Http/Controllers/
├── Models/
├── Services/
├── Jobs/
├── routes/web.php
└── database/migrations/
The provider loads everything automatically:
class ExampleServiceProvider extends ServiceProvider
{
public function boot(): void
{
$this->loadRoutesFrom(__DIR__.'/routes/web.php');
$this->loadMigrationsFrom(__DIR__.'/database/migrations');
}
}
App\Providers\ModuleServiceProvider discovers and registers every module's provider, so you don't have to wire each one up manually.
Creating a new module
Scaffold a module with one command:
php artisan saas:make-module ProjectManagement
This generates the controller, model, service, routes and migration folders ready to go. Add your routes under the standard middleware stack:
Route::middleware(['auth', 'verified', 'client.scope'])
->prefix('app/projects')
->name('client.projects.')
->group(function () {
Route::get('/', [ProjectController::class, 'index'])->name('index');
});
Place React pages in resources/js/Pages/{ModuleName}/ — they use the existing ClientLayout and Inertia routing automatically.
Conventions
- Keep modules independent — avoid cross-module imports. Shared logic belongs in the Shared module or
app/Services/. - Distinct migration timestamps prevent collisions with core migrations.
- Module permissions are seeded by the module's seeder.
The channel driver pattern
New messaging channels implement ChannelDriverInterface and register with ChannelManager. Each driver provides send(), processWebhookPayload() and verifyCreds(), so the inbox and campaigns work with any channel uniformly.
➡️ Next: REST API.