Skip to content

🔌 [Driver] Turso Multi-Tenant Router + Schema Diff Engine + Driver Plugin #406

@hotlong

Description

@hotlong

Summary

基于已有的 @objectql/driver-turso (v4.2.2, 836 行完整实现) 进行增量升级,新增:

  1. Multi-Tenant Router — 请求级租户路由工厂
  2. Schema Diff Engine — 自动化迁移生成
  3. TursoDriverPlugin — ObjectStack 内核插件封装

⚠️ 重要:已有代码现状

组件 位置 状态
TursoDriver (完整 CRUD) packages/drivers/turso/src/turso-driver.ts ✅ v4.2.2 已完成
query-compiler.ts packages/drivers/turso/src/query-compiler.ts ✅ 已完成
type-mapper.ts packages/drivers/turso/src/type-mapper.ts ✅ 已完成
result-mapper.ts packages/drivers/turso/src/result-mapper.ts ✅ 已完成
Schema introspect TursoDriver.introspectSchema() ✅ 已完成
Schema sync / init TursoDriver.init() + syncSchema() ✅ 已完成
Transactions beginTransaction / commit / rollback ✅ 已完成
Bulk ops bulkCreate / bulkUpdate / bulkDelete ✅ 已完成
DriverInterface v4.0 executeQuery / executeCommand ✅ 已完成

以下任务为增量开发,不重写已有功能。

开发任务

Part 1: Multi-Tenant Router (NEW — ~1 周)

  • 1.1 multi-tenant-router.tspackages/drivers/turso/src/multi-tenant-router.ts (NEW)

    export interface MultiTenantConfig {
      urlTemplate: string;     // 'libsql://{tenant}-org.turso.io'
      groupAuthToken?: string;
      clientCacheTTL?: number; // ms, default 5min
      onTenantCreate?: (tenantId: string) => Promise<TursoDriverConfig>;
      onTenantDelete?: (tenantId: string) => Promise<void>;
    }
    
    export function createMultiTenantRouter(config: MultiTenantConfig): {
      getDriverForTenant(tenantId: string): Promise<TursoDriver>;
      invalidateCache(tenantId: string): void;
      destroyAll(): Promise<void>;
    };
    • urlTemplate{tenant} 替换为 tenantId
    • 进程级 Map<string, { driver: TursoDriver, expiresAt: number }> 缓存
    • TTL 过期后 disconnect() 并重新创建
    • Serverless 安全:无全局状态泄漏
  • 1.2 Turso Platform API Clientpackages/drivers/turso/src/turso-platform-api.ts (NEW)

    export class TursoPlatformAPI {
      constructor(config: { orgSlug: string; apiToken: string });
      createDatabase(name: string, group?: string): Promise<{ hostname: string }>;
      deleteDatabase(name: string): Promise<void>;
      createToken(dbName: string, options?: { expiration?: string; authorization?: string }): Promise<{ jwt: string }>;
      listDatabases(): Promise<Array<{ name: string; hostname: string }>>;
    }
    • 封装 Turso REST API (https://api.turso.tech/v1/organizations/{org}/databases)
    • 用于 Cloud 端调用
  • 1.3 Router 测试packages/drivers/turso/test/multi-tenant-router.test.ts

    • 使用 :memory: 模式测试多租户路由
    • Mock Turso Platform API
    • 缓存过期/失效测试
    • ≥90% 覆盖率

Part 2: Schema Diff Engine (NEW — ~1 周)

  • 2.1 schema-differ.tspackages/drivers/turso/src/schema-differ.ts (NEW)

    export interface CurrentSchema {
      tables: Array<{ name: string; columns: Array<{ name: string; type: string; notnull: boolean; pk: boolean }> }>;
    }
    
    export interface SchemaDiff {
      newTables: Array<{ name: string; columns: string[] }>;
      newColumns: Array<{ table: string; column: string; type: string }>;
      removedColumns: Array<{ table: string; column: string }>;
      typeChanges: Array<{ table: string; column: string; from: string; to: string }>;
    }
    
    export function diffSchema(current: CurrentSchema, desired: ObjectDefinition[]): SchemaDiff;
    export function generateMigrationSQL(diff: SchemaDiff): string[];
    • 复用已有的 TursoDriver.introspectSchema() 获取当前结构
    • 对比期望的 ObjectDefinition[] 生成 DDL
    • 处理 SQLite ALTER TABLE 限制(不支持 MODIFY COLUMN → 表重建策略)
    • 排除系统表 (sys_*, sqlite_*)
  • 2.2 migration-executor.tspackages/drivers/turso/src/migration-executor.ts (NEW)

    export interface MigrationResult {
      applied: number;
      logs: string[];
      duration: number; // ms
    }
    
    export async function executeMigrations(
      driver: TursoDriver,
      migrations: string[]
    ): Promise<MigrationResult>;
    • 使用 driver.execute() (已有) 批量执行 DDL
    • 逐条记录日志
    • 错误时返回已执行步骤信息
  • 2.3 Diff 测试packages/drivers/turso/test/schema-differ.test.ts

    • 新表检测、新列检测、类型变更检测
    • 空 diff 场景
    • ≥90% 覆盖率

Part 3: Kernel Plugin 封装 (NEW — ~2 天)

  • 3.1 turso-driver-plugin.tspackages/drivers/turso/src/turso-driver-plugin.ts (NEW)

    import type { RuntimePlugin, RuntimeContext } from '@objectstack/types';
    
    export class TursoDriverPlugin implements RuntimePlugin {
      name = 'driver-turso';
      constructor(private config: TursoDriverConfig) {}
    
      async install(ctx: RuntimeContext): Promise<void> {
        const driver = new TursoDriver(this.config);
        await driver.connect();
        ctx.engine.ql?.setDriver?.(driver);
      }
    
      async onStart(ctx: RuntimeContext): Promise<void> {
        // Health check on kernel start
      }
    }
  • 3.2 更新 exportspackages/drivers/turso/src/index.ts

    • 导出新增的 router、differ、plugin、platform API

文件变更汇总

Action File
NEW src/multi-tenant-router.ts
NEW src/turso-platform-api.ts
NEW src/schema-differ.ts
NEW src/migration-executor.ts
NEW src/turso-driver-plugin.ts
MODIFY src/index.ts — 添加新 exports
NEW test/multi-tenant-router.test.ts
NEW test/schema-differ.test.ts
NEW test/migration-executor.test.ts

Acceptance Criteria

  • Multi-tenant router 可通过 tenantId 获取独立 TursoDriver 实例
  • Schema diff 可正确检测新表/新列/类型变更
  • Migration executor 可批量执行 DDL 并返回日志
  • Kernel plugin 可注册到 ObjectKernel
  • pnpm test 全通过,新增代码 ≥90% 覆盖率
  • pnpm build 零错误
  • :memory: 模式支持 CI 无外部依赖

Labels

driver, turso, multi-tenant, schema-migration, P0

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