inmanturbo/enterprise

Enterprise Starter Kit for laravel.

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

Type:project

pkg:composer/inmanturbo/enterprise

dev-main 2026-02-19 09:20 UTC

This package is auto-updated.

Last update: 2026-02-19 09:20:29 UTC


README

inmanturbo/enterprise

An enterprise-grade Laravel starter kit with event sourcing and organization-based multi-tenancy.

Installation

Laravel Herd

Install with Herd

Laravel Installer

laravel new enterprise --using=inmanturbo/enterprise

Post-Install

php artisan migrate --database=landlord --path=database/migrations/landlord
php artisan db:seed
composer run dev

Default Accounts

After seeding, these accounts are available:

Email Password Role
admin@example.com password Site Admin
jane@example.com password Member
bob@example.com password Member

All users belong to the default organization Acme Corp (domain: enterprise.test).

What's Included

  • Event-sourced writes via aggregate roots (User, Organization)
  • Organization-based multi-tenancy with per-org tenant databases
  • Auto-provisioning of tenant databases on organization creation
  • Fortify authentication — login, registration, password reset, email verification, two-factor authentication
  • Admin panel for managing organizations and users
  • Organization management — member management, role assignment, settings
  • Tenant-scoped media library infrastructure (ready for your domain models)
  • Registration modes — open (public) or invite-only
  • Dark mode, responsive design, organization switcher

Architecture

Event Sourcing

All writes flow through aggregate roots. Aggregates validate business rules, record domain events, and persist them to an event store. Projectors listen to those events and update read models (Eloquent tables). There is no command bus — aggregates are called directly from controllers and Livewire components.

Aggregates: UserAggregate, OrganizationAggregate

Projectors: UserProjector, OrganizationProjector, OrganizationUserProjector, TenantDatabaseProjector

Events: 19 domain events in app/StoredEvents/Landlord/ covering user lifecycle, organization management, role assignment, and tenant database provisioning.

Dual Event Stores

  • Landlord — stores all platform-level events (users, organizations, tenant provisioning)
  • Tenant — each tenant database includes its own stored_events and snapshots tables for tenant-scoped event sourcing

Multi-Tenancy

The platform uses a landlord/tenant database split powered by Spatie Laravel Multitenancy:

  • Landlord database — users, organizations, organization memberships, tenant database records, platform event store
  • Tenant databases — one per organization, auto-provisioned on creation, containing tenant-scoped data (event store, snapshots, media)

Tenant resolution is two-phase:

  1. Domain-basedTenantFinder matches the request hostname against organization domains
  2. User-based — when no domain match, the authenticated user's current_organization_id determines the active tenant

Registration Modes

Configured via the ENTERPRISE_REGISTRATION_MODE environment variable in config/enterprise.php:

Mode Behavior
open (default) Public registration enabled. Each new user gets an auto-created organization and tenant database.
invite Registration disabled. Site admins create users and assign them to organizations.

Roles & Permissions

Authorization is enforced across four tiers:

Role Scope Capabilities
Site Admin Platform-wide Full access to admin panel. Manage all organizations and users. Can act as org owner in any organization.
Org Owner Single organization Edit org settings, manage members (invite, change roles, activate/deactivate, remove). Cannot be removed from the organization.
Org Admin Single organization admin role on the pivot. Currently equivalent to member (reserved for future granular permissions).
Org Member Single organization member role on the pivot. Access to the organization's tenant-scoped features.

Site admin status is stored on the users.is_admin column. Org roles (admin, member) are stored on the organization_user pivot via the Role enum.

Admin Panel

Available at /admin/ (requires site admin):

  • Organizations (/admin/organizations) — list, create, edit organizations. Search by name/domain. Activate/deactivate organizations.
  • Users (/admin/users) — list, create, edit users. Search by name/email. Filter by organization. Activate/deactivate users. Set admin status.

Organization Management

Available to org owners and site admins:

  • Settings (/organization/settings) — edit organization name
  • Members (/organization/members) — search members, change roles, activate/deactivate, remove members, invite new members
  • Org Switcher — sidebar dropdown to switch between organizations the user belongs to

Media Library

Tenant-scoped file storage infrastructure powered by Spatie Media Library:

  • Private originals — stored at storage/app/private/tenants/{id}/media
  • Public conversions — stored at storage/app/public/tenants/{id}/media
  • Authenticated file serving — private media served via GET /media/{media} (requires auth + active tenant)
  • Infrastructure-only — no models implement HasMedia yet. The media table, disk configuration, and serving route are in place, ready for your domain models.

Database Architecture

Landlord Tables

users, organizations, organization_user, tenant_databases, stored_events, snapshots, cache, jobs, job_batches, failed_jobs, sessions, password_reset_tokens

Tenant Tables

stored_events, snapshots, media

Migration Paths

  • Landlord: database/migrations/landlord/
  • Tenant: database/migrations/

Tenant databases support mixed drivers — each organization's tenant database can use sqlite, mysql, mariadb, or pgsql independently.

Deployment

php artisan deploy

This runs landlord migrations followed by tenant migrations across all organizations.

Development

composer run dev     # Runs server, queue listener, log tail (Pail), and Vite concurrently
composer run lint    # Laravel Pint code formatting
composer run test    # Pest test suite

Testing

Tests use Pest 4 with SQLite for both landlord and tenant database connections (configured in phpunit.xml). Landlord migrations are loaded automatically via AppServiceProvider.

php artisan test --compact
php artisan test --compact --filter=testName

Tech Stack

License

The MIT License (MIT). See LICENSE for details.