Skip to content

feat: Cloud-Native Multi-Tenant Provisioning Protocol (Turso + Metadata Pipeline)#795

Merged
hotlong merged 4 commits intomainfrom
copilot/define-protocol-level-schemas
Feb 24, 2026
Merged

feat: Cloud-Native Multi-Tenant Provisioning Protocol (Turso + Metadata Pipeline)#795
hotlong merged 4 commits intomainfrom
copilot/define-protocol-level-schemas

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 24, 2026

Protocol-level schemas, contracts, and driver specs for the "Register → Instant ObjectOS" architecture: Turso DB-per-Tenant, metadata-driven deployment, shared compute with isolated data.

Turso Driver Protocol

  • data/driver/turso-multi-tenant.zod.tsTursoMultiTenantConfigSchema (URL template, group auth, resolver strategy), TursoGroupSchema (region, replicas, schema DB), TenantDatabaseLifecycleSchema (create/delete/suspend hooks)
  • contracts/turso-platform.tsITursoPlatformService interface: createDatabase, deleteDatabase, listDatabases, createToken, revokeTokens
  • data/driver-sql.zod.tsSQLiteDataTypeMappingDefaults constant, SQLiteAlterTableLimitations (documents table rebuild strategy)

Tenant Provisioning

  • system/provisioning.zod.tsTenantProvisioningRequestSchema (orgId, plan, region), TenantProvisioningResultSchema (tenantId, connectionUrl, steps), status/plan/region enums, ProvisioningStepSchema
  • system/tenant.zod.ts — Extended TenantSchema with databaseProvider (turso|postgres|memory), connectionConfig, provisioningStatus, plan. Added TenantUsageSchema, QuotaEnforcementResultSchema, expanded TenantQuotaSchema with maxObjects, maxRecordsPerObject, maxDeploymentsPerDay, maxStorageBytes
  • contracts/provisioning-service.tsIProvisioningService: provision, suspend, resume, destroy, migrate plan

Metadata-Driven Deployment

  • system/deploy-bundle.zod.tsDeployBundleSchema, DeployManifestSchema, DeployDiffSchema, MigrationPlanSchema, DeployValidationResultSchema, DeployStatusEnum
  • contracts/schema-diff-service.tsISchemaDiffService: introspect → diff → generateMigrations → applyMigrations
  • contracts/deploy-pipeline-service.tsIDeployPipelineService: validateBundle → planDeployment → executeDeployment → rollbackDeployment

Tenant-Aware Runtime

  • kernel/context.zod.tsTenantRuntimeContextSchema extends KernelContextSchema with tenantId, tenantPlan, tenantRegion, tenantDbUrl
  • contracts/tenant-router.tsITenantRouter: resolveTenant, getTenantClient, invalidateCache

App Installation

  • system/app-install.zod.tsAppManifestSchema (snake_case name, version, objects, dependencies), AppCompatibilityCheckSchema, AppInstallRequestSchema, AppInstallResultSchema
  • contracts/app-lifecycle-service.tsIAppLifecycleService: checkCompatibility, installApp, uninstallApp, upgradeApp
// Example: Turso multi-tenant config
const config = TursoMultiTenantConfigSchema.parse({
  organizationSlug: 'myorg',
  urlTemplate: 'libsql://{tenant_id}-myorg.turso.io',
  groupAuthToken: process.env.TURSO_GROUP_AUTH_TOKEN,
  tenantResolverStrategy: 'token',
  group: {
    name: 'production',
    primaryLocation: 'iad',
    replicaLocations: ['lhr', 'nrt'],
    schemaDatabase: 'schema-db',
  },
});

88 new tests across 6 test files (4 new + 2 updated). All 225 test files / 6363 tests pass.

Original prompt

This section details on the original issue you should resolve

<issue_title>🏗️ [Protocol] Cloud-Native Multi-Tenant Provisioning Protocol (Turso + Metadata Pipeline)</issue_title>
<issue_description>

Summary

Define and implement the protocol-level schemas, contracts, and driver specifications required to support the "注册即开通" (Register → Instant ObjectOS) architecture: Turso DB-per-Tenant + Metadata-Driven Deployment Pipeline + Shared Compute with Isolated Data.

Motivation

ObjectStack Cloud needs a complete protocol layer to support:

  1. Turso DB-per-Tenant — Each tenant gets an independent Turso/libSQL database at registration
  2. Metadata-Driven Deployment — Schema push → Zod validate → DDL sync (no Docker/CI/CD needed)
  3. Shared Runtime + Isolated Data — Serverless functions are shared; data is physically isolated per tenant
  4. App Marketplace Install — Install apps by injecting metadata + schema sync into tenant DB

This issue covers protocol and spec changes only (Zod schemas, TypeScript types, contracts). The runtime implementation is tracked in a separate issue.

Architecture Decision Record

Decision Choice Rationale
Tenant DB Turso (DB-per-Tenant) $0 free tier for 500 DBs; native 10K+ DBs; per-query pricing
Deploy Pipeline Metadata-Driven (no build) Schema push = DDL sync; 2-5s deploys vs 2-15min traditional
Runtime Model Shared Compute + Request-level Routing $0 compute cost; Serverless stateless = safe tenant isolation
Control Plane DB Neon PostgreSQL (keep existing) Already in use by Cloud; fixed cost for org/billing/audit
Bundle Storage Cloudflare R2 10GB free; $0 egress; S3-compatible API
Isolation Level isolated_db Matches TenantIsolationLevel in tenant.zod.ts

Task Breakdown

Part A: Turso Driver Protocol Completion (spec)

Status: Phase 0 (Schema) ✅ Done → Phase A (Core Driver) 🔴 Needs Implementation

  • A1. Turso Multi-Tenant Router Schemapackages/spec/src/data/driver/turso-multi-tenant.zod.ts

    • Define TursoMultiTenantConfigSchema with urlTemplate, groupAuthToken, tenantResolverStrategy
    • Define TenantDatabaseLifecycleSchema with onTenantCreate, onTenantDelete, onTenantSuspend hooks
    • Define TursoGroupSchema for Turso Database Group configuration (region, primary location)
    • Add to packages/spec/src/data/index.ts exports
    • Write tests in packages/spec/src/data/driver/turso-multi-tenant.test.ts
  • A2. Turso Platform API Contractpackages/spec/src/contracts/turso-platform.ts

    • Define ITursoPlatformService interface: createDatabase(), deleteDatabase(), listDatabases(), createToken(), revokeToken()
    • Define TursoDatabaseInfo response schema
    • Define TursoTokenScope enum (full-access, read-only)
    • This contract will be implemented by @objectstack/driver-turso package
  • A3. SQLite Dialect for SQL Compiler — Extend packages/spec/src/data/driver-sql.zod.ts

    • Verify SQLDialectSchema already includes 'sqlite' ✅ (confirmed)
    • Add SQLiteDataTypeMappingDefaults constant with TEXT/REAL/INTEGER/BLOB mappings
    • Add SQLiteAlterTableLimitations documentation constant (no MODIFY COLUMN, table rebuild strategy)

Part B: Tenant Provisioning Protocol

  • B1. Tenant Provisioning Schemapackages/spec/src/system/provisioning.zod.ts (NEW FILE)

    // Schemas to define:
    TenantProvisioningRequestSchema    // Input: orgId, plan, region
    TenantProvisioningResultSchema     // Output: tenantId, connectionUrl, status
    TenantProvisioningStatusEnum       // 'provisioning' | 'active' | 'suspended' | 'failed' | 'destroying'
    TenantPlanSchema                   // 'free' | 'pro' | 'enterprise' with quota definitions
    TenantRegionSchema                 // Available deployment regions
    ProvisioningStepSchema             // Individual step status tracking
    • Add tests: packages/spec/src/system/provisioning.test.ts
    • Export from packages/spec/src/system/index.ts
  • B2. Extend TenantSchema for Tursopackages/spec/src/system/tenant.zod.ts

    • Add databaseProvider field to TenantSchema: z.enum(['turso', 'postgres', 'memory'])
    • Add connectionConfig field: z.object({ url, authToken, group }) (encrypted at rest)
    • Add provisioningStatus field using TenantProvisioningStatusEnum
    • Add plan field referencing TenantPlanSchema
    • Update existing tests to cover new fields
  • B3. Provisioning Service Contractpackages/spec/src/contracts/provisioning-service.ts (NEW FILE)

    interface IProvisioningService {
      provisionTenant(request: TenantProvisioningRequest): Promise<TenantProvisioningResult>;
      suspendTenant(tenantId: string): Promise<void>;
      resumeTenant(tenantId: string): Promise<void>;
      destroyTenant(tenantId: string): Promise<void>;
      getTenantStatus(tenantId: s...

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectstack-play Error Error Feb 24, 2026 3:58am
spec Error Error Feb 24, 2026 3:58am

Request Review

- Part A: Turso multi-tenant router schema, platform API contract, SQLite type mappings
- Part B: Tenant provisioning schema, extended TenantSchema with Turso fields, provisioning service contract
- Part C: Deploy bundle schema, schema diff service contract, deploy pipeline service contract
- Part D: Tenant runtime context schema, tenant router contract, quota enforcement schemas
- Part E: App install bundle schema, app lifecycle service contract
- All index exports updated (data, system, contracts)
- 66 new tests across 4 test files (225 total test files, 6341 tests passing)

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Define protocol-level schemas for cloud-native provisioning feat: Cloud-Native Multi-Tenant Provisioning Protocol (Turso + Metadata Pipeline) Feb 24, 2026
Copilot AI requested a review from hotlong February 24, 2026 03:44
@hotlong
Copy link
Copy Markdown
Collaborator

hotlong commented Feb 24, 2026

@copilot 仔细评估是否已完成所有开发需求

…Schema, QuotaEnforcementResult, TenantRuntimeContext

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 24, 2026

@copilot 仔细评估是否已完成所有开发需求

完成了所有需求的逐项评估,以下是对照 Issue 任务清单的完成状态:

Part A: Turso Driver Protocol ✅

  • A1: TursoMultiTenantConfigSchema (urlTemplate, groupAuthToken, tenantResolverStrategy), TenantDatabaseLifecycleSchema (onTenantCreate/Delete/Suspend hooks), TursoGroupSchema + exports + 15 tests
  • A2: ITursoPlatformService (createDatabase, deleteDatabase, listDatabases, createToken, revokeTokens), TursoDatabaseInfo, TursoTokenScope
  • A3: SQLiteDataTypeMappingDefaults (TEXT/REAL/INTEGER/BLOB), SQLiteAlterTableLimitations

Part B: Tenant Provisioning ✅

  • B1: TenantProvisioningRequestSchema, TenantProvisioningResultSchema, TenantProvisioningStatusEnum, TenantPlanSchema, TenantRegionSchema, ProvisioningStepSchema + 18 tests
  • B2: Extended TenantSchema with databaseProvider, connectionConfig, provisioningStatus, plan更新了现有测试覆盖新字段 (commit 0fa5203)
  • B3: IProvisioningService 全部6个方法

Part C: Metadata-Driven Deployment ✅

  • C1: DeployBundleSchema, DeployManifestSchema, DeployDiffSchema, MigrationPlanSchema, DeployValidationResultSchema, DeployStatusEnum + 18 tests
  • C2: ISchemaDiffService (introspect → diff → generateMigrations → applyMigrations)
  • C3: IDeployPipelineService (validateBundle → planDeployment → executeDeployment → rollbackDeployment)

Part D: Tenant-Aware Runtime ✅

  • D1: TenantRuntimeContextSchema extending KernelContextSchema补充了5个测试 (commit 0fa5203)
  • D2: ITenantRouter (resolveTenant, getTenantClient, invalidateCache)
  • D3: TenantQuotaSchema extended (maxObjects, maxRecordsPerObject, maxDeploymentsPerDay, maxStorageBytes) + TenantUsageSchema + QuotaEnforcementResultSchema补充了相关测试

Part E: App Installation ✅

  • E1: AppManifestSchema, AppCompatibilityCheckSchema, AppInstallRequestSchema, AppInstallResultSchema + 15 tests
  • E2: IAppLifecycleService (checkCompatibility, installApp, uninstallApp, upgradeApp)

All 225 test files / 6363 tests passing. Roadmap updated.

@hotlong hotlong marked this pull request as ready for review February 24, 2026 04:04
Copilot AI review requested due to automatic review settings February 24, 2026 04:04
@hotlong hotlong merged commit 713445f into main Feb 24, 2026
1 of 3 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive Cloud-Native Multi-Tenant Provisioning Protocol for ObjectStack, enabling the "Register → Instant ObjectOS" architecture with Turso DB-per-Tenant, metadata-driven deployment, and shared compute with isolated data.

Changes:

  • Added Turso multi-tenant driver protocol with DB-per-Tenant configuration, lifecycle hooks, and group management schemas
  • Created tenant provisioning protocol with request/result schemas, status tracking, and plan/region enums
  • Implemented metadata-driven deployment bundle protocol with schema diff, migration plans, and validation
  • Added app installation protocol for marketplace apps with compatibility checking and install workflows
  • Extended tenant, kernel context, and SQL driver schemas to support multi-tenant provisioning
  • Defined 6 new service contracts (ITursoPlatformService, IProvisioningService, ISchemaDiffService, IDeployPipelineService, ITenantRouter, IAppLifecycleService)

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/spec/src/system/tenant.zod.ts Extended TenantSchema with databaseProvider, connectionConfig, provisioningStatus, plan fields; added TenantUsageSchema and QuotaEnforcementResultSchema; expanded TenantQuotaSchema with deployment quotas
packages/spec/src/system/tenant.test.ts Added 185 lines of comprehensive tests for new tenant schema extensions
packages/spec/src/system/provisioning.zod.ts New file defining tenant provisioning protocol with status/plan/region enums, provisioning steps, and request/result schemas
packages/spec/src/system/provisioning.test.ts New file with 173 lines of tests covering all provisioning schemas
packages/spec/src/system/deploy-bundle.zod.ts New file defining deployment protocol with deploy status, schema diff, migration plans, validation, and bundle schemas
packages/spec/src/system/deploy-bundle.test.ts New file with 201 lines of tests for deployment bundle schemas
packages/spec/src/system/app-install.zod.ts New file defining app installation protocol with manifest, compatibility check, and install request/result schemas
packages/spec/src/system/app-install.test.ts New file with 167 lines of tests for app installation schemas
packages/spec/src/system/index.ts Added exports for provisioning, deploy-bundle, and app-install modules
packages/spec/src/kernel/context.zod.ts Extended KernelContextSchema with TenantRuntimeContextSchema for tenant-aware runtime context
packages/spec/src/kernel/context.test.ts Added 72 lines of tests for TenantRuntimeContextSchema
packages/spec/src/data/index.ts Added export for turso-multi-tenant driver
packages/spec/src/data/driver/turso-multi-tenant.zod.ts New file defining Turso multi-tenant router configuration with resolver strategies, group config, and lifecycle hooks
packages/spec/src/data/driver/turso-multi-tenant.test.ts New file with 183 lines of comprehensive tests for Turso driver schemas
packages/spec/src/data/driver-sql.zod.ts Added SQLiteDataTypeMappingDefaults and SQLiteAlterTableLimitations constants for SQLite dialect support
packages/spec/src/contracts/turso-platform.ts New contract defining ITursoPlatformService interface for Turso Platform API operations
packages/spec/src/contracts/provisioning-service.ts New contract defining IProvisioningService interface for tenant lifecycle management
packages/spec/src/contracts/schema-diff-service.ts New contract defining ISchemaDiffService interface for schema introspection and migration generation
packages/spec/src/contracts/deploy-pipeline-service.ts New contract defining IDeployPipelineService interface for metadata-driven deployments
packages/spec/src/contracts/tenant-router.ts New contract defining ITenantRouter interface for tenant-aware request routing
packages/spec/src/contracts/app-lifecycle-service.ts New contract defining IAppLifecycleService interface for app installation/upgrade/uninstall
packages/spec/src/contracts/index.ts Added exports for all new provisioning and deployment contracts
docs/NEXT_STEP.md Updated checklist to mark deployment protocol and service contracts as complete

Comment on lines 70 to +95
maxStorage: z.number().int().positive().optional().describe('Maximum storage in bytes'),

/**
* API rate limit (requests per minute)
*/
apiRateLimit: z.number().int().positive().optional().describe('API requests per minute'),

/**
* Maximum number of custom objects the tenant can create
*/
maxObjects: z.number().int().positive().optional().describe('Maximum number of custom objects'),

/**
* Maximum records per object/table
*/
maxRecordsPerObject: z.number().int().positive().optional().describe('Maximum records per object'),

/**
* Maximum deployments allowed per day
*/
maxDeploymentsPerDay: z.number().int().positive().optional().describe('Maximum deployments per day'),

/**
* Maximum storage in bytes
*/
maxStorageBytes: z.number().int().positive().optional().describe('Maximum storage in bytes'),
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a redundancy in TenantQuotaSchema: both maxStorage (line 70) and maxStorageBytes (line 95) represent storage limits in bytes. Consider removing the deprecated maxStorage field or clarifying their difference in documentation if they serve different purposes.

Copilot uses AI. Check for mistakes.
Comment on lines +177 to +218
export const SQLiteDataTypeMappingDefaults: DataTypeMapping = {
text: 'TEXT',
number: 'REAL',
boolean: 'INTEGER',
date: 'TEXT',
datetime: 'TEXT',
json: 'TEXT',
uuid: 'TEXT',
binary: 'BLOB',
};

/**
* SQLite ALTER TABLE Limitations.
*
* SQLite has limited ALTER TABLE support compared to other SQL databases.
* This constant documents the known limitations that affect migration planning.
* The schema diff service must use the "table rebuild" strategy for operations
* that SQLite cannot perform natively.
*
* @see https://www.sqlite.org/lang_altertable.html
*/
export const SQLiteAlterTableLimitations = {
/** SQLite supports ADD COLUMN */
supportsAddColumn: true,
/** SQLite supports RENAME COLUMN (3.25.0+) */
supportsRenameColumn: true,
/** SQLite supports DROP COLUMN (3.35.0+) */
supportsDropColumn: true,
/** SQLite does NOT support MODIFY/ALTER COLUMN type */
supportsModifyColumn: false,
/** SQLite does NOT support adding constraints to existing columns */
supportsAddConstraint: false,
/**
* When an unsupported alteration is needed, the migration planner
* must use the 12-step table rebuild strategy:
* 1. CREATE new table with desired schema
* 2. Copy data from old table
* 3. DROP old table
* 4. RENAME new table to old name
*/
rebuildStrategy: 'create_copy_drop_rename',
} as const;
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new SQLite-specific constants SQLiteDataTypeMappingDefaults and SQLiteAlterTableLimitations lack test coverage. Add tests to verify that SQLiteDataTypeMappingDefaults conforms to the DataTypeMapping type and that SQLiteAlterTableLimitations has the expected structure and values.

Copilot uses AI. Check for mistakes.
Comment on lines +199 to +206
provisioningStatus: z.enum([
'provisioning', 'active', 'suspended', 'failed', 'destroying',
]).optional().describe('Current provisioning lifecycle status'),

/**
* Tenant subscription plan
*/
plan: z.enum(['free', 'pro', 'enterprise']).optional().describe('Subscription plan'),
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tenant plan enum is defined inline here instead of reusing TenantPlanSchema from provisioning.zod.ts. For consistency and DRY principles, consider importing and using TenantPlanSchema instead of duplicating the enum definition. The same applies to provisioningStatus which duplicates TenantProvisioningStatusEnum.

Copilot uses AI. Check for mistakes.
tenantId: z.string().min(1).describe('Resolved tenant identifier'),

/** Tenant subscription plan */
tenantPlan: z.enum(['free', 'pro', 'enterprise']).describe('Tenant subscription plan'),
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tenant plan enum is defined inline here instead of reusing TenantPlanSchema from provisioning.zod.ts. For consistency and DRY principles, import TenantPlanSchema and use it here: tenantPlan: TenantPlanSchema.describe('Tenant subscription plan').

Copilot uses AI. Check for mistakes.
tenantPlan: z.enum(['free', 'pro', 'enterprise']).describe('Tenant subscription plan'),

/** Tenant deployment region */
tenantRegion: z.string().min(1).describe('Tenant deployment region'),
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tenantRegion field is defined as a plain string (z.string().min(1)) instead of using the TenantRegionSchema enum from provisioning.zod.ts. For type safety and validation consistency, consider using TenantRegionSchema to ensure only valid regions are accepted.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🏗️ [Protocol] Cloud-Native Multi-Tenant Provisioning Protocol (Turso + Metadata Pipeline)

3 participants