vendure-entity-reviewing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVendure Entity Reviewing
Vendure实体审查
Purpose
审查目的
Audit Vendure entities for violations and TypeORM anti-patterns.
审计Vendure实体是否存在违规情况和TypeORM反模式。
Review Workflow
审查流程
Step 1: Identify Entity Files
步骤1:识别实体文件
bash
undefinedbash
undefinedFind entity files
查找实体文件
find . -name "*.entity.ts"
find . -name "*.entity.ts"
Find migration files
查找迁移文件
find . -name "migration.ts" -o -name "Migration.ts"
undefinedfind . -name "migration.ts" -o -name "Migration.ts"
undefinedStep 2: Run Automated Checks
步骤2:运行自动化检查
bash
undefinedbash
undefined=== CRITICAL VIOLATIONS ===
=== 严重违规 ===
Not extending VendureEntity
未继承VendureEntity
grep -rn "export class.Entity" --include=".entity.ts" | grep -v "extends VendureEntity"
grep -rn "export class.Entity" --include=".entity.ts" | grep -v "extends VendureEntity"
Missing @Entity decorator
缺少@Entity装饰器
grep -rn "export class.Entity" --include=".entity.ts" | grep -v "@Entity"
grep -rn "export class.Entity" --include=".entity.ts" | grep -v "@Entity"
Direct repository injection (should use TransactionalConnection)
直接注入Repository(应使用TransactionalConnection)
grep -rn "@InjectRepository" --include="*.service.ts"
grep -rn "@InjectRepository" --include="*.service.ts"
=== HIGH PRIORITY ===
=== 高优先级 ===
Missing indexes on foreign keys
外键缺少索引
grep -rn "@ManyToOne|@OneToMany" --include="*.entity.ts" -B 2 | grep -v "@Index"
grep -rn "@ManyToOne|@OneToMany" --include="*.entity.ts" -B 2 | grep -v "@Index"
Missing DeepPartial constructor
缺少DeepPartial构造函数
grep -rn "export class.extends VendureEntity" --include=".entity.ts" -A 5 | grep -v "DeepPartial"
grep -rn "export class.extends VendureEntity" --include=".entity.ts" -A 5 | grep -v "DeepPartial"
Using 'any' type
使用'any'类型
grep -rn ": any" --include="*.entity.ts"
grep -rn ": any" --include="*.entity.ts"
=== MEDIUM PRIORITY ===
=== 中优先级 ===
Missing nullable specification
未指定nullable属性
grep -rn "@Column()" --include="*.entity.ts" | head -20
grep -rn "@Column()" --include="*.entity.ts" | head -20
Date stored as string (should be timestamp)
日期以字符串形式存储(应使用timestamp类型)
grep -rn "type: 'varchar'.*[dD]ate|[dD]ate.type: 'varchar'" --include=".entity.ts"
undefinedgrep -rn "type: 'varchar'.*[dD]ate|[dD]ate.type: 'varchar'" --include=".entity.ts"
undefinedStep 3: Manual Review Checklist
步骤3:人工审查检查清单
Entity Structure
实体结构
- Extends VendureEntity
- @Entity() decorator present
- DeepPartial<T> constructor
- Proper column types
- Nullable specified where needed
- 继承了VendureEntity
- 存在@Entity()装饰器
- 包含DeepPartial<T>构造函数
- 列类型正确
- 必要时指定了nullable属性
Relations
关联关系
- @Index on foreign key columns
- Cascade options appropriate
- OnDelete behavior specified
- Eager loading only where necessary
- 外键列添加了@Index
- 级联选项设置合理
- 指定了OnDelete行为
- 仅在必要时使用即时加载
Migrations
迁移文件
- Migration file exists for new entities
- Migration has both up() and down()
- Indexes created in migration
- Column types match entity
- 新实体对应的迁移文件已创建
- 迁移文件同时包含up()和down()方法
- 迁移中创建了索引
- 列类型与实体定义一致
Severity Classification
严重程度分类
CRITICAL (Must Fix)
严重(必须修复)
- Not extending VendureEntity
- Missing @Entity decorator
- Direct repository injection
- No migration for schema change
- 未继承VendureEntity
- 缺少@Entity装饰器
- 直接注入Repository
- 模式变更未创建迁移文件
HIGH (Should Fix)
高优先级(应该修复)
- Missing index on foreign key
- No DeepPartial constructor
- Using any type
- Missing onDelete behavior
- 外键缺少索引
- 没有DeepPartial构造函数
- 使用any类型
- 缺少onDelete行为定义
MEDIUM (Should Fix)
中优先级(建议修复)
- Missing nullable specification
- Date stored as string
- No column default values
- 未指定nullable属性
- 日期以字符串形式存储
- 未设置列默认值
Common Violations
常见违规情况
1. Not Extending VendureEntity
1. 未继承VendureEntity
Violation:
typescript
@Entity()
export class MyEntity {
// Missing extends!
@PrimaryGeneratedColumn()
id: number;
}Fix:
typescript
@Entity()
export class MyEntity extends VendureEntity {
constructor(input?: DeepPartial<MyEntity>) {
super(input);
}
}违规代码:
typescript
@Entity()
export class MyEntity {
// 缺少继承!
@PrimaryGeneratedColumn()
id: number;
}修复方案:
typescript
@Entity()
export class MyEntity extends VendureEntity {
constructor(input?: DeepPartial<MyEntity>) {
super(input);
}
}2. Missing Index on Foreign Key
2. 外键缺少索引
Violation:
typescript
@ManyToOne(() => Product)
product: Product;
@Column()
productId: number; // No index!Fix:
typescript
@Index()
@ManyToOne(() => Product)
product: Product;
@Column()
productId: number;违规代码:
typescript
@ManyToOne(() => Product)
product: Product;
@Column()
productId: number; // 没有索引!修复方案:
typescript
@Index()
@ManyToOne(() => Product)
product: Product;
@Column()
productId: number;3. Direct Repository Injection
3. 直接注入Repository
Violation:
typescript
@Injectable()
export class MyService {
constructor(
@InjectRepository(MyEntity) // WRONG
private repo: Repository<MyEntity>,
) {}
}Fix:
typescript
@Injectable()
export class MyService {
constructor(
private connection: TransactionalConnection, // CORRECT
) {}
async find(ctx: RequestContext) {
return this.connection.getRepository(ctx, MyEntity).find();
}
}违规代码:
typescript
@Injectable()
export class MyService {
constructor(
@InjectRepository(MyEntity) // 错误用法
private repo: Repository<MyEntity>,
) {}
}修复方案:
typescript
@Injectable()
export class MyService {
constructor(
private connection: TransactionalConnection, // 正确用法
) {}
async find(ctx: RequestContext) {
return this.connection.getRepository(ctx, MyEntity).find();
}
}4. Missing DeepPartial Constructor
4. 缺少DeepPartial构造函数
Violation:
typescript
@Entity()
export class MyEntity extends VendureEntity {
@Column()
name: string;
// No constructor!
}Fix:
typescript
@Entity()
export class MyEntity extends VendureEntity {
constructor(input?: DeepPartial<MyEntity>) {
super(input);
}
@Column()
name: string;
}违规代码:
typescript
@Entity()
export class MyEntity extends VendureEntity {
@Column()
name: string;
// 缺少构造函数!
}修复方案:
typescript
@Entity()
export class MyEntity extends VendureEntity {
constructor(input?: DeepPartial<MyEntity>) {
super(input);
}
@Column()
name: string;
}5. Using Any Type
5. 使用Any类型
Violation:
typescript
@Column({ type: 'simple-json' })
metadata: any; // No type safety!Fix:
typescript
interface MyMetadata {
key: string;
value: number;
}
@Column({ type: 'simple-json', nullable: true })
metadata: MyMetadata | null;违规代码:
typescript
@Column({ type: 'simple-json' })
metadata: any; // 没有类型安全!修复方案:
typescript
interface MyMetadata {
key: string;
value: number;
}
@Column({ type: 'simple-json', nullable: true })
metadata: MyMetadata | null;Quick Detection Commands
快速检测命令
bash
undefinedbash
undefinedAll-in-one entity audit
一站式实体审计
echo "=== CRITICAL: Not extending VendureEntity ===" &&
grep -rn "export class.Entity" --include=".entity.ts" | grep -v "extends VendureEntity" &&
echo "" &&
echo "=== HIGH: Missing @Index ===" &&
grep -rn "@ManyToOne" --include=".entity.ts" -B 2 | grep -v "@Index" &&
echo "" &&
echo "=== MEDIUM: Using any ===" &&
grep -rn ": any" --include=".entity.ts"
grep -rn "export class.Entity" --include=".entity.ts" | grep -v "extends VendureEntity" &&
echo "" &&
echo "=== HIGH: Missing @Index ===" &&
grep -rn "@ManyToOne" --include=".entity.ts" -B 2 | grep -v "@Index" &&
echo "" &&
echo "=== MEDIUM: Using any ===" &&
grep -rn ": any" --include=".entity.ts"
---echo "=== 严重违规:未继承VendureEntity ===" &&
grep -rn "export class.Entity" --include=".entity.ts" | grep -v "extends VendureEntity" &&
echo "" &&
echo "=== 高优先级:缺少@Index ===" &&
grep -rn "@ManyToOne" --include=".entity.ts" -B 2 | grep -v "@Index" &&
echo "" &&
echo "=== 中优先级:使用any类型 ===" &&
grep -rn ": any" --include=".entity.ts"
grep -rn "export class.Entity" --include=".entity.ts" | grep -v "extends VendureEntity" &&
echo "" &&
echo "=== 高优先级:缺少@Index ===" &&
grep -rn "@ManyToOne" --include=".entity.ts" -B 2 | grep -v "@Index" &&
echo "" &&
echo "=== 中优先级:使用any类型 ===" &&
grep -rn ": any" --include=".entity.ts"
---Migration Review Checklist
迁移文件审查检查清单
When entity changes, verify:
- Migration file created
- Table/columns match entity
- Indexes created for foreign keys
- down() properly reverses up()
- No data loss in down()
- Column types correct (int, varchar, timestamp, etc.)
当实体发生变更时,需验证:
- 已创建迁移文件
- 表/列与实体定义匹配
- 为外键创建了索引
- down()方法能正确回滚up()的变更
- down()操作不会导致数据丢失
- 列类型正确(int、varchar、timestamp等)
Review Output Template
审查输出模板
markdown
undefinedmarkdown
undefinedEntity Review: [Entity Name]
实体审查:[实体名称]
Summary
摘要
[Overview of entity quality]
[实体质量概述]
Critical Issues (Must Fix)
严重问题(必须修复)
- [Issue] -
file:line
- [问题描述] -
文件:行号
High Priority
高优先级问题
- [Issue] -
file:line
- [问题描述] -
文件:行号
Passed Checks
通过的检查项
- Extends VendureEntity
- @Entity decorator present
- Migration exists
- 继承了VendureEntity
- 存在@Entity装饰器
- 已创建迁移文件
Recommendations
建议
- [Suggestions]
---[改进建议]
---Cross-Reference
交叉参考
All rules match patterns in vendure-entity-writing skill.
所有规则均与vendure-entity-writing技能中的模式匹配。
Related Skills
相关技能
- vendure-entity-writing - Entity patterns
- vendure-plugin-reviewing - Plugin-level review
- vendure-entity-writing - 实体编写规范
- vendure-plugin-reviewing - 插件级审查