@@ -4,15 +4,29 @@ Multi-tenant context management and routing service for ObjectStack.
44
55## Overview
66
7- This service provides tenant identification and context resolution for multi-tenant ObjectStack deployments. It supports multiple identification strategies and manages tenant-specific database routing.
7+ This service provides comprehensive multi-tenant infrastructure for ObjectStack deployments, including:
8+
9+ - Tenant identification and context resolution
10+ - Turso Platform API integration for automated database provisioning
11+ - Tenant database schema initialization
12+ - Global control plane management
13+ - Package installation per tenant
814
915## Features
1016
17+ ### Phase 1 (Complete)
1118- ** Multiple Identification Sources** : Subdomain, custom domain, HTTP headers, JWT claims, session
1219- ** UUID-Based Tenant Naming** : Immutable tenant identifiers (not organization slugs)
1320- ** Tenant Context Caching** : Performance optimization for frequently accessed tenants
1421- ** Flexible Configuration** : Priority-based identification source ordering
1522
23+ ### Phase 2 (Complete)
24+ - ** Turso Platform API Integration** : Automated database creation via Turso Platform API
25+ - ** Tenant-Specific Auth Tokens** : Secure, database-specific authentication
26+ - ** Global Control Plane** : System objects for tenant registry and package installations
27+ - ** Schema Initialization** : Automated tenant database schema setup
28+ - ** Package Management** : Per-tenant package installation and schema migration
29+
1630## Installation
1731
1832``` bash
@@ -21,28 +35,108 @@ pnpm add @objectstack/service-tenant
2135
2236## Usage
2337
24- ### Basic Setup
38+ ### Basic Setup (Tenant Routing)
2539
2640``` typescript
2741import { createTenantPlugin } from ' @objectstack/service-tenant' ;
2842import { ObjectKernel } from ' @objectstack/core' ;
2943
3044const kernel = new ObjectKernel ();
3145
32- // Create tenant plugin
46+ // Create tenant plugin with routing configuration
3347const tenantPlugin = createTenantPlugin ({
34- enabled: true ,
35- identificationSources: [' header' , ' custom_domain' , ' jwt_claim' ],
36- tenantHeaderName: ' X-Tenant-ID' ,
37- customDomainMapping: {
38- ' app.acme.com' : ' 550e8400-e29b-41d4-a716-446655440000' ,
48+ routing: {
49+ enabled: true ,
50+ identificationSources: [' header' , ' custom_domain' , ' jwt_claim' ],
51+ tenantHeaderName: ' X-Tenant-ID' ,
52+ customDomainMapping: {
53+ ' app.acme.com' : ' 550e8400-e29b-41d4-a716-446655440000' ,
54+ },
3955 },
56+ registerSystemObjects: true , // Register control plane objects
4057});
4158
4259await kernel .use (tenantPlugin );
4360await kernel .bootstrap ();
4461```
4562
63+ ### Tenant Provisioning
64+
65+ ``` typescript
66+ import {
67+ TenantProvisioningService ,
68+ TursoPlatformClient ,
69+ } from ' @objectstack/service-tenant' ;
70+
71+ // Production mode: with Turso Platform API
72+ const provisioningService = new TenantProvisioningService ({
73+ turso: {
74+ apiToken: process .env .TURSO_API_TOKEN ! ,
75+ organization: ' my-org' ,
76+ },
77+ controlPlaneDriver: globalDriver , // Global control plane driver
78+ defaultRegion: ' us-east-1' ,
79+ databaseGroup: ' production-tenants' ,
80+ });
81+
82+ // Provision a new tenant
83+ const result = await provisioningService .provisionTenant ({
84+ organizationId: ' org-123' ,
85+ plan: ' pro' ,
86+ region: ' us-west-2' ,
87+ storageLimitMb: 5120 ,
88+ });
89+
90+ console .log (' Tenant provisioned:' , result .tenant );
91+ // {
92+ // id: '550e8400-e29b-41d4-a716-446655440000',
93+ // databaseUrl: 'libsql://550e8400-e29b-41d4-a716-446655440000.turso.io',
94+ // authToken: '<encrypted-token>',
95+ // status: 'active',
96+ // ...
97+ // }
98+ ```
99+
100+ ### Development Mode (No Turso API)
101+
102+ ``` typescript
103+ // Development/Mock mode: no Turso Platform API required
104+ const devService = new TenantProvisioningService ({
105+ defaultRegion: ' us-east-1' ,
106+ });
107+
108+ const result = await devService .provisionTenant ({
109+ organizationId: ' org-123' ,
110+ plan: ' free' ,
111+ });
112+
113+ // Returns mock tenant with warnings
114+ console .log (result .warnings );
115+ // ['Running in mock mode - Turso Platform API credentials not configured']
116+ ```
117+
118+ ### Schema Initialization
119+
120+ ``` typescript
121+ import { TenantSchemaInitializer } from ' @objectstack/service-tenant' ;
122+
123+ const initializer = new TenantSchemaInitializer ();
124+
125+ // Initialize tenant database with base schema
126+ await initializer .initializeTenantSchema (
127+ tenant .databaseUrl ,
128+ tenant .authToken ,
129+ baseObjects , // Optional: base objects to create
130+ );
131+
132+ // Install package schema
133+ await initializer .installPackageSchema (
134+ tenant .databaseUrl ,
135+ tenant .authToken ,
136+ packageObjects ,
137+ );
138+ ```
139+
46140### Resolving Tenant Context
47141
48142``` typescript
0 commit comments