Appearance
Tenant Management
Platform admins create and manage lab tenants from Admin Portal → Tenants. Each tenant represents one diagnostic laboratory with its own database, users, and subscription.
Tenant list columns
| Column | Description |
|---|---|
| Name / Slug | Display name and URL slug (/portal/{slug}) |
| Status | PendingSetup, Active, Suspended, Inactive |
| Payment | Trial, Current, Unpaid, Overdue |
| Locked | Read-only indicator |
| Provisioning | Pending, InProgress, Completed, Failed |
| Plan | Active subscription package name |
| Created | Registration date |
Create / edit tenant form
| Field | Required | Description |
|---|---|---|
| Name | Yes | Lab display name |
| Slug | Yes | URL-safe identifier; used in portal URL and database name |
| Logo URL | No | Branding for public portal |
| Portal URL | No | Override default portal link |
| Contact email | No | Primary lab contact |
| Contact phone | No | Primary lab phone |
| Status | Yes | Operational status |
| Payment status | Yes | Billing state |
| Trial ends at | No | UTC datetime; auto-locks when expired |
| Notes | No | Internal operator notes |
API: POST /admin/tenants (create), PUT /admin/tenants/{id} (update).
Provisioning
New tenants need a dedicated PostgreSQL database:
| Action | Endpoint | Result |
|---|---|---|
| Provision | POST /admin/tenants/{id}/provision | Creates easelab_tenant_{slug}, runs migrations, seeds defaults |
Monitor provisioningStatus:
| Value | Meaning |
|---|---|
Pending | Not started |
InProgress | Running |
Completed | Ready for use |
Failed | Check provisioningError |
Lock and unlock
Lock (read-only mode)
POST /admin/tenants/{id}/lock with { "reason": "..." }
| Effect | Detail |
|---|---|
isLocked | Set to true |
| Mutations | Blocked for tenant users (HTTP 403, TENANT_READONLY) |
| Reads | Still allowed |
| Billing routes | Exempt — tenant can still subscribe |
Unlock
POST /admin/tenants/{id}/unlock — clears lock and restores write access.
Automatic locks also occur when trials expire or subscriptions lapse. See Billing Troubleshooting.
Billing section
From the tenant detail view, operators with platform.tenants.billing can:
| Action | Description |
|---|---|
| View subscription | Active plan, expiry, usage |
| Change plan | Assign a different package |
| Adjust payment status | Mark current, unpaid, trial |
| Set trial end | Extend or shorten trial period |
| View payment history | Manual payment records |
Tenant users manage checkout through /billing in the tenant portal.
Custom domain
Branded patient portals can use a custom hostname (e.g. reports.mylab.pk):
| Step | Endpoint | Action |
|---|---|---|
| 1. Set hostname | POST /admin/tenants/{id}/custom-domain | { "hostname": "reports.mylab.pk" } |
| 2. Configure DNS | — | Add CNAME/TXT records shown in response |
| 3. Verify | POST /admin/tenants/{id}/custom-domain/verify | Confirms DNS propagation |
| 4. Disable | DELETE /admin/tenants/{id}/custom-domain | Removes custom domain |
DNS records include verification tokens. Until verified, the default slug URL remains active.
See also Public Portal: Custom Domain.
Tenant users
| Endpoint | Purpose |
|---|---|
GET /admin/tenants/{id}/users | List tenant staff |
PUT /admin/tenants/{id}/users/{userId}/email | Correct owner email |
Impersonation
Support staff can sign in as the tenant owner for troubleshooting. See Impersonation.