/** * ✅ GOOD EXAMPLE: Clean repository interface * * Repository interface uses only domain types, keeping it persistence-agnostic. * ORM implementation details stay in infrastructure layer. */ interface IUserRepository { findById(id: UserId): Promise findByEmail(email: Email): Promise save(user: User): Promise delete(id: UserId): Promise findAll(criteria: UserSearchCriteria): Promise } 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, ) {} } class User { constructor( private readonly id: UserId, private email: Email, private name: string, ) {} getId(): UserId { return this.id } getEmail(): Email { return this.email } getName(): string { return this.name } }