Awesome-omni-skill review-architecture
Verify DDD patterns, Clean Architecture boundaries, and bITdevKit-specific conventions in modular monolith projects
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/review-architecture" ~/.claude/skills/diegosouzapw-awesome-omni-skill-review-architecture && rm -rf "$T"
skills/development/review-architecture/SKILL.mdArchitecture Review Skill (DDD + Clean Architecture)
Specialized architectural review for modular monoliths using Domain-Driven Design (DDD), Clean/Onion Architecture, and bITdevKit patterns. This skill verifies layer boundaries, domain purity, CQRS patterns, and proper use of Result<T> error handling.
When to Apply This Skill
Use this skill when:
- Conducting architecture reviews of new features or modules
- Reviewing pull requests that add/modify domain models, commands, queries, or endpoints
- Refactoring existing code to align with DDD/Clean Architecture
- Onboarding new developers to the architectural patterns
- Validating that layer boundaries remain intact after changes
- Auditing cross-module dependencies in a modular monolith
Architecture Overview
Layer Structure (Onion/Clean Architecture)
Dependencies flow inward only from outer layers to inner layers:
┌─────────────────────────────────────────┐ │ Presentation (Outermost) │ Minimal API endpoints, DTOs │ ┌───────────────────────────────────┐ │ │ │ Infrastructure │ │ EF Core, Repositories, Jobs │ │ ┌─────────────────────────────┐ │ │ │ │ │ Application │ │ │ Commands, Queries, Handlers │ │ │ ┌───────────────────────┐ │ │ │ │ │ │ │ Domain (Innermost) │ │ │ │ Aggregates, Entities, Value Objects │ │ │ │ Pure Business Logic │ │ │ │ Domain Events, Enumerations │ │ │ │ ZERO Dependencies │ │ │ │ │ │ │ └───────────────────────┘ │ │ │ │ │ └─────────────────────────────┘ │ │ │ └───────────────────────────────────┘ │ └─────────────────────────────────────────┘
Module Organization
Each module under
src/Modules/<ModuleName> follows this structure:
CoreModule/ ├── CoreModule.Domain/ # Pure business logic (NO external dependencies) │ └── Model/ │ ├── CustomerAggregate/ │ │ ├── Customer.cs (Aggregate Root) │ │ └── Events/ │ ├── EmailAddress.cs (Value Object) │ └── CustomerStatus.cs (Enumeration) ├── CoreModule.Application/ # Use case orchestration (references Domain only) │ ├── Commands/ │ │ ├── CustomerCreateCommand.cs │ │ └── CustomerCreateCommandHandler.cs │ └── Queries/ ├── CoreModule.Infrastructure/ # Technical implementation (references Domain + Application) │ ├── EntityFramework/ │ │ ├── CoreModuleDbContext.cs │ │ └── Configurations/ │ └── Repositories/ └── CoreModule.Presentation/ # Endpoints & DTOs (references Application via IRequester) └── Web/ └── Endpoints/ └── CustomerEndpoints.cs
Review Priorities
🔴 CRITICAL Issues (Must Fix Before Merge)
These violations break architectural boundaries or introduce serious design flaws:
- Layer boundary violations: Dependency flows outward (e.g., Domain → Application, Application → Infrastructure)
- Cross-module direct references: Modules directly referencing each other (breaks modular isolation)
- Domain impurity: Domain layer has external dependencies (EF Core, Application, Infrastructure)
- DbContext in Application/Domain: Direct DbContext usage outside Infrastructure layer
- Public setters on aggregates/entities: Breaks encapsulation; use change methods instead
- Exceptions for business rules: Using exceptions instead of Result<T> for expected failures
- Test independence violations: Tests sharing mutable state or depending on execution order
- Resource leaks: IDisposable not properly disposed (missing using statements)
- Endpoints with business logic: Business rules implemented in Presentation layer
🟡 IMPORTANT Issues (Should Fix Soon)
These issues affect maintainability, consistency, or future extensibility:
- CQRS naming violations: Commands/queries not following
pattern[Entity][Action]Command/Query - Repository pattern violations: Not using IGenericRepository<T> in Application layer
- Strongly-typed ID inconsistency: Missing
attributes[TypedEntityId<Guid>] - Specification pattern ignored: Complex queries inline instead of using specifications
- IRequester not used: Endpoints directly instantiating handlers instead of using IRequester.SendAsync
- N+1 query problems: Missing .Include() causing excessive database round-trips
- Async/await violations: Blocking on async code (.Result, .Wait())
- CancellationToken missing: Async methods not accepting CancellationToken parameters
- Domain event naming: Not in past tense or missing "DomainEvent" suffix
🟢 SUGGESTIONS (Nice to Have)
These improve code quality but are not blocking:
- XML documentation: Missing on public APIs
- Mapster configuration: Ad-hoc mapping instead of MapperRegister
- OpenAPI metadata: Endpoints missing .WithName, .WithSummary, .Produces<T>
- Modern C# features: Opportunities to use pattern matching, expression-bodied members, etc.
- Value object naming: Generic names (Email) instead of descriptive (EmailAddress)
Quick Reference to Detailed Guidance
This skill includes comprehensive checklists, examples, and templates:
Checklists (6 files)
- Layer Boundaries: Verify dependency flow, detect circular references
- Domain Patterns: Validate aggregates, entities, value objects, domain events
- CQRS Patterns: Check commands, queries, handlers, validators, IRequester usage
- Repository & Data Access: Ensure proper abstraction, specification pattern, N+1 detection
- Presentation Endpoints: Validate thin adapters, IRequester delegation, OpenAPI docs
- Result & Error Handling: Enforce Result<T> pattern, HTTP mapping, error clarity
Examples (5 files)
- Aggregate Patterns: WRONG vs CORRECT aggregate implementations
- Value Object Patterns: WRONG vs CORRECT value object implementations
- CQRS Examples: Command/query structure, handler delegation, IRequester usage
- Result Pattern Examples: Using Result<T> instead of exceptions
- Layer Violations: Common boundary violations and how to fix them
Documentation (2 files)
- ADR Quick Reference: One-paragraph summaries of all 20 ADRs with quick lookup
- bITdevKit Patterns: IRequester/INotifier, repository behaviors, module registration
Templates (2 files)
- Architecture Review Template: Comment format for violations
- Review Summary Template: Summary format with ADR references
Example Workflow: Conducting an Architecture Review
Step 1: Identify Scope
Determine which modules and layers are affected:
# Check which files changed in a PR git diff main...feature-branch --name-only | grep "src/Modules/" # Example output: # src/Modules/CoreModule/CoreModule.Domain/Model/CustomerAggregate/Customer.cs # src/Modules/CoreModule/CoreModule.Application/Commands/CustomerCreateCommand.cs # src/Modules/CoreModule/CoreModule.Presentation/Web/Endpoints/CustomerEndpoints.cs
Layers affected: Domain, Application, Presentation
Step 2: Check Layer Boundaries (🔴 CRITICAL)
Use: checklists/01-layer-boundaries.md
Verify dependencies flow inward only:
- ✅ Domain: No
statements referencing Application, Infrastructure, or Presentationusing - ✅ Application: Only
statements referencing Domainusing - ✅ Presentation: Uses
to call Application layerIRequester.SendAsync()
Reference: ADR-0001 (Clean/Onion Architecture)
Step 3: Validate Domain Patterns (🔴 CRITICAL)
Use: checklists/02-domain-patterns.md
Check aggregate
Customer.cs:
- ✅ Private setters on all properties
- ✅ Factory method
returnsCustomer.Create()Result<Customer> - ✅ Change methods (
,ChangeName
) returnChangeEmailResult<Customer> - ✅ Domain events registered (
)CustomerCreatedDomainEvent - ✅
attribute on[TypedEntityId<Guid>]CustomerId - ✅ Collection exposed as
IReadOnlyCollection<Address>
Reference: ADR-0012 (Domain Logic in Domain Layer), ADR-0008 (Typed Entity IDs)
Step 4: Review CQRS Implementation (🟡 IMPORTANT)
Use: checklists/03-cqrs-patterns.md
Check
CustomerCreateCommand.cs:
- ✅ Named
(followsCustomerCreateCommand
pattern)[Entity][Action]Command - ✅ Nested
class usingValidatorAbstractValidator<T> - ✅ Handler uses
, NOT DbContextIGenericRepository<Customer> - ✅ Handler delegates to
(domain), not business logic in handlerCustomer.Create() - ✅ Returns
Result<CustomerId>
Reference: ADR-0011 (Application Logic in Commands/Queries), ADR-0009 (FluentValidation)
Step 5: Validate Repository Usage (🔴 CRITICAL)
Use: checklists/04-repository-data-access.md
Check handler:
- ✅ Injects
(abstraction)IGenericRepository<Customer> - ❌ Injects
directly → WRONG (ADR-0004 violation)CoreModuleDbContext
Fix: Replace DbContext with repository abstraction.
Reference: ADR-0004 (Repository Pattern with Decorator Behaviors)
Step 6: Review Endpoints (🟡 IMPORTANT)
Use: checklists/05-presentation-endpoints.md
Check
CustomerEndpoints.cs:
- ✅ Derives from
EndpointsBase - ✅ Uses
to delegate to ApplicationIRequester.SendAsync(command, ct) - ✅ Uses
to map.MapHttpCreated()
to HTTP 201Result<CustomerId> - ✅ Includes
parameterCancellationToken ct - ⚠️ Missing
→ SUGGESTION (🟢).WithName("CreateCustomer")
Reference: ADR-0014 (Minimal API Endpoints), ADR-0005 (Requester/Notifier)
Step 7: Check Result<T> Error Handling (🔴 CRITICAL)
Use: checklists/06-result-error-handling.md
Check error handling:
- ✅
returnsCustomer.Create()Result<Customer> - ✅ Validation failures return
Result.Failure("error message") - ❌
in domain method → WRONG (ADR-0002 violation)throw new ValidationException()
Fix: Replace exception with
Result<T>.
Reference: ADR-0002 (Result Pattern for Error Handling)
Step 8: Generate Review Summary
Use: templates/review-summary-template.md
Create summary with:
- Issues Found: 🔴 2, 🟡 1, 🟢 1
- Top 3 Priorities: DbContext in Application (ADR-0004), Exception for business rule (ADR-0002), Missing endpoint name (🟢)
- Architecture Compliance: ⚠️ (critical issues present)
- ADRs Referenced: ADR-0001, ADR-0002, ADR-0004, ADR-0005, ADR-0008, ADR-0009, ADR-0011, ADR-0012, ADR-0014
Integration with Architectural Decision Records (ADRs)
This skill references 20 Architectural Decision Records (ADRs) located in
docs/ADR/. Each ADR documents a key architectural decision with context, rationale, and consequences.
How to Use ADRs in Reviews
- Identify the pattern: Determine which architectural pattern is involved (e.g., layer boundaries, CQRS, Result<T>)
- Find the ADR: Use docs/adr-quick-reference.md to locate the relevant ADR
- Reference in feedback: Cite the ADR number and title in review comments (e.g., "ADR-0001: Clean/Onion Architecture")
- Explain the impact: Use the ADR's rationale to explain why the violation matters
Key ADRs by Category
Core Architecture:
- ADR-0001: Clean/Onion Architecture with Strict Layer Boundaries
- ADR-0003: Modular Monolith Architecture
Domain & Data:
- ADR-0012: Domain Logic Encapsulation in Domain Layer
- ADR-0008: Typed Entity IDs using Source Generators
- ADR-0007: Entity Framework Core with Code-First Migrations
Application Layer:
- ADR-0011: Application Logic in Commands & Queries
- ADR-0009: FluentValidation Strategy
- ADR-0010: Mapster for Object Mapping
Error Handling:
- ADR-0002: Result Pattern for Error Handling
Presentation & API:
- ADR-0014: Minimal API Endpoints with DTO Exposure
- ADR-0005: Requester/Notifier (Mediator) Pattern
Infrastructure:
- ADR-0004: Repository Pattern with Decorator Behaviors
- ADR-0019: Specification Pattern for Repository Queries
See docs/adr-quick-reference.md for complete list with one-paragraph summaries.
Common Violation Patterns
🔴 CRITICAL: Domain → Application Dependency
Symptom: Domain layer references Application types (commands, queries, handlers)
// WRONG: Domain references Application namespace MyApp.Domain.CustomerAggregate; using MyApp.Application.Commands; // ❌ Domain → Application dependency public class Customer : AggregateRoot<CustomerId> { public CustomerCreatedCommand ToCommand() // ❌ Domain knows about Application { return new CustomerCreatedCommand(this.FirstName, this.LastName); } }
Why Critical: Violates ADR-0001 (Clean/Onion Architecture). Domain must be pure business logic with ZERO external dependencies.
Fix: Remove Application reference. Application layer creates commands from domain entities, not vice versa.
Reference: examples/layer-violations.md
🔴 CRITICAL: Application → Infrastructure (DbContext)
Symptom: Application handlers inject DbContext directly
// WRONG: Application uses DbContext namespace MyApp.Application.Commands; using MyApp.Infrastructure.EntityFramework; // ❌ Application → Infrastructure dependency public class CustomerCreateCommandHandler { private readonly CoreModuleDbContext context; // ❌ Direct DbContext usage public async Task<Result<CustomerId>> Handle(CustomerCreateCommand request, CancellationToken ct) { var customer = Customer.Create(...); this.context.Customers.Add(customer); // ❌ Application knows about EF Core await this.context.SaveChangesAsync(ct); } }
Why Critical: Violates ADR-0001 (layer boundaries) and ADR-0004 (repository pattern). Application layer cannot reference Infrastructure.
Fix: Use
IGenericRepository<Customer> abstraction.
Reference: examples/layer-violations.md, checklists/04-repository-data-access.md
🔴 CRITICAL: Exceptions for Business Rules
Symptom: Domain methods throw exceptions for validation failures
// WRONG: Exception for business rule public static Customer Create(string name, string email) { if (string.IsNullOrWhiteSpace(name)) { throw new ValidationException("Name is required"); // ❌ Exception for expected failure } return new Customer(name, email); }
Why Critical: Violates ADR-0002 (Result Pattern). Exceptions should only be used for truly exceptional cases, not expected failures.
Fix: Return
Result<Customer> instead.
Reference: examples/result-pattern-examples.md
🟡 IMPORTANT: CQRS Naming Violations
Symptom: Commands/queries not following naming conventions
// WRONG: Poor naming public sealed record CreateCustomerRequest(...) : IRequest<Result<CustomerId>>; // ❌ "Request" suffix public sealed record GetCustomer(...) : IRequest<Result<CustomerModel>>; // ❌ Missing "Query" suffix
Why Important: Violates ADR-0011 (CQRS patterns). Inconsistent naming makes codebase harder to navigate.
Fix: Use
[Entity][Action]Command and [Entity][Action]Query patterns.
Reference: checklists/03-cqrs-patterns.md
🟡 IMPORTANT: N+1 Query Problem
Symptom: Missing .Include() causes multiple database round-trips
// WRONG: N+1 query problem var customers = await repository.FindAllAsync(cancellationToken: ct); foreach (var customer in customers) { // Each iteration triggers a separate query for addresses! var addresses = customer.Addresses.ToList(); }
Why Important: Performance issue. Can cause significant slowdowns with large datasets.
Fix: Use eager loading with specifications.
Reference: checklists/04-repository-data-access.md
Success Criteria for Architecture Reviews
Code passes architectural review when:
- ✅ No layer boundary violations: Dependencies flow inward only
- ✅ Domain layer is pure: ZERO external dependencies (only bITdevKit domain abstractions)
- ✅ No circular module references: Modules are self-contained
- ✅ Repository abstractions used: Application uses
, not DbContextIGenericRepository<T> - ✅ Result<T> pattern enforced: Domain methods return Result for failures, not exceptions
- ✅ Aggregates properly encapsulated: Private setters, change methods, factory methods
- ✅ CQRS naming consistent: Commands/queries follow
pattern[Entity][Action]Command/Query - ✅ Endpoints are thin adapters: No business logic in Presentation layer
- ✅ IRequester pattern used: Endpoints delegate to Application via
IRequester.SendAsync() - ✅ No N+1 query problems: Proper eager loading with .Include() or specifications
- ✅ CancellationToken propagated: All async methods accept and pass CancellationToken
- ✅ Test independence: No shared mutable state between tests
Tips for Effective Architecture Reviews
Do
- Start with layer boundaries: Verify dependencies flow inward before checking patterns
- Reference ADRs: Always cite the relevant ADR number and title in feedback
- Provide examples: Show WRONG vs CORRECT code, not just abstract explanations
- Explain impact: Don't just say "this violates ADR-0001", explain why it matters
- Use checklists systematically: Work through checklists sequentially to avoid missing issues
- Distinguish CRITICAL vs IMPORTANT: Use emoji indicators (🔴🟡🟢) to prioritize feedback
- Test architecture rules: Suggest NetArchTest rules to prevent future violations
Don't
- Mix code quality and architecture: Focus on architectural concerns; use review-code skill for code quality
- Overwhelm with minor issues: Prioritize critical and important issues over suggestions
- Accept "it works" as justification: Architecture violations accumulate technical debt
- Skip positive feedback: Acknowledge good patterns when you see them
- Review without ADR context: Always consult ADRs to understand the rationale behind patterns
Related Skills
- review-code: Use for code quality, security, testing, performance, and documentation reviews
- domain-add-aggregate: Use to scaffold new domain aggregates following DDD patterns
- adr-writer: Use to create new ADRs for architectural decisions
References
- AGENTS.md: Project-specific architecture patterns and conventions
- .github/copilot-instructions.md: Detailed coding guidelines
- docs/ADR/: All 20 Architectural Decision Records
- bITdevKit Documentation: Official bITdevKit patterns and features
Version: 1.0 Last Updated: 2026-01-14 Maintainer: bITdevKit Team