1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-06-21 05:54:03 +00:00
tenancy/resources/boost/guidelines/core.blade.php

193 lines
8.4 KiB
PHP

<stancl-tenancy-guidelines>
=== core rules ===
# Stancl Tenancy Guidelines
These guidelines apply to Laravel applications using `stancl/tenancy`. Keep this file concise for Laravel Boost. For detailed package behavior, load the focused references in `resources/boost/skills/laravel-tenancy/references`.
## Package Context
- Composer package: `stancl/tenancy`
- Service provider: `Stancl\Tenancy\TenancyServiceProvider`
- Facades: `Tenancy` and `GlobalCache`
- Core manager: `Stancl\Tenancy\Tenancy`
- Default tenant model: `Stancl\Tenancy\Database\Models\Tenant`
- Default domain model: `Stancl\Tenancy\Database\Models\Domain`
- Default tenant key column: `tenant_id`
- Reserved dynamic tenant connection name: `tenant`
## Focused References
Load the focused reference matching the task before implementing changes:
- `resources/boost/skills/laravel-tenancy/references/installation.md` for install and publishing
- `resources/boost/skills/laravel-tenancy/references/configuration.md` for `config/tenancy.php`
- `resources/boost/skills/laravel-tenancy/references/identification.md` for middleware and resolvers
- `resources/boost/skills/laravel-tenancy/references/routing-assets.md` for routes, route modes, cloned routes, and tenant assets
- `resources/boost/skills/laravel-tenancy/references/context-api.md` for `tenancy()`, `tenant()`, `run()`, and `central()`
- `resources/boost/skills/laravel-tenancy/references/bootstrappers.md` for tenant-aware Laravel service scoping
- `resources/boost/skills/laravel-tenancy/references/database-tenancy.md` for database isolation and database managers
- `resources/boost/skills/laravel-tenancy/references/migrations-commands.md` for tenant Artisan commands
- `resources/boost/skills/laravel-tenancy/references/models-domains.md` for tenant/domain models and single-database traits
- `resources/boost/skills/laravel-tenancy/references/filesystem-cache-queue.md` for storage, cache, sessions, Redis, and queues
- `resources/boost/skills/laravel-tenancy/references/lifecycle-jobs.md` for tenant event pipelines and provisioning
- `resources/boost/skills/laravel-tenancy/references/resource-syncing.md` for synced central and tenant resources
- `resources/boost/skills/laravel-tenancy/references/impersonation.md` for tenant user impersonation
- `resources/boost/skills/laravel-tenancy/references/pending-tenants.md` for pending tenant pools
- `resources/boost/skills/laravel-tenancy/references/rls.md` for PostgreSQL row-level security
- `resources/boost/skills/laravel-tenancy/references/features.md` for optional package features
- `resources/boost/skills/laravel-tenancy/references/integrations.md` for URL, mail, broadcasting, Fortify, Scout, Livewire, Telescope, and Vite
- `resources/boost/skills/laravel-tenancy/references/testing.md` for test coverage guidance
## Installation Rules
Use the package installer unless intentionally publishing one tag:
```bash
composer require stancl/tenancy
php artisan tenancy:install --no-interaction
php artisan migrate
php artisan tenants:migrate
```
The installer publishes:
- `config/tenancy.php`
- `routes/tenant.php`
- `app/Providers/TenancyServiceProvider.php`
- central tenant and domain migrations
- `database/migrations/tenant`
Review `config/tenancy.php` before running migrations. Decide identification, central domains, route mode, bootstrappers, database isolation, and tenant migration path before writing application code.
## Core Workflow
- Decide tenant identification first: domain, subdomain, domain-or-subdomain, path, request data, or origin header.
- Keep central, tenant, and universal routes explicit with package middleware and route modes.
- Choose database isolation early: separate tenant databases, PostgreSQL schemas, single-database tenancy, or PostgreSQL RLS.
- Configure bootstrappers before writing application workarounds.
- Put tenant migrations in `database/migrations/tenant` unless `tenancy.migration_parameters` changes the path.
- Use package context APIs instead of manually mutating framework state.
- Test central and tenant contexts for every tenancy-sensitive change.
## Tenant Context Rules
Use package APIs:
```php
tenancy()->initialize($tenant);
$tenant->run(fn () => null);
tenancy()->central(fn () => null);
tenancy()->end();
```
Do not manually change database connections, cache prefixes, filesystem roots, queue payloads, session stores, URL roots, mail config, or broadcasting config when a package bootstrapper owns that concern.
## Identification Rules
Built-in tenant identification middleware:
- `InitializeTenancyByDomain`
- `InitializeTenancyBySubdomain`
- `InitializeTenancyByDomainOrSubdomain`
- `InitializeTenancyByPath`
- `InitializeTenancyByRequestData`
- `InitializeTenancyByOriginHeader`
Use `PreventAccessFromUnwantedDomains` only with domain-oriented identification middleware recognized by `tenancy.identification.domain_identification_middleware`.
For path identification, check `PathTenantResolver` config before changing route parameters. For request-data identification, configure header, cookie, and query parameter names explicitly.
## Routing Rules
The package registers route middleware groups:
- `clone`
- `universal`
- `tenant`
- `central`
Use `routes/tenant.php` for tenant application routes when using the published stub. Use `CloneRoutesAsTenant` for package route integration instead of manually duplicating package routes.
When `tenancy.routes` is true, tenant asset routes are loaded from `assets/routes.php`. If `filesystem.url_override` is enabled for local public disks, run:
```bash
php artisan tenants:link
```
## Database And Model Rules
- Never use `tenant` as a template tenant connection name.
- Add tenant-specific migrations to `database/migrations/tenant`.
- Use tenant commands for tenant databases, not normal Laravel migration commands.
- If using auto-increment tenant IDs, set `models.id_generator` to `null` and update the tenants migration together.
- Custom tenant models must implement `Stancl\Tenancy\Contracts\Tenant`.
- Custom domain models must implement `Stancl\Tenancy\Contracts\Domain`.
- Use package traits for single-database tenancy instead of hand-written tenant filters.
## Command Rules
Use package commands for tenant-aware operations:
```bash
php artisan tenants:migrate
php artisan tenants:rollback
php artisan tenants:migrate-fresh
php artisan tenants:seed
php artisan tenants:run cache:clear
php artisan tenant:tinker
php artisan tenants:dump
php artisan tenants:list
php artisan tenants:down
php artisan tenants:up
php artisan tenants:link
php artisan tenants:pending-create
php artisan tenants:pending-clear
php artisan tenants:purge-impersonation-tokens
php artisan tenants:rls
```
Use `php artisan help <command>` to confirm options in the installed app. Use `--tenants=*` when only selected tenants should be affected.
## Feature Rules
Enable optional features through `tenancy.features` only when needed:
- `UserImpersonation`
- `TelescopeTags`
- `CrossDomainRedirect`
- `ViteBundler`
- `DisallowSqliteAttach`
- `TenantConfig`
Prefer `TenantConfigBootstrapper` over the deprecated `TenantConfig` feature for mapping tenant attributes into config. Publish and migrate impersonation/resource-syncing migrations before enabling those workflows.
## Testing Rules
Every tenancy behavior change needs tests covering the relevant central and tenant contexts.
Verify the task-specific behavior:
- tenant identification success and failure
- central routes stay central
- tenant routes initialize tenancy
- database, cache, filesystem, queue, session, URL, mail, or broadcasting scoping
- tenant migrations, seeds, and command options
- tenant lifecycle jobs and event pipelines
- optional features only when enabled
- context restoration after `run()` and `central()` callbacks
## Common Pitfalls
- Running normal `php artisan migrate` and expecting tenant databases to migrate
- Forgetting `php artisan tenants:migrate` after tenants exist
- Mixing central and tenant routes without route mode decisions
- Using `PreventAccessFromUnwantedDomains` with non-domain identification
- Forgetting `identification.central_domains` for domain/subdomain apps
- Manually changing framework state instead of using bootstrappers
- Enabling resolver caching without invalidation coverage
- Enabling `filesystem.asset_helper_override` without checking third-party asset calls
- Using single-database tenancy without consistent tenant scoping
- Skipping central-context tests after adding tenant behavior
</stancl-tenancy-guidelines>