Architecture Overview
Multi-Tenancy
Database-per-tenant strategy with automatic tenant identification
Domain-Based Routing
Separate route files for system and tenant domains
Service Layer
Business logic encapsulated in service classes
Inertia Integration
Server-side rendering with Vue components
Multi-Tenancy
The application uses Stancl Tenancy to provide database isolation for each customer.How It Works
1
Tenant Identification
The tenancy middleware identifies tenants by subdomain:
2
Database Switching
Stancl automatically switches database connections based on the current tenant:
3
Isolated Data
Each tenant’s data is completely isolated:
Tenant Model
app/Models/System/Tenant.php
Models
Models are organized intoSystem and Tenant namespaces:
System Models (Central Database)
- Tenant
- Plan
- Feature
- User
app/Models/System/Tenant.php
Tenant Models (Tenant Databases)
app/Models/Tenant/User.php
Important: Tenant models use the tenant database connection, automatically set by Stancl Tenancy middleware.
Controllers
Controllers are organized by domain (System vs Tenant) and responsibility:System Controllers
app/Http/Controllers/System/DashboardController.php
Resource Controllers
Use Laravel’s resource controller pattern:app/Http/Controllers/System/TenantController.php
Services
Business logic is encapsulated in service classes:app/Services/System/TenantService.php
Service Benefits
Encapsulation
Encapsulation
Business logic is centralized, making controllers thin and focused on HTTP concerns.
Reusability
Reusability
Services can be used from controllers, commands, jobs, and tests.
Testability
Testability
Services are easy to test in isolation with dependency injection.
Transaction Management
Transaction Management
Complex operations with multiple database calls are wrapped in transactions.
Routing
Routes are organized by domain:System Routes
routes/web.php
Tenant Routes
routes/tenant.php
Middleware
Key middleware in the application:InitializeTenancyByDomain
Identifies tenant by subdomain and switches database connection
HandleInertiaRequests
Shares data across all Inertia pages (auth user, flash messages)
auth
Ensures user is authenticated before accessing protected routes
verified
Ensures user has verified their email address
Database Migrations
Central Database Migrations
database/migrations/create_plans_table.php
Tenant Database Migrations
database/migrations/tenant/create_users_table.php
Migrations in
database/migrations/tenant/ run automatically when a new tenant is created.Authentication
The application uses Laravel Fortify for authentication:- Features
- Configuration
- Customization
- Login / Logout
- Registration
- Password Reset
- Email Verification
- Two-Factor Authentication
- Password Confirmation
API Development
API routes are defined inroutes/api.php:
routes/api.php
Commands
Custom Artisan commands for administrative tasks:Best Practices
Controller Design
Controller Design
- Keep controllers thin, delegate to services
- Use resource controllers for CRUD operations
- Validate requests with Form Request classes
- Return Inertia responses for frontend views
Service Layer
Service Layer
- Encapsulate complex business logic
- Use dependency injection
- Return models or collections, not views
- Wrap multi-step operations in transactions
Multi-Tenancy
Multi-Tenancy
- Never query tenant data from system context
- Always use
tenant()helper to get current tenant - Test tenant isolation thoroughly
- Use
$tenant->run()to execute code in tenant context
Database
Database
- Use eager loading to prevent N+1 queries
- Index foreign keys and frequently queried columns
- Use database transactions for data consistency
- Leverage Eloquent relationships
Next Steps
Testing
Learn how to test Laravel controllers and services
Frontend Development
Integrate backend with Vue components