4a78ba288276e2dc72f317a1ed27f87655f9f0a1
\u53ea\u6539 schema \u5c42\u9762\uff1a - src/server/db/fields.ts: $defaultFn(() => Bun.randomUUIDv7()) \u2192 default(sql`uuidv7()`) - AGENTS.md Stack & runtime: \u52a0 PG18+ \u786c\u7ea6\u675f - AGENTS.md Drizzle \u8282\u8bf4\u660e DB-side uuidv7\uff08\u5355\u8c03\u3001\u4f7f\u7528 DB \u65f6\u949f\uff09 - AGENTS.md Bun-native \u539f\u5219\u533a\u5206 app-code UUIDv7 \u4e0e DB PK - AGENTS.md Don'ts \u9996\u6761\u52a0 "AI \u4e0d\u80fd\u8dd1 db:generate" \u4f9d\u7136\u9700\u8981\u4f60\u624b\u52a8\u8dd1 `bun run db:generate` \u4ee5\uff1a 1) \u751f\u6210\u65b0 migration\uff08\u5e94\u8be5\u662f DROP \u8001\u8868 + CREATE \u65b0\u8868\uff0c \u6216\u4f60\u624b\u5199 ALTER COLUMN id SET DEFAULT uuidv7()\uff09 2) \u91cd\u751f migrations.gen.ts \u672c commit \u72b6\u6001\u4e0b\u8fd0\u884c\u65f6\u5c1a\u4e0d\u53ef\u7528\uff08\u8001 migration \u672a\u8bbe DEFAULT\uff0c \u63d2\u5165\u4f1a\u62a5 NOT NULL \u9519\uff09\uff1bdb:generate \u540e\u91cd\u65b0 build/compile/deploy \u624d\u662f \u5b8c\u6574\u72b6\u6001\u3002fix / typecheck / test 3/3 \u5747\u8fc7\uff08\u9759\u6001\u68c0\u67e5\u4e0d\u4f9d\u8d56 migration\uff09\u3002
fullstack-starter
一个单二进制的全栈应用 starter——bun run compile 出来的 ./server 文件就是你要部署的全部产物,自带 HTTP 服务、SSR、API、嵌入式 SQL 迁移,运行时不依赖 Node、不依赖源码、不依赖外部 migration 目录。
技术栈:Bun · TanStack Start (React 19 SSR) · ORPC(契约优先 API)· Drizzle ORM · PostgreSQL · Tailwind v4 · Biome。
为什么用这个
- 部署最简:发布只拷一个二进制文件。先
./server migrate再./server,完事。 - 契约优先:在
*.contract.ts用 Zod 定义一次,前端、后端、OpenAPI 文档自动同步。 - 类型严格:TypeScript strict,杜绝
any/@ts-ignore/as any等类型逃逸。 - 开箱可跑:路径别名、文件路由、ORPC 接线、Tailwind、热重载、错误页全部预接好。
快速开始
cp .env.example .env # 把里面的 DATABASE_URL 改成你的 Postgres
bun install
bun run db:push # 开发期:把 schema 直接同步到 DB(不写 migration 文件)
bun run dev # http://localhost:3000
打开浏览器:
http://localhost:3000/— Todo 示例页http://localhost:3000/api/docs— Scalar 渲染的 API 文档
目录结构(你需要关心的部分)
src/
├── routes/ # 文件路由:页面 + API 端点
├── server/
│ ├── api/
│ │ ├── contracts/ # Zod 契约(client / server 共享)
│ │ └── routers/ # 业务实现
│ └── db/ # Drizzle schema + 嵌入式 migrations
├── client/ # 前端 hooks、ORPC 客户端
└── components/ # UI 组件
加一个功能(以 post 为例)
每一步都很短,按顺序填即可:
- 建表:
src/server/db/schema/post.ts定义postTable,记得展开...generatedFields(自动注入id/createdAt/updatedAt)。 - 导出表:在
src/server/db/schema/index.ts加export * from './post'。 - 写契约:
src/server/api/contracts/post.contract.ts用drizzle-zod从表派生 Zod schema。 - 挂契约:在
src/server/api/contracts/index.ts把post加进contract对象。 - 写实现:
src/server/api/routers/post.router.ts实现os.post.*.handler(...)。 - 挂路由:在
src/server/api/routers/index.ts把post加进router对象。 - 写前端 hook:
src/client/queries/post.ts导出useInvalidatePosts等失效辅助。 - 写页面:
src/routes/<page>.tsx用useSuspenseQuery读、mutate写;mutation 的onSuccess调用第 7 步的 helper。 - 生成 migration:
bun run db:generate把 SQL 写到./drizzle/并嵌入二进制。
完工。bun run dev 已自动热重载。
部署
永远先 migrate 再 serve。Migration 已嵌入二进制;部署只发一个 ./server 文件。
./server migrate # 应用嵌入式 migration(用 $DATABASE_URL)
./server # 启动 HTTP 服务(默认子命令)
./server --help # 列出所有子命令
仓库自带 compose.yaml(一次性 migrate 服务先跑完,再启动 app):
docker compose up --build
Kubernetes 上:把 ./server migrate 放进 initContainer 或 Helm pre-upgrade Job,主容器跑 ./server。
脚本一览
| 命令 | 作用 |
|---|---|
bun run dev |
Vite 开发服务器(端口 3000,strict) |
bun run build |
构建到 .output/(bun run compile 会用到) |
bun run compile |
生成单二进制 out/server-<target> |
bun run typecheck |
TypeScript 类型检查 |
bun run test |
运行所有 *.test.ts |
bun run fix |
Biome 格式化 + lint + 整理 imports |
bun run db:push |
开发期:直接同步 schema 到 DB(不写 migration 文件) |
bun run db:generate |
写 SQL migration 到 ./drizzle/ 并嵌入二进制 |
bun run db:embed |
仅重生 migrations.gen.ts(手改了 ./drizzle/*.sql 后用) |
bun run db:migrate |
通过 drizzle-kit 在本地应用 migration(开发便利) |
bun run db:studio |
Drizzle Studio(可视化 DB) |
跨平台编译:bun run compile:{linux,darwin,windows}[:arch]。
端点
| 路径 | 用途 |
|---|---|
/ |
Todo 示例 UI |
/health |
存活探针(不查 DB,纯文本 ok) |
/api/rpc |
ORPC RPC 端点(client 直连) |
/api/docs |
Scalar 渲染的 API 文档 |
/api/spec.json |
OpenAPI spec |
提交前
bun run fix && bun run typecheck && bun run test
没有 CI、没有 pre-commit hook——上面三条由你自觉跑。
Description
Languages
TypeScript
98.7%
Dockerfile
1%
JavaScript
0.2%