Files
imbytecat 6bedc1d60d refactor: 降级 Drizzle ORM 至 0.45.x 稳定版,对齐 Better Auth 兼容性
- drizzle-orm 1.0.0-beta.15 → 0.45.2, drizzle-kit → 0.31.10
- RQBv2 defineRelations() → 旧版 relations() 回调语法
- drizzle-orm/zod → drizzle-zod 独立包
- auth/schema.ts 改由 Better Auth CLI 生成(bun run db:auth)
- db/schema/index.ts 选择性导出表(不导出生成文件中的旧版 relations)
- 删除 db:push script,强制 db:generate → db:migrate 工作流
- 重建迁移基线(删除旧迁移目录,全新生成初始迁移)
2026-03-31 20:18:15 +08:00

6.4 KiB

AGENTS.md - AI Coding Agent Guidelines

Guidelines for AI agents working in this Bun monorepo.

Product Vision

Kairos 是一个人生操作系统(Personal Life OS)。所有开发决策必须服务于这个愿景。

Kairos 将个人生活的每一个维度 —— 财务、订阅、健康、资产、决策 —— 整合进一个统一的、自托管的平台。

设计信条

  1. 数据主权 —— 自托管、本地优先。用户数据不离开用户的机器,除非用户自己决定。
  2. 关联即洞察 —— 孤立数据是噪音,关联数据是洞察。所有模块共享统一数据层。
  3. 可扩展基座 —— 架构必须支持模块的独立扩展和自定义。

Agent 决策指南

  • 这是否让用户更完整地掌控自己的数据? 如果否,重新考虑。
  • 这个模块的数据是否可以被其他模块关联使用? 如果不能,说明数据模型设计有问题。
  • 这个功能是否可以在完全离线/自托管环境下工作? 如果不能,必须提供无外部依赖的替代方案。
  • 新增的功能是否通过 ORPC 契约暴露? Web 和 CLI 必须能同等访问所有能力。

Project Overview

This project uses Bun exclusively as both the JavaScript runtime and package manager. Do NOT use Node.js / npm / yarn / pnpm. Always prefer bun run <script> over bun <script> to avoid conflicts with Bun built-in subcommands. Never use npm, npx, or node.

  • Monorepo: Bun workspaces + Turborepo orchestration
  • Runtime: Bun (see mise.toml for version) — NOT Node.js
  • Package Manager: Bun — NOT npm / yarn / pnpm
  • Apps: apps/server — TanStack Start fullstack web app (see apps/server/AGENTS.md)
  • Packages: packages/tsconfig — shared TS configs

Build / Lint / Test Commands

# Root (via Turbo)
bun run dev              # Start all apps in dev mode
bun run build            # Build all apps
bun run compile          # Compile server to standalone binary
bun run fix              # Lint + format (Biome auto-fix)
bun run typecheck        # TypeScript check across monorepo

# Database (in apps/server) — ALWAYS use migration workflow, never db:push
bun run db:auth          # Regenerate Better Auth schema (after upgrading better-auth)
bun run db:generate      # Generate migrations from schema changes
bun run db:migrate       # Run pending migrations
bun run db:studio        # Open Drizzle Studio

# Server CLI (in apps/server)
bun run cli auth reset-password   # Reset owner password

# Testing (not yet configured)
bun test path/to/test.ts # Run single test file

Code Style (TypeScript)

Formatting (Biome)

  • Indent: 2 spaces | Line width: 120 | Line endings: LF
  • Quotes: Single ' | Semicolons: Omit (ASI)
  • Arrow parentheses: Always (x) => x

Imports

Biome auto-organizes. Order: 1) External packages → 2) Internal @/* aliases → 3) Type imports (import type { ... })

TypeScript Strictness

  • strict: true, noUncheckedIndexedAccess: true, verbatimModuleSyntax: true
  • Use @/* path aliases (maps to src/*)

Naming Conventions

Type Convention Example
Files (utils) kebab-case auth-utils.ts
Files (components) PascalCase UserProfile.tsx
Components PascalCase arrow const Button = () => {}
Functions camelCase getUserById
Constants UPPER_SNAKE MAX_RETRIES
Types/Interfaces PascalCase UserProfile
Drizzle tables camelCase, no suffix user, category (NOT userTable)

React Patterns

  • Components: arrow functions (enforced by Biome)
  • Data fetching: useSuspenseQuery(orpc.feature.list.queryOptions())
  • Let React Compiler handle memoization (no manual useMemo/useCallback)

Error Handling

  • Use try-catch for async operations; throw descriptive errors
  • ORPC: Use ORPCError with proper codes (NOT_FOUND, UNAUTHORIZED, INTERNAL_SERVER_ERROR)
  • Never use empty catch blocks

Database (Drizzle ORM + postgres-js)

  • ORM: Drizzle ORM 0.45.x (stable)
  • Driver: drizzle-orm/postgres-js (NOT bun-sql)
  • Validation: drizzle-zod (separate package, NOT drizzle-orm/zod)
  • Relations: Defined via relations() from drizzle-orm — callback syntax
  • Query style: db.query.tableName.findMany({ where: (t, { eq }) => eq(t.col, val), orderBy: (t, { asc }) => asc(t.col) })
  • Auth schema: Generated by Better Auth CLI (bun run db:auth), never hand-edit
  • Schema re-export: db/schema/index.ts selectively exports tables only (not relations) from auth schema
  • Migration workflow: Always db:generatedb:migrate. Never use db:push.

Environment Variables

  • Use @t3-oss/env-core with Zod validation in src/env.ts
  • Server vars: no prefix | Client vars: VITE_ prefix required
  • Never commit .env files

Dependency Management

  • All versions centralized in root package.json catalog field
  • Workspace packages use "catalog:" — never hardcode versions
  • Internal packages use "workspace:*" references

Development Principles

  1. No backward compatibility — Always use the latest API and patterns. Never keep deprecated code paths.
  2. Always sync documentation — When code changes, immediately update AGENTS.md and related docs.
  3. Forward-only migration — When upgrading dependencies, fully adopt the new API.

Critical Rules

DO:

  • Run bun run fix before committing
  • Use @/* path aliases (not relative imports)
  • Include createdAt/updatedAt on all tables
  • Use catalog: for dependency versions

DON'T:

  • Use npm, npx, node, yarn, pnpm — always use bun / bunx
  • Edit src/routeTree.gen.ts (auto-generated)
  • Use as any, @ts-ignore, @ts-expect-error
  • Commit .env files
  • Use empty catch blocks catch(e) {}
  • Hardcode dependency versions in workspace packages
  • Leave docs out of sync with code changes

Directory Structure

.
├── apps/
│   └── server/              # TanStack Start fullstack app (see apps/server/AGENTS.md)
├── packages/
│   └── tsconfig/            # Shared TS configs
├── biome.json               # Linting/formatting config
├── turbo.json               # Turbo task orchestration
└── package.json             # Workspace root + dependency catalog

See Also

  • apps/server/AGENTS.md — Detailed server app architecture, ORPC patterns, UI conventions