Public Access
Make meeting lifecycle stateful
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace MeetingAssistant.Speakers;
|
||||
|
||||
@@ -8,8 +9,6 @@ public sealed class SpeakerIdentity
|
||||
|
||||
public string? CanonicalName { get; set; }
|
||||
|
||||
public int TranscriptionCount { get; set; }
|
||||
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
|
||||
public DateTimeOffset UpdatedAt { get; set; }
|
||||
@@ -20,6 +19,11 @@ public sealed class SpeakerIdentity
|
||||
|
||||
public List<SpeakerSnippet> Snippets { get; set; } = [];
|
||||
|
||||
public List<SpeakerIdentityReference> References { get; set; } = [];
|
||||
|
||||
[NotMapped]
|
||||
public int ReferenceCount => References.Count;
|
||||
|
||||
public string? GetDisplayName()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(CanonicalName))
|
||||
@@ -35,6 +39,65 @@ public sealed class SpeakerIdentity
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SpeakerIdentityReference
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public int SpeakerIdentityId { get; set; }
|
||||
|
||||
public SpeakerIdentity? SpeakerIdentity { get; set; }
|
||||
|
||||
public string MeetingNotePath { get; set; } = "";
|
||||
|
||||
public string TranscriptPath { get; set; } = "";
|
||||
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
}
|
||||
|
||||
public static class SpeakerIdentityReferences
|
||||
{
|
||||
public static SpeakerIdentityReference Create(
|
||||
string meetingNotePath,
|
||||
string transcriptPath,
|
||||
DateTimeOffset createdAt)
|
||||
{
|
||||
return new SpeakerIdentityReference
|
||||
{
|
||||
MeetingNotePath = meetingNotePath,
|
||||
TranscriptPath = transcriptPath,
|
||||
CreatedAt = createdAt
|
||||
};
|
||||
}
|
||||
|
||||
public static void AddIfMissing(
|
||||
SpeakerIdentity identity,
|
||||
SpeakerIdentityReference reference,
|
||||
DateTimeOffset? createdAt = null)
|
||||
{
|
||||
if (IsEmpty(reference) || identity.References.Any(existing => IsSame(existing, reference)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
identity.References.Add(Create(
|
||||
reference.MeetingNotePath,
|
||||
reference.TranscriptPath,
|
||||
createdAt ?? reference.CreatedAt));
|
||||
}
|
||||
|
||||
private static bool IsEmpty(SpeakerIdentityReference reference)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(reference.MeetingNotePath) &&
|
||||
string.IsNullOrWhiteSpace(reference.TranscriptPath);
|
||||
}
|
||||
|
||||
private static bool IsSame(SpeakerIdentityReference first, SpeakerIdentityReference second)
|
||||
{
|
||||
return string.Equals(first.MeetingNotePath, second.MeetingNotePath, StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(first.TranscriptPath, second.TranscriptPath, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SpeakerCandidateName
|
||||
{
|
||||
public int Id { get; set; }
|
||||
@@ -85,10 +148,15 @@ public sealed class SpeakerIdentityDbContext : DbContext
|
||||
|
||||
public DbSet<SpeakerSnippet> SpeakerSnippets => Set<SpeakerSnippet>();
|
||||
|
||||
public DbSet<SpeakerIdentityReference> SpeakerIdentityReferences => Set<SpeakerIdentityReference>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<SpeakerIdentity>(entity =>
|
||||
{
|
||||
entity.Property<int>("TranscriptionCount")
|
||||
.HasDefaultValue(0);
|
||||
|
||||
entity.HasMany(identity => identity.CandidateNames)
|
||||
.WithOne(candidate => candidate.SpeakerIdentity)
|
||||
.HasForeignKey(candidate => candidate.SpeakerIdentityId)
|
||||
@@ -103,6 +171,11 @@ public sealed class SpeakerIdentityDbContext : DbContext
|
||||
.WithOne(snippet => snippet.SpeakerIdentity)
|
||||
.HasForeignKey(snippet => snippet.SpeakerIdentityId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
entity.HasMany(identity => identity.References)
|
||||
.WithOne(reference => reference.SpeakerIdentity)
|
||||
.HasForeignKey(reference => reference.SpeakerIdentityId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<SpeakerCandidateName>()
|
||||
@@ -112,5 +185,9 @@ public sealed class SpeakerIdentityDbContext : DbContext
|
||||
modelBuilder.Entity<SpeakerAlias>()
|
||||
.HasIndex(alias => new { alias.SpeakerIdentityId, alias.Name })
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<SpeakerIdentityReference>()
|
||||
.HasIndex(reference => new { reference.SpeakerIdentityId, reference.MeetingNotePath, reference.TranscriptPath })
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user