--- task_id: sprint_2_story_1_task_2 story: sprint_2_story_1 status: in_progress estimated_hours: 4 created_date: 2025-11-05 start_date: 2025-11-05 assignee: Backend Team --- # Task 2: Create AuditLog Entity and Repository **Story**: Story 1 - Audit Log Foundation (Phase 1) **Estimated**: 4 hours ## Description Create the AuditLog domain entity and repository pattern implementation to support CRUD operations and querying audit logs with proper multi-tenant isolation. ## Acceptance Criteria - [ ] AuditLog entity created in Domain layer - [ ] IAuditLogRepository interface defined - [ ] AuditLogRepository implementation with EF Core - [ ] Multi-tenant query filtering applied - [ ] Unit tests for repository methods ## Implementation Details **Files to Create**: 1. **Domain Entity**: `colaflow-api/src/ColaFlow.Domain/Entities/AuditLog.cs` ```csharp public class AuditLog { public Guid Id { get; set; } public Guid TenantId { get; set; } public string EntityType { get; set; } = string.Empty; public Guid EntityId { get; set; } public AuditAction Action { get; set; } // Enum: Create, Update, Delete public Guid? UserId { get; set; } public DateTime Timestamp { get; set; } public string? OldValues { get; set; } // JSONB stored as string public string? NewValues { get; set; } // JSONB stored as string } public enum AuditAction { Create, Update, Delete } ``` 2. **Repository Interface**: `colaflow-api/src/ColaFlow.Domain/Repositories/IAuditLogRepository.cs` ```csharp public interface IAuditLogRepository { Task GetByIdAsync(Guid id); Task> GetByEntityAsync(string entityType, Guid entityId); Task AddAsync(AuditLog auditLog); Task SaveChangesAsync(CancellationToken cancellationToken = default); } ``` 3. **Repository Implementation**: `colaflow-api/src/ColaFlow.Infrastructure/Repositories/AuditLogRepository.cs` ```csharp public class AuditLogRepository : IAuditLogRepository { private readonly ColaFlowDbContext _context; private readonly ITenantContext _tenantContext; public AuditLogRepository(ColaFlowDbContext context, ITenantContext tenantContext) { _context = context; _tenantContext = tenantContext; } public async Task> GetByEntityAsync(string entityType, Guid entityId) { var tenantId = _tenantContext.TenantId; return await _context.AuditLogs .Where(a => a.TenantId == tenantId && a.EntityType == entityType && a.EntityId == entityId) .OrderByDescending(a => a.Timestamp) .ToListAsync(); } // ... other methods } ``` 4. **EF Core Configuration**: `colaflow-api/src/ColaFlow.Infrastructure/Data/Configurations/AuditLogConfiguration.cs` ```csharp public class AuditLogConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ToTable("AuditLogs"); builder.HasKey(a => a.Id); builder.Property(a => a.EntityType).IsRequired().HasMaxLength(100); builder.Property(a => a.Action).IsRequired(); builder.Property(a => a.Timestamp).IsRequired(); // JSONB columns builder.Property(a => a.OldValues).HasColumnType("jsonb"); builder.Property(a => a.NewValues).HasColumnType("jsonb"); // Multi-tenant global query filter builder.HasQueryFilter(a => a.TenantId == Guid.Empty); // Will be replaced by TenantContext } } ``` ## Testing - Unit tests for repository methods - Verify multi-tenant filtering works - Test JSONB serialization/deserialization --- **Created**: 2025-11-05 by Backend Agent