Browse Source

📝 docs(rules): update entity time field specification

- simplify timestamp column definitions using CreateDateColumn and UpdateDateColumn
- add comment for time fields in user tracking rules

♻️ refactor(templates): optimize template entity and remove schema file

- add comments for all columns in Template entity
- remove previewUrl field from Template entity
- replace manual timestamp columns with CreateDateColumn and UpdateDateColumn
- delete template.schema.ts file
yourname 3 months ago
parent
commit
9d9a1ccbbe

+ 5 - 16
.roo/rules/10-entity.md

@@ -83,22 +83,11 @@ isDeleted!: number;
 ## 6. 时间字段规范
 
 ```typescript
-// 创建时间 (自动设置)
-@Column({ 
-  name: 'created_at',
-  type: 'timestamp', 
-  default: () => 'CURRENT_TIMESTAMP'
-})
-createdAt!: Date;
-
-// 更新时间 (自动更新)
-@Column({
-  name: 'updated_at',
-  type: 'timestamp',
-  default: () => 'CURRENT_TIMESTAMP',
-  onUpdate: 'CURRENT_TIMESTAMP' 
-})
-updatedAt!: Date;
+  @CreateDateColumn({ name: 'created_at', comment: '创建时间' })
+  createdAt!: Date;
+
+  @UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
+  updatedAt!: Date;
 ```
 
 ## 7. Zod Schema 规范

+ 3 - 3
.roo/rules/15-user-tracking.md

@@ -56,10 +56,10 @@ export class YourEntity {
   @Column({ name: 'updated_by', type: 'int', nullable: true, comment: '更新用户ID' })
   updatedBy?: number;
   
-  @CreateDateColumn({ name: 'created_at' })
+  @CreateDateColumn({ name: 'created_at', comment: '创建时间' })
   createdAt!: Date;
-  
-  @UpdateDateColumn({ name: 'updated_at' })
+
+  @UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
   updatedAt!: Date;
 }
 ```

+ 12 - 24
src/server/modules/templates/template.entity.ts

@@ -1,54 +1,42 @@
-import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';
+import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
 import { File } from '@/server/modules/files/file.entity';
 
 @Entity('templates')
 export class Template {
-  @PrimaryGeneratedColumn({ unsigned: true })
+  @PrimaryGeneratedColumn({ unsigned: true, comment: '模板ID,主键自增' })
   id!: number;
 
-  @Column({ name: 'title', type: 'varchar', length: 255 })
+  @Column({ name: 'title', type: 'varchar', length: 255, comment: '模板标题' })
   title!: string;
 
-  @Column({ name: 'description', type: 'text', nullable: true })
+  @Column({ name: 'description', type: 'text', nullable: true, comment: '模板描述' })
   description!: string | null;
 
-  @Column({ name: 'file_id', type: 'int', unsigned: true })
+  @Column({ name: 'file_id', type: 'int', unsigned: true, comment: '关联文件ID' })
   fileId!: number;
 
   @ManyToOne(() => File)
   @JoinColumn({ name: 'file_id', referencedColumnName: 'id' })
   file!: File;
 
-  @Column({ name: 'preview_url', type: 'varchar', length: 500, nullable: true })
-  previewUrl!: string | null;
-
-  @Column({ name: 'category', type: 'varchar', length: 100 })
+  @Column({ name: 'category', type: 'varchar', length: 100, comment: '模板分类' })
   category!: string;
 
-  @Column({ name: 'is_free', type: 'tinyint', default: 0 })
+  @Column({ name: 'is_free', type: 'tinyint', default: 0, comment: '是否免费:0-收费,1-免费' })
   isFree!: number;
 
-  @Column({ name: 'download_count', type: 'int', unsigned: true, default: 0 })
+  @Column({ name: 'download_count', type: 'int', unsigned: true, default: 0, comment: '下载次数' })
   downloadCount!: number;
 
-  @Column({ name: 'is_disabled', type: 'tinyint', default: 0 })
+  @Column({ name: 'is_disabled', type: 'tinyint', default: 0, comment: '是否禁用:0-启用,1-禁用' })
   isDisabled!: number;
 
-  @Column({ name: 'is_deleted', type: 'tinyint', default: 0 })
+  @Column({ name: 'is_deleted', type: 'tinyint', default: 0, comment: '是否删除:0-未删除,1-已删除' })
   isDeleted!: number;
 
-  @Column({ 
-    name: 'created_at', 
-    type: 'timestamp', 
-    default: () => 'CURRENT_TIMESTAMP' 
-  })
+  @CreateDateColumn({ name: 'created_at', comment: '创建时间' })
   createdAt!: Date;
 
-  @Column({ 
-    name: 'updated_at', 
-    type: 'timestamp', 
-    default: () => 'CURRENT_TIMESTAMP',
-    onUpdate: 'CURRENT_TIMESTAMP' 
-  })
+  @UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
   updatedAt!: Date;
 }

+ 0 - 133
src/server/modules/templates/template.schema.ts

@@ -1,133 +0,0 @@
-import { z } from '@hono/zod-openapi';
-
-// 基础模板Schema
-export const TemplateSchema = z.object({
-  id: z.number().int().positive().openapi({
-    description: '模板ID',
-    example: 1
-  }),
-  title: z.string().min(1).max(255).openapi({
-    description: '模板标题',
-    example: '销售合同模板'
-  }),
-  description: z.string().max(2000).nullable().openapi({
-    description: '模板描述',
-    example: '标准销售合同模板,适用于一般商品销售场景'
-  }),
-  fileId: z.number().int().positive().openapi({
-    description: '文件ID',
-    example: 1
-  }),
-  file: z.object({
-    id: z.number().int().positive().openapi({ description: '文件ID' }),
-    name: z.string().max(255).openapi({ description: '文件名', example: 'contract-template.docx' }),
-    fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/files/contract-template.docx' }),
-    type: z.string().nullable().openapi({ description: '文件类型', example: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }),
-    size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
-  }).nullable().optional().openapi({
-    description: '文件信息'
-  }),
-  previewUrl: z.string().url().nullable().openapi({
-    description: '预览URL',
-    example: 'https://example.com/preview/contract-template'
-  }),
-  category: z.string().max(100).openapi({
-    description: '模板分类',
-    example: '合同'
-  }),
-  isFree: z.coerce.number().int().min(0).max(1).openapi({
-    description: '是否免费(0-否 1-是)',
-    example: 0
-  }),
-  downloadCount: z.coerce.number().int().min(0).openapi({
-    description: '下载次数',
-    example: 100
-  }),
-  isDisabled: z.coerce.number().int().min(0).max(1).openapi({
-    description: '是否禁用(0-否 1-是)',
-    example: 0
-  }),
-  isDeleted: z.coerce.number().int().min(0).max(1).openapi({
-    description: '是否删除(0-否 1-是)',
-    example: 0
-  }),
-  createdAt: z.coerce.date().openapi({
-    description: '创建时间',
-    example: '2024-01-01T00:00:00Z'
-  }),
-  updatedAt: z.coerce.date().openapi({
-    description: '更新时间',
-    example: '2024-01-01T00:00:00Z'
-  })
-});
-
-// 创建模板DTO
-export const CreateTemplateDto = z.object({
-  title: z.string().min(1).max(255).openapi({
-    description: '模板标题',
-    example: '销售合同模板'
-  }),
-  description: z.string().max(2000).nullable().optional().openapi({
-    description: '模板描述',
-    example: '标准销售合同模板'
-  }),
-  fileId: z.number().int().positive().openapi({
-    description: '文件ID',
-    example: 1
-  }),
-  category: z.string().max(100).openapi({
-    description: '模板分类',
-    example: '合同'
-  }),
-  isFree: z.coerce.number().int().min(0).max(1).default(0).openapi({
-    description: '是否免费',
-    example: 0
-  })
-});
-
-// 更新模板DTO
-export const UpdateTemplateDto = z.object({
-  title: z.string().min(1).max(255).optional().openapi({
-    description: '模板标题',
-    example: '更新后的模板标题'
-  }),
-  description: z.string().max(2000).nullable().optional().openapi({
-    description: '模板描述',
-    example: '更新后的描述'
-  }),
-  fileId: z.number().int().positive().optional().openapi({
-    description: '文件ID',
-    example: 2
-  }),
-  category: z.string().max(100).optional().openapi({
-    description: '模板分类',
-    example: '合同'
-  }),
-  isFree: z.coerce.number().int().min(0).max(1).optional().openapi({
-    description: '是否免费',
-    example: 1
-  }),
-  isDisabled: z.coerce.number().int().min(0).max(1).optional().openapi({
-    description: '是否禁用',
-    example: 0
-  })
-});
-
-// 列表响应Schema
-export const TemplateListResponse = z.object({
-  data: z.array(TemplateSchema),
-  pagination: z.object({
-    total: z.number().openapi({
-      example: 100,
-      description: '总记录数'
-    }),
-    current: z.number().openapi({
-      example: 1,
-      description: '当前页码'
-    }),
-    pageSize: z.number().openapi({
-      example: 10,
-      description: '每页数量'
-    })
-  })
-});