6bedc1d60d
- 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 工作流 - 重建迁移基线(删除旧迁移目录,全新生成初始迁移)
6.4 KiB
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 将个人生活的每一个维度 —— 财务、订阅、健康、资产、决策 —— 整合进一个统一的、自托管的平台。
设计信条
- 数据主权 —— 自托管、本地优先。用户数据不离开用户的机器,除非用户自己决定。
- 关联即洞察 —— 孤立数据是噪音,关联数据是洞察。所有模块共享统一数据层。
- 可扩展基座 —— 架构必须支持模块的独立扩展和自定义。
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>overbun <script>to avoid conflicts with Bun built-in subcommands. Never usenpm,npx, ornode.
- Monorepo: Bun workspaces + Turborepo orchestration
- Runtime: Bun (see
mise.tomlfor version) — NOT Node.js - Package Manager: Bun — NOT npm / yarn / pnpm
- Apps:
apps/server— TanStack Start fullstack web app (seeapps/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 tosrc/*)
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-catchfor async operations; throw descriptive errors - ORPC: Use
ORPCErrorwith 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(NOTbun-sql) - Validation:
drizzle-zod(separate package, NOTdrizzle-orm/zod) - Relations: Defined via
relations()fromdrizzle-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.tsselectively exports tables only (not relations) from auth schema - Migration workflow: Always
db:generate→db:migrate. Never usedb:push.
Environment Variables
- Use
@t3-oss/env-corewith Zod validation insrc/env.ts - Server vars: no prefix | Client vars:
VITE_prefix required - Never commit
.envfiles
Dependency Management
- All versions centralized in root
package.jsoncatalogfield - Workspace packages use
"catalog:"— never hardcode versions - Internal packages use
"workspace:*"references
Development Principles
- No backward compatibility — Always use the latest API and patterns. Never keep deprecated code paths.
- Always sync documentation — When code changes, immediately update
AGENTS.mdand related docs. - Forward-only migration — When upgrading dependencies, fully adopt the new API.
Critical Rules
DO:
- Run
bun run fixbefore committing - Use
@/*path aliases (not relative imports) - Include
createdAt/updatedAton all tables - Use
catalog:for dependency versions
DON'T:
- Use
npm,npx,node,yarn,pnpm— always usebun/bunx - Edit
src/routeTree.gen.ts(auto-generated) - Use
as any,@ts-ignore,@ts-expect-error - Commit
.envfiles - 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