Bläddra i källkod

📝 docs(rules): add user tracking configuration specification

- document the automatic handling of operator ID fields in CRUD modules
- detail configuration methods including default and custom field names
- provide multiple usage examples for different scenarios
- explain working principles and compatibility approach
- include best practices and common questions sections
yourname 8 månader sedan
förälder
incheckning
5a356e5a5f
1 ändrade filer med 185 tillägg och 0 borttagningar
  1. 185 0
      .roo/rules/15-user-tracking.md

+ 185 - 0
.roo/rules/15-user-tracking.md

@@ -0,0 +1,185 @@
+# 通用CRUD操作人ID字段配置规范
+
+## 概述
+
+本规范定义了如何在通用CRUD模块中自动处理操作人ID字段,确保创建和更新操作时自动记录操作用户信息。
+
+## 新增功能
+
+通用CRUD模块已支持自动注入操作人ID字段,包含以下功能:
+
+1. **创建时自动记录创建人ID**
+2. **更新时自动记录更新人ID**
+3. **灵活配置字段名称**
+4. **向后兼容现有实现**
+
+## 配置方式
+
+### 1. 在CrudOptions中配置用户跟踪
+
+```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,
+  middleware: [authMiddleware],
+  // 用户跟踪配置
+  userTracking: {
+    createdByField: 'createdBy',    // 创建人ID字段名,默认 'createdBy'
+    updatedByField: 'updatedBy'     // 更新人ID字段名,默认 'updatedBy'
+  }
+});
+```
+
+### 2. 实体类定义要求
+
+实体必须包含与配置对应的字段:
+
+```typescript
+@Entity('your_entities')
+export class YourEntity {
+  @PrimaryGeneratedColumn({ unsigned: true })
+  id!: number;
+
+  // 业务字段...
+  
+  @Column({ name: 'created_by', type: 'int', nullable: true, comment: '创建用户ID' })
+  createdBy?: number;
+  
+  @Column({ name: 'updated_by', type: 'int', nullable: true, comment: '更新用户ID' })
+  updatedBy?: number;
+  
+  @CreateDateColumn({ name: 'created_at' })
+  createdAt!: Date;
+  
+  @UpdateDateColumn({ name: 'updated_at' })
+  updatedAt!: Date;
+}
+```
+
+### 3. 字段命名约定
+
+| 配置字段名 | 推荐数据库字段名 | 类型 | 说明 |
+|------------|------------------|------|------|
+| createdByField | created_by | int/string | 创建人用户ID |
+| updatedByField | updated_by | int/string | 更新人用户ID |
+
+## 配置示例
+
+### 示例1:使用默认字段名
+
+```typescript
+const routes = createCrudRoutes({
+  entity: MyEntity,
+  createSchema: CreateMyEntityDto,
+  updateSchema: UpdateMyEntityDto,
+  getSchema: MyEntitySchema,
+  listSchema: MyEntitySchema,
+  userTracking: {} // 使用默认字段名 createdBy 和 updatedBy
+});
+```
+
+### 示例2:自定义字段名
+
+```typescript
+const routes = createCrudRoutes({
+  entity: MyEntity,
+  createSchema: CreateMyEntityDto,
+  updateSchema: UpdateMyEntityDto,
+  getSchema: MyEntitySchema,
+  listSchema: MyEntitySchema,
+  userTracking: {
+    createdByField: 'created_user_id',
+    updatedByField: 'modified_user_id'
+  }
+});
+```
+
+### 示例3:只记录创建人
+
+```typescript
+const routes = createCrudRoutes({
+  entity: MyEntity,
+  createSchema: CreateMyEntityDto,
+  updateSchema: UpdateMyEntityDto,
+  getSchema: MyEntitySchema,
+  listSchema: MyEntitySchema,
+  userTracking: {
+    createdByField: 'created_by',
+    updatedByField: undefined // 不记录更新人
+  }
+});
+```
+
+### 示例4:兼容现有字段名
+
+```typescript
+const routes = createCrudRoutes({
+  entity: Linkman,
+  createSchema: CreateLinkmanDto,
+  updateSchema: UpdateLinkmanDto,
+  getSchema: LinkmanSchema,
+  listSchema: LinkmanSchema,
+  userTracking: {
+    createdByField: 'createdUserId', // 匹配现有字段
+    updatedByField: 'updatedUserId'  // 匹配现有字段
+  }
+});
+```
+
+## 工作原理
+
+1. **创建操作**:
+   - 当用户创建新记录时,系统自动从认证上下文中提取用户ID
+   - 将用户ID注入到配置的创建人字段中
+   - 如果未配置createdByField,则跳过此步骤
+
+2. **更新操作**:
+   - 当用户更新记录时,系统自动从认证上下文中提取用户ID
+   - 将用户ID注入到配置的更新人字段中
+   - 如果未配置updatedByField,则跳过此步骤
+
+3. **向后兼容**:
+   - 未配置userTracking时,保持原有行为不变
+   - 所有现有代码无需修改即可继续运行
+
+## 注意事项
+
+1. **认证要求**:必须在路由中添加`authMiddleware`才能获取用户信息
+2. **字段类型**:用户ID字段应支持存储用户ID的数据类型(通常为int或varchar)
+3. **数据库字段**:确保实体类中定义的数据库字段名与配置一致
+4. **空值处理**:如果用户未登录,相关字段将保持为null
+
+## 最佳实践
+
+1. **统一命名**:在项目中统一使用相同的字段命名约定
+2. **索引优化**:为操作人ID字段添加数据库索引以提高查询性能
+3. **关联查询**:可以通过relations配置加载操作人详情
+4. **审计功能**:结合时间戳字段实现完整的操作审计
+
+## 常见问题
+
+### Q: 如何支持字符串类型的用户ID?
+A: 实体类字段类型设置为varchar即可,系统会自动处理字符串类型
+
+### Q: 可以配置不同的用户ID字段吗?
+A: 可以,通过createdByField和updatedByField分别配置
+
+### Q: 会影响现有实体吗?
+A: 不会,只有配置了userTracking的实体才会启用此功能
+
+### Q: 如何获取操作人详情?
+A: 在relations中配置用户关联关系即可:
+```typescript
+const routes = createCrudRoutes({
+  entity: YourEntity,
+  relations: ['createdByUser', 'updatedByUser'],
+  // ...其他配置
+});