数据库
数据库
使用 InsForge + Drizzle ORM 管理数据
HackerStart 使用 InsForge 作为后端服务(认证、数据库、API),配合 Drizzle ORM 进行类型安全的数据库操作。
架构
浏览器 → TanStack Start → InsForge SDK → InsForge Server → PostgreSQL
↓
Drizzle ORM(类型定义 + Schema 管理)- InsForge SDK:提供认证、数据库 CRUD、RLS 等高级功能
- Drizzle ORM:TypeScript 类型定义,用于 schema 管理和 migration 生成
- PostgreSQL:底层数据库,由 InsForge 管理
HackerStart 的数据库操作主要通过 InsForge SDK 完成(认证、用户管理、RLS),Drizzle 用于 schema 定义和 migration 管理。客户端代码不直接使用 Drizzle 查询数据库。
InsForge 设置
方式一:Local InsForge(本地开发,推荐)
使用 InsForge CLI 在本地启动 InsForge 服务:
# 安装 InsForge CLI(如果还没安装)
pnpm add -g @insforge/cli
# 启动本地 InsForge
insforge start启动后,InsForge 会提供以下信息:
- App URL(如
http://localhost:10700)→ 填入INSFORGE_URL和VITE_INSFORGE_URL - Anon Key → 填入
INSFORGE_ANON_KEY和VITE_INSFORGE_ANON_KEY - API Key → 填入
INSFORGE_API_KEY
方式二:InsForge Cloud(生产环境)
如果你使用 InsForge Cloud,在 InsForge Dashboard 中获取连接信息:
- 创建一个 InsForge 项目
- 在项目设置中找到 URL、Anon Key 和 API Key
- 填入
.env文件
环境变量
| 变量 | 必需 | 说明 |
|---|---|---|
INSFORGE_URL | ✅ | InsForge 服务地址(服务端) |
INSFORGE_ANON_KEY | ✅ | InsForge 匿名密钥(服务端) |
INSFORGE_API_KEY | ✅ | InsForge API 密钥,用于 admin 操作(仅服务端,不可暴露给浏览器) |
VITE_INSFORGE_URL | ✅ | 浏览器端 InsForge 地址(通常和 INSFORGE_URL 相同) |
VITE_INSFORGE_ANON_KEY | ✅ | 浏览器端 InsForge 匿名密钥(通常和 INSFORGE_ANON_KEY 相同) |
INSFORGE_API_KEY 只在服务端使用,不要以 VITE_ 前缀暴露给浏览器。
初始化数据库 Schema
InsForge 启动后,需要应用 HackerStart 的数据库 schema:
# 使用 InsForge CLI 执行 schema.sql
insforge db query src/db/schema.sql
# 或在 InsForge Dashboard 的 SQL Editor 中执行 src/db/schema.sql 的内容Schema 包含以下核心表:
| 表名 | 说明 |
|---|---|
workspaces | 工作区(tenant 数据隔离的基本单位) |
workspace_memberships | 工作区成员与角色 |
workspace_invitations | 工作区邀请 |
organizations | 组织(多工作区治理层) |
organization_memberships | 组织成员与角色 |
events | Event 基础记录 |
ticket_types | Event 票种目录 |
event_participant_registrations | Event 参与者注册关系 |
tickets | Event 入场凭证和 check-in 状态 |
event_organizer_assignments | Event organizer 分配 |
event_operator_assignments | Event operator 分配 |
event_access_grants | Event scoped access grant |
tenant_feature_gates | 工作区级别功能开关 |
app_config_values | 全局配置 |
tenant_config_overrides | 工作区配置覆盖 |
config_audit_events | 配置变更审计日志 |
platform_admins | 平台管理员 |
SDK 使用
服务端标准客户端(认证操作)
import { createInsForgeServerClient } from '@/lib/insforge/server'
const client = createInsForgeServerClient()
// 用于 signIn, signUp, signOut 等认证操作服务端 Admin 客户端(绕过 RLS)
import { createInsForgeAdminClient } from '@/lib/insforge/server'
const client = createInsForgeAdminClient()
// 用于工作区管理、成员查询等需要 admin 权限的操作
// 仅在服务端使用,不可暴露给浏览器浏览器端客户端
import { createInsForgeClient } from '@/lib/insforge/client'
const client = createInsForgeClient()数据库查询函数
数据库查询函数位于 src/db/queries/ 目录:
src/db/queries/
├── workspaces.ts # 工作区管理
├── workspace-memberships.ts # 成员管理
├── workspace-invitations.ts # 邀请管理
├── organizations.ts # 组织管理
├── events.ts # Event 关系与 scoped grant
├── events-public.ts # 公开 Explore 查询
├── platform-admins.server.ts # 平台管理员管理
└── tenant-feature-gates.ts # 功能开关Schema 管理
Drizzle schema 定义在 src/db/drizzle/schema.ts,用于生成 migration:
# 生成 migration
pnpm db:generate
# 检查 schema 状态
pnpm db:checkRLS(行级安全)
所有租户相关表都启用了 RLS。关键原则:
- 业务表通过
tenant_id实现数据隔离 - 成员查询通过
workspace_memberships验证归属关系 - 写入策略结合角色判断(
owner/admin/operator) - RLS helper 函数使用
SECURITY DEFINER避免递归
Events 公开报名会创建 membership_kind='event_attendee' 的轻量成员关系。工作区内部 RLS、成员列表和 tenant resolver 默认只接受 membership_kind='collaborator',避免公开活动参与者获得工作区协作权限。
详见《角色与权限》。