feat: add repository pattern validation (v0.5.0)

Add comprehensive Repository Pattern validation to detect violations
and ensure proper domain-infrastructure separation.

Features:
- ORM type detection in repository interfaces (25+ patterns)
- Concrete repository usage detection in use cases
- Repository instantiation detection (new Repository())
- Domain language validation for repository methods
- Smart violation reporting with fix suggestions

Tests:
- 31 new tests for repository pattern detection
- 292 total tests passing (100% pass rate)
- 96.77% statement coverage, 83.82% branch coverage

Examples:
- 8 example files (4 bad patterns, 4 good patterns)
- Demonstrates Clean Architecture and SOLID principles
This commit is contained in:
imfozilbek
2025-11-24 20:11:33 +05:00
parent 3fecc98676
commit 0534fdf1bd
23 changed files with 2149 additions and 2 deletions

View File

@@ -0,0 +1,81 @@
/**
* ✅ GOOD EXAMPLE: Domain language in repository
*
* Repository interface uses domain-driven method names that reflect business operations.
* Method names are self-documenting and align with ubiquitous language.
*/
interface IUserRepository {
findById(id: UserId): Promise<User | null>
findByEmail(email: Email): Promise<User | null>
findActiveUsers(): Promise<User[]>
save(user: User): Promise<void>
delete(id: UserId): Promise<void>
search(criteria: UserSearchCriteria): Promise<User[]>
countActiveUsers(): Promise<number>
existsByEmail(email: Email): Promise<boolean>
}
class UserId {
constructor(private readonly value: string) {}
getValue(): string {
return this.value
}
}
class Email {
constructor(private readonly value: string) {}
getValue(): string {
return this.value
}
}
class UserSearchCriteria {
constructor(
public readonly isActive?: boolean,
public readonly registeredAfter?: Date,
public readonly department?: string,
) {}
}
class User {
constructor(
private readonly id: UserId,
private email: Email,
private name: string,
private isActive: boolean,
) {}
getId(): UserId {
return this.id
}
getEmail(): Email {
return this.email
}
getName(): string {
return this.name
}
isUserActive(): boolean {
return this.isActive
}
activate(): void {
this.isActive = true
}
deactivate(): void {
this.isActive = false
}
}