using System.Linq.Expressions; namespace DigitalData.EmailProfiler.Application.Interfaces.Repositories; /// /// Base repository interface for common CRUD operations with AutoMapper support. /// Changes are automatically saved after each operation - no explicit SaveChanges needed. /// /// Entity type public interface IRepository where TEntity : class { // ==================== QUERY OPERATIONS ==================== Task GetByIdAsync(int id, CancellationToken cancellationToken = default); Task> GetAllAsync(CancellationToken cancellationToken = default); Task> FindAsync(Expression> predicate, CancellationToken cancellationToken = default); Task FirstOrDefaultAsync(Expression> predicate, CancellationToken cancellationToken = default); Task ExistsAsync(Expression> predicate, CancellationToken cancellationToken = default); Task CountAsync(Expression>? predicate = null, CancellationToken cancellationToken = default); // ==================== CREATE OPERATIONS ==================== /// /// Create entity from DTO using AutoMapper and save immediately. /// /// Created entity with ID populated Task CreateAsync(TDto dto, CancellationToken cancellationToken = default) where TDto : class; // ==================== UPDATE OPERATIONS ==================== /// /// Update ALL entities matching expression using DTO via AutoMapper. /// WARNING: This can update multiple records. Use UpdateSingleAsync for single-record updates. /// /// Number of entities updated Task UpdateAsync(Expression> predicate, TDto dto, CancellationToken cancellationToken = default) where TDto : class; /// /// Update SINGLE entity matching expression using DTO via AutoMapper. /// SAFETY: Throws exception if zero or multiple entities match the predicate. /// /// Thrown when zero or multiple entities match Task UpdateSingleAsync(Expression> predicate, TDto dto, CancellationToken cancellationToken = default) where TDto : class; // ==================== DELETE OPERATIONS ==================== /// /// Delete ALL entities matching expression. /// WARNING: This can delete multiple records. Use DeleteSingleAsync for single-record deletes. /// /// Number of entities deleted Task DeleteAsync(Expression> predicate, CancellationToken cancellationToken = default); /// /// Delete SINGLE entity matching expression. /// SAFETY: Throws exception if zero or multiple entities match the predicate. /// /// Thrown when zero or multiple entities match Task DeleteSingleAsync(Expression> predicate, CancellationToken cancellationToken = default); }