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>
4.2 KiB
4.2 KiB
task_id, story, status, estimated_hours, created_date, assignee
| task_id | story | status | estimated_hours | created_date | assignee |
|---|---|---|---|---|---|
| sprint_2_story_2_task_2 | sprint_2_story_2 | not_started | 3 | 2025-11-05 | Backend Team |
Task 2: Integrate User Context Tracking
Story: Story 2 - Audit Log Core Features (Phase 2) Estimated: 3 hours
Description
Enhance audit logging to automatically capture the current user (UserId) from HTTP context for every operation. This provides accountability and traceability.
Acceptance Criteria
- UserId automatically captured from JWT token
- System operations (null user) handled correctly
- User information enriched in audit logs
- Integration tests verify user tracking
- Performance not impacted
Implementation Details
Already Implemented in Story 1!
The AuditLogInterceptor already captures UserId from HTTP context:
private Guid? GetCurrentUserId()
{
var userIdClaim = _httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier);
return userIdClaim != null ? Guid.Parse(userIdClaim.Value) : null;
}
This Task: Add User Information Enrichment
- Add User Navigation Property:
colaflow-api/src/ColaFlow.Domain/Entities/AuditLog.cs
public class AuditLog
{
// ... existing properties ...
public Guid? UserId { get; set; }
// Navigation property
public User? User { get; set; }
}
- Update EF Configuration:
colaflow-api/src/ColaFlow.Infrastructure/Data/Configurations/AuditLogConfiguration.cs
public void Configure(EntityTypeBuilder<AuditLog> builder)
{
// ... existing configuration ...
// User relationship (optional foreign key)
builder.HasOne(a => a.User)
.WithMany()
.HasForeignKey(a => a.UserId)
.OnDelete(DeleteBehavior.SetNull); // Don't delete audit logs when user is deleted
}
- Enrich Query Results:
colaflow-api/src/ColaFlow.Infrastructure/Repositories/AuditLogRepository.cs
public async Task<List<AuditLog>> GetByEntityAsync(string entityType, Guid entityId)
{
var tenantId = _tenantContext.TenantId;
return await _context.AuditLogs
.Include(a => a.User) // Include user info
.Where(a => a.TenantId == tenantId && a.EntityType == entityType && a.EntityId == entityId)
.OrderByDescending(a => a.Timestamp)
.ToListAsync();
}
- Handle System Operations: Update
AuditLogInterceptorto handle null users gracefully:
private Guid? GetCurrentUserId()
{
try
{
var userIdClaim = _httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier);
if (userIdClaim != null && Guid.TryParse(userIdClaim.Value, out var userId))
{
return userId;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to get current user ID for audit log");
}
return null; // System operation or anonymous
}
Example Audit Log with User Info:
{
"Id": "abc-123",
"EntityType": "Project",
"Action": "Update",
"UserId": "user-456",
"User": {
"Id": "user-456",
"UserName": "john.doe@example.com",
"DisplayName": "John Doe"
},
"Timestamp": "2025-11-05T10:30:00Z",
"ChangedFields": {
"Title": { "OldValue": "Old", "NewValue": "New" }
}
}
Technical Notes
- Use
OnDelete(DeleteBehavior.SetNull)to preserve audit logs when users are deleted - Handle null users gracefully (system operations, background jobs)
- Use
Include(a => a.User)for enriched query results - Consider caching user info for performance (future optimization)
Testing
Integration Tests:
[Fact]
public async Task CreateProject_ShouldCaptureCurrentUser()
{
// Arrange
var userId = Guid.NewGuid();
SetCurrentUser(userId); // Helper to set HTTP context user
// Act
var projectId = await Mediator.Send(new CreateProjectCommand { /* ... */ });
// Assert
var auditLog = await Context.AuditLogs
.Include(a => a.User)
.FirstAsync(a => a.EntityId == projectId);
Assert.Equal(userId, auditLog.UserId);
Assert.NotNull(auditLog.User);
}
[Fact]
public async Task SystemOperation_ShouldHaveNullUser()
{
// Test background job or system operation
// ...
}
Created: 2025-11-05 by Backend Agent