Architecture
A comprehensive overview of MailTrixy's technical architecture, design patterns, and system structure.
Tech Stack Overview
MailTrixy is built on a modern PHP stack designed for scalability, maintainability, and developer productivity.
| Technology | Version | Purpose |
|---|---|---|
| Laravel | 12.x | Backend framework, routing, ORM, queues, events |
| Livewire | 4.x | Reactive UI components without writing JavaScript |
| Alpine.js | 3.x | Lightweight JavaScript for interactive UI elements |
| Tailwind CSS | 4.x | Utility-first CSS framework for styling |
| MySQL | 8.0+ | Primary relational database |
| PHP | 8.2+ | Server-side programming language |
| Laravel Sanctum | 4.x | API token authentication |
| Laravel Cashier | 15.x | Subscription billing with Stripe |
Directory Structure
MailTrixy follows the standard Laravel directory structure with additional organization for domain-specific logic.
app/
├── Console/ # Artisan commands and Kernel
├── Events/ # Event classes for real-time notifications
├── Helpers/ # Global helper functions
├── Http/
│ ├── Controllers/ # HTTP controllers (API & Web)
│ ├── Middleware/ # Request middleware (workspace, throttle)
│ └── Requests/ # Form request validation
├── Jobs/ # 13 queue job classes
├── Livewire/ # 47 Livewire components
├── Mail/ # Mailable classes for transactional emails
├── Models/ # 49 Eloquent models
├── Notifications/ # Notification classes
├── Policies/ # Authorization policies
├── Services/ # Service layer classes
└── Traits/ # Shared traits (AuthorizesWorkspaceActions)
database/
├── factories/ # Model factories for testing
├── migrations/ # 41 migration files
└── seeders/ # Database seeders with demo data
resources/
├── css/ # Tailwind source files
└── views/
├── components/ # Blade components
├── email-templates/ # 52 email templates
├── layouts/ # Application layouts
└── livewire/ # Livewire component views
routes/
├── api.php # REST API routes (v1)
├── channels.php # Broadcasting channels
├── console.php # Console commands
└── web.php # Web routes
49 Models Overview
MailTrixy uses 49 Eloquent models organized across the following domains. Each model belongs to a workspace through the multi-tenant architecture.
| Domain | Models | Count |
|---|---|---|
| Core | User, Workspace, WorkspaceMember, WorkspaceInvitation, Role, Permission | 6 |
| EmailAccount, Email, EmailFolder, EmailAttachment, EmailSignature, EmailTemplate | 6 | |
| Conversations | Conversation, ConversationMessage, ConversationParticipant, ConversationAssignment, ConversationLabel | 5 |
| Contacts | Contact, ContactGroup, ContactField, ContactFieldValue, ContactNote, ContactActivity | 6 |
| Campaigns | Campaign, CampaignRecipient, CampaignAnalytics, CampaignTemplate, CampaignSchedule | 5 |
| Workflows | Workflow, WorkflowStep, WorkflowExecution, WorkflowPreset, WorkflowLog | 5 |
| AI | AiProvider, AiConversation, AiMessage, AiUsageLog, SentimentAnalysis | 5 |
| Knowledge Base | KnowledgeBase, KBDocument, KBChunk, KBWebsiteScrape | 4 |
| Billing | Plan, Subscription, Payment, Invoice | 4 |
| Misc | Tag, CannedResponse, Webhook | 3 |
41 Migrations
MailTrixy ships with 41 database migrations that create all the required tables and indexes. Migrations are timestamped and run sequentially to establish the correct foreign key relationships. Key migration groups include:
- Core tables — users, workspaces, workspace_members, roles, permissions (5 migrations)
- Email tables — email_accounts, emails, email_folders, email_attachments, email_signatures, email_templates (6 migrations)
- Conversation tables — conversations, conversation_messages, participants, assignments, labels (5 migrations)
- Contact tables — contacts, contact_groups, custom fields, field values, notes, activities (6 migrations)
- Campaign tables — campaigns, campaign_recipients, analytics, templates, schedules (5 migrations)
- Workflow tables — workflows, steps, executions, presets, logs (5 migrations)
- AI tables — ai_providers, ai_conversations, ai_messages, usage_logs, sentiment_analyses (5 migrations)
- Knowledge base tables — knowledge_bases, kb_documents, kb_chunks, kb_website_scrapes (4 migrations)
47 Livewire Components
The frontend is powered by 47 Livewire components that provide reactive, real-time user interfaces without heavy JavaScript. Components are organized by feature domain:
- Inbox — ConversationList, ConversationView, MessageComposer, EmailViewer, FolderTree (5 components)
- Contacts — ContactTable, ContactForm, ContactImport, ContactGroupManager, ContactFieldEditor, MergeContacts (6 components)
- Campaigns — CampaignBuilder, CampaignList, TemplateEditor, RecipientSelector, CampaignAnalytics, ScheduleManager (6 components)
- Workflows — WorkflowBuilder, WorkflowList, StepEditor, WorkflowPresets, ExecutionLog (5 components)
- AI — AiChatPanel, AiReplyGenerator, SentimentViewer, AiSettings, SpendingCapManager (5 components)
- Knowledge Base — KBManager, DocumentUploader, WebsiteScraper, ChunkViewer (4 components)
- Settings — WorkspaceSettings, AccountSettings, EmailAccountManager, SignatureEditor, NotificationPreferences, WebhookManager (6 components)
- Admin — AdminDashboard, PlanManager, UserManager, PaymentGatewaySettings, GlobalSettings, SystemHealth (6 components)
- Shared — TagSelector, FileUploader, RichTextEditor, Modal (4 components)
Multi-Tenant Workspace Architecture
MailTrixy uses a single-database, multi-tenant architecture where every data record belongs to a workspace. Workspace isolation is enforced at multiple levels:
- Global Scope — A
WorkspaceScopeis automatically applied to all workspace-scoped models, ensuring queries only return data belonging to the current workspace. - Middleware — The
SetCurrentWorkspacemiddleware resolves the active workspace from the session or subdomain and binds it to the application container. - Model Trait — Models use the
BelongsToWorkspacetrait which auto-assignsworkspace_idon creation and applies the global scope. - Policy Layer — Authorization policies verify that the authenticated user belongs to the same workspace as the requested resource.
// Example: BelongsToWorkspace trait
trait BelongsToWorkspace
{
protected static function bootBelongsToWorkspace(): void
{
static::addGlobalScope(new WorkspaceScope);
static::creating(function ($model) {
if (! $model->workspace_id) {
$model->workspace_id = current_workspace_id();
}
});
}
public function workspace(): BelongsTo
{
return $this->belongsTo(Workspace::class);
}
}
Service Layer Pattern
Business logic is encapsulated in dedicated service classes rather than being placed directly in controllers or Livewire components. This provides clean separation of concerns and makes the codebase testable.
- EmailSyncService — Handles IMAP connection, folder synchronization, and email parsing.
- CampaignService — Manages campaign creation, scheduling, sending, and analytics tracking.
- WorkflowEngine — Executes workflow steps, evaluates conditions, and manages execution state.
- AiService — Abstracts AI provider communication, token counting, and spending cap enforcement.
- KnowledgeBaseService — Handles document chunking, embedding generation, and semantic search.
- BillingService — Manages subscription lifecycle, plan limits, and payment gateway integration.
- ContactService — Handles contact CRUD, group management, import/export, and merge operations.
- WebhookService — Manages webhook registration, payload signing, delivery, and retry logic.
Trait Usage
MailTrixy makes extensive use of PHP traits to share behavior across classes without inheritance hierarchies.
| Trait | Used By | Purpose |
|---|---|---|
| AuthorizesWorkspaceActions | Livewire components | Verifies that the current user has permission to perform an action within the active workspace |
| BelongsToWorkspace | Eloquent models | Auto-assigns workspace_id, applies global scope for tenant isolation |
| HasCustomFields | Contact model | Manages dynamic custom field values with get/set accessors |
| TracksActivity | Contact, Conversation | Automatically logs create, update, and delete events to the activity timeline |
| EncryptsAttributes | EmailAccount, AiProvider | Transparently encrypts and decrypts sensitive fields (tokens, API keys) |
| HasTags | Contact, Conversation, Email | Polymorphic tag relationship for categorization and filtering |