project_name: '188-179-template-6' user_name: 'Root' date: '2026-01-08T00:00:00.000Z' sections_completed:
This file contains critical rules and patterns that AI agents must follow when implementing code in this project. Focus on unobvious details that agents might otherwise miss.
| 类别 | 技术 | 版本 | 用途 |
|---|---|---|---|
| 包管理 | pnpm | 10.18.3 | Monorepo工作空间管理 |
| TypeScript | typescript | 5.9.3 | 类型安全,严格模式 |
| 前端框架 | React | 19.1.0 | Web应用UI |
| 前端框架 | Taro | 3.x | 小程序开发 |
| 构建工具 | Vite | 7.x | 快速构建和热重载 |
| 后端框架 | Hono | 4.8.5 | API服务器 |
| 数据库ORM | TypeORM | 0.3.25 | 数据库操作 |
| 数据库 | PostgreSQL | 17 | 主数据库 |
| 缓存 | Redis | 7 | 缓存和会话 |
| 存储 | MinIO | 8.0.5 | 对象存储 |
| 测试类型 | 工具 | 版本 | 用途 |
|---|---|---|---|
| Web/后端测试 | Vitest | 3.2.4 | 主要测试运行器 |
| Mini UI测试 | Jest | 最新 | Mini UI包测试 |
| E2E测试 | Playwright | 1.55.0 | 端到端测试 |
| 组件测试 | Testing Library | 16.3.0 | React组件测试 |
| DOM环境 | Happy DOM | 18.0.1 | 轻量级DOM环境 |
| 库 | 版本 | 用途 |
|---|---|---|
| Radix UI | Latest | 无障碍组件库 |
| Tailwind CSS | 4.1.11 | 样式框架 |
| Heroicons | 2.2.0 | 图标库 |
| Ant Design Icons | 6.0.0 | 补充图标 |
psql -h 127.0.0.1 -U postgresstrict: true,禁止 any 类型user.service.ts)UserService)getUserById)API_BASE_URL)I 前缀 (如: User)Monorepo 协议: 使用 workspace:* 引用内部包
"@d8d/shared-types": "workspace:*"
响应类型提取: 使用 InferResponseType 从客户端提取
import type { InferResponseType } from 'hono/client'
// 基础响应类型
type UserResponse = InferResponseType<typeof userClient.$get, 200>;
// 获取嵌套数据
type UserData = InferResponseType<typeof userClient.$get, 200>['data'][0];
// ⚠️ 路径参数注意::id 必须用中括号
type DetailResponse = InferResponseType<typeof userClient[':id']['$get'], 200>;
请求类型提取: 使用 InferRequestType 提取
import type { InferRequestType } from 'hono/client'
// POST 请求体类型
type CreateUserRequest = InferRequestType<typeof userClient.$post>['json'];
// PUT 请求体类型
type UpdateUserRequest = InferRequestType<typeof userClient[':id']['$put']>['json'];
常见错误:
// ❌ 错误::id 路径忘记中括号
InferResponseType<typeof client[':id'].$get, 200>
// ✅ 正确::id 必须用中括号
InferResponseType<typeof client[':id']['$get'], 200>
类型命名规范:
[ResourceName]Response[ResourceName]Requestpnpm test --testNamePattern "测试名称"console.debug 会显示test-results/**/error-context.mdimport 配合 vi.mocked,不用 requirerm -f .git/index.lock && git add <文件> && git commit -m "消息"@tanstack/react-query 管理服务器状态react-hook-form + @hookform/resolversdata-testid,优先 getByTestId()表单调试:
form.handleSubmit(handleSubmit, (errors) => console.debug('表单验证错误:', errors))
布局规范:
// ❌ View 默认横向布局
<View><Text>行1</Text><Text>行2</Text></View>
// ✅ 添加 flex flex-col
<View className="flex flex-col">
<Text>行1</Text>
<Text>行2</Text>
</View>
图标使用:
// ✅ 正确:Heroicons 图标类 + 尺寸
<View className="i-heroicons-chevron-left-20-solid w-5 h-5" />
// ❌ 错误:使用 emoji
<Text>🔔</Text>
Navbar 配置:
leftIcon="", leftText=""leftIcon="i-heroicons-chevron-left-20-solid"测试框架: 使用 Jest 而非 Vitest
路由定义:
import { OpenAPIHono } from '@hono/zod-openapi'
const app = new OpenAPIHono()
响应验证:
import { parseWithAwait, createZodErrorResponse } from '@d8d/shared-utils'
app.get('/custom', async (c) => {
try {
const result = await service.getData()
// ✅ 必须验证响应
const validated = await parseWithAwait(Schema, result)
return c.json(validated, 200)
} catch (error) {
if (error instanceof z.ZodError) {
return c.json(createZodErrorResponse(error), 400)
}
}
})
Entity 定义:
@Entity('table_name')
export class Example {
@PrimaryGeneratedColumn({
name: 'id',
type: 'int',
unsigned: true,
comment: '主键ID'
})
id!: number
@Column({
name: 'field_name',
type: 'varchar',
length: 100,
nullable: false,
comment: '字段描述'
})
@Index('idx_field_name', { unique: true })
fieldName!: string
}
Service 层:
export class ExampleService extends GenericCrudService<Example> {
override async create(data: Partial<Example>): Promise<Example> {
// 业务逻辑检查
return super.create(data)
}
}
Schema 定义:
import { z } from 'zod'
export const ExampleSchema = z.object({
id: z.number().int().positive().openapi({
description: 'ID',
example: 1
}),
// ✅ Zod 4.0 需要泛型参数
createdAt: z.coerce.date<Date>().openapi({
description: '创建时间'
}),
amount: z.coerce.number<number>().openapi({
description: '金额'
})
})
不导出推断类型: RPC 自动推断,无需手动导出
*.test.ts*.spec.tstests/unit, tests/integration, tests/e2e# 运行特定测试
pnpm test --testNamePattern "测试名称"
# Mini UI 测试(使用 Jest)
cd mini && pnpm test --testNamePattern "名称"
# E2E 测试
pnpm test:e2e:chromium
# 类型检查(可用 grep 过滤)
pnpm typecheck 2>&1 | grep "pattern"
console.debug 会显示,其他 console 被屏蔽test-results/**/error-context.md表单调试:
form.handleSubmit(handleSubmit, (errors) => console.debug('表单验证错误:', errors))
createTestXxx(overrides) 函数yongren-api.test.ts, yongren-routes.test.tsJSDoc: 公共 API 必须包含完整 JSDoc 注释
/**
* 函数描述(简洁说明)
*
* @param paramName - 参数描述
* @param paramTwo - 参数描述
* @throws {ErrorType} 错误条件
* @example
* ```ts
* await functionName(page, 'arg', 'value');
* ```
*/
README: 每个包必须有独立的 README 说明用途和使用方法
关键逻辑: 复杂业务逻辑必须添加注释说明
包结构:
packages/example-module/
├── src/
│ ├── entities/ # 数据实体
│ ├── services/ # 业务逻辑
│ ├── schemas/ # 验证 Schema
│ ├── routes/ # API 路由
│ ├── middleware/ # 中间件
│ ├── utils/ # 工具函数
│ └── index.ts # 包入口
├── tests/
└── README.md
导出规范: 在 index.ts 统一导出
export * from './entities';
export * from './services';
export { exampleRoutes } from './routes';
export { exampleSchema } from './schemas';
// ❌ 禁止:使用 any 类型
function process(data: any) { }
// ❌ 禁止:直接导入 schema 类型(可能导致 Date/string 不匹配)
import { UserSchema } from './schema';
type User = z.infer<typeof UserSchema>;
// ❌ 禁止:Zod 4.0 缺少泛型参数
createdAt: z.coerce.date()
amount: z.coerce.number()
// ✅ 正确:使用 RPC 推断类型
type UserResponse = InferResponseType<typeof userClient.$get, 200>;
type UserData = InferResponseType<typeof userClient.$get, 200>['data'][0];
// ❌ 禁止:在单个 Form 组件上动态切换 props
<Form mode={isEdit ? 'edit' : 'create'} />
// ✅ 正确:使用条件渲染两个独立 Form
{isEdit ? <EditForm /> : <CreateForm />}
// ❌ 禁止:使用 getByText 查找可能重复的文本
screen.getByText('保存')
// ✅ 正确:添加 data-testid 并使用
<button data-testid="save-button">保存</button>
screen.getByTestId('save-button')
// ❌ 禁止:RPC 路径参数忘记中括号
InferResponseType<typeof client[':id'].$get, 200>
// ✅ 正确::id 必须用中括号
InferResponseType<typeof client[':id']['$get'], 200>
// ❌ 禁止:忘记 flex flex-col
<View>
<Text>行1</Text>
<Text>行2</Text>
</View>
// ✅ 正确:添加 flex flex-col
<View className="flex flex-col">
<Text>行1</Text>
<Text>行2</Text>
</View>
// ❌ 禁止:使用 emoji 图标
<Text>🔔</Text>
<Text>←</Text>
// ✅ 正确:使用 Heroicons 图标类
<View className="i-heroicons-bell-20-solid w-5 h-5" />
<View className="i-heroicons-chevron-left-20-solid w-5 h-5" />
// ❌ 禁止:在 Mini UI 包内使用别名导入
import { utils } from '@/utils'
// ✅ 正确:使用相对路径
import { utils } from '../../utils'
// ❌ 禁止:Entity 列定义省略属性
@Column({ name: 'email' })
email!: string;
// ✅ 正确:完整定义
@Column({
name: 'email',
type: 'varchar',
length: 100,
nullable: false,
comment: '邮箱'
})
email!: string;
// ❌ 禁止:覆盖方法不使用 override
async create(data: Partial<T>): Promise<T> {
return super.create(data);
}
// ✅ 正确:使用 override 关键字
override async create(data: Partial<T>): Promise<T> {
return super.create(data);
}
// ❌ 禁止:自定义路由不验证响应
app.get('/custom', async (c) => {
const result = await service.getData();
return c.json(result, 200);
})
// ✅ 正确:使用 parseWithAwait 验证
app.get('/custom', async (c) => {
const result = await service.getData();
const validated = await parseWithAwait(Schema, result);
return c.json(validated, 200);
})
// ❌ 禁止:物理删除
await repository.delete(id);
// ✅ 正确:使用 status 字段软删除
await repository.update(id, { status: 0 });
// ❌ 禁止:在 Vitest 中使用 console.log(被屏蔽)
console.log('debug info');
// ✅ 正确:使用 console.debug
console.debug('debug info');
// ❌ 禁止:Mini UI 使用 Vitest
// mini-ui-packages/xxx/package.json
"test": "vitest"
// ✅ 正确:Mini UI 使用 Jest
"test": "jest"
// ❌ 禁止:测试中使用 require
const utils = require('./utils');
// ✅ 正确:使用 import
import { utils } from './utils';
// 配合 vi.mocked 使用
const mockedUtils = vi.mocked(utils);
188-179-template-6/
├── packages/ # 核心共享包和业务模块 (61个)
├── allin-packages/ # AllIn业务模块 (15个)
├── mini-ui-packages/ # 小程序UI组件库 (18个)
├── web/ # 管理后台应用
├── mini/ # 员工小程序 (Taro)
├── mini-talent/ # 人才小程序 (Taro)
├── docs/ # 项目文档
└── _bmad-output/ # BMAD工作流输出
# 启动所有应用
pnpm dev
# 仅启动管理后台
pnpm run dev:web
# 构建所有包
pnpm build
# 运行测试
pnpm test
# 类型检查
pnpm typecheck
日期: 2026-01-08 版本: 1.0 状态: 已完成,已针对 LLM 优化
此文档由 generate-project-context 工作流生成。更新项目时请保持此文档同步。