This is a SaaS boilerplate built on top of the Laravel framework. Built to provide developers with a template to kickoff their SaaS application, without the hustle for repetitive tasks such as user account setup, subscriptions and role management.
Inspired by domain-driven approach.
Laravel's main app folder is restructured to: App, Domain and Http.
- App
- Console
- Controllers
- Exceptions
- Providers
- Traits
- TwoFactor
- ViewComposers
- Domain
- Account
- Auth
- Events
- Listeners
- Rules
- Projects
- Subscriptions
- Teams
- Users
- Models
- Filters
- Observers
- Http
- Account
- Controllers
- Requests
- Auth
- Controllers
- Requests
- Middleware
- Subscriptions
- Teams
- Users
- Policies
- Resources
- Account
- Authentication
- Login / Registration
- Email Activation
- Two Factor Login (only when enabled)
- Subscription with Stripe
- User plans
- Team plans
- Account (User Account)
- Profile Update
- Change Password
- Two Factor Authentication
- Subscription
- Cancel Subscription
- Resume Subscription
- Swap Plan
- Update Card
- API Tokens
- Single Database Multi-tenancy
- Admin
- User Management
- Create Users (and assign role)
- Manage User Roles
- Role & Permissions Management
- User Management
- Developer Panel
- Manage OAuth Clients
- Manage Personal Access Tokens
- Other features
- Filtering (extendable)
- API access (starter template)
Note: Some features may be subjected to change. Other features may not be listed since they are under development or do not qualify as a standard / main SaaS feature. Some common features will not be listed as well.
-
Fork, clone or download this repository.
-
Run
composer installif its the initial setup orcomposer update. -
Setup your environment keys in .env (If .env does not exist then copy / rename .env.example as .env)
-
Run
php artisan migratefor initial tables setup. -
Optional: Run
php artisan db:seed --class=RoleTableSeederto set the initial roles and permissions, then followstep 7below to assign a user the initial permissions and roles. -
Optional: To create a
rootadmin; Runphp artisan role:assign [email protected] admin-root. Substitute[email protected]with an existing user email.admin-rootis the default root Admin role.Note: You must follow
step 5above first to setup the root admin.
php artisan make:channel \SAAS\App\Broadcasting{name}
php artisan make:console \SAAS\App\Console\Commands{name}
php artisan make:exception \SAAS\App\Exceptions{name}
php artisan make:job \SAAS\Domain{namespace}\Jobs{name}
php artisan make:event \SAAS\Domain{namespace}\Events{name}
php artisan make:listener \SAAS\Domain{namespace}\Listeners{name}
php artisan make:mail \SAAS\Domain{namespace}\Mail{name}
php artisan make:model \SAAS\Domain{namespace}\Models{name}
php artisan make:notification \SAAS\Domain{namespace}\Notifications{name}
php artisan make:policy \SAAS\Http{namespace}\Policies{name}
php artisan make:rule \SAAS\Domain{namespace}\Rules{name}
Note: Some files can be placed in the app/App folder if they are intended to be used globally
php artisan make:{command} \SAAS\App\{namespace}\{name}
- Admin: Assign user a role
Use
php artisan role:assign <email> <role-slug>:<email>is the user's email and<role-slug>is the slug of the role you wish to assign the user.
When pushing the project to a platform or production environment, assets or urls may be broken if the platform enforces HTTPS.
To enable urls to use HTTPS:
Set FORCE_HTTPS variable in .env file to true.
By default FORCE_HTTPS is false.
Note: If FORCE_HTTPS does not exist in your .env,
just add it as a new variable and assign a boolean value true or false.
This dynamically tells Laravel to force urls to use HTTPS which is especially handy in fixing or preventing broken assets urls.
See miracuthbert/laravel-multi-tenancy
To start using single databse multi-tenancy call ForTenants trait on a model
use Miracuthbert\Multitenancy\Traits\ForTenants;
class Project extends Model
{
use ForTenants;
}Once you have setup the model as show above. Just call CRUD operations directly.
Tenant relationships are handled automatically.
$projects = Project::create([
'name' => 'Project 1'
]);
$projects = Project::get();To perform CRUD operations on models with ForTenants trait can be done by
adding withoutForTenants scope when fetching records associated with that model.
$projects = Project::withoutForTenants()->get();This comes in handy for example in: admin or moderation operations
All tenant routes are under the routes folder in the tenant.php file.
Note: Tenant routes follow the same structure as other routes
The main reason we place all tenant routes separately is to handle route binding and its much easier to know which routes are for tenants.
- Main
- PHP (>=8)
- Laravel (Minimal 9)
- Laravel Cashier (can be switched)
- UI (can be switched)
- Bootstrap (v4)
- Font awesome
- Simple Line Icons
- jQuery
- VueJs
- Development
- nodejs
- npm
- Stripe (payment gateway)
- Authy by Twilio (two factor authentication)
Roles and Permissions: See miracuthbert/laravel-rolesMulti-tenancy: See miracuthbert/laravel-multi-tenancy
If you discover a security vulnerability, please send an e-mail to Cuthbert Mirambo via [email protected]. All security vulnerabilities will be promptly addressed.