fa9046a03e
SharedKernel: - IAuditLog/AuditEvent — append-only audit contract any module writes through. - EditDistance (Levenshtein + normalized) — the north-star metric, available from day one; consumed at edit-and-approve in M5. Governance module (references SharedKernel only): - AuditEntry entity; internal GovernanceDbContext (schema "governance") + InitialGovernance migration; AuditLog implements IAuditLog. - GET /api/governance/audit — owner-only (ViewAuditLog), returns recent entries. Wiring (via the SharedKernel IAuditLog interface — no module references Governance): - OrgBoard records team.created, task.created, task.moved, task.assigned. - Identity records invitation.created, member.joined. Verified: build green; ArchitectureTests 8/8 (Governance references only SharedKernel; audit flows through the shared interface); IntegrationTests 20/20 — board flow now asserts task.created/task.moved appear in the audit log, plus EditDistance unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
28 lines
989 B
C#
28 lines
989 B
C#
using Microsoft.EntityFrameworkCore;
|
|
using TeamUp.Modules.Governance.Domain;
|
|
using TeamUp.SharedKernel.Persistence;
|
|
|
|
namespace TeamUp.Modules.Governance.Persistence;
|
|
|
|
internal sealed class GovernanceDbContext(DbContextOptions<GovernanceDbContext> options)
|
|
: DbContext(options), IModuleDbContext
|
|
{
|
|
public DbSet<AuditEntry> AuditEntries => Set<AuditEntry>();
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
modelBuilder.HasDefaultSchema("governance");
|
|
|
|
modelBuilder.Entity<AuditEntry>(entry =>
|
|
{
|
|
entry.ToTable("audit_entries");
|
|
entry.HasKey(a => a.Id);
|
|
entry.Property(a => a.Action).HasMaxLength(100).IsRequired();
|
|
entry.Property(a => a.EntityType).HasMaxLength(100).IsRequired();
|
|
entry.Property(a => a.Details).HasMaxLength(2000);
|
|
entry.HasIndex(a => a.OccurredAtUtc);
|
|
entry.HasIndex(a => new { a.EntityType, a.EntityId });
|
|
});
|
|
}
|
|
}
|