using System; using System.Threading; using System.Threading.Tasks; using Codex.Dal; using Codex.Dal.Entities; using FluentValidation; using OpenHarbor.CQRS.Abstractions; namespace Codex.CQRS.Commands; /// /// Creates a new conversation for grouping related messages /// public record CreateConversationCommand { /// Conversation title public string Title { get; init; } = string.Empty; /// Optional summary or description public string? Summary { get; init; } } public class CreateConversationCommandHandler : ICommandHandler { private readonly CodexDbContext _dbContext; public CreateConversationCommandHandler(CodexDbContext dbContext) { _dbContext = dbContext; } public async Task HandleAsync(CreateConversationCommand command, CancellationToken cancellationToken = default) { var conversation = new Conversation { Id = Guid.NewGuid(), Title = command.Title, Summary = command.Summary, StartedAt = DateTime.UtcNow, LastMessageAt = DateTime.UtcNow, IsActive = true, MessageCount = 0 }; _dbContext.Conversations.Add(conversation); await _dbContext.SaveChangesAsync(cancellationToken); return conversation.Id; } } public class CreateConversationCommandValidator : AbstractValidator { public CreateConversationCommandValidator() { RuleFor(x => x.Title) .NotEmpty().WithMessage("Title is required") .MaximumLength(500).WithMessage("Title cannot exceed 500 characters"); RuleFor(x => x.Summary) .MaximumLength(2000).WithMessage("Summary cannot exceed 2000 characters") .When(x => !string.IsNullOrEmpty(x.Summary)); } }