跳到主要内容

01 · 分层全景

## 六层栈：从运行时底座到接口横切

点步进器或图里的任意一层聚焦；下方详情会列出该层的真实依赖与选它的理由。上层依赖下层，越往上越贴近请求、越薄。

上层依赖下层

提示：悬停某一层看它的一句话定位，点击则展开该层的依赖清单与选型理由。

01

键盘 ← → 切层 · P 导览 · Esc 退出聚焦

02 · 选型原则

## 四条不成文的规矩

这些原则不写在代码里，但决定了上面每一层为什么长这样。

### 单体优先，无独立后端

Next Route Handlers + Server Actions 同仓同进程，省一层网络与部署；要对外集成再开 `MCP` / Agent API Key，不为「后端」单独起一套服务。

### 类型贯通到库

Drizzle `schema.ts` 即类型源头，Zod 守外部边界，端到端 TypeScript，无 codegen 步骤——改一张表，编译器立刻在调用处报错。

### 凭据不明文落库

密码 bcrypt、AI 密钥 AES-256 加密后入库、危险操作走确认闸门。安全不靠自觉，靠结构——明文永不落盘。

### 一份 schema，两处运行

同一份 Drizzle schema：生产走 PostgreSQL、本地走 SQLite，本地零外部依赖起跑；查询避开方言特有语法，靠 ORM 抹平差异。

03 · 关键抉择

## 六个岔路口，选了什么、放弃了什么

每一条都有真实备选。列出来是为了让「为什么不是那个」也留痕。

### ORM

选择 | Drizzle ORM
备选 | Prisma
理由 | SQL-first、无生成步骤、schema 即类型，pg + sqlite 双方言；轻到能塞进 serverless 冷启动。

### PostgreSQL 驱动

选择 | postgres.js
备选 | node-postgres（pg）
理由 | 更快、标签模板 SQL；prepare:false + max:1 适配连接池 / serverless，不踩预处理语句缓存坑。

### API 形态

选择 | Route Handlers + Server Actions
备选 | 独立 Nest / Express 服务
理由 | 同仓同进程、共享类型、一键部署；对外集成才开 MCP + Agent API Key，不为「后端」单独起一套。

### 鉴权

选择 | Better Auth
备选 | NextAuth / Clerk
理由 | 自托管、drizzle adapter 存库、内置 2FA；无外部依赖与按量计费，账号数据全在自己库里。

### 数据库迁移

选择 | 手写 SQL 迁移
备选 | drizzle-kit push（生产）
理由 | 生产用可审计的原生 SQL（含 pgvector / pg_trgm 扩展），drizzle-kit 只在本地开发用。

### 缓存 / KV

选择 | Upstash Redis
备选 | 自建 Redis 实例
理由 | HTTP 协议、serverless 友好、免运维；只做缓存与轻状态，主数据永远以 PostgreSQL 为准。

04 · 完整选型清单

## 10 个域，一屏看全后端依赖

逐条取自 `apps/web/src/server` 与 `package.json`。颜色标出每个依赖在选型里的角色。

### 后端依赖面板

核心主干是自持的服务端逻辑；托管服务把横切外包；基建类是自托管基础设施与加密；虚线红 是仅本地或可替换项。

运行时 & 语言runtime
Node 22 TypeScript 5.9 Next 16 Server Actions tsx
数据库 & ORMdatabase
PostgreSQL pgvector pg_trgm drizzle-orm postgres.js better-sqlite3 drizzle-kit
鉴权 & 安全auth
better-auth @better-auth/drizzle-adapter two-factor bcryptjs AES-256 · node:crypto
AI 运行时ai-runtime
ai · Vercel AI SDK @ai-sdk/openai @mastra/core @mastra/ai-sdk @modelcontextprotocol/sdk mcp-handler
校验 & 契约contract
zod http 统一响应 分页 pagination
缓存 & KVcache
@upstash/redis
存储 & 上传storage
S3 预签名 local-storage 兜底 uploadthing sharp
领域服务domains
assistant kb doc-library agent dashboard notification public-site
落档 & 可观测observability
thread / run / step 落库 响应头 Thread-Id / Run-Id
工具链tooling
tsx drizzle-kit vitest eslint biome check
主干核心主干 托管托管服务 · SaaS 基建自托管 / 基础设施 / 加密 备选仅本地 · 可替换

### 选型边界（known tensions）

- 全部塞进一个 Next 进程：好处是零网络、共享类型；代价是重活（长任务、批处理）只能靠 `maxDuration` 与外挂队列，量大了要拆服务。
- 双方言（PG / SQLite）要靠纪律：查询一律走 Drizzle、避开方言特有语法；pgvector / pg_trgm 是 Postgres 独有，SQLite 模式下相关能力降级。
- 迁移是手写 SQL：可审计但需人肉保证与 Drizzle schema 同步，drizzle-kit 仅辅助本地。
- 缓存 / 限流依赖 Upstash 可用性：Redis 只做加速与轻状态，主数据永远以 PostgreSQL 为准，Redis 挂了不影响正确性。
- AI 供应商密钥虽 AES-256 加密，但密钥管理仍在应用层：轮换与泄露响应需要额外流程，当前靠确认闸门 + 全量落档兜底。