vendure-plugin-reviewing

📁 meriley/claude-code-skills 📅 14 days ago
1
总安装量
1
周安装量
#48277
全站排名
安装命令
npx skills add https://github.com/meriley/claude-code-skills --skill vendure-plugin-reviewing

Agent 安装分布

pi 1
opencode 1
cursor 1
codex 1
claude-code 1
gemini-cli 1

Skill 文档

Vendure Plugin Reviewing

Purpose

Audit Vendure plugins for violations of best practices, security issues, and anti-patterns.

When NOT to Use

  • Creating new plugins (use vendure-plugin-writing)
  • GraphQL-only review (use vendure-graphql-reviewing)
  • Entity-only review (use vendure-entity-reviewing)

Review Workflow

Step 1: Identify Plugin Files

# Find all plugin files
find . -name "*.plugin.ts" -o -name "*-plugin.ts"

# Find all service files
find . -name "*.service.ts"

# Find all entity files
find . -name "*.entity.ts"

Step 2: Run Automated Checks

# === CRITICAL VIOLATIONS ===

# Missing @VendurePlugin decorator
grep -rn "export class.*Plugin" --include="*plugin.ts" | grep -v "@VendurePlugin"

# Missing PluginCommonModule import
grep -rn "@VendurePlugin" --include="*plugin.ts" -A 10 | grep -v "PluginCommonModule"

# Direct database access (bypassing TransactionalConnection)
grep -rn "getRepository\|createQueryBuilder\|getConnection" --include="*.service.ts" | grep -v "TransactionalConnection"

# === HIGH PRIORITY ===

# Missing @Injectable on services
grep -rn "export class.*Service" --include="*.service.ts" | grep -v "@Injectable"

# Hardcoded configuration values
grep -rn "localhost\|127.0.0.1\|apiKey.*=.*['\"]" --include="*.plugin.ts" --include="*.service.ts"

# Missing RequestContext parameter
grep -rn "async.*\(" --include="*.service.ts" | grep -v "ctx.*RequestContext\|RequestContext.*ctx"

# === MEDIUM PRIORITY ===

# Missing init() static method
grep -rn "export class.*Plugin" --include="*plugin.ts" -A 20 | grep -v "static init"

# Missing default options
grep -rn "this.options = options" --include="*plugin.ts" | grep -v "...default\|...options"

# Missing lifecycle cleanup
grep -rn "onApplicationBootstrap" --include="*plugin.ts" | xargs -I{} sh -c 'grep -L "onApplicationShutdown" {} 2>/dev/null'

Step 3: Manual Review Checklist

Plugin Structure

  • @VendurePlugin decorator present
  • PluginCommonModule in imports
  • All entities in entities array
  • All services in providers array
  • Static init() method with defaults
  • Options interface with types

Services

  • @Injectable() decorator on all services
  • RequestContext as first parameter
  • TransactionalConnection for DB access
  • No direct TypeORM repository access
  • Proper error handling

Lifecycle

  • OnApplicationBootstrap if initialization needed
  • OnApplicationShutdown if cleanup needed
  • Async/await on lifecycle methods
  • Strategy init() calls in bootstrap

Configuration

  • Options interface defined
  • Default values for all options
  • No hardcoded secrets
  • Environment variable usage for sensitive data

Severity Classification

CRITICAL (Must Fix Before Merge)

  • Missing @VendurePlugin decorator
  • Direct database access bypassing services
  • Missing PluginCommonModule import
  • Hardcoded secrets or API keys
  • Security vulnerabilities

HIGH (Should Fix Before Merge)

  • Missing @Injectable decorator
  • Missing RequestContext in service methods
  • Hardcoded configuration values
  • Missing error handling
  • No default options

MEDIUM (Should Fix)

  • Missing lifecycle cleanup (shutdown)
  • No configuration validation
  • Poor naming conventions
  • Missing TypeScript types

LOW (Suggestions)

  • Missing documentation
  • Could use better error messages
  • Performance improvements possible

Review Output Template

## Vendure Plugin Review: [Plugin Name]

### Summary

[Brief overview of plugin purpose and review findings]

### Critical Issues (Must Fix)

- [ ] [Issue description] - `file:line`

### High Priority

- [ ] [Issue description] - `file:line`

### Medium Priority

- [ ] [Issue description] - `file:line`

### Passed Checks

- [x] @VendurePlugin decorator present
- [x] PluginCommonModule imported
- [x] All services @Injectable

### Recommendations

- [Improvement suggestions]

Common Violations

1. Missing PluginCommonModule

Violation:

@VendurePlugin({
  imports: [],  // Missing PluginCommonModule!
  providers: [MyService],
})

Fix:

@VendurePlugin({
  imports: [PluginCommonModule],
  providers: [MyService],
})

2. Direct Database Access

Violation:

@Injectable()
export class MyService {
  constructor(
    @InjectRepository(MyEntity) // WRONG
    private repo: Repository<MyEntity>,
  ) {}
}

Fix:

@Injectable()
export class MyService {
  constructor(
    private connection: TransactionalConnection, // CORRECT
  ) {}

  async findAll(ctx: RequestContext) {
    return this.connection.getRepository(ctx, MyEntity).find();
  }
}

3. Missing RequestContext

Violation:

async findAll(): Promise<MyEntity[]> {  // Missing ctx!
  return this.connection.getRepository(MyEntity).find();
}

Fix:

async findAll(ctx: RequestContext): Promise<MyEntity[]> {
  return this.connection.getRepository(ctx, MyEntity).find();
}

4. Hardcoded Options

Violation:

static init(options: MyOptions): typeof MyPlugin {
  this.options = options;  // No defaults!
  return MyPlugin;
}

Fix:

static init(options: MyOptions = {}): typeof MyPlugin {
  this.options = {
    ...defaultOptions,  // Always merge with defaults
    ...options,
  };
  return MyPlugin;
}

5. Strategy Without Lifecycle

Violation:

static init(options: { strategy: MyStrategy }) {
  this.options = options;
  // Strategy init() never called!
}

Fix:

async onApplicationBootstrap(): Promise<void> {
  if (typeof MyPlugin.options.strategy.init === 'function') {
    await MyPlugin.options.strategy.init(this.injector);
  }
}

Quick Detection Commands

# All-in-one audit script
echo "=== CRITICAL ===" && \
grep -rn "export class.*Plugin" --include="*plugin.ts" | grep -v "@VendurePlugin" && \
echo "=== HIGH ===" && \
grep -rn "export class.*Service" --include="*.service.ts" | grep -v "@Injectable" && \
echo "=== MEDIUM ===" && \
grep -rn "TODO\|FIXME\|HACK" --include="*.ts"

Cross-Reference

All rules in this skill match patterns documented in vendure-plugin-writing skill.

When reviewing, verify the plugin follows the patterns in:

  • vendure-plugin-writing (plugin structure)
  • vendure-graphql-writing (if has API extensions)
  • vendure-entity-writing (if has entities)
  • vendure-admin-ui-writing (if has UI extensions)

Related Skills

  • vendure-plugin-writing – Plugin creation patterns
  • vendure-graphql-reviewing – GraphQL-specific review
  • vendure-entity-reviewing – Entity-specific review
  • vendure-admin-ui-reviewing – UI-specific review