using Books.Api.EventFlow.ReadModels; using Dapper; using Npgsql; namespace Books.Api.EventFlow.Repositories; public class AttachmentRepository(NpgsqlDataSource dataSource) : IAttachmentRepository { private const string SelectColumns = """ aggregate_id AS Id, company_id AS CompanyId, file_name AS FileName, original_file_name AS OriginalFileName, content_type AS ContentType, file_size AS FileSize, storage_path AS StoragePath, uploaded_by AS UploadedBy, uploaded_at AS UploadedAt, draft_id AS DraftId, transaction_id AS TransactionId, retention_end_date AS RetentionEndDate, is_deleted AS IsDeleted """; public async Task GetByIdAsync(string id, CancellationToken cancellationToken = default) { await using var connection = await dataSource.OpenConnectionAsync(cancellationToken); var sql = $""" SELECT {SelectColumns} FROM attachment_read_models WHERE aggregate_id = @Id AND is_deleted = FALSE """; return await connection.QuerySingleOrDefaultAsync(sql, new { Id = id }); } public async Task GetByStoragePathAsync(string storagePath, CancellationToken cancellationToken = default) { await using var connection = await dataSource.OpenConnectionAsync(cancellationToken); var sql = $""" SELECT {SelectColumns} FROM attachment_read_models WHERE storage_path = @StoragePath AND is_deleted = FALSE """; return await connection.QuerySingleOrDefaultAsync(sql, new { StoragePath = storagePath }); } public async Task> GetByCompanyIdAsync(string companyId, CancellationToken cancellationToken = default) { await using var connection = await dataSource.OpenConnectionAsync(cancellationToken); var sql = $""" SELECT {SelectColumns} FROM attachment_read_models WHERE company_id = @CompanyId AND is_deleted = FALSE ORDER BY uploaded_at DESC """; var result = await connection.QueryAsync(sql, new { CompanyId = companyId }); return result.ToList(); } public async Task> GetByDraftIdAsync(string draftId, CancellationToken cancellationToken = default) { await using var connection = await dataSource.OpenConnectionAsync(cancellationToken); var sql = $""" SELECT {SelectColumns} FROM attachment_read_models WHERE draft_id = @DraftId AND is_deleted = FALSE ORDER BY uploaded_at ASC """; var result = await connection.QueryAsync(sql, new { DraftId = draftId }); return result.ToList(); } public async Task> GetByTransactionIdAsync(string transactionId, CancellationToken cancellationToken = default) { await using var connection = await dataSource.OpenConnectionAsync(cancellationToken); var sql = $""" SELECT {SelectColumns} FROM attachment_read_models WHERE transaction_id = @TransactionId AND is_deleted = FALSE ORDER BY uploaded_at ASC """; var result = await connection.QueryAsync(sql, new { TransactionId = transactionId }); return result.ToList(); } public async Task> GetByIdsAsync(IEnumerable ids, CancellationToken cancellationToken = default) { await using var connection = await dataSource.OpenConnectionAsync(cancellationToken); var sql = $""" SELECT {SelectColumns} FROM attachment_read_models WHERE aggregate_id = ANY(@Ids) AND is_deleted = FALSE ORDER BY uploaded_at ASC """; var result = await connection.QueryAsync(sql, new { Ids = ids.ToArray() }); return result.ToList(); } }