2.2 Provision tenant
Outcome
A new tenant DB exists on a chosen db_server, all tenant migrations applied, and a row
exists in identity.tenant with status active.
Prerequisites
- 2.1 Intake complete.
What "provisioning" actually does
Steps
Run the provisioning CLI
pnpm tsx scripts/provision-tenant.ts \--slug acme \--name "Acme Behavioral Health" \--region eastus2 \--vertical behavioral \--states OH,IN \--tier standard \--requested-by "you@medsuite.com"The CLI:
- Picks the least-loaded
db_serverfor the region. - Creates the tenant DB and the app-tier role.
- Runs all
packages/database/src/migrations/tenant/*migrations on the tenant DB. - Inserts
identity.tenant(status='active'). - Stores the new app-tier password in Key Vault under
rcm_tenant_<slug>_app_password. - Writes a
TENANT_PROVISIONEDaudit row. - Prints the resulting
tenant_idand a smoke-summary.
- Picks the least-loaded
Verify in the Admin UI
Admin → Tenantsshould now show Acme Behavioral Health with statusactive.Spot-check the tenant DB
TENANT_DB_PASS=$(az keyvault secret show \--vault-name kv-rcm-prod-eastus2 \--name rcm_tenant_acme_app_password --query value -o tsv)psql "host=pg-rcm-tenant-eastus2-01.postgres.database.azure.com \user=rcm_tenant_acme_app dbname=rcm_tenant_acme sslmode=require password=$TENANT_DB_PASS" \-c "SELECT count(*) FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog','information_schema');"You should see ~100 tables (this is the tenant schema baseline).
Slug naming rules
- Lowercase letters, digits, and hyphens only.
- 3–32 characters.
- Reserved slugs are blocked:
admin,api,app,ops,www,static,docs,master,platform,health.
What's NOT done yet
After this step the tenant is provisioned but has zero users, zero org structure, no ingestion feeds, no payer config. That's 2.5–2.10.
Validation
| Check | Expected |
|---|---|
identity.tenant WHERE slug='acme' | 1 row, status='active' |
identity.tenant_audit WHERE event_type='TENANT_PROVISIONED' | 1 row matching the slug |
| Tenant DB exists | psql connect succeeds |
| Migrations applied | knex_migrations count matches Phase 1 master baseline |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| CLI: "no eligible db_server" | All db_server rows in the region are at capacity | Add a new db_server row + provision a new flexible server (see Phase 1.2). |
| Migration X fails partway | Tenant DB partially created | The CLI is idempotent — rerun. If still failing, drop the half-created DB and rerun. |
| Slug rejected | Reserved or duplicated | Pick a different slug. |