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>
This commit is contained in:
Yaojia Wang
2025-11-04 22:56:31 +01:00
parent d6cf86a4da
commit ebb56cc9f8
19 changed files with 4030 additions and 0 deletions

View File

@@ -0,0 +1,175 @@
---
task_id: sprint_2_story_1_task_4
story: sprint_2_story_1
status: not_started
estimated_hours: 4
created_date: 2025-11-05
assignee: 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`
```csharp
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
// ...
}
}
```
2. **Interceptor Tests**: `colaflow-api/tests/ColaFlow.Infrastructure.Tests/Interceptors/AuditLogInterceptorTests.cs`
```csharp
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