Explorar el Código

📝 docs(architecture): add detailed generic CRUD development standards

- create generic-crud-standards.md documenting core components and usage guidelines
- update architecture.md to reference new CRUD standards document
- add CRUD development specifications to coding-standards.md
- update architecture index with CRUD standards navigation

📝 docs(architecture): enhance CRUD documentation with best practices and examples

- document GenericCrudService methods and parameters
- provide step-by-step usage examples for entity, schema and route creation
- add advanced features section covering relation handling and complex filtering
- include best practices for entity design, schema validation and performance optimization
yourname hace 4 meses
padre
commit
0243752a47

+ 1 - 0
docs/architecture.md

@@ -608,6 +608,7 @@ src/server/
 - **文件位置**: `src/server/utils/generic-crud.service.ts`
 - **文件位置**: `src/server/utils/generic-crud.service.ts`
 - **路由生成**: `src/server/utils/generic-crud.routes.ts`
 - **路由生成**: `src/server/utils/generic-crud.routes.ts`
 - **优化重点**: 增强错误处理、添加测试覆盖、优化性能
 - **优化重点**: 增强错误处理、添加测试覆盖、优化性能
+- **详细规范**: 参见 [通用CRUD规范](./architecture/generic-crud-standards.md)
 
 
 **文件管理服务**:
 **文件管理服务**:
 - **责任**: 提供MinIO对象存储集成,支持文件上传、下载、删除等操作
 - **责任**: 提供MinIO对象存储集成,支持文件上传、下载、删除等操作

+ 7 - 0
docs/architecture/coding-standards.md

@@ -22,3 +22,10 @@
 - **数据库集成**: 使用测试数据库,避免污染生产数据
 - **数据库集成**: 使用测试数据库,避免污染生产数据
 - **错误处理**: 测试各种错误场景和边界条件
 - **错误处理**: 测试各种错误场景和边界条件
 - **日志一致性**: 测试日志格式和错误信息
 - **日志一致性**: 测试日志格式和错误信息
+
+## 通用CRUD开发规范
+- **CRUD开发**: 遵循 [通用CRUD规范](./generic-crud-standards.md) 进行开发
+- **实体设计**: 所有实体必须继承 `ObjectLiteral`,包含时间戳字段
+- **Schema设计**: 创建、更新、响应使用不同的Zod schema
+- **路由生成**: 使用 `createCrudRoutes` 自动生成API路由
+- **用户跟踪**: 实现用户跟踪功能记录操作人信息

+ 323 - 0
docs/architecture/generic-crud-standards.md

@@ -0,0 +1,323 @@
+# 通用 CRUD 规范
+
+## 版本信息
+| 版本 | 日期 | 描述 | 作者 |
+|------|------|------|------|
+| 1.0 | 2025-10-15 | 创建通用 CRUD 规范文档 | Winston |
+
+## 概述
+
+通用 CRUD(Create, Read, Update, Delete)系统是本项目的核心基础设施,提供类型安全、可扩展的数据操作服务。基于 TypeORM 和 Hono 框架构建,支持自动生成 OpenAPI 文档、关联查询、用户跟踪等高级功能。
+
+## 设计原则
+
+### 核心原则
+- **类型安全**: 基于 TypeScript 的完整类型支持
+- **可扩展性**: 支持自定义扩展和业务逻辑注入
+- **一致性**: 统一的 API 设计和错误处理
+- **性能优化**: 支持分页、缓存、关联查询优化
+- **安全性**: 内置用户跟踪和权限控制
+
+### 架构模式
+- **服务层**: `GenericCrudService` 提供核心 CRUD 操作
+- **路由层**: `createCrudRoutes` 自动生成 RESTful API 路由
+- **实体层**: TypeORM 实体定义数据模型
+- **验证层**: Zod schema 提供输入验证
+
+## 核心组件
+
+### 1. GenericCrudService
+
+**位置**: `src/server/utils/generic-crud.service.ts`
+
+**核心功能**:
+- 分页列表查询(支持搜索、排序、复杂筛选)
+- 单个实体查询(支持关联关系)
+- 创建、更新、删除操作
+- 用户跟踪(创建人、更新人)
+- 关联字段处理
+
+**主要方法**:
+```typescript
+// 分页查询
+async getList(
+  page: number = 1,
+  pageSize: number = 10,
+  keyword?: string,
+  searchFields?: string[],
+  where?: Partial<T>,
+  relations: string[] = [],
+  order: { [P in keyof T]?: 'ASC' | 'DESC' } = {},
+  filters?: { [key: string]: any }
+): Promise<[T[], number]>
+
+// 根据ID查询
+async getById(id: number, relations: string[] = []): Promise<T | null>
+
+// 创建实体
+async create(data: DeepPartial<T>, userId?: string | number): Promise<T>
+
+// 更新实体
+async update(id: number, data: Partial<T>, userId?: string | number): Promise<T | null>
+
+// 删除实体
+async delete(id: number): Promise<boolean>
+```
+
+### 2. ConcreteCrudService
+
+**位置**: `src/server/utils/concrete-crud.service.ts`
+
+**用途**: 简化 `GenericCrudService` 的实例化,自动注入数据源。
+
+**使用示例**:
+```typescript
+const userService = new ConcreteCrudService(User, {
+  userTracking: { createdByField: 'createdBy', updatedByField: 'updatedBy' }
+});
+```
+
+### 3. createCrudRoutes
+
+**位置**: `src/server/utils/generic-crud.routes.ts`
+
+**功能**: 自动生成完整的 CRUD 路由,包括:
+- `GET /` - 分页列表
+- `GET /{id}` - 单个实体详情
+- `POST /` - 创建实体
+- `PUT /{id}` - 更新实体
+- `DELETE /{id}` - 删除实体
+
+**支持特性**:
+- 自动 OpenAPI 文档生成
+- 输入验证(Zod schema)
+- 错误处理统一
+- 中间件支持
+- 只读模式
+
+## 使用指南
+
+### 1. 创建实体类
+
+```typescript
+// user.entity.ts
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
+
+@Entity()
+export class User {
+  @PrimaryGeneratedColumn()
+  id: number;
+
+  @Column({ unique: true })
+  username: string;
+
+  @Column({ nullable: true })
+  email: string | null;
+
+  @CreateDateColumn()
+  createdAt: Date;
+
+  @UpdateDateColumn()
+  updatedAt: Date;
+}
+```
+
+### 2. 创建 Zod Schema
+
+```typescript
+// user.schema.ts
+import { z } from '@hono/zod-openapi';
+
+export const UserCreateSchema = z.object({
+  username: z.string().min(3).max(50),
+  email: z.string().email().optional().nullable(),
+});
+
+export const UserUpdateSchema = UserCreateSchema.partial();
+
+export const UserGetSchema = z.object({
+  id: z.number(),
+  username: z.string(),
+  email: z.string().email().nullable(),
+  createdAt: z.string().datetime(),
+  updatedAt: z.string().datetime(),
+});
+
+export const UserListSchema = UserGetSchema;
+```
+
+### 3. 注册 CRUD 路由
+
+```typescript
+// api/users/index.ts
+import { createCrudRoutes } from '../../../utils/generic-crud.routes';
+import { User } from '../../../modules/users/user.entity';
+import {
+  UserCreateSchema,
+  UserUpdateSchema,
+  UserGetSchema,
+  UserListSchema
+} from '../../../modules/users/user.schema';
+
+export const userRoutes = createCrudRoutes({
+  entity: User,
+  createSchema: UserCreateSchema,
+  updateSchema: UserUpdateSchema,
+  getSchema: UserGetSchema,
+  listSchema: UserListSchema,
+  searchFields: ['username', 'email'],
+  relations: ['roles'],
+  middleware: [authMiddleware],
+  userTracking: {
+    createdByField: 'createdBy',
+    updatedByField: 'updatedBy'
+  }
+});
+```
+
+### 4. 在 API 中注册路由
+
+```typescript
+// api/index.ts
+import { userRoutes } from './users';
+
+const app = new OpenAPIHono();
+app.route('/users', userRoutes);
+```
+
+## 高级功能
+
+### 关联字段处理
+
+支持多对多、一对多等关联关系的自动处理:
+
+```typescript
+const roleRoutes = createCrudRoutes({
+  entity: Role,
+  // ... schemas
+  relationFields: {
+    permissions: {
+      relationName: 'permissions',
+      targetEntity: Permission
+    }
+  }
+});
+```
+
+### 复杂筛选
+
+支持多种筛选方式:
+
+```typescript
+// 精确匹配
+filters: '{"status": 1}'
+
+// 范围查询
+filters: '{"createdAt": {"gte": "2024-01-01", "lte": "2024-12-31"}}'
+
+// IN 查询
+filters: '{"status": [1, 2, 3]}'
+
+// 模糊匹配
+filters: '{"name": "%keyword%"}'
+```
+
+### 关联字段搜索
+
+支持嵌套关联字段的搜索:
+
+```typescript
+// 搜索用户关联的角色名称
+searchFields: ['username', 'roles.name']
+
+// 搜索嵌套关联
+searchFields: ['contract.client.name']
+```
+
+## 最佳实践
+
+### 1. 实体设计
+- 所有实体必须继承 `ObjectLiteral`
+- 使用 TypeORM 装饰器定义字段
+- 包含 `createdAt` 和 `updatedAt` 时间戳
+- 考虑软删除需求
+
+### 2. Schema 设计
+- 创建和更新使用不同的 schema
+- 响应 schema 应包含完整字段
+- 使用 `.optional()` 和 `.nullable()` 明确字段可选性
+
+### 3. 性能优化
+- 合理设置分页大小(默认10条)
+- 为常用查询字段添加索引
+- 使用关联查询时注意 N+1 问题
+- 考虑缓存策略
+
+### 4. 安全性
+- 使用用户跟踪记录操作人
+- 实现适当的权限控制
+- 验证所有输入数据
+- 避免敏感信息暴露
+
+## 扩展和自定义
+
+### 自定义业务逻辑
+
+```typescript
+class CustomUserService extends ConcreteCrudService<User> {
+  async createWithValidation(data: UserCreateDto): Promise<User> {
+    // 自定义验证逻辑
+    await this.validateUniqueUsername(data.username);
+
+    // 调用父类方法
+    return super.create(data);
+  }
+
+  private async validateUniqueUsername(username: string): Promise<void> {
+    const existing = await this.repository.findOne({ where: { username } });
+    if (existing) {
+      throw new Error('用户名已存在');
+    }
+  }
+}
+```
+
+### 自定义路由
+
+```typescript
+const customRoutes = new OpenAPIHono();
+
+// 使用通用 CRUD 路由
+customRoutes.route('/', createCrudRoutes(crudOptions));
+
+// 添加自定义路由
+customRoutes.post('/bulk-create', async (c) => {
+  // 自定义批量创建逻辑
+});
+```
+
+## 常见问题解答
+
+### Q: 如何处理复杂的业务逻辑?
+A: 继承 `ConcreteCrudService` 并添加自定义方法,或创建独立的业务服务类。
+
+### Q: 如何实现软删除?
+A: 在实体中添加 `deletedAt` 字段,重写 `delete` 方法实现软删除逻辑。
+
+### Q: 如何优化关联查询性能?
+A: 使用 `relations` 参数指定需要的关联关系,避免不必要的关联加载。
+
+### Q: 如何处理文件上传等非标准操作?
+A: 创建独立的文件管理服务,或扩展 CRUD 服务添加文件处理逻辑。
+
+## 相关文档
+
+- [主架构文档](../architecture.md)
+- [API 设计规范](./api-design-integration.md)
+- [数据模型规范](./data-model-schema-changes.md)
+- [测试策略](./testing-strategy.md)
+
+---
+
+**文档状态**: 正式版
+**下次评审**: 2025-11-15

+ 5 - 0
docs/architecture/index.md

@@ -35,6 +35,11 @@
   - [组件架构](./component-architecture.md)
   - [组件架构](./component-architecture.md)
     - [现有组件优化](./component-architecture.md#现有组件优化)
     - [现有组件优化](./component-architecture.md#现有组件优化)
     - [组件交互](./component-architecture.md#组件交互)
     - [组件交互](./component-architecture.md#组件交互)
+  - [通用CRUD规范](./generic-crud-standards.md)
+    - [设计原则](./generic-crud-standards.md#设计原则)
+    - [核心组件](./generic-crud-standards.md#核心组件)
+    - [使用指南](./generic-crud-standards.md#使用指南)
+    - [高级功能](./generic-crud-standards.md#高级功能)
   - [API设计和集成](./api-design-integration.md)
   - [API设计和集成](./api-design-integration.md)
     - [API集成策略](./api-design-integration.md#api集成策略)
     - [API集成策略](./api-design-integration.md#api集成策略)
     - [API端点示例](./api-design-integration.md#api端点示例)
     - [API端点示例](./api-design-integration.md#api端点示例)