Skip to content

πŸ—οΈ [Protocol] Cloud-Native Multi-Tenant Provisioning Protocol (Turso + Metadata Pipeline)Β #794

@hotlong

Description

@hotlong

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 Schema β€” packages/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 Contract β€” packages/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 Schema β€” packages/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 Turso β€” packages/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 Contract β€” packages/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: string): Promise<TenantProvisioningStatus>;
      migrateTenantPlan(tenantId: string, newPlan: TenantPlan): Promise<void>;
    }
    • Add to contracts index

Part C: Metadata-Driven Deployment Protocol

  • C1. Deploy Bundle Schema β€” packages/spec/src/system/deploy-bundle.zod.ts (NEW FILE)

    // Schemas to define:
    DeployBundleSchema       // Container for all metadata being deployed
    DeployManifestSchema     // Version, checksum, objects[], views[], flows[], permissions[]
    DeployDiffSchema         // What changed: added/modified/removed objects and fields
    DeployValidationResult   // Zod validation result for the entire bundle
    MigrationPlanSchema      // Ordered list of DDL statements to execute
    DeployStatusEnum         // 'validating' | 'diffing' | 'migrating' | 'registering' | 'ready' | 'failed'
    • Add tests
    • Export from system index
  • C2. Schema Diff Contract β€” packages/spec/src/contracts/schema-diff-service.ts (NEW FILE)

    interface ISchemaDiffService {
      introspect(driver: IDataDriver): Promise<CurrentSchema>;
      diff(current: CurrentSchema, desired: ObjectDefinition[]): DeployDiff;
      generateMigrations(diff: DeployDiff, dialect: SQLDialect): MigrationPlan;
      applyMigrations(driver: IDataDriver, plan: MigrationPlan): Promise<MigrationResult>;
    }
  • C3. Deploy Pipeline Contract β€” packages/spec/src/contracts/deploy-pipeline-service.ts (NEW FILE)

    interface IDeployPipelineService {
      validateBundle(bundle: DeployBundle): DeployValidationResult;
      planDeployment(tenantId: string, bundle: DeployBundle): Promise<MigrationPlan>;
      executeDeployment(tenantId: string, plan: MigrationPlan): Promise<DeployResult>;
      rollbackDeployment(tenantId: string, deploymentId: string): Promise<void>;
    }

Part D: Tenant-Aware Runtime Protocol

  • D1. Tenant Context Schema β€” Extend packages/spec/src/kernel/context.zod.ts

    • Add TenantRuntimeContextSchema extending KernelContextSchema
    • Include tenantId, tenantPlan, tenantRegion, tenantDbUrl
    • This context is constructed per-request from session β†’ org β†’ tenant lookup
  • D2. Tenant Router Contract β€” packages/spec/src/contracts/tenant-router.ts (NEW FILE)

    interface ITenantRouter {
      resolveTenant(session: AuthSession): Promise<TenantRuntimeContext>;
      getTenantClient(tenantId: string): Promise<IDataDriver>;
      invalidateCache(tenantId: string): void;
    }
  • D3. Tenant Quota Enforcement Schema β€” Extend packages/spec/src/system/tenant.zod.ts

    • Extend TenantQuotaSchema with maxObjects, maxRecordsPerObject, maxDeploymentsPerDay, maxStorageBytes
    • Add TenantUsageSchema for current usage tracking
    • Add QuotaEnforcementResult schema

Part E: App Installation Protocol

  • E1. App Install Bundle Schema β€” packages/spec/src/system/app-install.zod.ts (NEW FILE)

    AppManifestSchema       // name, version, objects[], views[], flows[], seedData[]
    AppInstallRequestSchema // tenantId, appId, config overrides
    AppInstallResultSchema  // installed objects, created tables, seeded records
    AppCompatibilityCheck   // Check kernel version, existing objects, conflicts
  • E2. App Lifecycle Contract β€” packages/spec/src/contracts/app-lifecycle-service.ts (NEW FILE)

    interface IAppLifecycleService {
      checkCompatibility(tenantId: string, manifest: AppManifest): Promise<CompatibilityResult>;
      installApp(tenantId: string, manifest: AppManifest, config: Record<string, unknown>): Promise<AppInstallResult>;
      upgradeApp(tenantId: string, appId: string, newManifest: AppManifest): Promise<AppInstallResult>;
      uninstallApp(tenantId: string, appId: string): Promise<void>;
    }

Files to Create/Modify

Action File Description
CREATE src/data/driver/turso-multi-tenant.zod.ts Multi-tenant Turso router schema
CREATE src/contracts/turso-platform.ts Turso Platform API contract
CREATE src/system/provisioning.zod.ts Tenant provisioning schemas
CREATE src/system/deploy-bundle.zod.ts Deploy bundle & diff schemas
CREATE src/system/app-install.zod.ts App installation schemas
CREATE src/contracts/provisioning-service.ts IProvisioningService
CREATE src/contracts/schema-diff-service.ts ISchemaDiffService
CREATE src/contracts/deploy-pipeline-service.ts IDeployPipelineService
CREATE src/contracts/tenant-router.ts ITenantRouter
CREATE src/contracts/app-lifecycle-service.ts IAppLifecycleService
MODIFY src/system/tenant.zod.ts Add databaseProvider, connectionConfig, plan
MODIFY src/kernel/context.zod.ts Add TenantRuntimeContext
MODIFY src/system/index.ts Export new modules
MODIFY src/contracts/index.ts Export new contracts

Acceptance Criteria

  • All new schemas have Zod definitions with .describe() annotations
  • All TypeScript types derived via z.infer<>
  • All contracts define async interfaces only (no implementation in spec)
  • All property keys use camelCase; all machine names use snake_case
  • All new files have corresponding .test.ts with β‰₯90% branch coverage
  • pnpm test passes across all packages
  • pnpm build succeeds with no TypeScript errors
  • Reference docs auto-generated for all new schemas
  • ROADMAP.md updated to reflect new Phase 6 progress

Labels

protocol, multi-tenant, turso, provisioning, P0

References

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions