Răsfoiți Sursa

Merge branch 'starter' of 139-template-116/d8d-vite-starter into starter

18617351030 4 luni în urmă
părinte
comite
5288b69a8b

+ 7 - 0
.roo/rules/10-entity.md

@@ -171,6 +171,7 @@ z.coerce.boolean().openapi({
 1. **创建Schema**:
    - 不包含`id`字段(由数据库自动生成)
    - 所有必填字段必须显式定义,不得为`optional()`
+   - 如字段为选填项(包括数据库允许为null的字段),必须显式添加`optional()`
    - 必须使用适当的coerce方法处理非字符串类型
 
 ```typescript
@@ -194,6 +195,12 @@ export const CreateEntityDto = z.object({
   expireDate: z.coerce.date().openapi({
     description: '过期日期',
     example: '2024-12-31T23:59:59Z'
+  }),
+  // 选填字段示例
+  // nullable字段必须显式添加optional()
+  description: z.string().max(500).nullable().optional().openapi({
+    description: '商品描述(选填)',
+    example: '这是一个可选的商品描述信息'
   })
 });
 ```

+ 18 - 0
.roo/rules/11-admin-frontend.md

@@ -0,0 +1,18 @@
+# 管理后台前端页面开发流程规范
+
+## 适用场景
+
+管理后台页面开发,包括列表页、详情页、表单页等后台功能页面的实现流程。
+
+## 开发流程
+
+### 1. **创建页面组件**
+   - 位置: `src/client/admin/pages/[EntityName].tsx`
+
+### 2. **注册路由配置**
+   - 位置: `src/client/admin/routes.tsx`
+     ```
+
+### 3. **添加菜单配置**
+   - 位置: `src/client/admin/menu.tsx`
+

+ 375 - 0
.roo/rules/11-custom-crud.md

@@ -0,0 +1,375 @@
+# 自定义复杂CRUD开发流程规范
+
+## 适用场景
+
+适用于包含复杂业务逻辑的实体,需要手动实现服务方法和路由处理的场景,如:
+- 复杂业务规则
+- 多表关联操作
+- 特殊权限控制
+- 非标准数据处理
+
+## 开发流程
+
+### 1. **创建实体**
+   - 位置: `src/server/modules/[模块名]/[实体名].entity.ts`
+   - 定义实体类和Zod Schema
+   - 示例:
+     ```typescript
+     import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
+     import { z } from '@hono/zod-openapi';
+     
+     @Entity('your_entity')
+     export class YourEntity {
+       @PrimaryGeneratedColumn({ unsigned: true })
+       id!: number;
+       
+       @Column({ name: 'name', type: 'varchar', length: 255 })
+       name!: string;
+       
+       // 其他业务字段...
+     }
+     
+     // Zod Schema定义
+     export const YourEntitySchema = z.object({
+       id: z.number().int().positive().openapi({ description: '实体ID' }),
+       name: z.string().max(255).openapi({ description: '名称', example: '示例名称' })
+       // 其他字段Schema...
+     });
+     
+     export const CreateYourEntityDto = z.object({
+       name: z.string().max(255).openapi({ description: '名称', example: '示例名称' })
+       // 其他创建字段...
+     });
+     
+     export const UpdateYourEntityDto = z.object({
+       name: z.string().max(255).optional().openapi({ description: '名称', example: '示例名称' })
+       // 其他更新字段...
+     });
+     ```
+
+### 2. **注册实体到数据源**
+   - 在`src/server/data-source.ts`中添加实体导入和注册:
+     ```typescript
+     // 实体类导入
+     import { YourEntity } from "./modules/[模块名]/[实体名].entity"
+     
+     export const AppDataSource = new DataSource({
+       // ...其他配置
+       entities: [
+         User, Role, YourEntity // 添加新实体到数组
+       ],
+       // ...其他配置
+     });
+     ```
+
+### 3. **创建自定义Service**
+   - 位置: `src/server/modules/[模块名]/[实体名].service.ts`
+   - 实现自定义业务逻辑和数据访问
+   - 示例:
+     ```typescript
+     import { DataSource, Repository } from 'typeorm';
+     import { YourEntity } from './your-entity.entity';
+     import { CreateYourEntityDto, UpdateYourEntityDto } from './your-entity.entity';
+     import { AppError } from '@/server/utils/errorHandler';
+     
+     export class YourEntityService {
+       private repository: Repository<YourEntity>;
+       
+       constructor(dataSource: DataSource) {
+         this.repository = dataSource.getRepository(YourEntity);
+       }
+       
+       /**
+        * 获取实体列表(带复杂过滤条件)
+        */
+       async findAll(filters: any): Promise<[YourEntity[], number]> {
+         const query = this.repository.createQueryBuilder('entity');
+         
+         // 添加复杂业务过滤逻辑
+         if (filters.status) {
+           query.andWhere('entity.status = :status', { status: filters.status });
+         }
+         
+         // 多表关联查询示例
+         if (filters.includeRelated) {
+           query.leftJoinAndSelect('entity.relatedEntity', 'related');
+         }
+         
+         const [items, total] = await query.getManyAndCount();
+         return [items, total];
+       }
+       
+       /**
+        * 根据ID获取单个实体
+        */
+       async findById(id: number): Promise<YourEntity> {
+         const entity = await this.repository.findOneBy({ id });
+         if (!entity) {
+           throw new AppError('实体不存在', 404);
+         }
+         return entity;
+       }
+       
+       /**
+        * 创建实体(带业务规则验证)
+        */
+       async create(data: CreateYourEntityDto): Promise<YourEntity> {
+         // 业务规则验证示例
+         const existing = await this.repository.findOneBy({ name: data.name });
+         if (existing) {
+           throw new AppError('名称已存在', 400);
+         }
+         
+         const entity = this.repository.create(data);
+         return this.repository.save(entity);
+       }
+       
+       /**
+        * 更新实体(带业务逻辑处理)
+        */
+       async update(id: number, data: UpdateYourEntityDto): Promise<YourEntity> {
+         const entity = await this.findById(id);
+         
+         // 业务逻辑处理示例
+         if (data.name && data.name !== entity.name) {
+           // 记录名称变更日志等业务操作
+         }
+         
+         Object.assign(entity, data);
+         return this.repository.save(entity);
+       }
+       
+       /**
+        * 删除实体(带权限检查)
+        */
+       async delete(id: number, userId: number): Promise<boolean> {
+         const entity = await this.findById(id);
+         
+         // 权限检查示例
+         if (entity.createdBy !== userId) {
+           throw new AppError('没有删除权限', 403);
+         }
+         
+         await this.repository.remove(entity);
+         return true;
+       }
+       
+       /**
+        * 自定义业务方法示例
+        */
+       async customBusinessOperation(params: any): Promise<any> {
+         // 实现复杂业务逻辑
+         // 可能包含事务、多表操作等
+       }
+     }
+     ```
+
+### 4. **创建自定义API路由**
+   - 目录结构:
+     ```
+     src/server/api/[实体名]/
+     ├── get.ts       # 列表查询
+     ├── post.ts      # 创建实体
+     ├── [id]/
+     │   ├── get.ts   # 获取单个实体
+     │   ├── put.ts   # 更新实体
+     │   └── delete.ts # 删除实体
+     └── index.ts     # 路由聚合
+     ```
+   
+   - **列表查询路由示例** (get.ts):
+     ```typescript
+     import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+     import { z } from 'zod';
+     import { YourEntitySchema } from '@/server/modules/your-module/your-entity.entity';
+     import { ErrorSchema } from '@/server/utils/errorHandler';
+     import { AppDataSource } from '@/server/data-source';
+     import { YourEntityService } from '@/server/modules/your-module/your-entity.service';
+     import { AuthContext } from '@/server/types/context';
+     import { authMiddleware } from '@/server/middleware/auth.middleware';
+     
+     // 查询参数Schema
+     const ListQuery = z.object({
+       page: z.coerce.number().int().positive().default(1).openapi({
+         description: '页码',
+         example: 1
+       }),
+       pageSize: z.coerce.number().int().positive().default(10).openapi({
+         description: '每页条数',
+         example: 10
+       }),
+       status: z.coerce.number().optional().openapi({
+         description: '状态过滤',
+         example: 1
+       })
+     });
+     
+     // 响应Schema
+     const ListResponse = z.object({
+       data: z.array(YourEntitySchema),
+       pagination: z.object({
+         total: z.number().openapi({ example: 100, description: '总记录数' }),
+         current: z.number().openapi({ example: 1, description: '当前页码' }),
+         pageSize: z.number().openapi({ example: 10, description: '每页数量' })
+       })
+     });
+     
+     // 路由定义
+     const routeDef = createRoute({
+       method: 'get',
+       path: '/',
+       middleware: [authMiddleware],
+       request: {
+         query: ListQuery
+       },
+       responses: {
+         200: {
+           description: '成功获取实体列表',
+           content: { 'application/json': { schema: ListResponse } }
+         },
+         400: {
+           description: '请求参数错误',
+           content: { 'application/json': { schema: ErrorSchema } }
+         },
+         500: {
+           description: '服务器错误',
+           content: { 'application/json': { schema: ErrorSchema } }
+         }
+       }
+     });
+     
+     // 路由实现
+     const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+       try {
+         const query = c.req.valid('query');
+         const service = new YourEntityService(AppDataSource);
+         
+         const [data, total] = await service.findAll({
+           status: query.status,
+           // 其他过滤条件
+         });
+         
+         return c.json({
+           data,
+           pagination: {
+             total,
+             current: query.page,
+             pageSize: query.pageSize
+           }
+         }, 200);
+       } catch (error) {
+         const { code = 500, message = '获取列表失败' } = error as Error & { code?: number };
+         return c.json({ code, message }, code);
+       }
+     });
+     
+     export default app;
+     ```
+     
+   - **创建实体路由示例** (post.ts):
+     ```typescript
+     import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+     import { CreateYourEntityDto, YourEntitySchema } from '@/server/modules/your-module/your-entity.entity';
+     import { ErrorSchema } from '@/server/utils/errorHandler';
+     import { AppDataSource } from '@/server/data-source';
+     import { YourEntityService } from '@/server/modules/your-module/your-entity.service';
+     import { AuthContext } from '@/server/types/context';
+     import { authMiddleware } from '@/server/middleware/auth.middleware';
+     
+     // 路由定义
+     const routeDef = createRoute({
+       method: 'post',
+       path: '/',
+       middleware: [authMiddleware],
+       request: {
+         body: {
+           content: {
+             'application/json': { schema: CreateYourEntityDto }
+           }
+         }
+       },
+       responses: {
+         200: {
+           description: '成功创建实体',
+           content: { 'application/json': { schema: YourEntitySchema } }
+         },
+         400: {
+           description: '请求参数错误',
+           content: { 'application/json': { schema: ErrorSchema } }
+         },
+         500: {
+           description: '服务器错误',
+           content: { 'application/json': { schema: ErrorSchema } }
+         }
+       }
+     });
+     
+     // 路由实现
+     const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+       try {
+         const data = await c.req.json();
+         const service = new YourEntityService(AppDataSource);
+         const result = await service.create(data);
+         return c.json(result, 200);
+       } catch (error) {
+         const { code = 500, message = '创建实体失败' } = error as Error & { code?: number };
+         return c.json({ code, message }, code);
+       }
+     });
+     
+     export default app;
+     ```
+     
+   - **路由聚合示例** (index.ts):
+     ```typescript
+     import { OpenAPIHono } from '@hono/zod-openapi';
+     import listRoute from './get';
+     import createRoute from './post';
+     import getByIdRoute from './[id]/get';
+     import updateRoute from './[id]/put';
+     import deleteRoute from './[id]/delete';
+     
+     const app = new OpenAPIHono()
+       .route('/', listRoute)
+       .route('/', createRoute)
+       .route('/', getByIdRoute)
+       .route('/', updateRoute)
+       .route('/', deleteRoute);
+     
+     export default app;
+     ```
+
+### 5. **注册路由**
+   - 在`src/server/api.ts`中添加路由注册:
+     ```typescript
+     import yourEntityRoutes from '@/server/api/your-entity/index';
+     
+     // 注册路由
+     api.route('/api/v1/your-entities', yourEntityRoutes);
+     ```
+
+### 6. **创建客户端API**
+   - 在`src/client/api.ts`中添加客户端定义:
+     ```typescript
+     import { hc } from 'hono/client';
+     import { YourEntityRoutes } from '@/server/api';
+     
+     export const yourEntityClient = hc<YourEntityRoutes>('/api/v1', {
+       fetch: axiosFetch,
+     }).api.v1['your-entities'];
+     ```
+
+### 7. **前端调用**
+    - 在页面组件(如`Users.tsx`)中:
+      - 使用`InferResponseType`提取响应类型
+      - 使用`InferRequestType`提取请求类型
+      - 示例:
+        ```typescript
+        type EntityResponse = InferResponseType<typeof entityClient.$get, 200>;
+        type CreateRequest = InferRequestType<typeof entityClient.$post>['json'];
+        ```
+
+### 8. **注册管理后台路由和菜单**
+    - **注册路由**:在`src/client/admin/routes.tsx`中添加路由配置
+      
+    - **注册菜单**:在`src/client/admin/menu.tsx`中添加菜单配置

+ 29 - 445
.roo/rules/11-entity-creation.md

@@ -16,456 +16,40 @@
 
 ## 标准通用CRUD开发流程
 
-### 1. **创建实体**
-   - 位置: `src/server/modules/[模块名]/[实体名].entity.ts`
-   - 参考已有实体文件如`user.entity.ts`
-   - 注意: 必须包含Zod Schema定义
-
-### 2. **注册实体到数据源**
-   - 在`src/server/data-source.ts`中添加实体导入和注册:
-     ```typescript
-     // 实体类导入
-     import { YourEntity } from "./modules/[模块名]/[实体名].entity"
-     
-     export const AppDataSource = new DataSource({
-       // ...其他配置
-       entities: [
-         User, Role, YourEntity // 添加新实体到数组
-       ],
-       // ...其他配置
-     });
-     ```
-
-### 3. **创建Service**
-   - 位置: `src/server/modules/[模块名]/[实体名].service.ts`
-   - 继承`GenericCrudService`
-   - 通过构造函数注入DataSource
-   ```typescript
-   import { GenericCrudService } from '@/server/utils/generic-crud.service';
-   import { DataSource } from 'typeorm';
-   import { YourEntity } from './your-entity.entity';
-   
-   export class YourEntityService extends GenericCrudService<YourEntity> {
-     constructor(dataSource: DataSource) {
-       super(dataSource, YourEntity);
-     }
-   }
-   ```
-
-### 4. **创建API路由**
-   - 使用`createCrudRoutes`快速生成CRUD路由:
-     ```typescript
-     import { createCrudRoutes } from '@/server/utils/generic-crud.routes';
-     import { YourEntity } from '@/server/modules/your-module/your-entity.entity';
-     import { YourEntitySchema, CreateYourEntityDto, UpdateYourEntityDto } from '@/server/modules/your-module/your-entity.entity';
-     import { authMiddleware } from '@/server/middleware/auth.middleware';
-     
-     const yourEntityRoutes = createCrudRoutes({
-       entity: YourEntity,
-       createSchema: CreateYourEntityDto,
-       updateSchema: UpdateYourEntityDto,
-       getSchema: YourEntitySchema,
-       listSchema: YourEntitySchema,
-       searchFields: ['name', 'description'], // 可选,指定搜索字段
-       middleware: [authMiddleware] // 可选,添加中间件
-     });
-     
-     export default yourEntityRoutes;
-     ```
-
-### 5. **注册路由**
-   - 在`src/server/api.ts`中添加路由注册:
-     ```typescript
-     import yourEntityRoutes from '@/server/api/your-entity/index';
-     
-     // 注册路由
-     api.route('/api/v1/your-entities', yourEntityRoutes);
-     ```
-
-### 6. **创建客户端API**
-   - 在`src/client/api.ts`中添加客户端定义:
-     ```typescript
-     import { hc } from 'hono/client';
-     import { YourEntityRoutes } from '@/server/api';
-     
-     export const yourEntityClient = hc<YourEntityRoutes>('/api/v1', {
-       fetch: axiosFetch,
-     }).api.v1['your-entities'];
-     ```
-
-6. **前端调用**
-   - 在页面组件(如`pages_users.tsx`)中:
-     - 使用`InferResponseType`提取响应类型
-     - 使用`InferRequestType`提取请求类型
-     - 示例:
-       ```typescript
-       type EntityResponse = InferResponseType<typeof entityClient.$get, 200>;
-       type CreateRequest = InferRequestType<typeof entityClient.$post>['json'];
-       ```
-
+适用于简单数据模型,无复杂业务逻辑,仅需基础CRUD操作的场景。采用`GenericCrudService`和`createCrudRoutes`快速生成接口。
+
+### 开发步骤概要
+
+1. **创建实体**:在`src/server/modules/[模块名]/[实体名].entity.ts`定义实体类和Zod Schema
+2. **注册实体**:在`src/server/data-source.ts`中注册新实体
+3. **创建Service**:继承`GenericCrudService`实现基础CRUD操作
+4. **创建API路由**:使用`createCrudRoutes`快速生成CRUD路由
+5. **注册路由**:在`src/server/api.ts`中注册路由
+6. **创建客户端API**:在`src/client/api.ts`中定义客户端调用方法
+7. **前端调用**:在页面组件中使用类型化API调用
+8. **注册路由和菜单**:
+   - 管理后台:在`src/client/admin/routes.tsx`中添加路由配置,在`src/client/admin/menu.tsx`中添加菜单配置
+   - 前台:在`src/client/home/routes.tsx`中添加路由配置
+
+详细流程请参见[标准通用CRUD开发流程规范](./11-standard-crud.md)
 ## 自定义复杂CRUD开发流程
 
-当实体需要复杂业务逻辑或非标准CRUD操作时,采用以下完整流程:
-
-### 1. **创建实体**
-   - 位置: `src/server/modules/[模块名]/[实体名].entity.ts`
-   - 定义实体类和Zod Schema
-   - 示例:
-     ```typescript
-     import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
-     import { z } from '@hono/zod-openapi';
-     
-     @Entity('your_entity')
-     export class YourEntity {
-       @PrimaryGeneratedColumn({ unsigned: true })
-       id!: number;
-       
-       @Column({ name: 'name', type: 'varchar', length: 255 })
-       name!: string;
-       
-       // 其他业务字段...
-     }
-     
-     // Zod Schema定义
-     export const YourEntitySchema = z.object({
-       id: z.number().int().positive().openapi({ description: '实体ID' }),
-       name: z.string().max(255).openapi({ description: '名称', example: '示例名称' })
-       // 其他字段Schema...
-     });
-     
-     export const CreateYourEntityDto = z.object({
-       name: z.string().max(255).openapi({ description: '名称', example: '示例名称' })
-       // 其他创建字段...
-     });
-     
-     export const UpdateYourEntityDto = z.object({
-       name: z.string().max(255).optional().openapi({ description: '名称', example: '示例名称' })
-       // 其他更新字段...
-     });
-     ```
-
-### 2. **注册实体到数据源**
-   - 在`src/server/data-source.ts`中添加实体导入和注册:
-     ```typescript
-     // 实体类导入
-     import { YourEntity } from "./modules/[模块名]/[实体名].entity"
-     
-     export const AppDataSource = new DataSource({
-       // ...其他配置
-       entities: [
-         User, Role, YourEntity // 添加新实体到数组
-       ],
-       // ...其他配置
-     });
-     ```
-
-### 3. **创建自定义Service**
-   - 位置: `src/server/modules/[模块名]/[实体名].service.ts`
-   - 实现自定义业务逻辑和数据访问
-   - 示例:
-     ```typescript
-     import { DataSource, Repository } from 'typeorm';
-     import { YourEntity } from './your-entity.entity';
-     import { CreateYourEntityDto, UpdateYourEntityDto } from './your-entity.entity';
-     import { AppError } from '@/server/utils/errorHandler';
-     
-     export class YourEntityService {
-       private repository: Repository<YourEntity>;
-       
-       constructor(dataSource: DataSource) {
-         this.repository = dataSource.getRepository(YourEntity);
-       }
-       
-       /**
-        * 获取实体列表(带复杂过滤条件)
-        */
-       async findAll(filters: any): Promise<[YourEntity[], number]> {
-         const query = this.repository.createQueryBuilder('entity');
-         
-         // 添加复杂业务过滤逻辑
-         if (filters.status) {
-           query.andWhere('entity.status = :status', { status: filters.status });
-         }
-         
-         // 多表关联查询示例
-         if (filters.includeRelated) {
-           query.leftJoinAndSelect('entity.relatedEntity', 'related');
-         }
-         
-         const [items, total] = await query.getManyAndCount();
-         return [items, total];
-       }
-       
-       /**
-        * 根据ID获取单个实体
-        */
-       async findById(id: number): Promise<YourEntity> {
-         const entity = await this.repository.findOneBy({ id });
-         if (!entity) {
-           throw new AppError('实体不存在', 404);
-         }
-         return entity;
-       }
-       
-       /**
-        * 创建实体(带业务规则验证)
-        */
-       async create(data: CreateYourEntityDto): Promise<YourEntity> {
-         // 业务规则验证示例
-         const existing = await this.repository.findOneBy({ name: data.name });
-         if (existing) {
-           throw new AppError('名称已存在', 400);
-         }
-         
-         const entity = this.repository.create(data);
-         return this.repository.save(entity);
-       }
-       
-       /**
-        * 更新实体(带业务逻辑处理)
-        */
-       async update(id: number, data: UpdateYourEntityDto): Promise<YourEntity> {
-         const entity = await this.findById(id);
-         
-         // 业务逻辑处理示例
-         if (data.name && data.name !== entity.name) {
-           // 记录名称变更日志等业务操作
-         }
-         
-         Object.assign(entity, data);
-         return this.repository.save(entity);
-       }
-       
-       /**
-        * 删除实体(带权限检查)
-        */
-       async delete(id: number, userId: number): Promise<boolean> {
-         const entity = await this.findById(id);
-         
-         // 权限检查示例
-         if (entity.createdBy !== userId) {
-           throw new AppError('没有删除权限', 403);
-         }
-         
-         await this.repository.remove(entity);
-         return true;
-       }
-       
-       /**
-        * 自定义业务方法示例
-        */
-       async customBusinessOperation(params: any): Promise<any> {
-         // 实现复杂业务逻辑
-         // 可能包含事务、多表操作等
-       }
-     }
-     ```
-
-### 4. **创建自定义API路由**
-   - 目录结构:
-     ```
-     src/server/api/[实体名]/
-     ├── get.ts       # 列表查询
-     ├── post.ts      # 创建实体
-     ├── [id]/
-     │   ├── get.ts   # 获取单个实体
-     │   ├── put.ts   # 更新实体
-     │   └── delete.ts # 删除实体
-     └── index.ts     # 路由聚合
-     ```
-   
-   - **列表查询路由示例** (get.ts):
-     ```typescript
-     import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
-     import { z } from 'zod';
-     import { YourEntitySchema } from '@/server/modules/your-module/your-entity.entity';
-     import { ErrorSchema } from '@/server/utils/errorHandler';
-     import { AppDataSource } from '@/server/data-source';
-     import { YourEntityService } from '@/server/modules/your-module/your-entity.service';
-     import { AuthContext } from '@/server/types/context';
-     import { authMiddleware } from '@/server/middleware/auth.middleware';
-     
-     // 查询参数Schema
-     const ListQuery = z.object({
-       page: z.coerce.number().int().positive().default(1).openapi({
-         description: '页码',
-         example: 1
-       }),
-       pageSize: z.coerce.number().int().positive().default(10).openapi({
-         description: '每页条数',
-         example: 10
-       }),
-       status: z.coerce.number().optional().openapi({
-         description: '状态过滤',
-         example: 1
-       })
-     });
-     
-     // 响应Schema
-     const ListResponse = z.object({
-       data: z.array(YourEntitySchema),
-       pagination: z.object({
-         total: z.number().openapi({ example: 100, description: '总记录数' }),
-         current: z.number().openapi({ example: 1, description: '当前页码' }),
-         pageSize: z.number().openapi({ example: 10, description: '每页数量' })
-       })
-     });
-     
-     // 路由定义
-     const routeDef = createRoute({
-       method: 'get',
-       path: '/',
-       middleware: [authMiddleware],
-       request: {
-         query: ListQuery
-       },
-       responses: {
-         200: {
-           description: '成功获取实体列表',
-           content: { 'application/json': { schema: ListResponse } }
-         },
-         400: {
-           description: '请求参数错误',
-           content: { 'application/json': { schema: ErrorSchema } }
-         },
-         500: {
-           description: '服务器错误',
-           content: { 'application/json': { schema: ErrorSchema } }
-         }
-       }
-     });
-     
-     // 路由实现
-     const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
-       try {
-         const query = c.req.valid('query');
-         const service = new YourEntityService(AppDataSource);
-         
-         const [data, total] = await service.findAll({
-           status: query.status,
-           // 其他过滤条件
-         });
-         
-         return c.json({
-           data,
-           pagination: {
-             total,
-             current: query.page,
-             pageSize: query.pageSize
-           }
-         }, 200);
-       } catch (error) {
-         const { code = 500, message = '获取列表失败' } = error as Error & { code?: number };
-         return c.json({ code, message }, code);
-       }
-     });
-     
-     export default app;
-     ```
-     
-   - **创建实体路由示例** (post.ts):
-     ```typescript
-     import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
-     import { CreateYourEntityDto, YourEntitySchema } from '@/server/modules/your-module/your-entity.entity';
-     import { ErrorSchema } from '@/server/utils/errorHandler';
-     import { AppDataSource } from '@/server/data-source';
-     import { YourEntityService } from '@/server/modules/your-module/your-entity.service';
-     import { AuthContext } from '@/server/types/context';
-     import { authMiddleware } from '@/server/middleware/auth.middleware';
-     
-     // 路由定义
-     const routeDef = createRoute({
-       method: 'post',
-       path: '/',
-       middleware: [authMiddleware],
-       request: {
-         body: {
-           content: {
-             'application/json': { schema: CreateYourEntityDto }
-           }
-         }
-       },
-       responses: {
-         200: {
-           description: '成功创建实体',
-           content: { 'application/json': { schema: YourEntitySchema } }
-         },
-         400: {
-           description: '请求参数错误',
-           content: { 'application/json': { schema: ErrorSchema } }
-         },
-         500: {
-           description: '服务器错误',
-           content: { 'application/json': { schema: ErrorSchema } }
-         }
-       }
-     });
-     
-     // 路由实现
-     const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
-       try {
-         const data = await c.req.json();
-         const service = new YourEntityService(AppDataSource);
-         const result = await service.create(data);
-         return c.json(result, 200);
-       } catch (error) {
-         const { code = 500, message = '创建实体失败' } = error as Error & { code?: number };
-         return c.json({ code, message }, code);
-       }
-     });
-     
-     export default app;
-     ```
-     
-   - **路由聚合示例** (index.ts):
-     ```typescript
-     import { OpenAPIHono } from '@hono/zod-openapi';
-     import listRoute from './get';
-     import createRoute from './post';
-     import getByIdRoute from './[id]/get';
-     import updateRoute from './[id]/put';
-     import deleteRoute from './[id]/delete';
-     
-     const app = new OpenAPIHono()
-       .route('/', listRoute)
-       .route('/', createRoute)
-       .route('/', getByIdRoute)
-       .route('/', updateRoute)
-       .route('/', deleteRoute);
-     
-     export default app;
-     ```
-
-### 5. **注册路由**
-   - 在`src/server/api.ts`中添加路由注册:
-     ```typescript
-     import yourEntityRoutes from '@/server/api/your-entity/index';
-     
-     // 注册路由
-     api.route('/api/v1/your-entities', yourEntityRoutes);
-     ```
+适用于包含复杂业务逻辑的实体,需要手动实现服务方法和路由处理的场景,如复杂业务规则、多表关联操作、特殊权限控制等。
 
-### 6. **创建客户端API**
-   - 在`src/client/api.ts`中添加客户端定义:
-     ```typescript
-     import { hc } from 'hono/client';
-     import { YourEntityRoutes } from '@/server/api';
-     
-     export const yourEntityClient = hc<YourEntityRoutes>('/api/v1', {
-       fetch: axiosFetch,
-     }).api.v1['your-entities'];
-     ```
+### 开发步骤概要
 
-### 7. **前端调用**
-   - 在页面组件(如`pages_users.tsx`)中:
-     - 使用`InferResponseType`提取响应类型
-     - 使用`InferRequestType`提取请求类型
-     - 示例:
-       ```typescript
-       type EntityResponse = InferResponseType<typeof entityClient.$get, 200>;
-       type CreateRequest = InferRequestType<typeof entityClient.$post>['json'];
-       ```
+1. **创建实体**:在`src/server/modules/[模块名]/[实体名].entity.ts`定义实体类和Zod Schema
+2. **注册实体**:在`src/server/data-source.ts`中注册新实体
+3. **创建自定义Service**:实现包含复杂业务逻辑的数据访问方法
+4. **创建自定义API路由**:手动实现CRUD路由及处理逻辑
+5. **注册路由**:在`src/server/api.ts`中注册路由
+6. **创建客户端API**:在`src/client/api.ts`中定义客户端调用方法
+7. **前端调用**:在页面组件中使用类型化API调用
+8. **注册路由和菜单**:
+   - 管理后台:在`src/client/admin/routes.tsx`中添加路由配置,在`src/client/admin/menu.tsx`中添加菜单配置
+   - 前台:在`src/client/home/routes.tsx`中添加路由配置
 
+详细流程请参见[自定义复杂CRUD开发流程规范](./11-custom-crud.md)
 ## 注意事项
 
 1. 实体Schema必须在实体文件中定义,路由中直接引用,不要重复定义

+ 33 - 0
.roo/rules/11-home-frontend.md

@@ -0,0 +1,33 @@
+# 前台Home页面开发流程规范 (Tailwind CSS版)
+
+## 适用场景
+
+前台用户界面开发,包括首页、登录页、注册页、会员中心等面向普通用户的页面实现流程。采用原生Tailwind CSS进行样式开发。不使用antd
+
+## 目录结构
+
+```
+src/client/home/
+├── index.tsx           # 入口文件
+├── routes.tsx          # 路由配置
+├── components/         # 共享组件
+│   ├── ErrorPage.tsx   # 错误页面
+│   ├── NotFoundPage.tsx # 404页面
+│   └── ProtectedRoute.tsx # 路由保护组件
+├── hooks/              # 自定义hooks
+│   └── AuthProvider.tsx # 认证上下文
+├── layouts/            # 布局组件
+│   └── MainLayout.tsx  # 主布局
+└── pages/              # 页面组件
+    ├── HomePage.tsx    # 首页
+    ├── LoginPage.tsx   # 登录页
+    ├── RegisterPage.tsx # 注册页
+    └── MemberPage.tsx  # 会员中心
+```
+
+### 1. **创建页面组件**
+   - 位置: `src/client/home/pages/[PageName].tsx`
+
+### 2. **注册路由配置**
+   - 位置: `src/client/home/routes.tsx`
+     ```

+ 100 - 0
.roo/rules/11-standard-crud.md

@@ -0,0 +1,100 @@
+# 标准通用CRUD开发流程规范
+
+## 适用场景
+
+适用于简单数据模型,无复杂业务逻辑,仅需基础CRUD操作的场景。采用`GenericCrudService`和`createCrudRoutes`快速生成接口。
+
+## 开发流程
+
+### 1. **创建实体**
+   - 位置: `src/server/modules/[模块名]/[实体名].entity.ts`
+   - 参考已有实体文件如`user.entity.ts`
+   - 注意: 必须包含Zod Schema定义
+
+### 2. **注册实体到数据源**
+   - 在`src/server/data-source.ts`中添加实体导入和注册:
+     ```typescript
+     // 实体类导入
+     import { YourEntity } from "./modules/[模块名]/[实体名].entity"
+     
+     export const AppDataSource = new DataSource({
+       // ...其他配置
+       entities: [
+         User, Role, YourEntity // 添加新实体到数组
+       ],
+       // ...其他配置
+     });
+     ```
+
+### 3. **创建Service**
+   - 位置: `src/server/modules/[模块名]/[实体名].service.ts`
+   - 继承`GenericCrudService`
+   - 通过构造函数注入DataSource
+   ```typescript
+   import { GenericCrudService } from '@/server/utils/generic-crud.service';
+   import { DataSource } from 'typeorm';
+   import { YourEntity } from './your-entity.entity';
+   
+   export class YourEntityService extends GenericCrudService<YourEntity> {
+     constructor(dataSource: DataSource) {
+       super(dataSource, YourEntity);
+     }
+   }
+   ```
+
+### 4. **创建API路由**
+   - 使用`createCrudRoutes`快速生成CRUD路由:
+     ```typescript
+     import { createCrudRoutes } from '@/server/utils/generic-crud.routes';
+     import { YourEntity } from '@/server/modules/your-module/your-entity.entity';
+     import { YourEntitySchema, CreateYourEntityDto, UpdateYourEntityDto } from '@/server/modules/your-module/your-entity.entity';
+     import { authMiddleware } from '@/server/middleware/auth.middleware';
+     
+     const yourEntityRoutes = createCrudRoutes({
+       entity: YourEntity,
+       createSchema: CreateYourEntityDto,
+       updateSchema: UpdateYourEntityDto,
+       getSchema: YourEntitySchema,
+       listSchema: YourEntitySchema,
+       searchFields: ['name', 'description'], // 可选,指定搜索字段
+       middleware: [authMiddleware] // 可选,添加中间件
+     });
+     
+     export default yourEntityRoutes;
+     ```
+
+### 5. **注册路由**
+   - 在`src/server/api.ts`中添加路由注册:
+     ```typescript
+     import yourEntityRoutes from '@/server/api/your-entity/index';
+     
+     // 注册路由
+     api.route('/api/v1/your-entities', yourEntityRoutes);
+     ```
+
+### 6. **创建客户端API**
+   - 在`src/client/api.ts`中添加客户端定义:
+     ```typescript
+     import { hc } from 'hono/client';
+     import { YourEntityRoutes } from '@/server/api';
+     
+     export const yourEntityClient = hc<YourEntityRoutes>('/api/v1', {
+       fetch: axiosFetch,
+     }).api.v1['your-entities'];
+     ```
+
+### 7. **前端调用**
+   - 在页面组件(如`Users.tsx`)中:
+     - 使用`InferResponseType`提取响应类型
+     - 使用`InferRequestType`提取请求类型
+     - 示例:
+       ```typescript
+       type EntityResponse = InferResponseType<typeof entityClient.$get, 200>;
+       type CreateRequest = InferRequestType<typeof entityClient.$post>['json'];
+       ```
+
+### 8. **注册管理后台路由和菜单**
+    - **注册路由**:在`src/client/admin/routes.tsx`中添加路由配置
+      
+    - **注册菜单**:在`src/client/admin/menu.tsx`中添加菜单配置
+