vsa-implementation-guard

VSA Implementation Guard

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "vsa-implementation-guard" with this command: npx skills add akiramei/blazor-enterprise-architecture-poc/akiramei-blazor-enterprise-architecture-poc-vsa-implementation-guard

VSA Implementation Guard

このスキルは Blazor VSA 実装時の自動ミス防止を目的とする。

C# コードを生成・修正する際に、このスキルの知識が自動的に適用される。

適用場面

  • C# コードの生成・修正

  • MediatR Handler の実装

  • FluentValidation Validator の実装

  • BoundaryService の実装

  • Entity の CanXxx() メソッド実装

禁止事項(NEVER DO)

  1. Handler 内で SaveChangesAsync() を呼ばない

// ❌ 禁止 public async Task<Result<Guid>> Handle(CreateProductCommand request, CancellationToken ct) { var entity = new Product(...); await _repository.AddAsync(entity, ct); await _dbContext.SaveChangesAsync(ct); // ← これを書かない! return Result.Success(entity.Id); }

// ✅ 正しい public async Task<Result<Guid>> Handle(CreateProductCommand request, CancellationToken ct) { var entity = new Product(...); await _repository.AddAsync(entity, ct); return Result.Success(entity.Id); // TransactionBehavior が SaveChanges を実行 }

理由: TransactionBehavior が Handler 実行後に自動で SaveChangesAsync を呼び出す。

  1. BoundaryService に業務ロジック(if文)を書かない

// ❌ 禁止: BoundaryService に業務ロジック public async Task<BoundaryDecision> ValidatePayAsync(OrderId id, CancellationToken ct) { var order = await _repository.GetByIdAsync(id, ct);

// ↓ これは業務ロジック!Entity.CanPay() に移動すべき
if (order.Status == OrderStatus.Paid)
    return BoundaryDecision.Deny("既に支払い済みです");

return BoundaryDecision.Allow();

}

// ✅ 正しい: Entity に委譲 public async Task<BoundaryDecision> ValidatePayAsync(OrderId id, CancellationToken ct) { var order = await _repository.GetByIdAsync(id, ct); if (order == null) return BoundaryDecision.Deny("注文が見つかりません"); // 存在チェックのみ許可

return order.CanPay();  // ★ 業務ロジックは Entity に委譲

}

理由: 業務ロジックは Entity が持つ。BoundaryService は委譲のみ。

  1. 例外を throw してエラーを伝播しない

// ❌ 禁止 if (product == null) throw new NotFoundException("Product not found");

// ✅ 正しい if (product == null) return Result.Fail<Product>("Product not found");

理由: 例外は本当に予期しないエラーのみ。ビジネスロジック上のエラーは Result<T> で伝播。

  1. Value Object の比較で .Value プロパティにアクセスしない

// ❌ LINQ変換エラー var board = await _dbContext.Boards .Where(b => b.Id.Value == guid) // EF Core が変換できない .FirstOrDefaultAsync();

// ✅ 正しい: インスタンス同士で比較 var boardId = BoardId.From(guid); var board = await _dbContext.Boards .Where(b => b.Id == boardId) .FirstOrDefaultAsync();

理由: EF Core は .Value プロパティへのアクセスを SQL に変換できない。

  1. Validator で DB アクセスしない

// ❌ 禁止: Validator 内で DB アクセス public class CreateBookingValidator : AbstractValidator<CreateBookingCommand> { public CreateBookingValidator(IBookingRepository repo) { RuleFor(x => x.RoomId) .MustAsync(async (roomId, ct) => await repo.ExistsAsync(roomId, ct)) .WithMessage("会議室が存在しません"); } }

// ✅ 正しい: 形式検証のみ public class CreateBookingValidator : AbstractValidator<CreateBookingCommand> { public CreateBookingValidator() { RuleFor(x => x.Title).NotEmpty().MaximumLength(100); RuleFor(x => x.StartTime).LessThan(x => x.EndTime); } }

理由: ValidationBehavior は形式検証のみ。存在確認は Handler 内で行う。

  1. Handler のメソッド名を HandleAsync にしない

// ❌ 禁止 public async Task<Result<Guid>> HandleAsync(...)

// ✅ 正しい public async Task<Result<Guid>> Handle(...)

理由: MediatR は Handle という名前のメソッドを探す。HandleAsync は規約外。

  1. Singleton で DbContext を注入しない

// ❌ 禁止: Captive Dependency 問題 services.AddSingleton<IMyService, MyService>();

// ✅ 正しい: すべて Scoped services.AddScoped<IMyService, MyService>();

理由: MediatR は Scoped で動作。Singleton が Scoped の依存関係を持つと問題発生。

必須パターン

項目 ルール

Command 戻り値 Result<T>

サービス登録 Scoped

Command インターフェース ICommand<Result<T>> (IRequest<T> 直接使用禁止)

Handler メソッド名 Handle (HandleAsync 禁止)

実装前チェックリスト

□ Handler 内で SaveChangesAsync を呼んでいないか? □ BoundaryService に業務ロジック(if文)がないか? □ Entity に CanXxx() メソッドがあるか? □ Result<T> でエラーを返しているか? □ Value Object はインスタンス同士で比較しているか? □ Validator は形式検証のみか? □ サービスは Scoped で登録しているか?

参照

詳細は catalog/COMMON_MISTAKES.md を参照。

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

vsa-pattern-selector

No summary provided by upstream source.

Repository SourceNeeds Review
General

vsa-boundary-modeler

No summary provided by upstream source.

Repository SourceNeeds Review
General

vsa-ui-enhancer

No summary provided by upstream source.

Repository SourceNeeds Review
General

PanchangaAPI — Vedic Astrology

Vedic astrology (Jyotish) REST API powered by Swiss Ephemeris. 24 endpoints: Panchanga, Kundali (300+ Yogas, Ashtakavarga, Doshas), KP system (249 sub-lords)...

Registry SourceRecently Updated