Database Migrations: Central and Per-Tenant Schemas
Complete reference for XHealtXperience’s two-tier migration system: the central platform schema and the per-clinic tenant schema managed by stancl/tenancy.
Use this file to discover all available pages before exploring further.
XHealtXperience uses stancl/tenancy to implement strict database-level multi-tenancy. Each clinic (tenant) owns a completely isolated SQLite or MySQL database, and Laravel runs a separate set of migrations for every new clinic that is provisioned. Understanding which migration files live where — and what they create — is essential before modifying or extending the schema.
database/migrations/Run once against the single central database that powers the platform itself: super-admin users, tenant registry, domain routing, and platform-wide permissions.
Tenant migrations
database/migrations/tenant/Run automatically inside each clinic’s isolated database whenever a new tenant is created — and can be re-run across all existing tenants with php artisan tenants:migrate.
Never place clinic-specific tables (patients, appointments, medical records, etc.) in database/migrations/. Conversely, never place tenancy infrastructure tables (tenants, domains) in database/migrations/tenant/. Mixing the two directories breaks tenant isolation and the automatic provisioning pipeline.
# Central database only (run once during setup)php artisan migrate# Apply pending central migrations (CI, deploy)php artisan migrate --force# Run tenant migrations across ALL existing clinicsphp artisan tenants:migrate# Roll back the last central migration batchphp artisan migrate:rollback
Tenant migrations for a newly created clinic are triggered automatically by stancl/tenancy’s JobPipeline — you do not need to run any command manually when onboarding a new clinic through the UI or API.
Adds two_factor_method column (e.g., totp, email) to central users.
2026_03_25_172327_create_permission_tables
Creates Spatie Permission tables (permissions, roles, model_has_permissions, model_has_roles, role_has_permissions) in the central DB for platform-level RBAC.
Scans every tenant database and removes residual Admin and Super Admin roles that should not exist in tenant context. Use --dry-run to preview which tenants are affected without making any changes.
# Preview what would be removedphp artisan roles:clean-stale --dry-run# Remove stale rolesphp artisan roles:clean-stale