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
Provision the tenant
Either:
- From the platform console at
admin.<env>.medsuiteone.ai/tenants/new— fills in the same fields and runs the provisioning orchestrator through aplatform_jobrow that the UI polls for progress (see Platform provisioning runbook). - From the CLI (break-glass when the SPA is unreachable):
pnpm --filter @medsuite/rcm-core provision-tenant \--slug acme \--display-name "Acme Behavioral Health" \--admin-email admin@acme.exampleThe CLI:
- Picks the least-loaded
db_serverfor the region. - Creates the tenant DB and the app-tier role.
- Runs all
packages/rcm-db/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.
- From the platform console at
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. |