Files
ColaFlow/docs/plans/sprint_2_story_1_task_4.md
Yaojia Wang ebb56cc9f8 feat(backend): Create Sprint 2 backend Stories and Tasks
Created detailed implementation plans for Sprint 2 backend work:

Story 1: Audit Log Foundation (Phase 1)
- Task 1: Design AuditLog database schema and create migration
- Task 2: Create AuditLog entity and Repository
- Task 3: Implement EF Core SaveChangesInterceptor
- Task 4: Write unit tests for audit logging
- Task 5: Integrate with ProjectManagement Module

Story 2: Audit Log Core Features (Phase 2)
- Task 1: Implement Changed Fields Detection (JSON Diff)
- Task 2: Integrate User Context Tracking
- Task 3: Add Multi-Tenant Isolation
- Task 4: Implement Audit Query API
- Task 5: Write Integration Tests

Story 3: Sprint Management Module
- Task 1: Create Sprint Aggregate Root and Domain Events
- Task 2: Implement Sprint Repository and EF Core Configuration
- Task 3: Create CQRS Commands and Queries
- Task 4: Implement Burndown Chart Calculation
- Task 5: Add SignalR Real-Time Notifications
- Task 6: Write Integration Tests

Total: 3 Stories, 16 Tasks, 24 Story Points (8+8+8)
Estimated Duration: 10-12 days

All tasks include:
- Detailed technical implementation guidance
- Code examples and file paths
- Testing requirements (>= 90% coverage)
- Performance benchmarks (< 5ms audit overhead)
- Multi-tenant security validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 22:56:31 +01:00

4.8 KiB

task_id, story, status, estimated_hours, created_date, assignee
task_id story status estimated_hours created_date assignee
sprint_2_story_1_task_4 sprint_2_story_1 not_started 4 2025-11-05 Backend Team

Task 4: Write Unit Tests for Audit Logging

Story: Story 1 - Audit Log Foundation (Phase 1) Estimated: 4 hours

Description

Create comprehensive unit tests for audit logging functionality to ensure correctness, multi-tenant isolation, and performance. Target >= 90% code coverage.

Acceptance Criteria

  • Unit tests for AuditLogRepository created
  • Unit tests for AuditLogInterceptor created
  • Test coverage >= 90%
  • All tests passing
  • Performance tests verify < 5ms overhead

Implementation Details

Files to Create:

  1. Repository Tests: colaflow-api/tests/ColaFlow.Infrastructure.Tests/Repositories/AuditLogRepositoryTests.cs
public class AuditLogRepositoryTests
{
    [Fact]
    public async Task GetByEntityAsync_ShouldReturnAuditLogs_WhenEntityExists()
    {
        // Arrange
        var tenantId = Guid.NewGuid();
        var entityId = Guid.NewGuid();
        var options = CreateDbContextOptions();

        await using var context = new ColaFlowDbContext(options);
        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(t => t.TenantId).Returns(tenantId);

        var auditLog = new AuditLog
        {
            Id = Guid.NewGuid(),
            TenantId = tenantId,
            EntityType = "Project",
            EntityId = entityId,
            Action = AuditAction.Create,
            Timestamp = DateTime.UtcNow
        };
        context.AuditLogs.Add(auditLog);
        await context.SaveChangesAsync();

        var repository = new AuditLogRepository(context, tenantContext.Object);

        // Act
        var result = await repository.GetByEntityAsync("Project", entityId);

        // Assert
        Assert.Single(result);
        Assert.Equal(entityId, result[0].EntityId);
    }

    [Fact]
    public async Task GetByEntityAsync_ShouldNotReturnOtherTenantsLogs()
    {
        // Test multi-tenant isolation
        // ...
    }
}
  1. Interceptor Tests: colaflow-api/tests/ColaFlow.Infrastructure.Tests/Interceptors/AuditLogInterceptorTests.cs
public class AuditLogInterceptorTests
{
    [Fact]
    public async Task SavingChangesAsync_ShouldCreateAuditLog_WhenEntityCreated()
    {
        // Arrange
        var tenantId = Guid.NewGuid();
        var userId = Guid.NewGuid();
        var options = CreateDbContextOptions();

        var tenantContext = new Mock<ITenantContext>();
        tenantContext.Setup(t => t.TenantId).Returns(tenantId);

        var httpContextAccessor = CreateMockHttpContextAccessor(userId);

        var interceptor = new AuditLogInterceptor(tenantContext.Object, httpContextAccessor);

        await using var context = new ColaFlowDbContext(options);
        context.AddInterceptors(interceptor);

        var project = new Project
        {
            Id = Guid.NewGuid(),
            TenantId = tenantId,
            Name = "Test Project",
            Key = "TEST"
        };

        // Act
        context.Projects.Add(project);
        await context.SaveChangesAsync();

        // Assert
        var auditLogs = await context.AuditLogs.ToListAsync();
        Assert.Single(auditLogs);
        Assert.Equal("Project", auditLogs[0].EntityType);
        Assert.Equal(AuditAction.Create, auditLogs[0].Action);
        Assert.Equal(userId, auditLogs[0].UserId);
    }

    [Fact]
    public async Task SavingChangesAsync_ShouldCaptureOldAndNewValues_WhenEntityUpdated()
    {
        // Test old vs new values capture
        // ...
    }

    [Fact]
    public async Task SavingChangesAsync_ShouldHaveLowPerformanceOverhead()
    {
        // Arrange
        var stopwatch = Stopwatch.StartNew();

        // Act
        // Create 100 entities and measure time
        for (int i = 0; i < 100; i++)
        {
            context.Projects.Add(new Project { /* ... */ });
            await context.SaveChangesAsync();
        }

        stopwatch.Stop();

        // Assert
        var avgTime = stopwatch.ElapsedMilliseconds / 100.0;
        Assert.True(avgTime < 5, $"Average time {avgTime}ms exceeds 5ms target");
    }
}

Test Cases to Cover:

  1. Create operation audit logging
  2. Update operation audit logging
  3. Delete operation audit logging
  4. Multi-tenant isolation (audit logs filtered by TenantId)
  5. UserId capture from HTTP context
  6. Old/New values serialization
  7. Performance overhead < 5ms
  8. Null userId handling (system operations)

Technical Notes

  • Use in-memory database for fast unit tests
  • Mock ITenantContext and IHttpContextAccessor
  • Use Stopwatch for performance benchmarks
  • Target >= 90% code coverage

Testing

  • Run: dotnet test --filter "FullyQualifiedName~AuditLog"
  • Verify all tests pass
  • Check code coverage report

Created: 2025-11-05 by Backend Agent