Backend (Laravel)
The backend is a stateless REST API built with Laravel. All business logic, authentication, billing, and data access lives here.
Key Directories
Controllers
app/Http/Controllers/
├── Admin/ # 14 controllers — super admin panel
│ ├── AdminDashboardController
│ ├── AdminUserController
│ ├── AdminOrganizationController
│ ├── AdminPlanController
│ ├── AdminSettingsController
│ ├── AdminEmailTemplateController
│ ├── AdminFeatureFlagController
│ ├── AdminAuditLogController
│ ├── AdminQueueController
│ ├── AdminHealthController
│ ├── AdminRoleController
│ ├── AdminPermissionController
│ ├── AdminOrgRoleController
│ └── AdminUsageController
├── Auth/ # 11 controllers — all auth methods
│ ├── LoginController
│ ├── RegisterController
│ ├── MagicLinkController
│ ├── OAuthController
│ ├── MfaController
│ ├── SamlController
│ ├── PasswordResetController
│ ├── EmailVerificationController
│ ├── SessionController
│ ├── PersonalTokenController
│ └── LogoutController
├── Organization/ # 6 controllers — multi-tenancy
│ ├── OrganizationController
│ ├── MemberController
│ ├── InvitationController
│ ├── WebhookController
│ ├── SamlConfigController
│ └── OrgSessionController
├── Custom/ # Your controllers go here
├── BillingController
├── BillingWebhookController
├── ApiKeyController
├── ProfileController
├── FileController
├── NotificationController
├── EntitlementController
├── FeatureFlagController
└── UsageController
Models
app/Models/
├── User # Auth, MFA, roles, orgs
├── Organization # Multi-tenant workspace
├── OrganizationUser # Pivot with role
├── Plan # Subscription plans
├── ApiKey # Hashed API keys
├── Invitation # Email invitations
├── Webhook # Webhook endpoints
├── WebhookDelivery # Delivery tracking
├── AuditLog # Activity tracking
├── AppSetting # Key-value settings
├── EmailTemplate # Editable email templates
├── FeatureFlag # Feature flag definitions
├── MagicLink # Passwordless tokens
├── OrgRoleTemplate # Custom org roles
├── UsageRecord # Usage metrics
├── SamlConfiguration # SSO config per org
├── OrgDomain # Verified domains for SSO
└── Custom/ # Your models go here
Billing Drivers
app/Billing/
├── StripeCashierDriver # Stripe via Laravel Cashier
├── PaddleDriver # Paddle
├── MercadoPagoDriver # MercadoPago
├── LemonSqueezyDriver # Lemon Squeezy
├── PayPalDriver # PayPal
└── NullBillingDriver # No-op (free plans)
All implement the BillingGateway interface. Switch gateways from admin settings without code changes.
Middleware
app/Http/Middleware/
├── Authenticate # Sanctum auth
├── AuthenticateApiKey # API key auth
├── SetActiveOrganization # Resolves current org
├── CheckEntitlement # Feature gating (entitled:feature)
├── CheckOrgPermission # Org-level RBAC (org.can:perm)
├── CheckApiKeyScope # API key scope enforcement
├── ApiKeyRateLimiter # Per-key rate limiting
├── TrackApiUsage # Usage metering
├── AuditRequest # Audit logging
├── EnsureMfaVerified # MFA challenge gate
├── EnforceOrgMfa # Org-wide MFA requirement
└── SecurityHeaders # CSP, X-Frame-Options, etc.
Routes
All routes are in two files:
routes/api.php— core routes (auth, orgs, billing, admin)routes/custom.php— your feature routes (auto-loaded inside the auth middleware group)
Config
config/saas.php
Tenant mode, feature definitions, and default plan entitlements.
return [
'tenant_mode' => env('SAAS_TENANT_MODE', 'organization'), // or 'personal'
'features' => [
'api_keys' => ['label' => 'API Keys', 'description' => 'Programmatic API access'],
'webhooks' => ['label' => 'Webhooks', 'description' => 'HTTP POST notifications'],
'billing' => ['label' => 'Billing', 'description' => 'Subscription management'],
'invitations' => ['label' => 'Team Invitations', 'description' => 'Invite members to organizations'],
'usage' => ['label' => 'Usage', 'description' => 'Usage metrics and analytics'],
'projects' => ['label' => 'Projects', 'description' => 'Project management module'],
],
'plans' => [
'free' => [
'features' => ['invitations', 'projects'],
'limits' => ['api_keys' => 0, 'members' => 3, 'storage_mb' => 100],
],
'pro' => [
'features' => ['api_keys', 'webhooks', 'invitations', 'billing', 'usage', 'projects'],
'limits' => ['api_keys' => 25, 'members' => 50, 'storage_mb' => 10000],
],
],
];
config/custom.php
Register your own features, webhook events, permissions, and resource limits. Everything added here appears automatically in the admin panel.
return [
'features' => [
'projects' => [
'label' => 'Projects',
'description' => 'Project management with statuses and comments',
],
],
'webhook_events' => [
'project.created' => [
'group' => 'Projects',
'description' => 'A new project was created',
],
],
'limits' => [
'projects' => 'Projects',
],
'permissions' => [
'view_projects',
'create_projects',
'update_projects',
'delete_projects',
],
];
routes/custom.php
Your feature routes. Auto-loaded inside the authenticated middleware group — all routes require auth and have access to the active organization.
use App\Http\Controllers\Custom\ProjectController;
Route::prefix('projects')
->middleware('entitled:projects')
->group(function () {
Route::get('/', [ProjectController::class, 'index'])
->middleware('org.can:view_projects');
Route::post('/', [ProjectController::class, 'store'])
->middleware('org.can:create_projects');
Route::get('/{project}', [ProjectController::class, 'show'])
->middleware('org.can:view_projects');
Route::patch('/{project}', [ProjectController::class, 'update'])
->middleware('org.can:update_projects');
Route::delete('/{project}', [ProjectController::class, 'destroy'])
->middleware('org.can:delete_projects');
});