feat: add aggregate boundary validation (v0.7.0)

Implement DDD aggregate boundary validation to detect and prevent direct
entity references across aggregate boundaries.

Features:
- Detect direct entity imports between aggregates
- Allow only ID or Value Object references
- Support multiple folder structures (domain/aggregates/*, domain/*, domain/entities/*)
- Filter allowed imports (value-objects, events, repositories, services)
- Critical severity level for violations
- 41 comprehensive tests with 92.55% coverage
- CLI output with detailed suggestions
- Examples of good and bad patterns

Breaking changes: None
Backwards compatible: Yes
This commit is contained in:
imfozilbek
2025-11-24 23:54:16 +05:00
parent 83b5dccee4
commit c75738ba51
16 changed files with 1297 additions and 12 deletions

View File

@@ -0,0 +1,45 @@
import { AggregateBoundaryViolation } from "../value-objects/AggregateBoundaryViolation"
/**
* Interface for detecting aggregate boundary violations in DDD
*
* Aggregate boundary violations occur when an entity from one aggregate
* directly references an entity from another aggregate. In DDD, aggregates
* should reference each other only by ID or Value Objects to maintain
* loose coupling and independence.
*/
export interface IAggregateBoundaryDetector {
/**
* Detects aggregate boundary violations in the given code
*
* Analyzes import statements to identify direct entity references
* across aggregate boundaries.
*
* @param code - Source code to analyze
* @param filePath - Path to the file being analyzed
* @param layer - The architectural layer of the file (should be 'domain')
* @returns Array of detected aggregate boundary violations
*/
detectViolations(
code: string,
filePath: string,
layer: string | undefined,
): AggregateBoundaryViolation[]
/**
* Checks if a file path belongs to an aggregate
*
* @param filePath - The file path to check
* @returns The aggregate name if found, undefined otherwise
*/
extractAggregateFromPath(filePath: string): string | undefined
/**
* Checks if an import path references an entity from another aggregate
*
* @param importPath - The import path to analyze
* @param currentAggregate - The aggregate of the current file
* @returns True if the import crosses aggregate boundaries inappropriately
*/
isAggregateBoundaryViolation(importPath: string, currentAggregate: string): boolean
}