---
project_name: '188-179-template-6'
user_name: 'Root'
date: '2026-01-08T00:00:00.000Z'
sections_completed:
  - technology_stack
  - language_rules
  - framework_rules
  - test_rules
  - code_quality_rules
  - anti_patterns
status: complete
rule_count: 50
optimized_for_llm: true
---

# Project Context for AI Agents

_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._

---

## Technology Stack & Versions

### Core Technologies

| 类别 | 技术 | 版本 | 用途 |
|------|------|------|------|
| **包管理** | 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 | 对象存储 |

### Testing Stack

| 测试类型 | 工具 | 版本 | 用途 |
|----------|------|------|------|
| **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环境 |

### UI Libraries

| 库 | 版本 | 用途 |
|----|------|------|
| Radix UI | Latest | 无障碍组件库 |
| Tailwind CSS | 4.1.11 | 样式框架 |
| Heroicons | 2.2.0 | 图标库 |
| Ant Design Icons | 6.0.0 | 补充图标 |

### Development Environment

- **Node.js**: 20.19.2
- **默认端口**: 8080
- **开发服务器**: 自动启动在8080端口
- **数据库连接**: `psql -h 127.0.0.1 -U postgres`

---

## Critical Implementation Rules

### 语言特定规则

#### TypeScript 配置
- **严格模式**: 所有项目启用 `strict: true`，禁止 `any` 类型
- **目标配置**: ES2022，ESNext 模块，bundler 解析
- **类型显式**: 函数参数、返回值必须有明确类型注解

#### 命名约定
- **文件名**: kebab-case (如: `user.service.ts`)
- **类名**: PascalCase (如: `UserService`)
- **函数/变量**: camelCase (如: `getUserById`)
- **常量**: UPPER_SNAKE_CASE (如: `API_BASE_URL`)
- **接口**: PascalCase，无 `I` 前缀 (如: `User`)

#### 包间依赖
- **Monorepo 协议**: 使用 `workspace:*` 引用内部包
  ```json
  "@d8d/shared-types": "workspace:*"
  ```

#### RPC 类型安全规范（关键）
- **响应类型提取**: 使用 `InferResponseType` 从客户端提取
  ```typescript
  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` 提取
  ```typescript
  import type { InferRequestType } from 'hono/client'

  // POST 请求体类型
  type CreateUserRequest = InferRequestType<typeof userClient.$post>['json'];

  // PUT 请求体类型
  type UpdateUserRequest = InferRequestType<typeof userClient[':id']['$put']>['json'];
  ```

- **常见错误**:
  ```typescript
  // ❌ 错误：:id 路径忘记中括号
  InferResponseType<typeof client[':id'].$get, 200>

  // ✅ 正确：:id 必须用中括号
  InferResponseType<typeof client[':id']['$get'], 200>
  ```

- **类型命名规范**:
  - 响应类型: `[ResourceName]Response`
  - 请求类型: `[ResourceName]Request`

#### 测试与调试
- **测试运行**: `pnpm test --testNamePattern "测试名称"`
- **Console 输出**: Vitest 中只有 `console.debug` 会显示
- **E2E 调试**: 失败时查看 `test-results/**/error-context.md`
- **类型导入**: 使用 `import` 配合 `vi.mocked`，不用 `require`

#### Git 操作
- **锁文件冲突**: `rm -f .git/index.lock && git add <文件> && git commit -m "消息"`

---

### 框架特定规则

#### React 19 (Web UI)
- **数据获取**: 使用 `@tanstack/react-query` 管理服务器状态
- **表单管理**: 使用 `react-hook-form` + `@hookform/resolvers`
- **组件模式**:
  - 编辑/新建使用条件渲染两个独立 Form 组件
  - 不在单个 Form 组件上动态切换 props
- **测试选择器**: 关键元素添加 `data-testid`，优先 `getByTestId()`
- **表单调试**:
  ```typescript
  form.handleSubmit(handleSubmit, (errors) => console.debug('表单验证错误:', errors))
  ```

#### Taro 3.x (小程序)
- **布局规范**:
  ```typescript
  // ❌ View 默认横向布局
  <View><Text>行1</Text><Text>行2</Text></View>

  // ✅ 添加 flex flex-col
  <View className="flex flex-col">
    <Text>行1</Text>
    <Text>行2</Text>
  </View>
  ```
- **图标使用**:
  ```typescript
  // ✅ 正确：Heroicons 图标类 + 尺寸
  <View className="i-heroicons-chevron-left-20-solid w-5 h-5" />

  // ❌ 错误：使用 emoji
  <Text>🔔</Text>
  ```
- **Navbar 配置**:
  - TabBar 页面: `leftIcon=""`, `leftText=""`
  - 二级页面: `leftIcon="i-heroicons-chevron-left-20-solid"`
- **测试框架**: 使用 Jest 而非 Vitest

#### Hono 4.x (API 服务器)
- **路由定义**:
  ```typescript
  import { OpenAPIHono } from '@hono/zod-openapi'

  const app = new OpenAPIHono()
  ```
- **响应验证**:
  ```typescript
  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)
      }
    }
  })
  ```

#### TypeORM 0.3.25 (数据库)
- **Entity 定义**:
  ```typescript
  @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 层**:
  ```typescript
  export class ExampleService extends GenericCrudService<Example> {
    override async create(data: Partial<Example>): Promise<Example> {
      // 业务逻辑检查
      return super.create(data)
    }
  }
  ```

#### Zod 4.x (验证)
- **Schema 定义**:
  ```typescript
  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 自动推断，无需手动导出

---

### 测试规则

#### 测试框架选择
- **Web/后端测试**: Vitest 3.2.4
- **Mini UI 测试**: Jest（注意：与 Web 不同）
- **E2E 测试**: Playwright 1.55.0
- **组件测试**: Testing Library 16.3.0
- **DOM 环境**: Happy DOM 18.0.1

#### 测试文件命名
- **Vitest 测试**: `*.test.ts`
- **Playwright E2E**: `*.spec.ts`
- **测试位置**: `tests/unit`, `tests/integration`, `tests/e2e`

#### 覆盖率目标
- **单元测试**: ≥80%
- **集成测试**: ≥60%
- **关键流程 E2E**: 100%

#### 测试命令
```bash
# 运行特定测试
pnpm test --testNamePattern "测试名称"

# Mini UI 测试（使用 Jest）
cd mini && pnpm test --testNamePattern "名称"

# E2E 测试
pnpm test:e2e:chromium

# 类型检查（可用 grep 过滤）
pnpm typecheck 2>&1 | grep "pattern"
```

#### 调试技巧
- **Vitest**: 只有 `console.debug` 会显示，其他 console 被屏蔽
- **E2E 失败**: 先查看 `test-results/**/error-context.md`
- **表单调试**:
  ```typescript
  form.handleSubmit(handleSubmit, (errors) => console.debug('表单验证错误:', errors))
  ```

#### 测试数据管理
- **工厂模式**: 使用 `createTestXxx(overrides)` 函数
- **数据库策略**:
  - 单元测试: 内存数据库或 mock
  - 集成测试: 专用测试数据库，事务回滚
  - E2E 测试: 接近生产环境

#### Mini UI 特殊规则
- **测试框架**: 必须使用 Jest，不能用 Vitest
- **运行位置**: 进入 mini 目录后运行测试
- **API 测试**: `yongren-api.test.ts`, `yongren-routes.test.ts`

---

### 代码质量与风格规则

#### 文档要求
- **JSDoc**: 公共 API 必须包含完整 JSDoc 注释
  ```typescript
  /**
   * 函数描述（简洁说明）
   *
   * @param paramName - 参数描述
   * @param paramTwo - 参数描述
   * @throws {ErrorType} 错误条件
   * @example
   * ```ts
   * await functionName(page, 'arg', 'value');
   * ```
   */
  ```
- **README**: 每个包必须有独立的 README 说明用途和使用方法
- **关键逻辑**: 复杂业务逻辑必须添加注释说明

#### 代码风格
- **缩进**: 使用 2 个空格（不使用 tab）
- **格式化**: 使用 Prettier 统一代码格式
- **Linting**: ESLint 配置 TypeScript 和 React 规则
- **提交前检查**: 使用 husky 进行 pre-commit 钩子检查

#### 代码组织
- **包结构**:
  ```
  packages/example-module/
  ├── src/
  │   ├── entities/        # 数据实体
  │   ├── services/        # 业务逻辑
  │   ├── schemas/         # 验证 Schema
  │   ├── routes/          # API 路由
  │   ├── middleware/      # 中间件
  │   ├── utils/           # 工具函数
  │   └── index.ts         # 包入口
  ├── tests/
  └── README.md
  ```
- **导出规范**: 在 `index.ts` 统一导出
  ```typescript
  export * from './entities';
  export * from './services';
  export { exampleRoutes } from './routes';
  export { exampleSchema } from './schemas';
  ```

#### 安全最佳实践
- **输入验证**: 使用 Zod Schema 验证所有输入
- **敏感数据**: 从响应中排除密码等敏感字段
- **SQL 注入**: 使用 TypeORM 参数化查询，不拼接 SQL
- **日志**: 不在日志中记录敏感信息

#### 性能优化
- **数据库查询**: 只查询需要的字段，使用索引
- **N+1 避免**: 使用 relations 而非循环查询
- **缓存**: 使用 Redis 缓存热点数据

---

### 关键禁止规则（Anti-Patterns）

#### TypeScript 类型禁令
```typescript
// ❌ 禁止：使用 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];
```

#### React/UI 禁令
```typescript
// ❌ 禁止：在单个 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>
```

#### Mini UI 禁令
```typescript
// ❌ 禁止：忘记 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'
```

#### 后端模块禁令
```typescript
// ❌ 禁止：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 });
```

#### 测试禁令
```typescript
// ❌ 禁止：在 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工作流输出
```

---

## 开发快速命令

```bash
# 启动所有应用
pnpm dev

# 仅启动管理后台
pnpm run dev:web

# 构建所有包
pnpm build

# 运行测试
pnpm test

# 类型检查
pnpm typecheck
```

---

## 使用指南

### 给 AI Agent

- **实施前必读**: 在编写任何代码之前，请完整阅读此文件
- **严格遵循**: 完全按照文档中记录的所有规则实施
- **存疑时**: 当不确定时，选择更严格的选项
- **更新维护**: 当出现新模式时，更新此文件

### 给人类开发者

- **保持精简**: 保持此文件专注于 AI Agent 的需求
- **技术栈变更**: 当技术栈变化时更新
- **季度评审**: 定期评审以删除过时规则
- **移除明显规则**: 随时间推移移除变得显而易见的规则

### 最后更新

**日期**: 2026-01-08
**版本**: 1.0
**状态**: 已完成，已针对 LLM 优化

---

_此文档由 generate-project-context 工作流生成。更新项目时请保持此文档同步。_
