using MeetingAssistant.Transcription; using MeetingAssistant.MeetingNotes; namespace MeetingAssistant.Recording; public interface ITranscriptStore { Task CreateSessionAsync(CancellationToken cancellationToken); Task CreateSessionAsync( MeetingAssistantOptions options, DateTimeOffset startedAt, CancellationToken cancellationToken); Task AppendAsync(TranscriptSession session, TranscriptionSegment segment, CancellationToken cancellationToken) { return AppendLineAndDiscardReferenceAsync( session, TranscriptLineFormatter.Format(segment).Line, cancellationToken); } private async Task AppendLineAndDiscardReferenceAsync( TranscriptSession session, string line, CancellationToken cancellationToken) { _ = await AppendLineAsync(session, line, cancellationToken); } Task AppendLineAsync( TranscriptSession session, string line, CancellationToken cancellationToken); Task ReplaceLineAsync( TranscriptSession session, TranscriptLineReference lineReference, string replacementLine, CancellationToken cancellationToken); Task ReplaceAsync( TranscriptSession session, IReadOnlyList replacementSegments, CancellationToken cancellationToken) { return ReplaceLinesAsync( session, replacementSegments.Select(segment => TranscriptLineFormatter.Format(segment).Line).ToList(), cancellationToken); } Task ReplaceLinesAsync( TranscriptSession session, IReadOnlyList replacementLines, CancellationToken cancellationToken); Task UpdateMetadataAsync( TranscriptSession session, MeetingSessionArtifacts artifacts, MeetingNote meetingNote, CancellationToken cancellationToken); } public sealed record TranscriptSession(string TranscriptPath); public sealed record TranscriptLineReference(string TranscriptPath, int BodyLineIndex, string OriginalLine); public static class TranscriptLineFormatter { public static FormattedTranscriptLine Format(TranscriptionSegment segment) { var speaker = NormalizeSpeaker(segment.Speaker); if (segment.Kind == TranscriptionSegmentKind.Marker) { return new FormattedTranscriptLine(segment.Text, speaker); } return new FormattedTranscriptLine( $"[{segment.Start:hh\\:mm\\:ss}] {speaker}: {segment.Text}", speaker); } public static string FormatSegmentLine(TranscriptionSegment segment) { return Format(segment).Line; } public static string NormalizeSpeaker(string? speaker) { return string.IsNullOrWhiteSpace(speaker) ? "Unknown" : speaker; } } public sealed record FormattedTranscriptLine(string Line, string Speaker);