Add audit logging, processing stages, delete functionality, and bug fixes

- Add audit logging system for tracking CV uploads, processing, deletion,
  report views, and PDF exports for billing/reference purposes
- Add processing stage display on dashboard instead of generic "Processing"
- Add delete button for CV checks on dashboard
- Fix duplicate primary key error in CompanyCache (race condition)
- Fix DbContext concurrency in Dashboard (concurrent delete/load operations)
- Fix ProcessCVCheckJob to handle deleted records gracefully
- Fix duplicate flags in verification report by deduplicating on Title+Description
- Remove internal cache notes from verification results
- Add EF migrations for ProcessingStage and AuditLog table

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-20 20:58:12 +01:00
parent 652aa2e612
commit 0eee5473e4
21 changed files with 1559 additions and 123 deletions

View File

@@ -6,6 +6,7 @@ public sealed record CVCheckDto
public required string OriginalFileName { get; init; }
public required string Status { get; init; }
public int? VeracityScore { get; init; }
public string? ProcessingStage { get; init; }
public required DateTime CreatedAt { get; init; }
public DateTime? CompletedAt { get; init; }
}

View File

@@ -0,0 +1,18 @@
namespace TrueCV.Application.Interfaces;
public interface IAuditService
{
Task LogAsync(Guid userId, string action, string? entityType = null, Guid? entityId = null, string? details = null, string? ipAddress = null);
}
public static class AuditActions
{
public const string CVUploaded = "CV_UPLOADED";
public const string CVProcessed = "CV_PROCESSED";
public const string CVDeleted = "CV_DELETED";
public const string ReportViewed = "REPORT_VIEWED";
public const string ReportExported = "REPORT_EXPORTED";
public const string UserLogin = "USER_LOGIN";
public const string UserLogout = "USER_LOGOUT";
public const string UserRegistered = "USER_REGISTERED";
}

View File

@@ -10,4 +10,5 @@ public interface ICVCheckService
Task<CVCheckDto?> GetCheckForUserAsync(Guid id, Guid userId);
Task<List<CVCheckDto>> GetUserChecksAsync(Guid userId);
Task<VeracityReport?> GetReportAsync(Guid checkId, Guid userId);
Task<bool> DeleteCheckAsync(Guid checkId, Guid userId);
}