1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-06-21 12:34:04 +00:00

Add detailed tenancy references and guidelines to boost resources

This commit is contained in:
eramitgupta 2026-06-02 12:33:02 +05:30
parent c94c0cd932
commit fde2bf0cf4
21 changed files with 1707 additions and 1 deletions

View file

@ -3,7 +3,7 @@ name: tenancy
description: "Activate when the user is building or debugging multi-tenant Laravel behavior with stancl/tenancy. Use for tenancy:install, tenant identification middleware, central and tenant routes, tenant model and domain model setup, multi-database or single-database tenancy, tenant-aware bootstrappers for database/cache/filesystem/queue/session/Redis, tenant context switching with tenancy()->initialize() or tenant()->run(), tenant migrations and seeders, tenant asset routes, pending tenants, resource syncing, user impersonation, RLS, Vite bundling, or testing tenant-aware behavior."
license: MIT
metadata:
author: laravel
author: Samuel Štancl
---
# Tenancy For Laravel
@ -28,6 +28,29 @@ Use `search-docs` first when it is available for Laravel integration patterns. F
Load `references/package.md` when the task needs package-specific detail beyond the core workflow in this file.
## Feature References
Load focused references when the task matches a specific package area:
- `references/installation.md` for install, publishing, and setup checks
- `references/configuration.md` for `config/tenancy.php` sections
- `references/identification.md` for middleware and resolvers
- `references/routing-assets.md` for tenant routes, route modes, cloned routes, and asset routes
- `references/context-api.md` for `tenancy()`, `tenant()`, `run()`, and `central()` behavior
- `references/bootstrappers.md` for tenant-aware Laravel service scoping
- `references/database-tenancy.md` for database isolation and tenant database managers
- `references/migrations-commands.md` for tenant Artisan commands
- `references/models-domains.md` for tenant/domain models and single-database traits
- `references/filesystem-cache-queue.md` for storage, cache, sessions, Redis, and queues
- `references/lifecycle-jobs.md` for events, provisioning, and cleanup pipelines
- `references/resource-syncing.md` for synced central and tenant resources
- `references/impersonation.md` for tenant user impersonation
- `references/pending-tenants.md` for pending tenant pools
- `references/rls.md` for PostgreSQL row-level security
- `references/features.md` for optional package features
- `references/integrations.md` for URL, mail, broadcasting, Fortify, Scout, Livewire, Telescope, and Vite
- `references/testing.md` for test coverage guidance
## Package Surface
The package auto-discovers:

View file

@ -0,0 +1,42 @@
# Bootstrappers Reference
Use this when tenant context should affect Laravel services.
## Source Files
- `src/Bootstrappers/*`
- `assets/config.php`
## Defaults
- `DatabaseTenancyBootstrapper`
- `CacheTenancyBootstrapper`
- `FilesystemTenancyBootstrapper`
- `QueueTenancyBootstrapper`
- `DatabaseSessionBootstrapper`
## Optional Bootstrappers
- `CacheTagsBootstrapper`
- `DatabaseCacheBootstrapper`
- `RedisTenancyBootstrapper`
- `TenantConfigBootstrapper`
- `RootUrlBootstrapper`
- `UrlGeneratorBootstrapper`
- `MailConfigBootstrapper`
- `BroadcastingConfigBootstrapper`
- `BroadcastChannelPrefixBootstrapper`
- `FortifyRouteBootstrapper`
- `ScoutPrefixBootstrapper`
- `PostgresRLSBootstrapper`
- `PersistentQueueTenancyBootstrapper`
## Rules
- Configure bootstrappers before writing app-level workarounds.
- `DatabaseCacheBootstrapper` must run after `DatabaseTenancyBootstrapper`.
- `RedisTenancyBootstrapper` needs phpredis and is for direct Redis calls.
- Prefer `TenantConfigBootstrapper` over deprecated `TenantConfig` feature.
- Use `RootUrlBootstrapper` for CLI URL root behavior.
- Use `UrlGeneratorBootstrapper` for tenant-aware route generation.
- Inspect `tenancy()->getBootstrappers()` when context looks partially applied.

View file

@ -0,0 +1,34 @@
# Configuration Reference
Use this when changing `config/tenancy.php`.
## Source Files
- `assets/config.php`
- `src/TenancyServiceProvider.php`
## Must-Review Sections
- `models`: tenant, domain, impersonation token, tenant key column, ID generator.
- `identification`: central domains, default middleware, resolver settings.
- `bootstrappers`: runtime Laravel feature scoping.
- `database`: central connection, template tenant connection, DB managers, prefixes.
- `rls`: PostgreSQL RLS manager, user, and session variable.
- `cache`: prefix, stores, session scoping, tag base.
- `filesystem`: disks, root overrides, URL overrides, storage suffixing, asset override.
- `redis`: direct Redis connection prefixing.
- `features`: optional package features.
- `routes`: package asset route registration toggle.
- `default_route_mode`: central, tenant, or universal default route behavior.
- `pending`: pending tenant query inclusion and pool count.
- `migration_parameters`: tenant migration defaults.
- `seeder_parameters`: tenant seeder defaults.
## Rules
- Decide identification, database isolation, and bootstrappers before writing app code.
- Never use `tenant` as the template tenant connection name; it is reserved by the package.
- Set `models.id_generator` to `null` only when using auto-increment tenant IDs intentionally.
- Keep resolver caching disabled until invalidation behavior is tested.
- Keep `database.drop_tenant_databases_on_migrate_fresh` false unless local/dev destructive behavior is intended.
- Enable `filesystem.asset_helper_override` only after checking third-party package asset calls.

View file

@ -0,0 +1,45 @@
# Context API Reference
Use this when switching between tenant and central contexts.
## Source Files
- `src/Tenancy.php`
- `src/helpers.php`
- `src/Database/Concerns/TenantRun.php`
- `src/Database/Concerns/InitializationHelpers.php`
## Core API
```php
tenancy()->initialize($tenant);
tenancy()->end();
tenancy()->reinitialize();
tenancy()->central(fn () => null);
$tenant->run(fn () => null);
```
## Behavior
- `initialize()` accepts a tenant model, ID, or string key.
- Switching tenants ends the previous context first.
- `run()` restores the previous tenant or central context in `finally`.
- `central()` temporarily ends tenancy and restores prior tenant context.
- `reinitialize()` re-runs bootstrappers for the current tenant.
- `bootstrapFeatures()` is idempotent per feature, but feature bootstrapping is irreversible.
- `find()` resolves tenants through the configured tenant model.
## Helpers
- `tenancy()` returns the tenancy singleton.
- `tenant()` returns current tenant or tenant attribute.
- `central()` executes a callback in central context.
- `globalCache()` resolves central cache.
- `tenant_asset()` returns tenant asset URLs.
- `global_asset()` returns global asset URLs.
## Rules
- Do not manually mutate DB connections, cache prefixes, filesystem roots, queue payloads, sessions, or URL roots.
- Use atomic `run()` and `central()` when context must be restored safely.
- Test context restoration after exceptions.

View file

@ -0,0 +1,36 @@
# Database Tenancy Reference
Use this when changing tenant database isolation or managers.
## Source Files
- `src/Database/DatabaseManager.php`
- `src/Database/DatabaseConfig.php`
- `src/Database/TenantDatabaseManagers/*`
- `src/Bootstrappers/DatabaseTenancyBootstrapper.php`
- `assets/config.php`
## Supported Isolation
- Separate tenant databases.
- PostgreSQL schema isolation.
- Permission-controlled tenant database users.
- PostgreSQL RLS for single-database tenancy.
## Managers
- SQLite: `SQLiteDatabaseManager`
- MySQL/MariaDB: `MySQLDatabaseManager`
- PostgreSQL: `PostgreSQLDatabaseManager`
- SQL Server: `MicrosoftSQLDatabaseManager`
- Permission-controlled variants for MySQL, PostgreSQL, SQL Server.
- PostgreSQL schema managers for schema isolation.
## Rules
- `tenant` is a reserved dynamic connection name.
- Use `database.template_tenant_connection` for the tenant connection template.
- Use `database.tenant_host_connection_name` for database creation/deletion host connection.
- Tenant DB names are `prefix + tenant_id + suffix`.
- Use schema managers only when PostgreSQL schema isolation is intended.
- Test creation, migration, rollback, deletion, and connection restoration.

View file

@ -0,0 +1,30 @@
# Optional Features Reference
Use this when enabling or debugging classes in `tenancy.features`.
## Source Files
- `src/Features/*`
- `src/Tenancy.php`
## Features
- `UserImpersonation`
- `TelescopeTags`
- `CrossDomainRedirect`
- `ViteBundler`
- `DisallowSqliteAttach`
- `TenantConfig`
## Behavior
- Features are bootstrapped independently from tenant initialization.
- `tenancy()->bootstrapFeatures()` is idempotent per feature.
- Feature bootstrapping is irreversible during the request lifecycle.
- `TenantConfig` is deprecated in favor of `TenantConfigBootstrapper`.
## Rules
- Inspect the feature class before assuming behavior.
- Enable only the needed features.
- Test each enabled feature in central and tenant contexts where relevant.

View file

@ -0,0 +1,41 @@
# Filesystem Cache Queue Reference
Use this when tenant context affects storage, cache, sessions, Redis, or queues.
## Source Files
- `src/Bootstrappers/FilesystemTenancyBootstrapper.php`
- `src/Bootstrappers/CacheTenancyBootstrapper.php`
- `src/Bootstrappers/CacheTagsBootstrapper.php`
- `src/Bootstrappers/DatabaseCacheBootstrapper.php`
- `src/Bootstrappers/RedisTenancyBootstrapper.php`
- `src/Bootstrappers/QueueTenancyBootstrapper.php`
- `src/Bootstrappers/PersistentQueueTenancyBootstrapper.php`
- `src/Bootstrappers/DatabaseSessionBootstrapper.php`
- `src/Middleware/ScopeSessions.php`
## Filesystem
- `filesystem.disks` controls scoped disks.
- `filesystem.root_override` rewrites local disk roots.
- `filesystem.url_override` enables tenant-aware local public URLs.
- `filesystem.suffix_storage_path` controls `storage_path()` suffixing.
- `filesystem.asset_helper_override` makes `asset()` tenant-aware.
## Cache And Redis
- Cache tenancy prefixes configured stores through `cache.prefix`.
- Global central cache is available through `GlobalCache`/`globalCache()`.
- Redis tenancy is for direct Redis usage and requires phpredis.
## Queue
- Queue bootstrapper carries tenant context into queued jobs.
- Persistent queue bootstrapper is for workers intentionally staying tenant-aware.
## Rules
- Run `php artisan tenants:link` when tenant public local storage URLs are enabled.
- Be careful with `asset_helper_override`; third-party package assets may become tenant-aware.
- Scope sessions through config and `ScopeSessions` middleware where required.
- Test queued jobs in central and tenant contexts.

View file

@ -0,0 +1,43 @@
# Tenant Identification Reference
Use this when resolving tenants from requests.
## Source Files
- `src/Middleware/IdentificationMiddleware.php`
- `src/Middleware/InitializeTenancyByDomain.php`
- `src/Middleware/InitializeTenancyBySubdomain.php`
- `src/Middleware/InitializeTenancyByDomainOrSubdomain.php`
- `src/Middleware/InitializeTenancyByPath.php`
- `src/Middleware/InitializeTenancyByRequestData.php`
- `src/Middleware/InitializeTenancyByOriginHeader.php`
- `src/Middleware/PreventAccessFromUnwantedDomains.php`
- `src/Middleware/ScopeSessions.php`
- `src/Resolvers/*`
## Middleware
- `InitializeTenancyByDomain`
- `InitializeTenancyBySubdomain`
- `InitializeTenancyByDomainOrSubdomain`
- `InitializeTenancyByPath`
- `InitializeTenancyByRequestData`
- `InitializeTenancyByOriginHeader`
- `PreventAccessFromUnwantedDomains`
- `CheckTenantForMaintenanceMode`
- `ScopeSessions`
## Resolver Config
- `DomainTenantResolver`: cache, TTL, cache store.
- `PathTenantResolver`: tenant route parameter, route name prefix, tenant model column, allowed extra columns, cache.
- `RequestDataTenantResolver`: header, cookie, query parameter, tenant model column, cache.
## Rules
- Configure `identification.central_domains` for domain/subdomain strategies.
- Use `PreventAccessFromUnwantedDomains` only with configured domain identification middleware.
- For path identification, confirm the tenant parameter name before defining URLs.
- For request-data identification, set unused channels to `null`.
- If custom middleware is introduced, add it to the appropriate config category.
- Test success and failure identification paths.

View file

@ -0,0 +1,36 @@
# User Impersonation Reference
Use this when implementing tenant user impersonation.
## Source Files
- `src/Features/UserImpersonation.php`
- `src/Database/Models/ImpersonationToken.php`
- `assets/impersonation-migrations/*`
## Setup
```bash
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=impersonation-migrations
php artisan migrate
```
Enable feature:
```php
'features' => [
Stancl\Tenancy\Features\UserImpersonation::class,
],
```
## Command
```bash
php artisan tenants:purge-impersonation-tokens
```
## Rules
- Verify tenant match before logging in impersonated users.
- Test guard, redirect URL, remember flag, token TTL, and invalid token behavior.
- Purge expired tokens routinely.

View file

@ -0,0 +1,73 @@
# Installation Reference
Use this when installing or auditing `stancl/tenancy` setup.
## Source Files
- `src/Commands/Install.php`
- `src/TenancyServiceProvider.php`
- `assets/config.php`
- `assets/tenant_routes.stub.php`
- `assets/TenancyServiceProvider.stub.php`
- `assets/migrations/*`
## Required Steps
1. Install the package.
```bash
composer require stancl/tenancy
```
2. Run the installer non-interactively.
```bash
php artisan tenancy:install --no-interaction
```
3. Confirm these files exist:
- `config/tenancy.php`
- `routes/tenant.php`
- `app/Providers/TenancyServiceProvider.php`
- `database/migrations/2019_09_15_000010_create_tenants_table.php`
- `database/migrations/2019_09_15_000020_create_domains_table.php`
- `database/migrations/tenant`
4. Review `config/tenancy.php` before running migrations.
5. Run central migrations.
```bash
php artisan migrate
```
6. Add tenant migrations to `database/migrations/tenant`.
7. Create tenants and domains according to the identification strategy.
8. Run tenant migrations.
```bash
php artisan tenants:migrate
```
## Manual Publish Commands
Prefer `tenancy:install`. Use these only for targeted publishing:
```bash
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=config
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=routes
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=providers
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=migrations
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=impersonation-migrations
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=resource-syncing-migrations
```
## Installer Behavior
- Publishes config, routes, provider, and base migrations.
- Creates `database/migrations/tenant`.
- Skips files that already exist and warns instead of overwriting.
- Shows an interactive support prompt unless `--no-interaction` is used.

View file

@ -0,0 +1,44 @@
# Integrations Reference
Use this when tenancy integrates with URL generation, mail, broadcasting, Fortify, Scout, Livewire, Telescope, or Vite.
## Source Files
- `src/Bootstrappers/RootUrlBootstrapper.php`
- `src/Bootstrappers/UrlGeneratorBootstrapper.php`
- `src/Bootstrappers/MailConfigBootstrapper.php`
- `src/Bootstrappers/BroadcastingConfigBootstrapper.php`
- `src/Bootstrappers/BroadcastChannelPrefixBootstrapper.php`
- `src/Bootstrappers/Integrations/FortifyRouteBootstrapper.php`
- `src/Bootstrappers/Integrations/ScoutPrefixBootstrapper.php`
- `src/Features/TelescopeTags.php`
- `src/Features/ViteBundler.php`
- `assets/TenancyServiceProvider.stub.php`
## Bootstrappers
- `RootUrlBootstrapper`: tenant root URL for CLI/context URL generation.
- `UrlGeneratorBootstrapper`: tenant-aware route names and tenant parameters.
- `MailConfigBootstrapper`: tenant-specific mail config.
- `BroadcastingConfigBootstrapper`: tenant broadcaster config and manager.
- `BroadcastChannelPrefixBootstrapper`: tenant-prefixed broadcast channel names.
- `FortifyRouteBootstrapper`: tenant auth route/redirect integration.
- `ScoutPrefixBootstrapper`: tenant-specific Scout prefix.
## Features
- `TelescopeTags`: adds tenant tags when tenancy is initialized.
- `ViteBundler`: tenant-aware bundling behavior.
## Stub Hooks
- `overrideUrlInTenantContext()` shows how to set `RootUrlBootstrapper::$rootUrlOverride`.
- The Livewire v3 comment shows how to make the Livewire update route universal.
- `cloneRoutes()` shows the package route-cloning integration point.
## Rules
- Prefer bootstrappers over ad hoc service-provider config mutation.
- Test generated URLs in HTTP and CLI contexts.
- Test broadcast channel names and tenant-specific broadcaster credentials.
- Make third-party package routes universal or cloned only when intentionally accessible in tenant context.

View file

@ -0,0 +1,46 @@
# Lifecycle Jobs Reference
Use this when provisioning or deleting tenant resources through events and job pipelines.
## Source Files
- `assets/TenancyServiceProvider.stub.php`
- `src/Events/*`
- `src/Jobs/*`
- `src/Listeners/*`
- `src/Database/Models/Tenant.php`
- `src/Database/Models/Domain.php`
## Tenant Created Pipeline
The published application provider wires `TenantCreated` to a `JobPipeline` containing:
- `CreateDatabase`
- `MigrateDatabase`
- optional `SeedDatabase`
- optional `CreateStorageSymlinks`
- custom provisioning jobs
## Tenant Deletion Pipelines
The stub wires:
- `DeletingTenant` to `DeleteDomains`, optional `DeleteTenantStorage`, optional `RemoveStorageSymlinks`.
- `TenantDeleted` to `DeleteDatabase`, optional resource-syncing cleanup.
## Event Groups
- Tenant lifecycle events.
- Domain lifecycle events.
- Database lifecycle events.
- Tenancy initialization/end/bootstrap events.
- Pending tenant events.
- Resource syncing events.
- Storage symlink events.
## Rules
- Put provisioning and cleanup in event pipelines rather than controllers.
- Keep database, migration, seeding, storage, domain, and sync cleanup order explicit.
- Decide whether pipelines should be queued using `shouldBeQueued()`.
- Test tenant creation and deletion side effects.

View file

@ -0,0 +1,56 @@
# Migrations And Commands Reference
Use this for tenant-aware Artisan operations.
## Source Files
- `src/Commands/*`
- `src/Concerns/HasTenantOptions.php`
- `src/Concerns/ExtendsLaravelCommand.php`
- `src/Concerns/DealsWithMigrations.php`
- `assets/config.php`
## Tenant Migrations
Defaults from `tenancy.migration_parameters`:
- `--force` true
- `--path` `database/migrations/tenant`
- `--schema-path` `database/schema/tenant-schema.dump`
- `--realpath` true
Commands:
```bash
php artisan tenants:migrate
php artisan tenants:migrate --tenants=tenant-id
php artisan tenants:migrate --skip-failing
php artisan tenants:rollback
php artisan tenants:migrate-fresh
php artisan tenants:seed
```
## Tenant Operations
```bash
php artisan tenants:run cache:clear
php artisan tenant:tinker
php artisan tenants:list
php artisan tenant:dump
```
## Maintenance And Storage
```bash
php artisan tenants:down
php artisan tenants:up
php artisan tenants:link
php artisan tenants:link --remove
```
## Rules
- Use tenant commands for tenant DBs; normal `migrate` is central.
- Use `--tenants=*` to scope commands to selected tenants.
- Use `--skip-failing` only when failures should not stop execution.
- Use concurrent process options only after verifying tenant operations are safe in parallel.

View file

@ -0,0 +1,42 @@
# Models And Domains Reference
Use this when changing tenant/domain models or tenant-owned models.
## Source Files
- `src/Database/Models/Tenant.php`
- `src/Database/Models/Domain.php`
- `src/Contracts/Tenant.php`
- `src/Contracts/Domain.php`
- `src/Database/Concerns/*`
- `assets/migrations/*`
## Default Tenant Model
- Table: `tenants`
- Primary key: `id`
- Uses `VirtualColumn`, `CentralConnection`, `GeneratesIds`, `HasInternalKeys`, `TenantRun`, `InitializationHelpers`, `InvalidatesResolverCache`.
- Dispatches tenant lifecycle events.
## Default Domain Model
- Unique `domain` column.
- Belongs to configured tenant model using `Tenancy::tenantKeyColumn()`.
- Uses `CentralConnection`, `EnsuresDomainIsNotOccupied`, `ConvertsDomainsToLowercase`, `InvalidatesTenantsResolverCache`.
## Single-Database Traits
- `BelongsToTenant`
- `FillsCurrentTenant`
- `TenantConnection`
- `CentralConnection`
- `HasScopedValidationRules`
- `RLSModel`
## Rules
- Custom tenant models must implement `Stancl\Tenancy\Contracts\Tenant`.
- Custom domain models must implement `Stancl\Tenancy\Contracts\Domain`.
- Preserve resolver cache invalidation behavior when replacing models.
- Use tenant scoping traits consistently for single-database tenancy.
- If auto-increment tenant IDs are used, update config and migrations together.

View file

@ -2,6 +2,30 @@
This reference is for package-specific details that do not need to live in `SKILL.md`.
## Focused References
Load these smaller references for topic-specific work:
- `installation.md` for install, publishing, and setup checks
- `configuration.md` for `config/tenancy.php` sections
- `identification.md` for middleware and resolvers
- `routing-assets.md` for tenant routes, route modes, cloned routes, and asset routes
- `context-api.md` for `tenancy()`, `tenant()`, `run()`, and `central()` behavior
- `bootstrappers.md` for tenant-aware Laravel service scoping
- `database-tenancy.md` for database isolation and tenant database managers
- `migrations-commands.md` for tenant Artisan commands
- `models-domains.md` for tenant/domain models and single-database traits
- `filesystem-cache-queue.md` for storage, cache, sessions, Redis, and queues
- `lifecycle-jobs.md` for events, provisioning, and cleanup pipelines
- `resource-syncing.md` for synced central and tenant resources
- `impersonation.md` for tenant user impersonation
- `pending-tenants.md` for pending tenant pools
- `rls.md` for PostgreSQL row-level security
- `features.md` for optional package features
- `integrations.md` for URL, mail, broadcasting, Fortify, Scout, Livewire, Telescope, and Vite
- `testing.md` for test coverage guidance
## Main Entry Points
- `src/TenancyServiceProvider.php`

View file

@ -0,0 +1,33 @@
# Pending Tenants Reference
Use this when maintaining a pool of prepared tenants.
## Source Files
- `src/Commands/CreatePendingTenants.php`
- `src/Commands/ClearPendingTenants.php`
- `src/Database/Concerns/HasPending.php`
- `src/Database/Concerns/PendingScope.php`
- `src/Jobs/CreatePendingTenants.php`
- `src/Jobs/ClearPendingTenants.php`
## Config
- `pending.include_in_queries`
- `pending.count`, defaulting to `TENANCY_PENDING_COUNT` or 5
## Commands
```bash
php artisan tenants:pending-create
php artisan tenants:pending-create --count=10
php artisan tenants:pending-clear
php artisan tenants:pending-clear --older-than-days=7
php artisan tenants:pending-clear --older-than-hours=12
```
## Rules
- When `include_in_queries` is false, pending tenants are excluded from tenant queries and tenant commands.
- Use `withPending()`, `withoutPending()`, and `onlyPending()` intentionally.
- Test command behavior with and without pending tenants included in queries.

View file

@ -0,0 +1,32 @@
# Resource Syncing Reference
Use this when syncing central resources into tenant contexts.
## Source Files
- `src/ResourceSyncing/*`
- `assets/resource-syncing-migrations/*`
- `assets/TenancyServiceProvider.stub.php`
## Setup
Publish resource syncing migration:
```bash
php artisan vendor:publish --provider="Stancl\Tenancy\TenancyServiceProvider" --tag=resource-syncing-migrations
php artisan migrate
```
## Main Pieces
- `tenant_resources` table.
- `ResourceSyncing` classes and listeners.
- `SyncMaster`, `Syncable`, `TenantPivot`, `TenantMorphPivot`.
- Events such as `SyncedResourceSaved`, `SyncedResourceDeleted`, `CentralResourceAttachedToTenant`.
## Rules
- Use package events/listeners instead of custom tenant loops.
- Keep central and tenant resource lifecycles explicit.
- Configure soft-delete query behavior in the application `TenancyServiceProvider` when needed.
- Test create, update, delete, restore, attach, and detach behavior.

View file

@ -0,0 +1,33 @@
# PostgreSQL RLS Reference
Use this when implementing single-database PostgreSQL row-level security.
## Source Files
- `src/Bootstrappers/PostgresRLSBootstrapper.php`
- `src/RLS/*`
- `src/Database/Concerns/RLSModel.php`
- `src/Commands/CreateUserWithRLSPolicies.php`
- `tests/RLS/*`
## Config
- `rls.manager`
- `rls.user.username`
- `rls.user.password`
- `rls.session_variable_name`
- `PostgresRLSBootstrapper` in `bootstrappers`
## Command
```bash
php artisan tenants:rls
php artisan tenants:rls --force
```
## Rules
- Use PostgreSQL and single-database tenancy.
- Session variable name must be namespaced, for example `my.current_tenant`.
- RLS user is one tenant database user for all tenants, not one user per tenant.
- Test policies on every tenant-owned table.

View file

@ -0,0 +1,49 @@
# Routing And Assets Reference
Use this when working with tenant routes, route modes, cloned routes, or tenant assets.
## Source Files
- `assets/tenant_routes.stub.php`
- `assets/TenancyServiceProvider.stub.php`
- `assets/routes.php`
- `src/Actions/CloneRoutesAsTenant.php`
- `src/Enums/RouteMode.php`
- `src/Controllers/TenantAssetController.php`
## Published Tenant Routes
The stub groups tenant routes with:
- `web`
- `InitializeTenancyByDomain`
- `PreventAccessFromUnwantedDomains`
- `ScopeSessions`
The application `TenancyServiceProvider` loads `routes/tenant.php` under the `tenant` middleware group.
## Route Modes
The package registers these middleware groups:
- `clone`
- `universal`
- `tenant`
- `central`
`tenancy.default_route_mode` defaults to central. Override per route using route mode middleware.
## Asset Routes
When `tenancy.routes` is true, the package registers:
- `/tenancy/assets/{path?}` named `stancl.tenancy.asset`
- `/{tenant}/tenancy/assets/{path?}` named `tenant.stancl.tenancy.asset` for path identification
## Rules
- Keep central and tenant routes explicit.
- Use `routes/tenant.php` for tenant application routes when using the stub.
- Use `universal` only for routes intended to work in both contexts.
- Use `CloneRoutesAsTenant` for package route integration instead of manually duplicating route definitions.
- Disable package routes only if using external storage or a custom asset controller.

View file

@ -0,0 +1,43 @@
# Testing Reference
Use this when adding or reviewing tenancy behavior tests.
## Source Files
- `tests/TestCase.php`
- `tests/Pest.php`
- `tests/*`
## High-Value Test Areas
- Installation and published files.
- Central route access.
- Tenant route access.
- Domain, subdomain, path, request data, and origin header identification.
- Identification failures.
- Tenant context API restoration after success and exceptions.
- Database connection switching and reverting.
- Cache, Redis, filesystem, session, queue, URL, mail, and broadcasting scoping.
- Tenant migrations, rollbacks, seeds, and tenant command options.
- Tenant lifecycle jobs and event pipelines.
- Resource syncing.
- User impersonation.
- Pending tenants.
- RLS policies.
- Optional features.
## Useful Existing Tests
- `tests/AutomaticModeTest.php`
- `tests/ManualModeTest.php`
- `tests/RouteMiddlewareTest.php`
- `tests/PathIdentificationTest.php`
- `tests/RequestDataIdentificationTest.php`
- `tests/OriginHeaderIdentificationTest.php`
- `tests/TenantAssetTest.php`
- `tests/CommandsTest.php`
- `tests/QueueTest.php`
- `tests/SingleDatabaseTenancyTest.php`
- `tests/RLS/*`
- `tests/ResourceSyncingTest.php`
- `tests/TenantUserImpersonationTest.php`