This is the initial commit for the CODEX_ADK project, a full-stack AI agent management platform featuring: BACKEND (ASP.NET Core 8.0): - CQRS architecture with 6 commands and 7 queries - 16 API endpoints (all working and tested) - PostgreSQL database with 5 entities - AES-256 encryption for API keys - FluentValidation on all commands - Rate limiting and CORS configured - OpenAPI/Swagger documentation - Docker Compose setup (PostgreSQL + Ollama) FRONTEND (Flutter 3.x): - Dark theme with Svrnty branding - Collapsible sidebar navigation - CQRS API client with Result<T> error handling - Type-safe endpoints from OpenAPI schema - Multi-platform support (Web, iOS, Android, macOS, Linux, Windows) DOCUMENTATION: - Comprehensive API reference - Architecture documentation - Development guidelines for Claude Code - API integration guides - context-claude.md project overview Status: Backend ready (Grade A-), Frontend integration pending 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
65 lines
1.9 KiB
C#
65 lines
1.9 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// Creates a new conversation for grouping related messages
|
|
/// </summary>
|
|
public record CreateConversationCommand
|
|
{
|
|
/// <summary>Conversation title</summary>
|
|
public string Title { get; init; } = string.Empty;
|
|
|
|
/// <summary>Optional summary or description</summary>
|
|
public string? Summary { get; init; }
|
|
}
|
|
|
|
public class CreateConversationCommandHandler : ICommandHandler<CreateConversationCommand, Guid>
|
|
{
|
|
private readonly CodexDbContext _dbContext;
|
|
|
|
public CreateConversationCommandHandler(CodexDbContext dbContext)
|
|
{
|
|
_dbContext = dbContext;
|
|
}
|
|
|
|
public async Task<Guid> 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<CreateConversationCommand>
|
|
{
|
|
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));
|
|
}
|
|
}
|