Onlook数据库集成:Supabase与Drizzle ORM配置指南

Onlook数据库集成:Supabase与Drizzle ORM配置指南

【免费下载链接】onlook The open source Cursor for Designers. Design directly in your live React app and publish your changes to code. 【免费下载链接】onlook 项目地址: https://gitcode.com/GitHub_Trending/on/onlook

引言:为什么选择Supabase + Drizzle ORM组合?

在现代Web应用开发中,数据库集成是核心环节。Onlook项目选择了Supabase作为后端即服务(BaaS)平台,配合Drizzle ORM(对象关系映射器)构建了一套高效、类型安全的数据库解决方案。这种组合为开发者提供了:

  • 🚀 开箱即用的认证系统
  • 🔒 内置的行级安全策略
  • 📊 实时数据订阅功能
  • 🛡️ 类型安全的数据库操作
  • 🔧 强大的迁移工具链

本文将深入解析Onlook项目中Supabase与Drizzle ORM的配置细节,帮助你快速搭建类似的数据库架构。

环境配置与依赖安装

核心依赖包配置

首先,查看项目的package.json文件了解所需依赖:

{
  "devDependencies": {
    "supabase": "^2.6.8"
  }
}

对于Drizzle ORM,项目使用以下核心包:

// 典型依赖配置
{
  "dependencies": {
    "drizzle-orm": "^0.30.0",
    "postgres": "^3.4.4",
    "@supabase/supabase-js": "^2.38.0"
  },
  "devDependencies": {
    "drizzle-kit": "^0.20.0"
  }
}

Supabase本地开发配置

Onlook使用Supabase的本地开发模式,配置文件位于 apps/backend/supabase/config.toml

project_id = "onlook-web"

[api]
enabled = true
port = 54321
schemas = ["public", "storage"]
extra_search_path = ["public"]
max_rows = 100

[auth]
site_url = "https://onlook.com"
additional_redirect_urls = [
    "http://localhost:3000",
    "http://localhost:3000/auth/callback",
]
jwt_expiry = 36000

[db]
port = 54322

[studio]
port = 54323

Drizzle ORM配置详解

数据库连接配置

Drizzle的配置文件 packages/db/drizzle.config.ts 定义了数据库连接和迁移设置:

import { defineConfig } from 'drizzle-kit';

const DEFAULT_DATABASE_URL = 'postgresql://postgres:postgres@127.0.0.1:54322/postgres';

export default defineConfig({
    schema: './src/schema',
    out: '../../apps/backend/supabase/migrations',
    dialect: "postgresql",
    schemaFilter: ["public"],
    verbose: true,
    dbCredentials: {
        url: process.env.SUPABASE_DATABASE_URL ?? DEFAULT_DATABASE_URL,
    },
    entities: {
        roles: {
            provider: 'supabase'
        }
    }
});

数据库客户端实现

数据库连接客户端在 packages/db/src/client.ts 中实现:

import * as schema from '@onlook/db/src/schema';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';

const globalForDb = globalThis as unknown as {
    conn: postgres.Sql | undefined;
};

const conn = globalForDb.conn ?? postgres(process.env.SUPABASE_DATABASE_URL!, { prepare: false });
if (process.env.NODE_ENV !== 'production') globalForDb.conn = conn;

export const db = drizzle(conn, { schema });
export type DrizzleDb = typeof db;

数据模型定义与架构设计

模块化Schema组织

Onlook采用模块化的Schema组织方式:

mermaid

Supabase认证集成Schema

认证相关的Schema定义在 packages/db/src/schema/supabase/user.ts

import { jsonb, pgSchema, text, timestamp, uuid } from 'drizzle-orm/pg-core';

export const authSchema = pgSchema('auth');

export const authUsers = authSchema.table('users', {
    id: uuid('id').primaryKey(),
    email: text('email').notNull(),
    emailConfirmedAt: timestamp('email_confirmed_at'),
    rawUserMetaData: jsonb('raw_user_meta_data'),
});

export type AuthUser = typeof authUsers.$inferSelect;

数据库种子数据与测试

种子数据配置

项目提供了完整的种子数据配置,位于 packages/db/src/seed/supabase.ts

import { createClient } from "@supabase/supabase-js";
import { SEED_USER } from "./constants";

export const seedSupabaseUser = async () => {
    console.log('Seeding Supabase user...');

    if (!process.env.SUPABASE_URL || !process.env.SUPABASE_SERVICE_ROLE_KEY) {
        throw new Error('SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY must be set');
    }

    const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_SERVICE_ROLE_KEY);

    // 检查用户是否已存在
    const { data: { user: existingUser } } = await supabase.auth.admin.getUserById(SEED_USER.ID);

    if (existingUser) {
        console.log('User already exists, skipping user creation');
        return;
    }

    // 创建测试用户
    const { data, error } = await supabase.auth.admin.createUser({
        id: SEED_USER.ID,
        email: SEED_USER.EMAIL,
        password: SEED_USER.PASSWORD,
        email_confirm: true,
        user_metadata: {
            first_name: SEED_USER.FIRST_NAME,
            last_name: SEED_USER.LAST_NAME,
            display_name: SEED_USER.DISPLAY_NAME,
            avatar_url: SEED_USER.AVATAR_URL,
        },
    });

    if (error) {
        console.error('Error seeding Supabase user:', error);
        throw error;
    }
    console.log('User seeded!');
};

开发工作流与命令脚本

常用开发命令

项目提供了完整的开发脚本,位于 apps/backend/package.json

{
  "scripts": {
    "start": "supabase start",
    "stop": "supabase stop",
    "push": "supabase db push",
    "reset": "supabase db reset",
    "db:gen": "supabase gen types --lang=typescript --local --schema public > ../../packages/supabase/src/types/db.ts",
    "test": "cd supabase/functions/api && deno test"
  }
}

典型开发流程

mermaid

环境变量配置指南

必需的环境变量

# Supabase配置
SUPABASE_URL=http://localhost:54321
SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# 数据库连接
SUPABASE_DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres

# 第三方认证(可选)
GITHUB_CLIENT_ID=env(GITHUB_CLIENT_ID)
GITHUB_SECRET=env(GITHUB_SECRET)
GOOGLE_CLIENT_ID=env(GOOGLE_CLIENT_ID)
GOOGLE_SECRET=env(GOOGLE_SECRET)

环境变量验证策略

在代码中实现环境变量验证:

function validateEnvVars() {
    const requiredVars = [
        'SUPABASE_URL',
        'SUPABASE_ANON_KEY', 
        'SUPABASE_SERVICE_ROLE_KEY',
        'SUPABASE_DATABASE_URL'
    ];

    const missingVars = requiredVars.filter(varName => !process.env[varName]);
    
    if (missingVars.length > 0) {
        throw new Error(`缺少必需的环境变量: ${missingVars.join(', ')}`);
    }
}

故障排除与最佳实践

常见问题解决方案

问题类型症状解决方案
连接超时无法连接到数据库检查Supabase服务状态,验证端口配置
认证失败401未授权错误验证JWT令牌和环境变量配置
迁移冲突迁移文件冲突使用supabase db reset重置数据库
类型错误TypeScript编译错误重新生成类型定义npm run db:gen

性能优化建议

  1. 连接池管理:在生产环境中配置适当的连接池大小
  2. 查询优化:使用Drizzle的索引和查询优化功能
  3. 缓存策略:实现查询结果缓存减少数据库压力
  4. 监控告警:设置数据库性能监控和告警机制

总结与展望

Onlook项目的Supabase与Drizzle ORM集成展示了一个现代化、类型安全的数据库解决方案。这种架构组合提供了:

  • 开发效率:快速的本地开发和测试环境
  • 类型安全:完整的TypeScript支持
  • 扩展性:模块化的Schema设计
  • 安全性:内置的行级安全和认证机制
  • 可维护性:清晰的迁移和版本控制

通过本文的详细指南,你可以快速在自己的项目中实现类似的数据库架构,享受Supabase和Drizzle ORM带来的开发便利性和生产稳定性。

记住,良好的数据库设计是应用成功的基石。花时间理解这些配置细节,将为你的项目带来长期的技术红利。

【免费下载链接】onlook The open source Cursor for Designers. Design directly in your live React app and publish your changes to code. 【免费下载链接】onlook 项目地址: https://gitcode.com/GitHub_Trending/on/onlook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值