From 47550b9d176fee9e7d0b598391ef19143dde9de7 Mon Sep 17 00:00:00 2001 From: "Robert J. Good" Date: Sat, 29 Aug 2026 00:02:12 -0700 Subject: [PATCH 1/6] naming conventions change --- src/Core.Application/{Actor => Actors}/ActorDto.cs | 0 src/Core.Application/{Actor => Actors}/ActorGuard.cs | 0 src/Core.Application/{Actor => Actors}/CreateOurActorCommand.cs | 0 .../{Actor => Actors}/CreateOurActorCommandValidator.cs | 0 .../{Actor => Actors}/DeleteOurActorByOwnerIdCommand.cs | 0 .../{Actor => Actors}/DeleteOurActorByOwnerIdCommandValidator.cs | 0 src/Core.Application/{Actor => Actors}/DeleteOurActorCommand.cs | 0 .../{Actor => Actors}/DeleteOurActorCommandValidator.cs | 0 src/Core.Application/{Actor => Actors}/GetMyActorQuery.cs | 0 .../{Actor => Actors}/GetMyActorQueryValidator.cs | 0 .../{Actor => Actors}/GetOurActorChatSessionQuery.cs | 0 .../{Actor => Actors}/GetOurActorChatSessionQueryValidator.cs | 0 .../{Actor => Actors}/GetOurActorChatSessionsPaginatedQuery.cs | 0 .../GetOurActorChatSessionsPaginatedQueryValidator.cs | 0 .../{Actor => Actors}/GetOurActorChatSessionsQuery.cs | 0 .../{Actor => Actors}/GetOurActorChatSessionsQueryValidator.cs | 0 src/Core.Application/{Actor => Actors}/GetOurActorQuery.cs | 0 .../{Actor => Actors}/GetOurActorQueryValidator.cs | 0 src/Core.Application/{Actor => Actors}/GetOurActorsByNameQuery.cs | 0 .../{Actor => Actors}/GetOurActorsByNameQueryValidator.cs | 0 src/Core.Application/{Actor => Actors}/SaveMyActorCommand.cs | 0 .../{Actor => Actors}/SaveMyActorCommandValidator.cs | 0 src/Core.Application/{Chat => Chats}/ChatGuard.cs | 0 src/Core.Application/{Chat => Chats}/ChatMessageDto.cs | 0 src/Core.Application/{Chat => Chats}/ChatSessionDto.cs | 0 .../{Chat => Chats}/CreateMyChatMessageCommand.cs | 0 .../{Chat => Chats}/CreateMyChatMessageCommandValidator.cs | 0 .../{Chat => Chats}/CreateMyChatSessionCommand.cs | 0 .../{Chat => Chats}/CreateMyChatSessionCommandValidator.cs | 0 .../{Chat => Chats}/DeleteMyChatSessionCommand.cs | 0 .../{Chat => Chats}/DeleteMyChatSessionCommandValidator.cs | 0 src/Core.Application/{Chat => Chats}/GetMyChatMessageQuery.cs | 0 .../{Chat => Chats}/GetMyChatMessageQueryValidator.cs | 0 .../{Chat => Chats}/GetMyChatMessagesPaginatedQuery.cs | 0 .../{Chat => Chats}/GetMyChatMessagesPaginatedQueryValidator.cs | 0 .../{Chat => Chats}/GetMyChatSessionMessagesQuery.cs | 0 .../{Chat => Chats}/GetMyChatSessionMessagesQueryValidator.cs | 0 src/Core.Application/{Chat => Chats}/GetMyChatSessionQuery.cs | 0 .../{Chat => Chats}/GetMyChatSessionQueryValidator.cs | 0 .../{Chat => Chats}/GetMyChatSessionsPaginatedQuery.cs | 0 .../{Chat => Chats}/GetMyChatSessionsPaginatedQueryValidator.cs | 0 src/Core.Application/{Chat => Chats}/GetMyChatSessionsQuery.cs | 0 .../{Chat => Chats}/GetMyChatSessionsQueryValidator.cs | 0 src/Core.Application/{Chat => Chats}/PatchMyChatSessionCommand.cs | 0 .../{Chat => Chats}/PatchMyChatSessionCommandValidator.cs | 0 src/Core.Domain/{Actor => Actors}/ActorEntity.cs | 0 src/Core.Domain/{Chat => Chats}/ChatMessageEntity.cs | 0 src/Core.Domain/{Chat => Chats}/ChatMessageRoles.cs | 0 src/Core.Domain/{Chat => Chats}/ChatSessionEntity.cs | 0 .../Endpoints/{Actor => Actors}/MyActorEndpoints.cs | 0 .../Endpoints/{Chat => Chats}/MyChatMessageEndpoints.cs | 0 .../Endpoints/{Chat => Chats}/MyChatSessionEndpoints.cs | 0 src/Presentation.Web/Features/{Chat => Chats}/ChatPage.razor | 0 src/Presentation.Web/Features/{Chat => Chats}/ChatPage.razor.js | 0 .../Features/{Chat => Chats}/Components/ChatActionStrip.razor | 0 .../Features/{Chat => Chats}/Components/ChatMessageList.razor | 0 .../Features/{Chat => Chats}/Components/ChatSessionEditForm.razor | 0 .../Features/{Chat => Chats}/Components/ChatSessionList.razor | 0 .../Features/{Chat => Chats}/Components/ChatSessionStrip.razor | 0 .../Features/{Chat => Chats}/Components/NewChatMessageCard.razor | 0 .../Features/{Chat => Chats}/Components/NewChatMessageInput.razor | 0 .../{Chat => Chats}/Components/NewChatSessionButton.razor | 0 .../{Chat => Chats}/Components/SuggestedPromptsStrip.razor | 0 .../Features/{Chat => Chats}/Formatting/IChatMessageFormatter.cs | 0 .../{Chat => Chats}/Formatting/MarkdownChatMessageFormatter.cs | 0 .../Features/{Chat => Chats}/Models/ChatActionOption.cs | 0 .../Features/{Chat => Chats}/Models/ChatMessageModel.cs | 0 .../Features/{Chat => Chats}/Models/ChatSessionModel.cs | 0 .../Features/{Chat => Chats}/Models/ChatSessionTreeViewItem.cs | 0 .../Features/{Chat => Chats}/Models/ChatSessionsModel.cs | 0 .../Features/{Chat => Chats}/Services/ChatService.cs | 0 .../{Actor => Actors}/CreateActorCommand.feature | 0 .../{Actor => Actors}/CreateActorCommand.feature.cs | 0 .../{Actor => Actors}/CreateActorCommandStepDefinitions.cs | 0 .../{Actor => Actors}/DeleteActorCommand.feature | 0 .../{Actor => Actors}/DeleteActorCommand.feature.cs | 0 .../{Actor => Actors}/DeleteActorCommandStepDefinitions.cs | 0 .../{Actor => Actors}/GetActorByOwnerIdQuery.feature | 0 .../{Actor => Actors}/GetActorByOwnerIdQuery.feature.cs | 0 .../{Actor => Actors}/GetActorByOwnerIdQueryStepDefinitions.cs | 0 src/Tests.Integration/{Actor => Actors}/GetActorQuery.feature | 0 src/Tests.Integration/{Actor => Actors}/GetActorQuery.feature.cs | 0 .../{Actor => Actors}/GetActorQueryStepDefinitions.cs | 0 .../{Actor => Actors}/GetOurActorsByNameQuery.feature | 0 .../{Actor => Actors}/GetOurActorsByNameQuery.feature.cs | 0 .../{Actor => Actors}/GetOurActorsByNameQueryStepDefinitions.cs | 0 src/Tests.Integration/{Actor => Actors}/SaveActorCommand.feature | 0 .../{Actor => Actors}/SaveActorCommand.feature.cs | 0 .../{Actor => Actors}/SaveActorCommandStepDefinitions.cs | 0 .../{Chat => Chats}/CreateChatMessageCommand.feature | 0 .../{Chat => Chats}/CreateChatMessageCommand.feature.cs | 0 .../{Chat => Chats}/CreateChatMessageCommandStepDefinitions.cs | 0 .../{Chat => Chats}/CreateChatSessionCommand.feature | 0 .../{Chat => Chats}/CreateChatSessionCommand.feature.cs | 0 .../{Chat => Chats}/CreateChatSessionCommandStepDefinitions.cs | 0 .../{Chat => Chats}/DeleteChatSessionCommand.feature | 0 .../{Chat => Chats}/DeleteChatSessionCommand.feature.cs | 0 .../{Chat => Chats}/DeleteChatSessionCommandStepDefinitions.cs | 0 src/Tests.Integration/{Chat => Chats}/GetChatMessageQuery.feature | 0 .../{Chat => Chats}/GetChatMessageQuery.feature.cs | 0 .../{Chat => Chats}/GetChatMessageQueryStepDefinitions.cs | 0 .../{Chat => Chats}/GetChatMessagesPaginatedQuery.feature | 0 .../{Chat => Chats}/GetChatMessagesPaginatedQuery.feature.cs | 0 .../GetChatMessagesPaginatedQueryStepDefinitions.cs | 0 .../{Chat => Chats}/GetMyChatSessionMessagesQuery.feature | 0 .../{Chat => Chats}/GetMyChatSessionMessagesQuery.feature.cs | 0 .../GetMyChatSessionMessagesQueryStepDefinitions.cs | 0 .../{Chat => Chats}/GetMyChatSessionQuery.feature | 0 .../{Chat => Chats}/GetMyChatSessionQuery.feature.cs | 0 .../{Chat => Chats}/GetMyChatSessionQueryStepDefinitions.cs | 0 .../{Chat => Chats}/GetMyChatSessionsPaginatedQuery.feature | 0 .../{Chat => Chats}/GetMyChatSessionsPaginatedQuery.feature.cs | 0 .../GetMyChatSessionsPaginatedQueryStepDefinitions.cs | 0 .../{Chat => Chats}/GetMyChatSessionsQuery.feature | 0 .../{Chat => Chats}/GetMyChatSessionsQuery.feature.cs | 0 .../{Chat => Chats}/GetMyChatSessionsQueryStepDefinitions.cs | 0 .../{Chat => Chats}/PatchChatSessionCommand.feature | 0 .../{Chat => Chats}/PatchChatSessionCommand.feature.cs | 0 .../{Chat => Chats}/PatchChatSessionCommandStepDefinitions.cs | 0 119 files changed, 0 insertions(+), 0 deletions(-) rename src/Core.Application/{Actor => Actors}/ActorDto.cs (100%) rename src/Core.Application/{Actor => Actors}/ActorGuard.cs (100%) rename src/Core.Application/{Actor => Actors}/CreateOurActorCommand.cs (100%) rename src/Core.Application/{Actor => Actors}/CreateOurActorCommandValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/DeleteOurActorByOwnerIdCommand.cs (100%) rename src/Core.Application/{Actor => Actors}/DeleteOurActorByOwnerIdCommandValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/DeleteOurActorCommand.cs (100%) rename src/Core.Application/{Actor => Actors}/DeleteOurActorCommandValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/GetMyActorQuery.cs (100%) rename src/Core.Application/{Actor => Actors}/GetMyActorQueryValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorChatSessionQuery.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorChatSessionQueryValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorChatSessionsPaginatedQuery.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorChatSessionsPaginatedQueryValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorChatSessionsQuery.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorChatSessionsQueryValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorQuery.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorQueryValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorsByNameQuery.cs (100%) rename src/Core.Application/{Actor => Actors}/GetOurActorsByNameQueryValidator.cs (100%) rename src/Core.Application/{Actor => Actors}/SaveMyActorCommand.cs (100%) rename src/Core.Application/{Actor => Actors}/SaveMyActorCommandValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/ChatGuard.cs (100%) rename src/Core.Application/{Chat => Chats}/ChatMessageDto.cs (100%) rename src/Core.Application/{Chat => Chats}/ChatSessionDto.cs (100%) rename src/Core.Application/{Chat => Chats}/CreateMyChatMessageCommand.cs (100%) rename src/Core.Application/{Chat => Chats}/CreateMyChatMessageCommandValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/CreateMyChatSessionCommand.cs (100%) rename src/Core.Application/{Chat => Chats}/CreateMyChatSessionCommandValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/DeleteMyChatSessionCommand.cs (100%) rename src/Core.Application/{Chat => Chats}/DeleteMyChatSessionCommandValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatMessageQuery.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatMessageQueryValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatMessagesPaginatedQuery.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatMessagesPaginatedQueryValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatSessionMessagesQuery.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatSessionMessagesQueryValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatSessionQuery.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatSessionQueryValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatSessionsPaginatedQuery.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatSessionsPaginatedQueryValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatSessionsQuery.cs (100%) rename src/Core.Application/{Chat => Chats}/GetMyChatSessionsQueryValidator.cs (100%) rename src/Core.Application/{Chat => Chats}/PatchMyChatSessionCommand.cs (100%) rename src/Core.Application/{Chat => Chats}/PatchMyChatSessionCommandValidator.cs (100%) rename src/Core.Domain/{Actor => Actors}/ActorEntity.cs (100%) rename src/Core.Domain/{Chat => Chats}/ChatMessageEntity.cs (100%) rename src/Core.Domain/{Chat => Chats}/ChatMessageRoles.cs (100%) rename src/Core.Domain/{Chat => Chats}/ChatSessionEntity.cs (100%) rename src/Presentation.Api/Endpoints/{Actor => Actors}/MyActorEndpoints.cs (100%) rename src/Presentation.Api/Endpoints/{Chat => Chats}/MyChatMessageEndpoints.cs (100%) rename src/Presentation.Api/Endpoints/{Chat => Chats}/MyChatSessionEndpoints.cs (100%) rename src/Presentation.Web/Features/{Chat => Chats}/ChatPage.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/ChatPage.razor.js (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/ChatActionStrip.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/ChatMessageList.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/ChatSessionEditForm.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/ChatSessionList.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/ChatSessionStrip.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/NewChatMessageCard.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/NewChatMessageInput.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/NewChatSessionButton.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Components/SuggestedPromptsStrip.razor (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Formatting/IChatMessageFormatter.cs (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Formatting/MarkdownChatMessageFormatter.cs (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Models/ChatActionOption.cs (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Models/ChatMessageModel.cs (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Models/ChatSessionModel.cs (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Models/ChatSessionTreeViewItem.cs (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Models/ChatSessionsModel.cs (100%) rename src/Presentation.Web/Features/{Chat => Chats}/Services/ChatService.cs (100%) rename src/Tests.Integration/{Actor => Actors}/CreateActorCommand.feature (100%) rename src/Tests.Integration/{Actor => Actors}/CreateActorCommand.feature.cs (100%) rename src/Tests.Integration/{Actor => Actors}/CreateActorCommandStepDefinitions.cs (100%) rename src/Tests.Integration/{Actor => Actors}/DeleteActorCommand.feature (100%) rename src/Tests.Integration/{Actor => Actors}/DeleteActorCommand.feature.cs (100%) rename src/Tests.Integration/{Actor => Actors}/DeleteActorCommandStepDefinitions.cs (100%) rename src/Tests.Integration/{Actor => Actors}/GetActorByOwnerIdQuery.feature (100%) rename src/Tests.Integration/{Actor => Actors}/GetActorByOwnerIdQuery.feature.cs (100%) rename src/Tests.Integration/{Actor => Actors}/GetActorByOwnerIdQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Actor => Actors}/GetActorQuery.feature (100%) rename src/Tests.Integration/{Actor => Actors}/GetActorQuery.feature.cs (100%) rename src/Tests.Integration/{Actor => Actors}/GetActorQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Actor => Actors}/GetOurActorsByNameQuery.feature (100%) rename src/Tests.Integration/{Actor => Actors}/GetOurActorsByNameQuery.feature.cs (100%) rename src/Tests.Integration/{Actor => Actors}/GetOurActorsByNameQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Actor => Actors}/SaveActorCommand.feature (100%) rename src/Tests.Integration/{Actor => Actors}/SaveActorCommand.feature.cs (100%) rename src/Tests.Integration/{Actor => Actors}/SaveActorCommandStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/CreateChatMessageCommand.feature (100%) rename src/Tests.Integration/{Chat => Chats}/CreateChatMessageCommand.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/CreateChatMessageCommandStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/CreateChatSessionCommand.feature (100%) rename src/Tests.Integration/{Chat => Chats}/CreateChatSessionCommand.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/CreateChatSessionCommandStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/DeleteChatSessionCommand.feature (100%) rename src/Tests.Integration/{Chat => Chats}/DeleteChatSessionCommand.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/DeleteChatSessionCommandStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetChatMessageQuery.feature (100%) rename src/Tests.Integration/{Chat => Chats}/GetChatMessageQuery.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetChatMessageQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetChatMessagesPaginatedQuery.feature (100%) rename src/Tests.Integration/{Chat => Chats}/GetChatMessagesPaginatedQuery.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetChatMessagesPaginatedQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionMessagesQuery.feature (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionMessagesQuery.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionMessagesQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionQuery.feature (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionQuery.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionsPaginatedQuery.feature (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionsPaginatedQuery.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionsPaginatedQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionsQuery.feature (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionsQuery.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/GetMyChatSessionsQueryStepDefinitions.cs (100%) rename src/Tests.Integration/{Chat => Chats}/PatchChatSessionCommand.feature (100%) rename src/Tests.Integration/{Chat => Chats}/PatchChatSessionCommand.feature.cs (100%) rename src/Tests.Integration/{Chat => Chats}/PatchChatSessionCommandStepDefinitions.cs (100%) diff --git a/src/Core.Application/Actor/ActorDto.cs b/src/Core.Application/Actors/ActorDto.cs similarity index 100% rename from src/Core.Application/Actor/ActorDto.cs rename to src/Core.Application/Actors/ActorDto.cs diff --git a/src/Core.Application/Actor/ActorGuard.cs b/src/Core.Application/Actors/ActorGuard.cs similarity index 100% rename from src/Core.Application/Actor/ActorGuard.cs rename to src/Core.Application/Actors/ActorGuard.cs diff --git a/src/Core.Application/Actor/CreateOurActorCommand.cs b/src/Core.Application/Actors/CreateOurActorCommand.cs similarity index 100% rename from src/Core.Application/Actor/CreateOurActorCommand.cs rename to src/Core.Application/Actors/CreateOurActorCommand.cs diff --git a/src/Core.Application/Actor/CreateOurActorCommandValidator.cs b/src/Core.Application/Actors/CreateOurActorCommandValidator.cs similarity index 100% rename from src/Core.Application/Actor/CreateOurActorCommandValidator.cs rename to src/Core.Application/Actors/CreateOurActorCommandValidator.cs diff --git a/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs b/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommand.cs similarity index 100% rename from src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs rename to src/Core.Application/Actors/DeleteOurActorByOwnerIdCommand.cs diff --git a/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs b/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommandValidator.cs similarity index 100% rename from src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs rename to src/Core.Application/Actors/DeleteOurActorByOwnerIdCommandValidator.cs diff --git a/src/Core.Application/Actor/DeleteOurActorCommand.cs b/src/Core.Application/Actors/DeleteOurActorCommand.cs similarity index 100% rename from src/Core.Application/Actor/DeleteOurActorCommand.cs rename to src/Core.Application/Actors/DeleteOurActorCommand.cs diff --git a/src/Core.Application/Actor/DeleteOurActorCommandValidator.cs b/src/Core.Application/Actors/DeleteOurActorCommandValidator.cs similarity index 100% rename from src/Core.Application/Actor/DeleteOurActorCommandValidator.cs rename to src/Core.Application/Actors/DeleteOurActorCommandValidator.cs diff --git a/src/Core.Application/Actor/GetMyActorQuery.cs b/src/Core.Application/Actors/GetMyActorQuery.cs similarity index 100% rename from src/Core.Application/Actor/GetMyActorQuery.cs rename to src/Core.Application/Actors/GetMyActorQuery.cs diff --git a/src/Core.Application/Actor/GetMyActorQueryValidator.cs b/src/Core.Application/Actors/GetMyActorQueryValidator.cs similarity index 100% rename from src/Core.Application/Actor/GetMyActorQueryValidator.cs rename to src/Core.Application/Actors/GetMyActorQueryValidator.cs diff --git a/src/Core.Application/Actor/GetOurActorChatSessionQuery.cs b/src/Core.Application/Actors/GetOurActorChatSessionQuery.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorChatSessionQuery.cs rename to src/Core.Application/Actors/GetOurActorChatSessionQuery.cs diff --git a/src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs b/src/Core.Application/Actors/GetOurActorChatSessionQueryValidator.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs rename to src/Core.Application/Actors/GetOurActorChatSessionQueryValidator.cs diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs b/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQuery.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs rename to src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQuery.cs diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs b/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQueryValidator.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs rename to src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQueryValidator.cs diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs b/src/Core.Application/Actors/GetOurActorChatSessionsQuery.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs rename to src/Core.Application/Actors/GetOurActorChatSessionsQuery.cs diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs b/src/Core.Application/Actors/GetOurActorChatSessionsQueryValidator.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs rename to src/Core.Application/Actors/GetOurActorChatSessionsQueryValidator.cs diff --git a/src/Core.Application/Actor/GetOurActorQuery.cs b/src/Core.Application/Actors/GetOurActorQuery.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorQuery.cs rename to src/Core.Application/Actors/GetOurActorQuery.cs diff --git a/src/Core.Application/Actor/GetOurActorQueryValidator.cs b/src/Core.Application/Actors/GetOurActorQueryValidator.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorQueryValidator.cs rename to src/Core.Application/Actors/GetOurActorQueryValidator.cs diff --git a/src/Core.Application/Actor/GetOurActorsByNameQuery.cs b/src/Core.Application/Actors/GetOurActorsByNameQuery.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorsByNameQuery.cs rename to src/Core.Application/Actors/GetOurActorsByNameQuery.cs diff --git a/src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs b/src/Core.Application/Actors/GetOurActorsByNameQueryValidator.cs similarity index 100% rename from src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs rename to src/Core.Application/Actors/GetOurActorsByNameQueryValidator.cs diff --git a/src/Core.Application/Actor/SaveMyActorCommand.cs b/src/Core.Application/Actors/SaveMyActorCommand.cs similarity index 100% rename from src/Core.Application/Actor/SaveMyActorCommand.cs rename to src/Core.Application/Actors/SaveMyActorCommand.cs diff --git a/src/Core.Application/Actor/SaveMyActorCommandValidator.cs b/src/Core.Application/Actors/SaveMyActorCommandValidator.cs similarity index 100% rename from src/Core.Application/Actor/SaveMyActorCommandValidator.cs rename to src/Core.Application/Actors/SaveMyActorCommandValidator.cs diff --git a/src/Core.Application/Chat/ChatGuard.cs b/src/Core.Application/Chats/ChatGuard.cs similarity index 100% rename from src/Core.Application/Chat/ChatGuard.cs rename to src/Core.Application/Chats/ChatGuard.cs diff --git a/src/Core.Application/Chat/ChatMessageDto.cs b/src/Core.Application/Chats/ChatMessageDto.cs similarity index 100% rename from src/Core.Application/Chat/ChatMessageDto.cs rename to src/Core.Application/Chats/ChatMessageDto.cs diff --git a/src/Core.Application/Chat/ChatSessionDto.cs b/src/Core.Application/Chats/ChatSessionDto.cs similarity index 100% rename from src/Core.Application/Chat/ChatSessionDto.cs rename to src/Core.Application/Chats/ChatSessionDto.cs diff --git a/src/Core.Application/Chat/CreateMyChatMessageCommand.cs b/src/Core.Application/Chats/CreateMyChatMessageCommand.cs similarity index 100% rename from src/Core.Application/Chat/CreateMyChatMessageCommand.cs rename to src/Core.Application/Chats/CreateMyChatMessageCommand.cs diff --git a/src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs b/src/Core.Application/Chats/CreateMyChatMessageCommandValidator.cs similarity index 100% rename from src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs rename to src/Core.Application/Chats/CreateMyChatMessageCommandValidator.cs diff --git a/src/Core.Application/Chat/CreateMyChatSessionCommand.cs b/src/Core.Application/Chats/CreateMyChatSessionCommand.cs similarity index 100% rename from src/Core.Application/Chat/CreateMyChatSessionCommand.cs rename to src/Core.Application/Chats/CreateMyChatSessionCommand.cs diff --git a/src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs b/src/Core.Application/Chats/CreateMyChatSessionCommandValidator.cs similarity index 100% rename from src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs rename to src/Core.Application/Chats/CreateMyChatSessionCommandValidator.cs diff --git a/src/Core.Application/Chat/DeleteMyChatSessionCommand.cs b/src/Core.Application/Chats/DeleteMyChatSessionCommand.cs similarity index 100% rename from src/Core.Application/Chat/DeleteMyChatSessionCommand.cs rename to src/Core.Application/Chats/DeleteMyChatSessionCommand.cs diff --git a/src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs b/src/Core.Application/Chats/DeleteMyChatSessionCommandValidator.cs similarity index 100% rename from src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs rename to src/Core.Application/Chats/DeleteMyChatSessionCommandValidator.cs diff --git a/src/Core.Application/Chat/GetMyChatMessageQuery.cs b/src/Core.Application/Chats/GetMyChatMessageQuery.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatMessageQuery.cs rename to src/Core.Application/Chats/GetMyChatMessageQuery.cs diff --git a/src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs b/src/Core.Application/Chats/GetMyChatMessageQueryValidator.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs rename to src/Core.Application/Chats/GetMyChatMessageQueryValidator.cs diff --git a/src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs b/src/Core.Application/Chats/GetMyChatMessagesPaginatedQuery.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs rename to src/Core.Application/Chats/GetMyChatMessagesPaginatedQuery.cs diff --git a/src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs b/src/Core.Application/Chats/GetMyChatMessagesPaginatedQueryValidator.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs rename to src/Core.Application/Chats/GetMyChatMessagesPaginatedQueryValidator.cs diff --git a/src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs b/src/Core.Application/Chats/GetMyChatSessionMessagesQuery.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs rename to src/Core.Application/Chats/GetMyChatSessionMessagesQuery.cs diff --git a/src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs b/src/Core.Application/Chats/GetMyChatSessionMessagesQueryValidator.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs rename to src/Core.Application/Chats/GetMyChatSessionMessagesQueryValidator.cs diff --git a/src/Core.Application/Chat/GetMyChatSessionQuery.cs b/src/Core.Application/Chats/GetMyChatSessionQuery.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatSessionQuery.cs rename to src/Core.Application/Chats/GetMyChatSessionQuery.cs diff --git a/src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs b/src/Core.Application/Chats/GetMyChatSessionQueryValidator.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs rename to src/Core.Application/Chats/GetMyChatSessionQueryValidator.cs diff --git a/src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs b/src/Core.Application/Chats/GetMyChatSessionsPaginatedQuery.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs rename to src/Core.Application/Chats/GetMyChatSessionsPaginatedQuery.cs diff --git a/src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs b/src/Core.Application/Chats/GetMyChatSessionsPaginatedQueryValidator.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs rename to src/Core.Application/Chats/GetMyChatSessionsPaginatedQueryValidator.cs diff --git a/src/Core.Application/Chat/GetMyChatSessionsQuery.cs b/src/Core.Application/Chats/GetMyChatSessionsQuery.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatSessionsQuery.cs rename to src/Core.Application/Chats/GetMyChatSessionsQuery.cs diff --git a/src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs b/src/Core.Application/Chats/GetMyChatSessionsQueryValidator.cs similarity index 100% rename from src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs rename to src/Core.Application/Chats/GetMyChatSessionsQueryValidator.cs diff --git a/src/Core.Application/Chat/PatchMyChatSessionCommand.cs b/src/Core.Application/Chats/PatchMyChatSessionCommand.cs similarity index 100% rename from src/Core.Application/Chat/PatchMyChatSessionCommand.cs rename to src/Core.Application/Chats/PatchMyChatSessionCommand.cs diff --git a/src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs b/src/Core.Application/Chats/PatchMyChatSessionCommandValidator.cs similarity index 100% rename from src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs rename to src/Core.Application/Chats/PatchMyChatSessionCommandValidator.cs diff --git a/src/Core.Domain/Actor/ActorEntity.cs b/src/Core.Domain/Actors/ActorEntity.cs similarity index 100% rename from src/Core.Domain/Actor/ActorEntity.cs rename to src/Core.Domain/Actors/ActorEntity.cs diff --git a/src/Core.Domain/Chat/ChatMessageEntity.cs b/src/Core.Domain/Chats/ChatMessageEntity.cs similarity index 100% rename from src/Core.Domain/Chat/ChatMessageEntity.cs rename to src/Core.Domain/Chats/ChatMessageEntity.cs diff --git a/src/Core.Domain/Chat/ChatMessageRoles.cs b/src/Core.Domain/Chats/ChatMessageRoles.cs similarity index 100% rename from src/Core.Domain/Chat/ChatMessageRoles.cs rename to src/Core.Domain/Chats/ChatMessageRoles.cs diff --git a/src/Core.Domain/Chat/ChatSessionEntity.cs b/src/Core.Domain/Chats/ChatSessionEntity.cs similarity index 100% rename from src/Core.Domain/Chat/ChatSessionEntity.cs rename to src/Core.Domain/Chats/ChatSessionEntity.cs diff --git a/src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs b/src/Presentation.Api/Endpoints/Actors/MyActorEndpoints.cs similarity index 100% rename from src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs rename to src/Presentation.Api/Endpoints/Actors/MyActorEndpoints.cs diff --git a/src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs b/src/Presentation.Api/Endpoints/Chats/MyChatMessageEndpoints.cs similarity index 100% rename from src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs rename to src/Presentation.Api/Endpoints/Chats/MyChatMessageEndpoints.cs diff --git a/src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs b/src/Presentation.Api/Endpoints/Chats/MyChatSessionEndpoints.cs similarity index 100% rename from src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs rename to src/Presentation.Api/Endpoints/Chats/MyChatSessionEndpoints.cs diff --git a/src/Presentation.Web/Features/Chat/ChatPage.razor b/src/Presentation.Web/Features/Chats/ChatPage.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/ChatPage.razor rename to src/Presentation.Web/Features/Chats/ChatPage.razor diff --git a/src/Presentation.Web/Features/Chat/ChatPage.razor.js b/src/Presentation.Web/Features/Chats/ChatPage.razor.js similarity index 100% rename from src/Presentation.Web/Features/Chat/ChatPage.razor.js rename to src/Presentation.Web/Features/Chats/ChatPage.razor.js diff --git a/src/Presentation.Web/Features/Chat/Components/ChatActionStrip.razor b/src/Presentation.Web/Features/Chats/Components/ChatActionStrip.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/ChatActionStrip.razor rename to src/Presentation.Web/Features/Chats/Components/ChatActionStrip.razor diff --git a/src/Presentation.Web/Features/Chat/Components/ChatMessageList.razor b/src/Presentation.Web/Features/Chats/Components/ChatMessageList.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/ChatMessageList.razor rename to src/Presentation.Web/Features/Chats/Components/ChatMessageList.razor diff --git a/src/Presentation.Web/Features/Chat/Components/ChatSessionEditForm.razor b/src/Presentation.Web/Features/Chats/Components/ChatSessionEditForm.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/ChatSessionEditForm.razor rename to src/Presentation.Web/Features/Chats/Components/ChatSessionEditForm.razor diff --git a/src/Presentation.Web/Features/Chat/Components/ChatSessionList.razor b/src/Presentation.Web/Features/Chats/Components/ChatSessionList.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/ChatSessionList.razor rename to src/Presentation.Web/Features/Chats/Components/ChatSessionList.razor diff --git a/src/Presentation.Web/Features/Chat/Components/ChatSessionStrip.razor b/src/Presentation.Web/Features/Chats/Components/ChatSessionStrip.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/ChatSessionStrip.razor rename to src/Presentation.Web/Features/Chats/Components/ChatSessionStrip.razor diff --git a/src/Presentation.Web/Features/Chat/Components/NewChatMessageCard.razor b/src/Presentation.Web/Features/Chats/Components/NewChatMessageCard.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/NewChatMessageCard.razor rename to src/Presentation.Web/Features/Chats/Components/NewChatMessageCard.razor diff --git a/src/Presentation.Web/Features/Chat/Components/NewChatMessageInput.razor b/src/Presentation.Web/Features/Chats/Components/NewChatMessageInput.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/NewChatMessageInput.razor rename to src/Presentation.Web/Features/Chats/Components/NewChatMessageInput.razor diff --git a/src/Presentation.Web/Features/Chat/Components/NewChatSessionButton.razor b/src/Presentation.Web/Features/Chats/Components/NewChatSessionButton.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/NewChatSessionButton.razor rename to src/Presentation.Web/Features/Chats/Components/NewChatSessionButton.razor diff --git a/src/Presentation.Web/Features/Chat/Components/SuggestedPromptsStrip.razor b/src/Presentation.Web/Features/Chats/Components/SuggestedPromptsStrip.razor similarity index 100% rename from src/Presentation.Web/Features/Chat/Components/SuggestedPromptsStrip.razor rename to src/Presentation.Web/Features/Chats/Components/SuggestedPromptsStrip.razor diff --git a/src/Presentation.Web/Features/Chat/Formatting/IChatMessageFormatter.cs b/src/Presentation.Web/Features/Chats/Formatting/IChatMessageFormatter.cs similarity index 100% rename from src/Presentation.Web/Features/Chat/Formatting/IChatMessageFormatter.cs rename to src/Presentation.Web/Features/Chats/Formatting/IChatMessageFormatter.cs diff --git a/src/Presentation.Web/Features/Chat/Formatting/MarkdownChatMessageFormatter.cs b/src/Presentation.Web/Features/Chats/Formatting/MarkdownChatMessageFormatter.cs similarity index 100% rename from src/Presentation.Web/Features/Chat/Formatting/MarkdownChatMessageFormatter.cs rename to src/Presentation.Web/Features/Chats/Formatting/MarkdownChatMessageFormatter.cs diff --git a/src/Presentation.Web/Features/Chat/Models/ChatActionOption.cs b/src/Presentation.Web/Features/Chats/Models/ChatActionOption.cs similarity index 100% rename from src/Presentation.Web/Features/Chat/Models/ChatActionOption.cs rename to src/Presentation.Web/Features/Chats/Models/ChatActionOption.cs diff --git a/src/Presentation.Web/Features/Chat/Models/ChatMessageModel.cs b/src/Presentation.Web/Features/Chats/Models/ChatMessageModel.cs similarity index 100% rename from src/Presentation.Web/Features/Chat/Models/ChatMessageModel.cs rename to src/Presentation.Web/Features/Chats/Models/ChatMessageModel.cs diff --git a/src/Presentation.Web/Features/Chat/Models/ChatSessionModel.cs b/src/Presentation.Web/Features/Chats/Models/ChatSessionModel.cs similarity index 100% rename from src/Presentation.Web/Features/Chat/Models/ChatSessionModel.cs rename to src/Presentation.Web/Features/Chats/Models/ChatSessionModel.cs diff --git a/src/Presentation.Web/Features/Chat/Models/ChatSessionTreeViewItem.cs b/src/Presentation.Web/Features/Chats/Models/ChatSessionTreeViewItem.cs similarity index 100% rename from src/Presentation.Web/Features/Chat/Models/ChatSessionTreeViewItem.cs rename to src/Presentation.Web/Features/Chats/Models/ChatSessionTreeViewItem.cs diff --git a/src/Presentation.Web/Features/Chat/Models/ChatSessionsModel.cs b/src/Presentation.Web/Features/Chats/Models/ChatSessionsModel.cs similarity index 100% rename from src/Presentation.Web/Features/Chat/Models/ChatSessionsModel.cs rename to src/Presentation.Web/Features/Chats/Models/ChatSessionsModel.cs diff --git a/src/Presentation.Web/Features/Chat/Services/ChatService.cs b/src/Presentation.Web/Features/Chats/Services/ChatService.cs similarity index 100% rename from src/Presentation.Web/Features/Chat/Services/ChatService.cs rename to src/Presentation.Web/Features/Chats/Services/ChatService.cs diff --git a/src/Tests.Integration/Actor/CreateActorCommand.feature b/src/Tests.Integration/Actors/CreateActorCommand.feature similarity index 100% rename from src/Tests.Integration/Actor/CreateActorCommand.feature rename to src/Tests.Integration/Actors/CreateActorCommand.feature diff --git a/src/Tests.Integration/Actor/CreateActorCommand.feature.cs b/src/Tests.Integration/Actors/CreateActorCommand.feature.cs similarity index 100% rename from src/Tests.Integration/Actor/CreateActorCommand.feature.cs rename to src/Tests.Integration/Actors/CreateActorCommand.feature.cs diff --git a/src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs b/src/Tests.Integration/Actors/CreateActorCommandStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs rename to src/Tests.Integration/Actors/CreateActorCommandStepDefinitions.cs diff --git a/src/Tests.Integration/Actor/DeleteActorCommand.feature b/src/Tests.Integration/Actors/DeleteActorCommand.feature similarity index 100% rename from src/Tests.Integration/Actor/DeleteActorCommand.feature rename to src/Tests.Integration/Actors/DeleteActorCommand.feature diff --git a/src/Tests.Integration/Actor/DeleteActorCommand.feature.cs b/src/Tests.Integration/Actors/DeleteActorCommand.feature.cs similarity index 100% rename from src/Tests.Integration/Actor/DeleteActorCommand.feature.cs rename to src/Tests.Integration/Actors/DeleteActorCommand.feature.cs diff --git a/src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs b/src/Tests.Integration/Actors/DeleteActorCommandStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs rename to src/Tests.Integration/Actors/DeleteActorCommandStepDefinitions.cs diff --git a/src/Tests.Integration/Actor/GetActorByOwnerIdQuery.feature b/src/Tests.Integration/Actors/GetActorByOwnerIdQuery.feature similarity index 100% rename from src/Tests.Integration/Actor/GetActorByOwnerIdQuery.feature rename to src/Tests.Integration/Actors/GetActorByOwnerIdQuery.feature diff --git a/src/Tests.Integration/Actor/GetActorByOwnerIdQuery.feature.cs b/src/Tests.Integration/Actors/GetActorByOwnerIdQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Actor/GetActorByOwnerIdQuery.feature.cs rename to src/Tests.Integration/Actors/GetActorByOwnerIdQuery.feature.cs diff --git a/src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs b/src/Tests.Integration/Actors/GetActorByOwnerIdQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs rename to src/Tests.Integration/Actors/GetActorByOwnerIdQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Actor/GetActorQuery.feature b/src/Tests.Integration/Actors/GetActorQuery.feature similarity index 100% rename from src/Tests.Integration/Actor/GetActorQuery.feature rename to src/Tests.Integration/Actors/GetActorQuery.feature diff --git a/src/Tests.Integration/Actor/GetActorQuery.feature.cs b/src/Tests.Integration/Actors/GetActorQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Actor/GetActorQuery.feature.cs rename to src/Tests.Integration/Actors/GetActorQuery.feature.cs diff --git a/src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs b/src/Tests.Integration/Actors/GetActorQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs rename to src/Tests.Integration/Actors/GetActorQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Actor/GetOurActorsByNameQuery.feature b/src/Tests.Integration/Actors/GetOurActorsByNameQuery.feature similarity index 100% rename from src/Tests.Integration/Actor/GetOurActorsByNameQuery.feature rename to src/Tests.Integration/Actors/GetOurActorsByNameQuery.feature diff --git a/src/Tests.Integration/Actor/GetOurActorsByNameQuery.feature.cs b/src/Tests.Integration/Actors/GetOurActorsByNameQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Actor/GetOurActorsByNameQuery.feature.cs rename to src/Tests.Integration/Actors/GetOurActorsByNameQuery.feature.cs diff --git a/src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs b/src/Tests.Integration/Actors/GetOurActorsByNameQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs rename to src/Tests.Integration/Actors/GetOurActorsByNameQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Actor/SaveActorCommand.feature b/src/Tests.Integration/Actors/SaveActorCommand.feature similarity index 100% rename from src/Tests.Integration/Actor/SaveActorCommand.feature rename to src/Tests.Integration/Actors/SaveActorCommand.feature diff --git a/src/Tests.Integration/Actor/SaveActorCommand.feature.cs b/src/Tests.Integration/Actors/SaveActorCommand.feature.cs similarity index 100% rename from src/Tests.Integration/Actor/SaveActorCommand.feature.cs rename to src/Tests.Integration/Actors/SaveActorCommand.feature.cs diff --git a/src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs b/src/Tests.Integration/Actors/SaveActorCommandStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs rename to src/Tests.Integration/Actors/SaveActorCommandStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/CreateChatMessageCommand.feature b/src/Tests.Integration/Chats/CreateChatMessageCommand.feature similarity index 100% rename from src/Tests.Integration/Chat/CreateChatMessageCommand.feature rename to src/Tests.Integration/Chats/CreateChatMessageCommand.feature diff --git a/src/Tests.Integration/Chat/CreateChatMessageCommand.feature.cs b/src/Tests.Integration/Chats/CreateChatMessageCommand.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/CreateChatMessageCommand.feature.cs rename to src/Tests.Integration/Chats/CreateChatMessageCommand.feature.cs diff --git a/src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs b/src/Tests.Integration/Chats/CreateChatMessageCommandStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs rename to src/Tests.Integration/Chats/CreateChatMessageCommandStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/CreateChatSessionCommand.feature b/src/Tests.Integration/Chats/CreateChatSessionCommand.feature similarity index 100% rename from src/Tests.Integration/Chat/CreateChatSessionCommand.feature rename to src/Tests.Integration/Chats/CreateChatSessionCommand.feature diff --git a/src/Tests.Integration/Chat/CreateChatSessionCommand.feature.cs b/src/Tests.Integration/Chats/CreateChatSessionCommand.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/CreateChatSessionCommand.feature.cs rename to src/Tests.Integration/Chats/CreateChatSessionCommand.feature.cs diff --git a/src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chats/CreateChatSessionCommandStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs rename to src/Tests.Integration/Chats/CreateChatSessionCommandStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/DeleteChatSessionCommand.feature b/src/Tests.Integration/Chats/DeleteChatSessionCommand.feature similarity index 100% rename from src/Tests.Integration/Chat/DeleteChatSessionCommand.feature rename to src/Tests.Integration/Chats/DeleteChatSessionCommand.feature diff --git a/src/Tests.Integration/Chat/DeleteChatSessionCommand.feature.cs b/src/Tests.Integration/Chats/DeleteChatSessionCommand.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/DeleteChatSessionCommand.feature.cs rename to src/Tests.Integration/Chats/DeleteChatSessionCommand.feature.cs diff --git a/src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chats/DeleteChatSessionCommandStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs rename to src/Tests.Integration/Chats/DeleteChatSessionCommandStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/GetChatMessageQuery.feature b/src/Tests.Integration/Chats/GetChatMessageQuery.feature similarity index 100% rename from src/Tests.Integration/Chat/GetChatMessageQuery.feature rename to src/Tests.Integration/Chats/GetChatMessageQuery.feature diff --git a/src/Tests.Integration/Chat/GetChatMessageQuery.feature.cs b/src/Tests.Integration/Chats/GetChatMessageQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/GetChatMessageQuery.feature.cs rename to src/Tests.Integration/Chats/GetChatMessageQuery.feature.cs diff --git a/src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetChatMessageQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs rename to src/Tests.Integration/Chats/GetChatMessageQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/GetChatMessagesPaginatedQuery.feature b/src/Tests.Integration/Chats/GetChatMessagesPaginatedQuery.feature similarity index 100% rename from src/Tests.Integration/Chat/GetChatMessagesPaginatedQuery.feature rename to src/Tests.Integration/Chats/GetChatMessagesPaginatedQuery.feature diff --git a/src/Tests.Integration/Chat/GetChatMessagesPaginatedQuery.feature.cs b/src/Tests.Integration/Chats/GetChatMessagesPaginatedQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/GetChatMessagesPaginatedQuery.feature.cs rename to src/Tests.Integration/Chats/GetChatMessagesPaginatedQuery.feature.cs diff --git a/src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetChatMessagesPaginatedQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs rename to src/Tests.Integration/Chats/GetChatMessagesPaginatedQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/GetMyChatSessionMessagesQuery.feature b/src/Tests.Integration/Chats/GetMyChatSessionMessagesQuery.feature similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionMessagesQuery.feature rename to src/Tests.Integration/Chats/GetMyChatSessionMessagesQuery.feature diff --git a/src/Tests.Integration/Chat/GetMyChatSessionMessagesQuery.feature.cs b/src/Tests.Integration/Chats/GetMyChatSessionMessagesQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionMessagesQuery.feature.cs rename to src/Tests.Integration/Chats/GetMyChatSessionMessagesQuery.feature.cs diff --git a/src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetMyChatSessionMessagesQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs rename to src/Tests.Integration/Chats/GetMyChatSessionMessagesQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/GetMyChatSessionQuery.feature b/src/Tests.Integration/Chats/GetMyChatSessionQuery.feature similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionQuery.feature rename to src/Tests.Integration/Chats/GetMyChatSessionQuery.feature diff --git a/src/Tests.Integration/Chat/GetMyChatSessionQuery.feature.cs b/src/Tests.Integration/Chats/GetMyChatSessionQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionQuery.feature.cs rename to src/Tests.Integration/Chats/GetMyChatSessionQuery.feature.cs diff --git a/src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetMyChatSessionQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs rename to src/Tests.Integration/Chats/GetMyChatSessionQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQuery.feature b/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQuery.feature similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQuery.feature rename to src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQuery.feature diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQuery.feature.cs b/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQuery.feature.cs rename to src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQuery.feature.cs diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs rename to src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsQuery.feature b/src/Tests.Integration/Chats/GetMyChatSessionsQuery.feature similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionsQuery.feature rename to src/Tests.Integration/Chats/GetMyChatSessionsQuery.feature diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsQuery.feature.cs b/src/Tests.Integration/Chats/GetMyChatSessionsQuery.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionsQuery.feature.cs rename to src/Tests.Integration/Chats/GetMyChatSessionsQuery.feature.cs diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetMyChatSessionsQueryStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs rename to src/Tests.Integration/Chats/GetMyChatSessionsQueryStepDefinitions.cs diff --git a/src/Tests.Integration/Chat/PatchChatSessionCommand.feature b/src/Tests.Integration/Chats/PatchChatSessionCommand.feature similarity index 100% rename from src/Tests.Integration/Chat/PatchChatSessionCommand.feature rename to src/Tests.Integration/Chats/PatchChatSessionCommand.feature diff --git a/src/Tests.Integration/Chat/PatchChatSessionCommand.feature.cs b/src/Tests.Integration/Chats/PatchChatSessionCommand.feature.cs similarity index 100% rename from src/Tests.Integration/Chat/PatchChatSessionCommand.feature.cs rename to src/Tests.Integration/Chats/PatchChatSessionCommand.feature.cs diff --git a/src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chats/PatchChatSessionCommandStepDefinitions.cs similarity index 100% rename from src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs rename to src/Tests.Integration/Chats/PatchChatSessionCommandStepDefinitions.cs From a8178d556294bd71599f253990430472d454ed63 Mon Sep 17 00:00:00 2001 From: "Robert J. Good" Date: Sat, 29 Aug 2026 00:02:22 -0700 Subject: [PATCH 2/6] naming convention update --- docs/governance/coding-standards.md | 3 +++ docs/governance/project-guide-blazor.md | 3 ++- docs/governance/style-guide.md | 4 +++- .../Abstractions/IAgentFrameworkContext.cs | 4 ++-- src/Core.Application/Actors/ActorDto.cs | 4 ++-- src/Core.Application/Actors/ActorGuard.cs | 2 +- src/Core.Application/Actors/CreateOurActorCommand.cs | 4 ++-- .../Actors/CreateOurActorCommandValidator.cs | 2 +- .../Actors/DeleteOurActorByOwnerIdCommand.cs | 2 +- .../Actors/DeleteOurActorByOwnerIdCommandValidator.cs | 2 +- src/Core.Application/Actors/DeleteOurActorCommand.cs | 2 +- .../Actors/DeleteOurActorCommandValidator.cs | 2 +- src/Core.Application/Actors/GetMyActorQuery.cs | 2 +- src/Core.Application/Actors/GetMyActorQueryValidator.cs | 2 +- .../Actors/GetOurActorChatSessionQuery.cs | 4 ++-- .../Actors/GetOurActorChatSessionQueryValidator.cs | 2 +- .../Actors/GetOurActorChatSessionsPaginatedQuery.cs | 4 ++-- .../GetOurActorChatSessionsPaginatedQueryValidator.cs | 2 +- .../Actors/GetOurActorChatSessionsQuery.cs | 4 ++-- .../Actors/GetOurActorChatSessionsQueryValidator.cs | 2 +- src/Core.Application/Actors/GetOurActorQuery.cs | 2 +- src/Core.Application/Actors/GetOurActorQueryValidator.cs | 2 +- src/Core.Application/Actors/GetOurActorsByNameQuery.cs | 2 +- .../Actors/GetOurActorsByNameQueryValidator.cs | 2 +- src/Core.Application/Actors/SaveMyActorCommand.cs | 4 ++-- .../Actors/SaveMyActorCommandValidator.cs | 2 +- src/Core.Application/Chats/ChatGuard.cs | 4 ++-- src/Core.Application/Chats/ChatMessageDto.cs | 4 ++-- src/Core.Application/Chats/ChatSessionDto.cs | 4 ++-- src/Core.Application/Chats/CreateMyChatMessageCommand.cs | 4 ++-- .../Chats/CreateMyChatMessageCommandValidator.cs | 2 +- src/Core.Application/Chats/CreateMyChatSessionCommand.cs | 6 +++--- .../Chats/CreateMyChatSessionCommandValidator.cs | 2 +- src/Core.Application/Chats/DeleteMyChatSessionCommand.cs | 2 +- .../Chats/DeleteMyChatSessionCommandValidator.cs | 2 +- src/Core.Application/Chats/GetMyChatMessageQuery.cs | 2 +- .../Chats/GetMyChatMessageQueryValidator.cs | 2 +- .../Chats/GetMyChatMessagesPaginatedQuery.cs | 2 +- .../Chats/GetMyChatMessagesPaginatedQueryValidator.cs | 2 +- .../Chats/GetMyChatSessionMessagesQuery.cs | 2 +- .../Chats/GetMyChatSessionMessagesQueryValidator.cs | 2 +- src/Core.Application/Chats/GetMyChatSessionQuery.cs | 2 +- .../Chats/GetMyChatSessionQueryValidator.cs | 2 +- .../Chats/GetMyChatSessionsPaginatedQuery.cs | 2 +- .../Chats/GetMyChatSessionsPaginatedQueryValidator.cs | 2 +- src/Core.Application/Chats/GetMyChatSessionsQuery.cs | 2 +- .../Chats/GetMyChatSessionsQueryValidator.cs | 2 +- src/Core.Application/Chats/PatchMyChatSessionCommand.cs | 2 +- .../Chats/PatchMyChatSessionCommandValidator.cs | 2 +- src/Core.Domain/Actors/ActorEntity.cs | 2 +- src/Core.Domain/Chats/ChatMessageEntity.cs | 2 +- src/Core.Domain/Chats/ChatMessageRoles.cs | 2 +- src/Core.Domain/Chats/ChatSessionEntity.cs | 2 +- src/Infrastructure.AgentFramework/Tools/ActorsTool.cs | 2 +- .../Tools/ChatMessagesTool.cs | 2 +- .../Tools/ChatSessionsTool.cs | 2 +- .../Persistence/AgentFrameworkContext.cs | 4 ++-- .../Persistence/Configurations/ActorsConfig.cs | 2 +- .../Persistence/Configurations/ChatMessagesConfig.cs | 2 +- .../Persistence/Configurations/ChatSessionsConfig.cs | 2 +- src/Presentation.Api/Endpoints/Actors/MyActorEndpoints.cs | 2 +- .../Endpoints/Chats/MyChatMessageEndpoints.cs | 2 +- .../Endpoints/Chats/MyChatSessionEndpoints.cs | 2 +- src/Presentation.Web/ConfigureServices.cs | 4 ++-- src/Presentation.Web/Features/Chats/ChatPage.razor | 8 ++++---- .../Features/Chats/Components/ChatActionStrip.razor | 2 +- .../Features/Chats/Components/ChatMessageList.razor | 6 +++--- .../Features/Chats/Components/ChatSessionList.razor | 4 ++-- .../Features/Chats/Components/ChatSessionStrip.razor | 4 ++-- .../Features/Chats/Components/NewChatMessageCard.razor | 4 ++-- .../Features/Chats/Components/NewChatMessageInput.razor | 4 ++-- .../Features/Chats/Formatting/IChatMessageFormatter.cs | 2 +- .../Chats/Formatting/MarkdownChatMessageFormatter.cs | 2 +- .../Features/Chats/Models/ChatActionOption.cs | 2 +- .../Features/Chats/Models/ChatMessageModel.cs | 2 +- .../Features/Chats/Models/ChatSessionModel.cs | 2 +- .../Features/Chats/Models/ChatSessionTreeViewItem.cs | 2 +- .../Features/Chats/Models/ChatSessionsModel.cs | 2 +- .../Features/Chats/Services/ChatService.cs | 4 ++-- .../Actors/CreateActorCommand.feature.cs | 6 +++--- .../Actors/CreateActorCommandStepDefinitions.cs | 4 ++-- .../Actors/DeleteActorCommand.feature.cs | 6 +++--- .../Actors/DeleteActorCommandStepDefinitions.cs | 4 ++-- .../Actors/GetActorByOwnerIdQuery.feature.cs | 6 +++--- .../Actors/GetActorByOwnerIdQueryStepDefinitions.cs | 4 ++-- src/Tests.Integration/Actors/GetActorQuery.feature.cs | 6 +++--- .../Actors/GetActorQueryStepDefinitions.cs | 4 ++-- .../Actors/GetOurActorsByNameQuery.feature.cs | 6 +++--- .../Actors/GetOurActorsByNameQueryStepDefinitions.cs | 4 ++-- src/Tests.Integration/Actors/SaveActorCommand.feature.cs | 6 +++--- .../Actors/SaveActorCommandStepDefinitions.cs | 4 ++-- .../Application/NotFoundSemanticsTests.cs | 4 ++-- .../Chats/CreateChatMessageCommand.feature.cs | 6 +++--- .../Chats/CreateChatMessageCommandStepDefinitions.cs | 6 +++--- .../Chats/CreateChatSessionCommand.feature.cs | 6 +++--- .../Chats/CreateChatSessionCommandStepDefinitions.cs | 6 +++--- .../Chats/DeleteChatSessionCommand.feature.cs | 6 +++--- .../Chats/DeleteChatSessionCommandStepDefinitions.cs | 4 ++-- .../Chats/GetChatMessageQuery.feature.cs | 6 +++--- .../Chats/GetChatMessageQueryStepDefinitions.cs | 4 ++-- .../Chats/GetChatMessagesPaginatedQuery.feature.cs | 6 +++--- .../Chats/GetChatMessagesPaginatedQueryStepDefinitions.cs | 4 ++-- .../Chats/GetMyChatSessionMessagesQuery.feature.cs | 6 +++--- .../Chats/GetMyChatSessionMessagesQueryStepDefinitions.cs | 4 ++-- .../Chats/GetMyChatSessionQuery.feature.cs | 6 +++--- .../Chats/GetMyChatSessionQueryStepDefinitions.cs | 4 ++-- .../Chats/GetMyChatSessionsPaginatedQuery.feature.cs | 6 +++--- .../GetMyChatSessionsPaginatedQueryStepDefinitions.cs | 4 ++-- .../Chats/GetMyChatSessionsQuery.feature.cs | 6 +++--- .../Chats/GetMyChatSessionsQueryStepDefinitions.cs | 4 ++-- .../Chats/PatchChatSessionCommand.feature.cs | 6 +++--- .../Chats/PatchChatSessionCommandStepDefinitions.cs | 4 ++-- .../Governance/ChatGovernanceInvocationTests.cs | 4 ++-- 113 files changed, 195 insertions(+), 189 deletions(-) diff --git a/docs/governance/coding-standards.md b/docs/governance/coding-standards.md index 3881d9d..7049ee4 100644 --- a/docs/governance/coding-standards.md +++ b/docs/governance/coding-standards.md @@ -6,6 +6,9 @@ Define implementation expectations for contributors and AI agents. ## Naming Standards - Projects and folders: PascalCase. - Namespaces: align with folder/project structure. +- Use plural folders for feature and collection boundaries, such as `Actors`, `Chats`, `Tools`, `Configurations`, and `Endpoints`. +- Name each source file after its primary type. Use singular or plural type names according to the type's responsibility, not mechanically: `ActorEntity.cs`, `ChatSession.cs`, `ChatSessionsQuery.cs`, and `ActorsTool.cs` are all valid. +- Do not create a file whose name duplicates a folder merely to satisfy a naming rule; use the type's precise responsibility in the filename. - Classes, records, enums: PascalCase. - Interfaces: `I` prefix + PascalCase. - Private fields: `_camelCase`. diff --git a/docs/governance/project-guide-blazor.md b/docs/governance/project-guide-blazor.md index a824e53..512b88c 100644 --- a/docs/governance/project-guide-blazor.md +++ b/docs/governance/project-guide-blazor.md @@ -80,7 +80,7 @@ Features │ ├── HomePage.razor │ -├── Chat +├── Chats │ ├── ChatPage.razor │ ├── Components │ ├── Models @@ -101,6 +101,7 @@ Features ## Rules +- Use plural feature folders for collection boundaries, such as `Chats`, `Assets`, and `Attestations`; name files after their primary singular or plural type responsibility. - Features own their components. - Features own their models. - Features own their services. diff --git a/docs/governance/style-guide.md b/docs/governance/style-guide.md index b5a99ee..b9c8ac1 100644 --- a/docs/governance/style-guide.md +++ b/docs/governance/style-guide.md @@ -24,7 +24,9 @@ Define repository-wide documentation and collaboration style. - Update affected docs when behavior or requirements change. ## GitHub Issue Style -- Include business problem, value, acceptance criteria, and out-of-scope items. +- Bug reports require the problem, steps to reproduce, expected behavior, error page URL, and screenshot. +- Feature requests require the problem and requested outcome; contributors may add supporting context when useful. +- Maintainers expand accepted work into feature documentation only when implementation planning needs additional detail. ## Pull Request Style - Summarize intent, changed layers, testing evidence, and follow-up risks. diff --git a/src/Core.Application/Abstractions/IAgentFrameworkContext.cs b/src/Core.Application/Abstractions/IAgentFrameworkContext.cs index f230365..3e2bfd9 100644 --- a/src/Core.Application/Abstractions/IAgentFrameworkContext.cs +++ b/src/Core.Application/Abstractions/IAgentFrameworkContext.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Domain.Actor; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Actors; +using Goodtocode.AgentFramework.Core.Domain.Chats; using Microsoft.EntityFrameworkCore.Metadata; namespace Goodtocode.AgentFramework.Core.Application.Abstractions; diff --git a/src/Core.Application/Actors/ActorDto.cs b/src/Core.Application/Actors/ActorDto.cs index 81af883..744a02c 100644 --- a/src/Core.Application/Actors/ActorDto.cs +++ b/src/Core.Application/Actors/ActorDto.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Domain.Actors; -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class ActorDto { diff --git a/src/Core.Application/Actors/ActorGuard.cs b/src/Core.Application/Actors/ActorGuard.cs index da71625..dbcde28 100644 --- a/src/Core.Application/Actors/ActorGuard.cs +++ b/src/Core.Application/Actors/ActorGuard.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public static class ActorGuard { diff --git a/src/Core.Application/Actors/CreateOurActorCommand.cs b/src/Core.Application/Actors/CreateOurActorCommand.cs index 2cefe7b..f7524f5 100644 --- a/src/Core.Application/Actors/CreateOurActorCommand.cs +++ b/src/Core.Application/Actors/CreateOurActorCommand.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Domain.Actors; -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class CreateOurActorCommand : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Actors/CreateOurActorCommandValidator.cs b/src/Core.Application/Actors/CreateOurActorCommandValidator.cs index 96d8776..955f4c7 100644 --- a/src/Core.Application/Actors/CreateOurActorCommandValidator.cs +++ b/src/Core.Application/Actors/CreateOurActorCommandValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class CreateOurActorCommandValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommand.cs b/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommand.cs index 08e50de..f58292c 100644 --- a/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommand.cs +++ b/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommand.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class DeleteActorByOwnerIdCommand : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommandValidator.cs b/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommandValidator.cs index 8fe05ad..fbebddd 100644 --- a/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommandValidator.cs +++ b/src/Core.Application/Actors/DeleteOurActorByOwnerIdCommandValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class DeleteOurActorByOwnerIdCommandValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/DeleteOurActorCommand.cs b/src/Core.Application/Actors/DeleteOurActorCommand.cs index c1a8252..3d2965c 100644 --- a/src/Core.Application/Actors/DeleteOurActorCommand.cs +++ b/src/Core.Application/Actors/DeleteOurActorCommand.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class DeleteOurActorCommand : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Actors/DeleteOurActorCommandValidator.cs b/src/Core.Application/Actors/DeleteOurActorCommandValidator.cs index 92434a5..d10b613 100644 --- a/src/Core.Application/Actors/DeleteOurActorCommandValidator.cs +++ b/src/Core.Application/Actors/DeleteOurActorCommandValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class DeleteOurActorCommandValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/GetMyActorQuery.cs b/src/Core.Application/Actors/GetMyActorQuery.cs index 1390d81..b6d95d7 100644 --- a/src/Core.Application/Actors/GetMyActorQuery.cs +++ b/src/Core.Application/Actors/GetMyActorQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetMyActorQuery : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Actors/GetMyActorQueryValidator.cs b/src/Core.Application/Actors/GetMyActorQueryValidator.cs index 11b5d7c..093d8cf 100644 --- a/src/Core.Application/Actors/GetMyActorQueryValidator.cs +++ b/src/Core.Application/Actors/GetMyActorQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetMyActorQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/GetOurActorChatSessionQuery.cs b/src/Core.Application/Actors/GetOurActorChatSessionQuery.cs index 286e71e..59dbb69 100644 --- a/src/Core.Application/Actors/GetOurActorChatSessionQuery.cs +++ b/src/Core.Application/Actors/GetOurActorChatSessionQuery.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorChatSessionQuery : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Actors/GetOurActorChatSessionQueryValidator.cs b/src/Core.Application/Actors/GetOurActorChatSessionQueryValidator.cs index 5e57f96..edff521 100644 --- a/src/Core.Application/Actors/GetOurActorChatSessionQueryValidator.cs +++ b/src/Core.Application/Actors/GetOurActorChatSessionQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorChatSessionQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQuery.cs b/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQuery.cs index 657d30f..f57e5e0 100644 --- a/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQuery.cs +++ b/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQuery.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorChatSessionsPaginatedQuery : UserScopedRequest, IRequest> { diff --git a/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQueryValidator.cs b/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQueryValidator.cs index 8825835..dc76c6a 100644 --- a/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQueryValidator.cs +++ b/src/Core.Application/Actors/GetOurActorChatSessionsPaginatedQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorChatSessionsPaginatedQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/GetOurActorChatSessionsQuery.cs b/src/Core.Application/Actors/GetOurActorChatSessionsQuery.cs index 09ff9b4..83f6937 100644 --- a/src/Core.Application/Actors/GetOurActorChatSessionsQuery.cs +++ b/src/Core.Application/Actors/GetOurActorChatSessionsQuery.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorChatSessionsQuery : UserScopedRequest, IRequest> { diff --git a/src/Core.Application/Actors/GetOurActorChatSessionsQueryValidator.cs b/src/Core.Application/Actors/GetOurActorChatSessionsQueryValidator.cs index 8b3e87d..eb386bc 100644 --- a/src/Core.Application/Actors/GetOurActorChatSessionsQueryValidator.cs +++ b/src/Core.Application/Actors/GetOurActorChatSessionsQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorChatSessionsQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/GetOurActorQuery.cs b/src/Core.Application/Actors/GetOurActorQuery.cs index 241a139..6f9a5f4 100644 --- a/src/Core.Application/Actors/GetOurActorQuery.cs +++ b/src/Core.Application/Actors/GetOurActorQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorQuery : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Actors/GetOurActorQueryValidator.cs b/src/Core.Application/Actors/GetOurActorQueryValidator.cs index a5c5907..aee4094 100644 --- a/src/Core.Application/Actors/GetOurActorQueryValidator.cs +++ b/src/Core.Application/Actors/GetOurActorQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/GetOurActorsByNameQuery.cs b/src/Core.Application/Actors/GetOurActorsByNameQuery.cs index 414be5e..1c4ef8d 100644 --- a/src/Core.Application/Actors/GetOurActorsByNameQuery.cs +++ b/src/Core.Application/Actors/GetOurActorsByNameQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorsByNameQuery : UserScopedRequest, IRequest> { diff --git a/src/Core.Application/Actors/GetOurActorsByNameQueryValidator.cs b/src/Core.Application/Actors/GetOurActorsByNameQueryValidator.cs index 93ffebf..7f13383 100644 --- a/src/Core.Application/Actors/GetOurActorsByNameQueryValidator.cs +++ b/src/Core.Application/Actors/GetOurActorsByNameQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class GetOurActorsByNameQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Actors/SaveMyActorCommand.cs b/src/Core.Application/Actors/SaveMyActorCommand.cs index e3536f0..e36c28d 100644 --- a/src/Core.Application/Actors/SaveMyActorCommand.cs +++ b/src/Core.Application/Actors/SaveMyActorCommand.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Domain.Actors; -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class SaveMyActorCommand : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Actors/SaveMyActorCommandValidator.cs b/src/Core.Application/Actors/SaveMyActorCommandValidator.cs index 51f6967..f207656 100644 --- a/src/Core.Application/Actors/SaveMyActorCommandValidator.cs +++ b/src/Core.Application/Actors/SaveMyActorCommandValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actor; +namespace Goodtocode.AgentFramework.Core.Application.Actors; public class SaveMyActorCommandValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/ChatGuard.cs b/src/Core.Application/Chats/ChatGuard.cs index 61da490..5f1e0fc 100644 --- a/src/Core.Application/Chats/ChatGuard.cs +++ b/src/Core.Application/Chats/ChatGuard.cs @@ -1,7 +1,7 @@ -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Chats; using Microsoft.Extensions.AI; -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public static class ChatGuard { diff --git a/src/Core.Application/Chats/ChatMessageDto.cs b/src/Core.Application/Chats/ChatMessageDto.cs index 447dcc4..ae8f824 100644 --- a/src/Core.Application/Chats/ChatMessageDto.cs +++ b/src/Core.Application/Chats/ChatMessageDto.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Chats; -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class ChatMessageDto { diff --git a/src/Core.Application/Chats/ChatSessionDto.cs b/src/Core.Application/Chats/ChatSessionDto.cs index 4349bcd..81ac784 100644 --- a/src/Core.Application/Chats/ChatSessionDto.cs +++ b/src/Core.Application/Chats/ChatSessionDto.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Chats; -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class ChatSessionDto { diff --git a/src/Core.Application/Chats/CreateMyChatMessageCommand.cs b/src/Core.Application/Chats/CreateMyChatMessageCommand.cs index 90cd4d7..ae60c1d 100644 --- a/src/Core.Application/Chats/CreateMyChatMessageCommand.cs +++ b/src/Core.Application/Chats/CreateMyChatMessageCommand.cs @@ -1,9 +1,9 @@ -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Chats; using Goodtocode.AgentFramework.Core.Application.Governance; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class CreateMyChatMessageCommand : UserScopedRequest, IRequest> { diff --git a/src/Core.Application/Chats/CreateMyChatMessageCommandValidator.cs b/src/Core.Application/Chats/CreateMyChatMessageCommandValidator.cs index f6cf481..5bb8a9b 100644 --- a/src/Core.Application/Chats/CreateMyChatMessageCommandValidator.cs +++ b/src/Core.Application/Chats/CreateMyChatMessageCommandValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class CreateMyChatMessageCommandValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/CreateMyChatSessionCommand.cs b/src/Core.Application/Chats/CreateMyChatSessionCommand.cs index 9bb7d21..0f8530e 100644 --- a/src/Core.Application/Chats/CreateMyChatSessionCommand.cs +++ b/src/Core.Application/Chats/CreateMyChatSessionCommand.cs @@ -1,10 +1,10 @@ -using Goodtocode.AgentFramework.Core.Domain.Actor; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Actors; +using Goodtocode.AgentFramework.Core.Domain.Chats; using Goodtocode.AgentFramework.Core.Application.Governance; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class CreateMyChatSessionCommand : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Chats/CreateMyChatSessionCommandValidator.cs b/src/Core.Application/Chats/CreateMyChatSessionCommandValidator.cs index aca3160..d220a90 100644 --- a/src/Core.Application/Chats/CreateMyChatSessionCommandValidator.cs +++ b/src/Core.Application/Chats/CreateMyChatSessionCommandValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class CreateMyChatSessionCommandValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/DeleteMyChatSessionCommand.cs b/src/Core.Application/Chats/DeleteMyChatSessionCommand.cs index 61f9ca9..7967db5 100644 --- a/src/Core.Application/Chats/DeleteMyChatSessionCommand.cs +++ b/src/Core.Application/Chats/DeleteMyChatSessionCommand.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class DeleteMyChatSessionCommand : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Chats/DeleteMyChatSessionCommandValidator.cs b/src/Core.Application/Chats/DeleteMyChatSessionCommandValidator.cs index 7b0536c..4529f80 100644 --- a/src/Core.Application/Chats/DeleteMyChatSessionCommandValidator.cs +++ b/src/Core.Application/Chats/DeleteMyChatSessionCommandValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class DeleteMyChatSessionCommandValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/GetMyChatMessageQuery.cs b/src/Core.Application/Chats/GetMyChatMessageQuery.cs index 1099452..ef37d71 100644 --- a/src/Core.Application/Chats/GetMyChatMessageQuery.cs +++ b/src/Core.Application/Chats/GetMyChatMessageQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatMessageQuery : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Chats/GetMyChatMessageQueryValidator.cs b/src/Core.Application/Chats/GetMyChatMessageQueryValidator.cs index 3688bac..ba69e39 100644 --- a/src/Core.Application/Chats/GetMyChatMessageQueryValidator.cs +++ b/src/Core.Application/Chats/GetMyChatMessageQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatMessageQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/GetMyChatMessagesPaginatedQuery.cs b/src/Core.Application/Chats/GetMyChatMessagesPaginatedQuery.cs index 8bedfbb..aa55939 100644 --- a/src/Core.Application/Chats/GetMyChatMessagesPaginatedQuery.cs +++ b/src/Core.Application/Chats/GetMyChatMessagesPaginatedQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatMessagesPaginatedQuery : UserScopedRequest, IRequest> { diff --git a/src/Core.Application/Chats/GetMyChatMessagesPaginatedQueryValidator.cs b/src/Core.Application/Chats/GetMyChatMessagesPaginatedQueryValidator.cs index bed6e21..29923b0 100644 --- a/src/Core.Application/Chats/GetMyChatMessagesPaginatedQueryValidator.cs +++ b/src/Core.Application/Chats/GetMyChatMessagesPaginatedQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatMessagesPaginatedQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/GetMyChatSessionMessagesQuery.cs b/src/Core.Application/Chats/GetMyChatSessionMessagesQuery.cs index c942052..90caa32 100644 --- a/src/Core.Application/Chats/GetMyChatSessionMessagesQuery.cs +++ b/src/Core.Application/Chats/GetMyChatSessionMessagesQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatSessionMessagesQuery : UserScopedRequest, IRequest> { diff --git a/src/Core.Application/Chats/GetMyChatSessionMessagesQueryValidator.cs b/src/Core.Application/Chats/GetMyChatSessionMessagesQueryValidator.cs index 7dc4d90..3a4e485 100644 --- a/src/Core.Application/Chats/GetMyChatSessionMessagesQueryValidator.cs +++ b/src/Core.Application/Chats/GetMyChatSessionMessagesQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatSessionMessagesQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/GetMyChatSessionQuery.cs b/src/Core.Application/Chats/GetMyChatSessionQuery.cs index 0fc29b4..76dbcfd 100644 --- a/src/Core.Application/Chats/GetMyChatSessionQuery.cs +++ b/src/Core.Application/Chats/GetMyChatSessionQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatSessionQuery : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Chats/GetMyChatSessionQueryValidator.cs b/src/Core.Application/Chats/GetMyChatSessionQueryValidator.cs index fac9808..e2ba9b2 100644 --- a/src/Core.Application/Chats/GetMyChatSessionQueryValidator.cs +++ b/src/Core.Application/Chats/GetMyChatSessionQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatSessionQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/GetMyChatSessionsPaginatedQuery.cs b/src/Core.Application/Chats/GetMyChatSessionsPaginatedQuery.cs index 047c74f..c345b09 100644 --- a/src/Core.Application/Chats/GetMyChatSessionsPaginatedQuery.cs +++ b/src/Core.Application/Chats/GetMyChatSessionsPaginatedQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatSessionsPaginatedQuery : UserScopedRequest, IRequest> { diff --git a/src/Core.Application/Chats/GetMyChatSessionsPaginatedQueryValidator.cs b/src/Core.Application/Chats/GetMyChatSessionsPaginatedQueryValidator.cs index 565d2f8..dcae49b 100644 --- a/src/Core.Application/Chats/GetMyChatSessionsPaginatedQueryValidator.cs +++ b/src/Core.Application/Chats/GetMyChatSessionsPaginatedQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatSessionsPaginatedQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/GetMyChatSessionsQuery.cs b/src/Core.Application/Chats/GetMyChatSessionsQuery.cs index a38ec0b..55fa0e9 100644 --- a/src/Core.Application/Chats/GetMyChatSessionsQuery.cs +++ b/src/Core.Application/Chats/GetMyChatSessionsQuery.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatSessionsQuery : UserScopedRequest, IRequest> { diff --git a/src/Core.Application/Chats/GetMyChatSessionsQueryValidator.cs b/src/Core.Application/Chats/GetMyChatSessionsQueryValidator.cs index 26163c3..82be05b 100644 --- a/src/Core.Application/Chats/GetMyChatSessionsQueryValidator.cs +++ b/src/Core.Application/Chats/GetMyChatSessionsQueryValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class GetMyChatSessionsQueryValidator : SecuredValidator { diff --git a/src/Core.Application/Chats/PatchMyChatSessionCommand.cs b/src/Core.Application/Chats/PatchMyChatSessionCommand.cs index 8d08b0f..998182b 100644 --- a/src/Core.Application/Chats/PatchMyChatSessionCommand.cs +++ b/src/Core.Application/Chats/PatchMyChatSessionCommand.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class PatchMyChatSessionCommand : UserScopedRequest, IRequest { diff --git a/src/Core.Application/Chats/PatchMyChatSessionCommandValidator.cs b/src/Core.Application/Chats/PatchMyChatSessionCommandValidator.cs index 1eb80c6..97c72b2 100644 --- a/src/Core.Application/Chats/PatchMyChatSessionCommandValidator.cs +++ b/src/Core.Application/Chats/PatchMyChatSessionCommandValidator.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chat; +namespace Goodtocode.AgentFramework.Core.Application.Chats; public class PatchMyChatSessionCommandValidator : SecuredValidator { diff --git a/src/Core.Domain/Actors/ActorEntity.cs b/src/Core.Domain/Actors/ActorEntity.cs index 11cf5a5..532ec3a 100644 --- a/src/Core.Domain/Actors/ActorEntity.cs +++ b/src/Core.Domain/Actors/ActorEntity.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Domain.Actor; +namespace Goodtocode.AgentFramework.Core.Domain.Actors; public class ActorEntity : SecuredEntity { diff --git a/src/Core.Domain/Chats/ChatMessageEntity.cs b/src/Core.Domain/Chats/ChatMessageEntity.cs index 44bcabf..c84ec9f 100644 --- a/src/Core.Domain/Chats/ChatMessageEntity.cs +++ b/src/Core.Domain/Chats/ChatMessageEntity.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Domain.Chat; +namespace Goodtocode.AgentFramework.Core.Domain.Chats; public class ChatMessageEntity : SecuredEntity, IDomainEntity { diff --git a/src/Core.Domain/Chats/ChatMessageRoles.cs b/src/Core.Domain/Chats/ChatMessageRoles.cs index 0199cd5..b98a163 100644 --- a/src/Core.Domain/Chats/ChatMessageRoles.cs +++ b/src/Core.Domain/Chats/ChatMessageRoles.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Domain.Chat; +namespace Goodtocode.AgentFramework.Core.Domain.Chats; public enum ChatMessageRole { diff --git a/src/Core.Domain/Chats/ChatSessionEntity.cs b/src/Core.Domain/Chats/ChatSessionEntity.cs index e8b7afd..9b58c5a 100644 --- a/src/Core.Domain/Chats/ChatSessionEntity.cs +++ b/src/Core.Domain/Chats/ChatSessionEntity.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Core.Domain.Chat; +namespace Goodtocode.AgentFramework.Core.Domain.Chats; public class ChatSessionEntity : SecuredEntity { diff --git a/src/Infrastructure.AgentFramework/Tools/ActorsTool.cs b/src/Infrastructure.AgentFramework/Tools/ActorsTool.cs index 8a8e38b..3ebef60 100644 --- a/src/Infrastructure.AgentFramework/Tools/ActorsTool.cs +++ b/src/Infrastructure.AgentFramework/Tools/ActorsTool.cs @@ -1,5 +1,5 @@ using System.ComponentModel; -using Goodtocode.AgentFramework.Core.Application.Actor; +using Goodtocode.AgentFramework.Core.Application.Actors; namespace Goodtocode.AgentFramework.Infrastructure.AgentFramework.Tools; diff --git a/src/Infrastructure.AgentFramework/Tools/ChatMessagesTool.cs b/src/Infrastructure.AgentFramework/Tools/ChatMessagesTool.cs index 03d91f7..2d5cbc2 100644 --- a/src/Infrastructure.AgentFramework/Tools/ChatMessagesTool.cs +++ b/src/Infrastructure.AgentFramework/Tools/ChatMessagesTool.cs @@ -1,5 +1,5 @@ using System.ComponentModel; -using Goodtocode.AgentFramework.Core.Application.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; namespace Goodtocode.AgentFramework.Infrastructure.AgentFramework.Tools; diff --git a/src/Infrastructure.AgentFramework/Tools/ChatSessionsTool.cs b/src/Infrastructure.AgentFramework/Tools/ChatSessionsTool.cs index 17e0894..a8b4654 100644 --- a/src/Infrastructure.AgentFramework/Tools/ChatSessionsTool.cs +++ b/src/Infrastructure.AgentFramework/Tools/ChatSessionsTool.cs @@ -1,5 +1,5 @@ using System.ComponentModel; -using Goodtocode.AgentFramework.Core.Application.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; namespace Goodtocode.AgentFramework.Infrastructure.AgentFramework.Tools; diff --git a/src/Infrastructure.SqlServer/Persistence/AgentFrameworkContext.cs b/src/Infrastructure.SqlServer/Persistence/AgentFrameworkContext.cs index 43e1525..eb4491c 100644 --- a/src/Infrastructure.SqlServer/Persistence/AgentFrameworkContext.cs +++ b/src/Infrastructure.SqlServer/Persistence/AgentFrameworkContext.cs @@ -1,7 +1,7 @@ using System.Reflection; using Goodtocode.AgentFramework.Core.Application.Abstractions; -using Goodtocode.AgentFramework.Core.Domain.Actor; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Actors; +using Goodtocode.AgentFramework.Core.Domain.Chats; using Microsoft.EntityFrameworkCore.ChangeTracking; namespace Goodtocode.AgentFramework.Infrastructure.SqlServer.Persistence; diff --git a/src/Infrastructure.SqlServer/Persistence/Configurations/ActorsConfig.cs b/src/Infrastructure.SqlServer/Persistence/Configurations/ActorsConfig.cs index 74cd99b..782e4af 100644 --- a/src/Infrastructure.SqlServer/Persistence/Configurations/ActorsConfig.cs +++ b/src/Infrastructure.SqlServer/Persistence/Configurations/ActorsConfig.cs @@ -1,4 +1,4 @@ -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Domain.Actors; namespace Goodtocode.AgentFramework.Infrastructure.SqlServer.Persistence.Configurations; diff --git a/src/Infrastructure.SqlServer/Persistence/Configurations/ChatMessagesConfig.cs b/src/Infrastructure.SqlServer/Persistence/Configurations/ChatMessagesConfig.cs index 7565f41..191d86f 100644 --- a/src/Infrastructure.SqlServer/Persistence/Configurations/ChatMessagesConfig.cs +++ b/src/Infrastructure.SqlServer/Persistence/Configurations/ChatMessagesConfig.cs @@ -1,4 +1,4 @@ -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Infrastructure.SqlServer.Persistence.Configurations; diff --git a/src/Infrastructure.SqlServer/Persistence/Configurations/ChatSessionsConfig.cs b/src/Infrastructure.SqlServer/Persistence/Configurations/ChatSessionsConfig.cs index b870908..e1cd0e9 100644 --- a/src/Infrastructure.SqlServer/Persistence/Configurations/ChatSessionsConfig.cs +++ b/src/Infrastructure.SqlServer/Persistence/Configurations/ChatSessionsConfig.cs @@ -1,4 +1,4 @@ -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Infrastructure.SqlServer.Persistence.Configurations; diff --git a/src/Presentation.Api/Endpoints/Actors/MyActorEndpoints.cs b/src/Presentation.Api/Endpoints/Actors/MyActorEndpoints.cs index 65e23dd..8e7ce1d 100644 --- a/src/Presentation.Api/Endpoints/Actors/MyActorEndpoints.cs +++ b/src/Presentation.Api/Endpoints/Actors/MyActorEndpoints.cs @@ -1,4 +1,4 @@ -using Goodtocode.AgentFramework.Core.Application.Actor; +using Goodtocode.AgentFramework.Core.Application.Actors; namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Actor; diff --git a/src/Presentation.Api/Endpoints/Chats/MyChatMessageEndpoints.cs b/src/Presentation.Api/Endpoints/Chats/MyChatMessageEndpoints.cs index 0ad98c9..25193b1 100644 --- a/src/Presentation.Api/Endpoints/Chats/MyChatMessageEndpoints.cs +++ b/src/Presentation.Api/Endpoints/Chats/MyChatMessageEndpoints.cs @@ -1,4 +1,4 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Chat; diff --git a/src/Presentation.Api/Endpoints/Chats/MyChatSessionEndpoints.cs b/src/Presentation.Api/Endpoints/Chats/MyChatSessionEndpoints.cs index 4663c1a..9b58d80 100644 --- a/src/Presentation.Api/Endpoints/Chats/MyChatSessionEndpoints.cs +++ b/src/Presentation.Api/Endpoints/Chats/MyChatSessionEndpoints.cs @@ -1,4 +1,4 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Chat; diff --git a/src/Presentation.Web/ConfigureServices.cs b/src/Presentation.Web/ConfigureServices.cs index b771f33..38fed3d 100644 --- a/src/Presentation.Web/ConfigureServices.cs +++ b/src/Presentation.Web/ConfigureServices.cs @@ -1,8 +1,8 @@ using System.Reflection; using Goodtocode.AgentFramework.Presentation.Web.Infrastructure.Auth; using Goodtocode.AgentFramework.Presentation.Web.Infrastructure.Storage; -using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Services; -using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Formatting; +using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Services; +using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Formatting; using Microsoft.Extensions.Options; using Microsoft.FluentUI.AspNetCore.Components; using Goodtocode.AgentFramework.Presentation.Web.Library.Auth.Services; diff --git a/src/Presentation.Web/Features/Chats/ChatPage.razor b/src/Presentation.Web/Features/Chats/ChatPage.razor index 6a6d07b..53dd56c 100644 --- a/src/Presentation.Web/Features/Chats/ChatPage.razor +++ b/src/Presentation.Web/Features/Chats/ChatPage.razor @@ -1,13 +1,13 @@ @page "/chat" -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Components -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Services +@using System.Text.RegularExpressions +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Components +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Services @using Goodtocode.AgentFramework.Presentation.Web.Library.Auth.Services @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.JSInterop -@using System.Text.RegularExpressions @attribute [Authorize] @implements IAsyncDisposable diff --git a/src/Presentation.Web/Features/Chats/Components/ChatActionStrip.razor b/src/Presentation.Web/Features/Chats/Components/ChatActionStrip.razor index d51e064..0af0d88 100644 --- a/src/Presentation.Web/Features/Chats/Components/ChatActionStrip.razor +++ b/src/Presentation.Web/Features/Chats/Components/ChatActionStrip.razor @@ -1,4 +1,4 @@ -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models @if (Actions.Count > 0) { diff --git a/src/Presentation.Web/Features/Chats/Components/ChatMessageList.razor b/src/Presentation.Web/Features/Chats/Components/ChatMessageList.razor index 472b599..f7fd898 100644 --- a/src/Presentation.Web/Features/Chats/Components/ChatMessageList.razor +++ b/src/Presentation.Web/Features/Chats/Components/ChatMessageList.razor @@ -1,7 +1,7 @@ -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Formatting -@using Microsoft.AspNetCore.Components @using System.Text.RegularExpressions +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Formatting +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models +@using Microsoft.AspNetCore.Components @inject IChatMessageFormatter ChatMessageFormatter diff --git a/src/Presentation.Web/Features/Chats/Components/ChatSessionList.razor b/src/Presentation.Web/Features/Chats/Components/ChatSessionList.razor index 5d81c62..5f3ac63 100644 --- a/src/Presentation.Web/Features/Chats/Components/ChatSessionList.razor +++ b/src/Presentation.Web/Features/Chats/Components/ChatSessionList.razor @@ -1,6 +1,6 @@ +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Services @using Goodtocode.AgentFramework.Presentation.Web.Library.Skeleton -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Services @inject IChatService chatService diff --git a/src/Presentation.Web/Features/Chats/Components/ChatSessionStrip.razor b/src/Presentation.Web/Features/Chats/Components/ChatSessionStrip.razor index b4e900d..bfbf0ab 100644 --- a/src/Presentation.Web/Features/Chats/Components/ChatSessionStrip.razor +++ b/src/Presentation.Web/Features/Chats/Components/ChatSessionStrip.razor @@ -1,6 +1,6 @@ +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Services @using Goodtocode.AgentFramework.Presentation.Web.Library.Skeleton -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Services @inject IChatService chatService diff --git a/src/Presentation.Web/Features/Chats/Components/NewChatMessageCard.razor b/src/Presentation.Web/Features/Chats/Components/NewChatMessageCard.razor index 7ccac09..212ac47 100644 --- a/src/Presentation.Web/Features/Chats/Components/NewChatMessageCard.razor +++ b/src/Presentation.Web/Features/Chats/Components/NewChatMessageCard.razor @@ -1,5 +1,5 @@ -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Services +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Services @inject IChatService chatService diff --git a/src/Presentation.Web/Features/Chats/Components/NewChatMessageInput.razor b/src/Presentation.Web/Features/Chats/Components/NewChatMessageInput.razor index d19cb80..f16ebaf 100644 --- a/src/Presentation.Web/Features/Chats/Components/NewChatMessageInput.razor +++ b/src/Presentation.Web/Features/Chats/Components/NewChatMessageInput.razor @@ -1,5 +1,5 @@ -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models -@using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Services +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models +@using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Services @inject IChatService chatService diff --git a/src/Presentation.Web/Features/Chats/Formatting/IChatMessageFormatter.cs b/src/Presentation.Web/Features/Chats/Formatting/IChatMessageFormatter.cs index ab5dd86..79ce009 100644 --- a/src/Presentation.Web/Features/Chats/Formatting/IChatMessageFormatter.cs +++ b/src/Presentation.Web/Features/Chats/Formatting/IChatMessageFormatter.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Formatting; +namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Formatting; public interface IChatMessageFormatter { diff --git a/src/Presentation.Web/Features/Chats/Formatting/MarkdownChatMessageFormatter.cs b/src/Presentation.Web/Features/Chats/Formatting/MarkdownChatMessageFormatter.cs index 85ba5e7..f520989 100644 --- a/src/Presentation.Web/Features/Chats/Formatting/MarkdownChatMessageFormatter.cs +++ b/src/Presentation.Web/Features/Chats/Formatting/MarkdownChatMessageFormatter.cs @@ -1,7 +1,7 @@ using System.Text.RegularExpressions; using Markdig; -namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Formatting; +namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Formatting; public sealed partial class MarkdownChatMessageFormatter : IChatMessageFormatter { diff --git a/src/Presentation.Web/Features/Chats/Models/ChatActionOption.cs b/src/Presentation.Web/Features/Chats/Models/ChatActionOption.cs index 6e866d9..53e1726 100644 --- a/src/Presentation.Web/Features/Chats/Models/ChatActionOption.cs +++ b/src/Presentation.Web/Features/Chats/Models/ChatActionOption.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models; +namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models; public sealed class ChatActionOption { diff --git a/src/Presentation.Web/Features/Chats/Models/ChatMessageModel.cs b/src/Presentation.Web/Features/Chats/Models/ChatMessageModel.cs index e78fbbf..f67ba4c 100644 --- a/src/Presentation.Web/Features/Chats/Models/ChatMessageModel.cs +++ b/src/Presentation.Web/Features/Chats/Models/ChatMessageModel.cs @@ -1,4 +1,4 @@ -namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models; +namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models; public class ChatMessageModel { diff --git a/src/Presentation.Web/Features/Chats/Models/ChatSessionModel.cs b/src/Presentation.Web/Features/Chats/Models/ChatSessionModel.cs index b5c547f..5ddf1f4 100644 --- a/src/Presentation.Web/Features/Chats/Models/ChatSessionModel.cs +++ b/src/Presentation.Web/Features/Chats/Models/ChatSessionModel.cs @@ -1,6 +1,6 @@ using System.ComponentModel; -namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models; +namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models; public class ChatSessionModel : INotifyPropertyChanged { diff --git a/src/Presentation.Web/Features/Chats/Models/ChatSessionTreeViewItem.cs b/src/Presentation.Web/Features/Chats/Models/ChatSessionTreeViewItem.cs index 5b7f2d1..4597ea3 100644 --- a/src/Presentation.Web/Features/Chats/Models/ChatSessionTreeViewItem.cs +++ b/src/Presentation.Web/Features/Chats/Models/ChatSessionTreeViewItem.cs @@ -1,6 +1,6 @@ using Microsoft.FluentUI.AspNetCore.Components; -namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models +namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models { public class ChatSessionTreeViewItem(ChatSessionModel session) : ITreeViewItem { diff --git a/src/Presentation.Web/Features/Chats/Models/ChatSessionsModel.cs b/src/Presentation.Web/Features/Chats/Models/ChatSessionsModel.cs index a2f365a..6f3f9f9 100644 --- a/src/Presentation.Web/Features/Chats/Models/ChatSessionsModel.cs +++ b/src/Presentation.Web/Features/Chats/Models/ChatSessionsModel.cs @@ -1,7 +1,7 @@ using System.Collections.ObjectModel; using System.ComponentModel; -namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models; +namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models; public class ChatSessionsModel : Collection { diff --git a/src/Presentation.Web/Features/Chats/Services/ChatService.cs b/src/Presentation.Web/Features/Chats/Services/ChatService.cs index 15bb8a4..3a0ff48 100644 --- a/src/Presentation.Web/Features/Chats/Services/ChatService.cs +++ b/src/Presentation.Web/Features/Chats/Services/ChatService.cs @@ -1,8 +1,8 @@ using Goodtocode.AgentFramework.Presentation.Web.Infrastructure.Http; -using Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Models; +using Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Models; using Goodtocode.AgentFramework.Presentation.Web.Library.Auth; -namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chat.Services; +namespace Goodtocode.AgentFramework.Presentation.Web.Features.Chats.Services; public interface IChatService { diff --git a/src/Tests.Integration/Actors/CreateActorCommand.feature.cs b/src/Tests.Integration/Actors/CreateActorCommand.feature.cs index e651fda..835ff4b 100644 --- a/src/Tests.Integration/Actors/CreateActorCommand.feature.cs +++ b/src/Tests.Integration/Actors/CreateActorCommand.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Actor +namespace Goodtocode.AgentFramework.Tests.Integration.Actors { @@ -28,7 +28,7 @@ public partial class CreateActorCommandFeature private static string[] featureTags = new string[] { "createActorCommand"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actor", "Create Actor Command", "As a owner\r\nWhen I want to save a new Actor\r\nThen I should see the Actor created " + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actors", "Create Actor Command", "As a owner\r\nWhen I want to save a new Actor\r\nThen I should see the Actor created " + "with the initial response", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "CreateActorCommand.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actor/CreateActorCommand.feature.ndjson", 3); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actors/CreateActorCommand.feature.ndjson", 3); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Create Actor")] diff --git a/src/Tests.Integration/Actors/CreateActorCommandStepDefinitions.cs b/src/Tests.Integration/Actors/CreateActorCommandStepDefinitions.cs index 355e5f8..4460439 100644 --- a/src/Tests.Integration/Actors/CreateActorCommandStepDefinitions.cs +++ b/src/Tests.Integration/Actors/CreateActorCommandStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Actor; -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; namespace Goodtocode.AgentFramework.Tests.Integration.Actor; diff --git a/src/Tests.Integration/Actors/DeleteActorCommand.feature.cs b/src/Tests.Integration/Actors/DeleteActorCommand.feature.cs index d9151ae..adafe39 100644 --- a/src/Tests.Integration/Actors/DeleteActorCommand.feature.cs +++ b/src/Tests.Integration/Actors/DeleteActorCommand.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Actor +namespace Goodtocode.AgentFramework.Tests.Integration.Actors { @@ -28,7 +28,7 @@ public partial class DeleteActorCommandFeature private static string[] featureTags = new string[] { "deleteActorCommand"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actor", "Delete Actor Command", "As a Actor owner\r\nWhen I select a Actor\r\nI can delete the Actor", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actors", "Delete Actor Command", "As a Actor owner\r\nWhen I select a Actor\r\nI can delete the Actor", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "DeleteActorCommand.feature" #line hidden @@ -118,7 +118,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actor/DeleteActorCommand.feature.ndjson", 4); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actors/DeleteActorCommand.feature.ndjson", 4); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Delete Actor")] diff --git a/src/Tests.Integration/Actors/DeleteActorCommandStepDefinitions.cs b/src/Tests.Integration/Actors/DeleteActorCommandStepDefinitions.cs index 7f13b7a..67eb3e7 100644 --- a/src/Tests.Integration/Actors/DeleteActorCommandStepDefinitions.cs +++ b/src/Tests.Integration/Actors/DeleteActorCommandStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Actor; -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; namespace Goodtocode.AgentFramework.Tests.Integration.Actor { diff --git a/src/Tests.Integration/Actors/GetActorByOwnerIdQuery.feature.cs b/src/Tests.Integration/Actors/GetActorByOwnerIdQuery.feature.cs index 1c0f603..b20f348 100644 --- a/src/Tests.Integration/Actors/GetActorByOwnerIdQuery.feature.cs +++ b/src/Tests.Integration/Actors/GetActorByOwnerIdQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Actor +namespace Goodtocode.AgentFramework.Tests.Integration.Actors { @@ -28,7 +28,7 @@ public partial class GetActorByOwnerIdQueryFeature private static string[] featureTags = new string[] { "getAuthorByOwnerIdQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actor", "Get Actor By OwnerId Query", "As a actor owner\r\nWhen I select an existing Actor\r\nI can see the actor detail", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actors", "Get Actor By OwnerId Query", "As a actor owner\r\nWhen I select an existing Actor\r\nI can see the actor detail", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetActorByOwnerIdQuery.feature" #line hidden @@ -118,7 +118,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actor/GetActorByOwnerIdQuery.feature.ndjson", 4); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actors/GetActorByOwnerIdQuery.feature.ndjson", 4); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get Actor By OwnerId")] diff --git a/src/Tests.Integration/Actors/GetActorByOwnerIdQueryStepDefinitions.cs b/src/Tests.Integration/Actors/GetActorByOwnerIdQueryStepDefinitions.cs index 51f5572..0e5293d 100644 --- a/src/Tests.Integration/Actors/GetActorByOwnerIdQueryStepDefinitions.cs +++ b/src/Tests.Integration/Actors/GetActorByOwnerIdQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Actor; -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; namespace Goodtocode.AgentFramework.Tests.Integration.Actor; diff --git a/src/Tests.Integration/Actors/GetActorQuery.feature.cs b/src/Tests.Integration/Actors/GetActorQuery.feature.cs index a5b97ff..8ebd6b2 100644 --- a/src/Tests.Integration/Actors/GetActorQuery.feature.cs +++ b/src/Tests.Integration/Actors/GetActorQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Actor +namespace Goodtocode.AgentFramework.Tests.Integration.Actors { @@ -28,7 +28,7 @@ public partial class GetActorQueryFeature private static string[] featureTags = new string[] { "getAuthorQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actor", "Get Actor Query", "As a actor owner\r\nWhen I select an existing Actor\r\nI can see the actor detail", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actors", "Get Actor Query", "As a actor owner\r\nWhen I select an existing Actor\r\nI can see the actor detail", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetActorQuery.feature" #line hidden @@ -118,7 +118,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actor/GetActorQuery.feature.ndjson", 5); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actors/GetActorQuery.feature.ndjson", 5); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get Actor")] diff --git a/src/Tests.Integration/Actors/GetActorQueryStepDefinitions.cs b/src/Tests.Integration/Actors/GetActorQueryStepDefinitions.cs index 32cb946..9841d1f 100644 --- a/src/Tests.Integration/Actors/GetActorQueryStepDefinitions.cs +++ b/src/Tests.Integration/Actors/GetActorQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Actor; -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; namespace Goodtocode.AgentFramework.Tests.Integration.Actor; diff --git a/src/Tests.Integration/Actors/GetOurActorsByNameQuery.feature.cs b/src/Tests.Integration/Actors/GetOurActorsByNameQuery.feature.cs index f95681e..7ca7b9f 100644 --- a/src/Tests.Integration/Actors/GetOurActorsByNameQuery.feature.cs +++ b/src/Tests.Integration/Actors/GetOurActorsByNameQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Actor +namespace Goodtocode.AgentFramework.Tests.Integration.Actors { @@ -28,7 +28,7 @@ public partial class GetOurActorsByNameQueryFeature private static string[] featureTags = new string[] { "getOurActorsByNameQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actor", "Get Our Actors By Name Query", "As a tenant user\r\nWhen I search actors by name\r\nI receive only matching actors fr" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actors", "Get Our Actors By Name Query", "As a tenant user\r\nWhen I search actors by name\r\nI receive only matching actors fr" + "om my tenant", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetOurActorsByNameQuery.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actor/GetOurActorsByNameQuery.feature.ndjson", 6); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actors/GetOurActorsByNameQuery.feature.ndjson", 6); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get actors by name")] diff --git a/src/Tests.Integration/Actors/GetOurActorsByNameQueryStepDefinitions.cs b/src/Tests.Integration/Actors/GetOurActorsByNameQueryStepDefinitions.cs index 7440fd6..3f9dd0b 100644 --- a/src/Tests.Integration/Actors/GetOurActorsByNameQueryStepDefinitions.cs +++ b/src/Tests.Integration/Actors/GetOurActorsByNameQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Actor; -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; namespace Goodtocode.AgentFramework.Tests.Integration.Actor; diff --git a/src/Tests.Integration/Actors/SaveActorCommand.feature.cs b/src/Tests.Integration/Actors/SaveActorCommand.feature.cs index 1234395..264eb82 100644 --- a/src/Tests.Integration/Actors/SaveActorCommand.feature.cs +++ b/src/Tests.Integration/Actors/SaveActorCommand.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Actor +namespace Goodtocode.AgentFramework.Tests.Integration.Actors { @@ -28,7 +28,7 @@ public partial class SaveActorCommandFeature private static string[] featureTags = new string[] { "saveActorCommand"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actor", "Save Actor Command", "As a owner\r\nWhen I want to save a new Actor\r\nThen I should see the Actor created " + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Actors", "Save Actor Command", "As a owner\r\nWhen I want to save a new Actor\r\nThen I should see the Actor created " + "with the initial response", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "SaveActorCommand.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actor/SaveActorCommand.feature.ndjson", 3); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Actors/SaveActorCommand.feature.ndjson", 3); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Save Actor")] diff --git a/src/Tests.Integration/Actors/SaveActorCommandStepDefinitions.cs b/src/Tests.Integration/Actors/SaveActorCommandStepDefinitions.cs index ed8fcb1..4aa1069 100644 --- a/src/Tests.Integration/Actors/SaveActorCommandStepDefinitions.cs +++ b/src/Tests.Integration/Actors/SaveActorCommandStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Actor; -using Goodtocode.AgentFramework.Core.Domain.Actor; +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; namespace Goodtocode.AgentFramework.Tests.Integration.Actor; diff --git a/src/Tests.Integration/Application/NotFoundSemanticsTests.cs b/src/Tests.Integration/Application/NotFoundSemanticsTests.cs index 7ad99f6..993676c 100644 --- a/src/Tests.Integration/Application/NotFoundSemanticsTests.cs +++ b/src/Tests.Integration/Application/NotFoundSemanticsTests.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Actor; -using Goodtocode.AgentFramework.Core.Application.Chat; +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Application.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Application; diff --git a/src/Tests.Integration/Chats/CreateChatMessageCommand.feature.cs b/src/Tests.Integration/Chats/CreateChatMessageCommand.feature.cs index f7b1ec2..e80162b 100644 --- a/src/Tests.Integration/Chats/CreateChatMessageCommand.feature.cs +++ b/src/Tests.Integration/Chats/CreateChatMessageCommand.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class CreateChatMessageCommandFeature private static string[] featureTags = new string[] { "createChatMessageCommand"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Create Chat Message Command", "As a chat user\r\nWhen I start a new Chat Message and enter an initial message\r\nThe" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Create Chat Message Command", "As a chat user\r\nWhen I start a new Chat Message and enter an initial message\r\nThe" + "n I should see the Chat Message created with the initial response", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "CreateChatMessageCommand.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/CreateChatMessageCommand.feature.ndjson", 8); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/CreateChatMessageCommand.feature.ndjson", 8); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Create Chat Message")] diff --git a/src/Tests.Integration/Chats/CreateChatMessageCommandStepDefinitions.cs b/src/Tests.Integration/Chats/CreateChatMessageCommandStepDefinitions.cs index 63d4d96..16f6476 100644 --- a/src/Tests.Integration/Chats/CreateChatMessageCommandStepDefinitions.cs +++ b/src/Tests.Integration/Chats/CreateChatMessageCommandStepDefinitions.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Actor; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Actors; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat; diff --git a/src/Tests.Integration/Chats/CreateChatSessionCommand.feature.cs b/src/Tests.Integration/Chats/CreateChatSessionCommand.feature.cs index 52625de..e335abe 100644 --- a/src/Tests.Integration/Chats/CreateChatSessionCommand.feature.cs +++ b/src/Tests.Integration/Chats/CreateChatSessionCommand.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class CreateChatSessionCommandFeature private static string[] featureTags = new string[] { "createChatSessionCommand"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Create Chat Session Command", "As a chat user\r\nWhen I start a new chat session and enter an initial message\r\nThe" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Create Chat Session Command", "As a chat user\r\nWhen I start a new chat session and enter an initial message\r\nThe" + "n I should see the chat session created with the initial response", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "CreateChatSessionCommand.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/CreateChatSessionCommand.feature.ndjson", 4); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/CreateChatSessionCommand.feature.ndjson", 4); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Create Chat Session")] diff --git a/src/Tests.Integration/Chats/CreateChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chats/CreateChatSessionCommandStepDefinitions.cs index 689a708..80807c7 100644 --- a/src/Tests.Integration/Chats/CreateChatSessionCommandStepDefinitions.cs +++ b/src/Tests.Integration/Chats/CreateChatSessionCommandStepDefinitions.cs @@ -1,6 +1,6 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Actor; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Actors; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat; diff --git a/src/Tests.Integration/Chats/DeleteChatSessionCommand.feature.cs b/src/Tests.Integration/Chats/DeleteChatSessionCommand.feature.cs index b725ca0..94a7083 100644 --- a/src/Tests.Integration/Chats/DeleteChatSessionCommand.feature.cs +++ b/src/Tests.Integration/Chats/DeleteChatSessionCommand.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class DeleteChatSessionCommandFeature private static string[] featureTags = new string[] { "deleteChatSessionCommand"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Delete Chat Session Command", "As a chat session owner\r\nWhen I select a chat session\r\nI can delete the chat sess" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Delete Chat Session Command", "As a chat session owner\r\nWhen I select a chat session\r\nI can delete the chat sess" + "ion", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "DeleteChatSessionCommand.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/DeleteChatSessionCommand.feature.ndjson", 5); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/DeleteChatSessionCommand.feature.ndjson", 5); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Delete Chat Session")] diff --git a/src/Tests.Integration/Chats/DeleteChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chats/DeleteChatSessionCommandStepDefinitions.cs index 274b4ba..856b3a9 100644 --- a/src/Tests.Integration/Chats/DeleteChatSessionCommandStepDefinitions.cs +++ b/src/Tests.Integration/Chats/DeleteChatSessionCommandStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat { diff --git a/src/Tests.Integration/Chats/GetChatMessageQuery.feature.cs b/src/Tests.Integration/Chats/GetChatMessageQuery.feature.cs index 3319983..8ddbcca 100644 --- a/src/Tests.Integration/Chats/GetChatMessageQuery.feature.cs +++ b/src/Tests.Integration/Chats/GetChatMessageQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class GetChatMessageQueryFeature private static string[] featureTags = new string[] { "getChatMessageQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Get Chat Message Query", "As a chat user\r\nWhen I select an existing Chat Message\r\nI can see the chat histor" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Get Chat Message Query", "As a chat user\r\nWhen I select an existing Chat Message\r\nI can see the chat histor" + "y messages", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetChatMessageQuery.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/GetChatMessageQuery.feature.ndjson", 5); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/GetChatMessageQuery.feature.ndjson", 5); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get Chat Message")] diff --git a/src/Tests.Integration/Chats/GetChatMessageQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetChatMessageQueryStepDefinitions.cs index e1428c4..e8b2ec2 100644 --- a/src/Tests.Integration/Chats/GetChatMessageQueryStepDefinitions.cs +++ b/src/Tests.Integration/Chats/GetChatMessageQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat; diff --git a/src/Tests.Integration/Chats/GetChatMessagesPaginatedQuery.feature.cs b/src/Tests.Integration/Chats/GetChatMessagesPaginatedQuery.feature.cs index eba1f0f..420eb34 100644 --- a/src/Tests.Integration/Chats/GetChatMessagesPaginatedQuery.feature.cs +++ b/src/Tests.Integration/Chats/GetChatMessagesPaginatedQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class GetChatMessagesPaginatedQueryFeature private static string[] featureTags = new string[] { "getChatMessagesPaginatedQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Get Chat Messages Paginated Query", "As an owner of Chat Messages\r\nWhen I get Chat Messages all or by date range\r\nI ca" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Get Chat Messages Paginated Query", "As an owner of Chat Messages\r\nWhen I get Chat Messages all or by date range\r\nI ca" + "n get a paginated collection of Chat Messages", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetChatMessagesPaginatedQuery.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/GetChatMessagesPaginatedQuery.feature.ndjson", 7); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/GetChatMessagesPaginatedQuery.feature.ndjson", 7); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get Chat Messages paginated")] diff --git a/src/Tests.Integration/Chats/GetChatMessagesPaginatedQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetChatMessagesPaginatedQueryStepDefinitions.cs index c0513f3..cf8b853 100644 --- a/src/Tests.Integration/Chats/GetChatMessagesPaginatedQueryStepDefinitions.cs +++ b/src/Tests.Integration/Chats/GetChatMessagesPaginatedQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat; diff --git a/src/Tests.Integration/Chats/GetMyChatSessionMessagesQuery.feature.cs b/src/Tests.Integration/Chats/GetMyChatSessionMessagesQuery.feature.cs index 80769b3..b1920ff 100644 --- a/src/Tests.Integration/Chats/GetMyChatSessionMessagesQuery.feature.cs +++ b/src/Tests.Integration/Chats/GetMyChatSessionMessagesQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class GetMyChatSessionMessagesQueryFeature private static string[] featureTags = new string[] { "getMyChatSessionMessagesQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Get My Chat Session Messages Query", "As a chat-session owner\r\nWhen I request messages for a chat session\r\nI receive on" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Get My Chat Session Messages Query", "As a chat-session owner\r\nWhen I request messages for a chat session\r\nI receive on" + "ly messages that I own within my tenant", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetMyChatSessionMessagesQuery.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/GetMyChatSessionMessagesQuery.feature.ndjson", 6); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/GetMyChatSessionMessagesQuery.feature.ndjson", 6); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get chat session messages")] diff --git a/src/Tests.Integration/Chats/GetMyChatSessionMessagesQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetMyChatSessionMessagesQueryStepDefinitions.cs index c877936..866a504 100644 --- a/src/Tests.Integration/Chats/GetMyChatSessionMessagesQueryStepDefinitions.cs +++ b/src/Tests.Integration/Chats/GetMyChatSessionMessagesQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat; diff --git a/src/Tests.Integration/Chats/GetMyChatSessionQuery.feature.cs b/src/Tests.Integration/Chats/GetMyChatSessionQuery.feature.cs index 46b27d3..b0ce4df 100644 --- a/src/Tests.Integration/Chats/GetMyChatSessionQuery.feature.cs +++ b/src/Tests.Integration/Chats/GetMyChatSessionQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class GetChatSessionQueryFeature private static string[] featureTags = new string[] { "getChatSessionQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Get Chat Session Query", "As a chat user\r\nWhen I select an existing chat session\r\nI can see the chat histor" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Get Chat Session Query", "As a chat user\r\nWhen I select an existing chat session\r\nI can see the chat histor" + "y messages", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetMyChatSessionQuery.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/GetMyChatSessionQuery.feature.ndjson", 5); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/GetMyChatSessionQuery.feature.ndjson", 5); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get chat session")] diff --git a/src/Tests.Integration/Chats/GetMyChatSessionQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetMyChatSessionQueryStepDefinitions.cs index 60f1921..44e4ef9 100644 --- a/src/Tests.Integration/Chats/GetMyChatSessionQueryStepDefinitions.cs +++ b/src/Tests.Integration/Chats/GetMyChatSessionQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat; diff --git a/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQuery.feature.cs b/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQuery.feature.cs index e406fb3..cd5df06 100644 --- a/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQuery.feature.cs +++ b/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class GetChatSessionsPaginatedQueryFeature private static string[] featureTags = new string[] { "getChatSessionsPaginatedQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Get Chat Sessions Paginated Query", "As an owner of chat sessions\r\nWhen I get chat sessions all or by date range\r\nI ca" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Get Chat Sessions Paginated Query", "As an owner of chat sessions\r\nWhen I get chat sessions all or by date range\r\nI ca" + "n get a paginated collection of chat sessions", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetMyChatSessionsPaginatedQuery.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/GetMyChatSessionsPaginatedQuery.feature.ndjson", 7); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/GetMyChatSessionsPaginatedQuery.feature.ndjson", 7); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get chat sessions paginated")] diff --git a/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQueryStepDefinitions.cs index 1099e98..ba83479 100644 --- a/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQueryStepDefinitions.cs +++ b/src/Tests.Integration/Chats/GetMyChatSessionsPaginatedQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat; diff --git a/src/Tests.Integration/Chats/GetMyChatSessionsQuery.feature.cs b/src/Tests.Integration/Chats/GetMyChatSessionsQuery.feature.cs index 6e505b6..87ff2d9 100644 --- a/src/Tests.Integration/Chats/GetMyChatSessionsQuery.feature.cs +++ b/src/Tests.Integration/Chats/GetMyChatSessionsQuery.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class GetChatSessionsQueryFeature private static string[] featureTags = new string[] { "getChatSessionsQuery"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Get Chat Sessions Query", "As a session owner\r\nWhen I query chat sessions optionally by date range\r\nI get al" + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Get Chat Sessions Query", "As a session owner\r\nWhen I query chat sessions optionally by date range\r\nI get al" + "l sessions that fit the date range", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "GetMyChatSessionsQuery.feature" @@ -119,7 +119,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/GetMyChatSessionsQuery.feature.ndjson", 6); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/GetMyChatSessionsQuery.feature.ndjson", 6); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 7, DisplayName="Get chat sessions")] diff --git a/src/Tests.Integration/Chats/GetMyChatSessionsQueryStepDefinitions.cs b/src/Tests.Integration/Chats/GetMyChatSessionsQueryStepDefinitions.cs index 833f1c5..1f1606b 100644 --- a/src/Tests.Integration/Chats/GetMyChatSessionsQueryStepDefinitions.cs +++ b/src/Tests.Integration/Chats/GetMyChatSessionsQueryStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat; diff --git a/src/Tests.Integration/Chats/PatchChatSessionCommand.feature.cs b/src/Tests.Integration/Chats/PatchChatSessionCommand.feature.cs index 76bbd0b..8fcce71 100644 --- a/src/Tests.Integration/Chats/PatchChatSessionCommand.feature.cs +++ b/src/Tests.Integration/Chats/PatchChatSessionCommand.feature.cs @@ -11,7 +11,7 @@ #region Designer generated code #pragma warning disable using Reqnroll; -namespace Goodtocode.AgentFramework.Tests.Integration.Chat +namespace Goodtocode.AgentFramework.Tests.Integration.Chats { @@ -28,7 +28,7 @@ public partial class PatchChatSessionCommandFeature private static string[] featureTags = new string[] { "patchChatSessionCommand"}; - private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chat", "Patch ChatSession Command", "As a creator\r\nI can patch a chatSession ", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Chats", "Patch ChatSession Command", "As a creator\r\nI can patch a chatSession ", global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); #line 1 "PatchChatSessionCommand.feature" #line hidden @@ -118,7 +118,7 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() { - return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chat/PatchChatSessionCommand.feature.ndjson", 5); + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Chats/PatchChatSessionCommand.feature.ndjson", 5); } [global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute(callerLineNumber: 6, DisplayName="Patch Chat Session")] diff --git a/src/Tests.Integration/Chats/PatchChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chats/PatchChatSessionCommandStepDefinitions.cs index d70821e..7be8917 100644 --- a/src/Tests.Integration/Chats/PatchChatSessionCommandStepDefinitions.cs +++ b/src/Tests.Integration/Chats/PatchChatSessionCommandStepDefinitions.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; namespace Goodtocode.AgentFramework.Tests.Integration.Chat { diff --git a/src/Tests.Integration/Governance/ChatGovernanceInvocationTests.cs b/src/Tests.Integration/Governance/ChatGovernanceInvocationTests.cs index eb32bd1..9682166 100644 --- a/src/Tests.Integration/Governance/ChatGovernanceInvocationTests.cs +++ b/src/Tests.Integration/Governance/ChatGovernanceInvocationTests.cs @@ -1,5 +1,5 @@ -using Goodtocode.AgentFramework.Core.Application.Chat; -using Goodtocode.AgentFramework.Core.Domain.Chat; +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; using Microsoft.Extensions.AI; namespace Goodtocode.AgentFramework.Tests.Integration.Governance; From c1fb1a0680cd7ecd8c2488a4948cb4b92a50d8d2 Mon Sep 17 00:00:00 2001 From: "Robert J. Good" Date: Sat, 29 Aug 2026 00:05:18 -0700 Subject: [PATCH 3/6] updated to best practices --- src/Core.Application/Actor/ActorDto.cs | 38 ++++ src/Core.Application/Actor/ActorGuard.cs | 29 +++ .../Actor/CreateOurActorCommand.cs | 30 +++ .../Actor/CreateOurActorCommandValidator.cs | 16 ++ .../Actor/DeleteOurActorByOwnerIdCommand.cs | 26 +++ ...DeleteOurActorByOwnerIdCommandValidator.cs | 10 + .../Actor/DeleteOurActorCommand.cs | 26 +++ .../Actor/DeleteOurActorCommandValidator.cs | 10 + src/Core.Application/Actor/GetMyActorQuery.cs | 20 ++ .../Actor/GetMyActorQueryValidator.cs | 9 + .../Actor/GetOurActorChatSessionQuery.cs | 23 ++ .../GetOurActorChatSessionQueryValidator.cs | 10 + .../GetOurActorChatSessionsPaginatedQuery.cs | 32 +++ ...ctorChatSessionsPaginatedQueryValidator.cs | 22 ++ .../Actor/GetOurActorChatSessionsQuery.cs | 29 +++ .../GetOurActorChatSessionsQueryValidator.cs | 18 ++ .../Actor/GetOurActorQuery.cs | 19 ++ .../Actor/GetOurActorQueryValidator.cs | 9 + .../Actor/GetOurActorsByNameQuery.cs | 25 +++ .../Actor/GetOurActorsByNameQueryValidator.cs | 9 + .../Actor/SaveMyActorCommand.cs | 44 ++++ .../Actor/SaveMyActorCommandValidator.cs | 16 ++ src/Core.Application/Chat/ChatGuard.cs | 89 ++++++++ src/Core.Application/Chat/ChatMessageDto.cs | 29 +++ src/Core.Application/Chat/ChatSessionDto.cs | 29 +++ .../Chat/CreateMyChatMessageCommand.cs | 83 ++++++++ .../CreateMyChatMessageCommandValidator.cs | 13 ++ .../Chat/CreateMyChatSessionCommand.cs | 97 +++++++++ .../CreateMyChatSessionCommandValidator.cs | 10 + .../Chat/DeleteMyChatSessionCommand.cs | 30 +++ .../DeleteMyChatSessionCommandValidator.cs | 10 + .../Chat/GetMyChatMessageQuery.cs | 28 +++ .../Chat/GetMyChatMessageQueryValidator.cs | 10 + .../Chat/GetMyChatMessagesPaginatedQuery.cs | 38 ++++ ...etMyChatMessagesPaginatedQueryValidator.cs | 23 ++ .../Chat/GetMyChatSessionMessagesQuery.cs | 26 +++ .../GetMyChatSessionMessagesQueryValidator.cs | 9 + .../Chat/GetMyChatSessionQuery.cs | 30 +++ .../Chat/GetMyChatSessionQueryValidator.cs | 10 + .../Chat/GetMyChatSessionsPaginatedQuery.cs | 32 +++ ...etMyChatSessionsPaginatedQueryValidator.cs | 23 ++ .../Chat/GetMyChatSessionsQuery.cs | 33 +++ .../Chat/GetMyChatSessionsQueryValidator.cs | 17 ++ .../Chat/PatchMyChatSessionCommand.cs | 34 +++ .../PatchMyChatSessionCommandValidator.cs | 13 ++ src/Core.Domain/Actor/ActorEntity.cs | 58 ++++++ src/Core.Domain/Chat/ChatMessageEntity.cs | 52 +++++ src/Core.Domain/Chat/ChatMessageRoles.cs | 9 + src/Core.Domain/Chat/ChatSessionEntity.cs | 66 ++++++ .../Endpoints/Actor/MyActorEndpoints.cs | 57 +++++ .../Endpoints/Chat/MyChatMessageEndpoints.cs | 88 ++++++++ .../Endpoints/Chat/MyChatSessionEndpoints.cs | 93 +++++++++ .../CreateActorCommandStepDefinitions.cs | 100 +++++++++ .../DeleteActorCommandStepDefinitions.cs | 78 +++++++ .../GetActorByOwnerIdQueryStepDefinitions.cs | 86 ++++++++ .../Actor/GetActorQueryStepDefinitions.cs | 94 +++++++++ .../GetOurActorsByNameQueryStepDefinitions.cs | 96 +++++++++ .../Actor/SaveActorCommandStepDefinitions.cs | 98 +++++++++ ...CreateChatMessageCommandStepDefinitions.cs | 104 +++++++++ ...CreateChatSessionCommandStepDefinitions.cs | 93 +++++++++ ...DeleteChatSessionCommandStepDefinitions.cs | 77 +++++++ .../GetChatMessageQueryStepDefinitions.cs | 108 ++++++++++ ...atMessagesPaginatedQueryStepDefinitions.cs | 197 ++++++++++++++++++ ...ChatSessionMessagesQueryStepDefinitions.cs | 122 +++++++++++ .../GetMyChatSessionQueryStepDefinitions.cs | 93 +++++++++ ...atSessionsPaginatedQueryStepDefinitions.cs | 188 +++++++++++++++++ .../GetMyChatSessionsQueryStepDefinitions.cs | 130 ++++++++++++ .../PatchChatSessionCommandStepDefinitions.cs | 85 ++++++++ 68 files changed, 3358 insertions(+) create mode 100644 src/Core.Application/Actor/ActorDto.cs create mode 100644 src/Core.Application/Actor/ActorGuard.cs create mode 100644 src/Core.Application/Actor/CreateOurActorCommand.cs create mode 100644 src/Core.Application/Actor/CreateOurActorCommandValidator.cs create mode 100644 src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs create mode 100644 src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs create mode 100644 src/Core.Application/Actor/DeleteOurActorCommand.cs create mode 100644 src/Core.Application/Actor/DeleteOurActorCommandValidator.cs create mode 100644 src/Core.Application/Actor/GetMyActorQuery.cs create mode 100644 src/Core.Application/Actor/GetMyActorQueryValidator.cs create mode 100644 src/Core.Application/Actor/GetOurActorChatSessionQuery.cs create mode 100644 src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs create mode 100644 src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs create mode 100644 src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs create mode 100644 src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs create mode 100644 src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs create mode 100644 src/Core.Application/Actor/GetOurActorQuery.cs create mode 100644 src/Core.Application/Actor/GetOurActorQueryValidator.cs create mode 100644 src/Core.Application/Actor/GetOurActorsByNameQuery.cs create mode 100644 src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs create mode 100644 src/Core.Application/Actor/SaveMyActorCommand.cs create mode 100644 src/Core.Application/Actor/SaveMyActorCommandValidator.cs create mode 100644 src/Core.Application/Chat/ChatGuard.cs create mode 100644 src/Core.Application/Chat/ChatMessageDto.cs create mode 100644 src/Core.Application/Chat/ChatSessionDto.cs create mode 100644 src/Core.Application/Chat/CreateMyChatMessageCommand.cs create mode 100644 src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs create mode 100644 src/Core.Application/Chat/CreateMyChatSessionCommand.cs create mode 100644 src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs create mode 100644 src/Core.Application/Chat/DeleteMyChatSessionCommand.cs create mode 100644 src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs create mode 100644 src/Core.Application/Chat/GetMyChatMessageQuery.cs create mode 100644 src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs create mode 100644 src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs create mode 100644 src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs create mode 100644 src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs create mode 100644 src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs create mode 100644 src/Core.Application/Chat/GetMyChatSessionQuery.cs create mode 100644 src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs create mode 100644 src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs create mode 100644 src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs create mode 100644 src/Core.Application/Chat/GetMyChatSessionsQuery.cs create mode 100644 src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs create mode 100644 src/Core.Application/Chat/PatchMyChatSessionCommand.cs create mode 100644 src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs create mode 100644 src/Core.Domain/Actor/ActorEntity.cs create mode 100644 src/Core.Domain/Chat/ChatMessageEntity.cs create mode 100644 src/Core.Domain/Chat/ChatMessageRoles.cs create mode 100644 src/Core.Domain/Chat/ChatSessionEntity.cs create mode 100644 src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs create mode 100644 src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs create mode 100644 src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs create mode 100644 src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs create mode 100644 src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs create mode 100644 src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs create mode 100644 src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs diff --git a/src/Core.Application/Actor/ActorDto.cs b/src/Core.Application/Actor/ActorDto.cs new file mode 100644 index 0000000..744a02c --- /dev/null +++ b/src/Core.Application/Actor/ActorDto.cs @@ -0,0 +1,38 @@ +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class ActorDto +{ + public Guid Id { get; set; } = Guid.Empty; + public string Name { get; set; } = string.Empty; + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + public string Email { get; set; } = string.Empty; + public Guid OwnerId { get; set; } + public Guid TenantId { get; set; } + public DateTime CreatedOn { get; private set; } = DateTime.UtcNow; + public DateTime? ModifiedOn { get; private set; } + public DateTime? DeletedOn { get; private set; } + + public static ActorDto CreateFrom(ActorEntity? entity) + { + if (entity is null) + { + return null!; + } + + return new ActorDto + { + Id = entity.Id, + FirstName = entity.FirstName ?? string.Empty, + LastName = entity.LastName ?? string.Empty, + Email = entity.Email ?? string.Empty, + OwnerId = entity.OwnerId, + TenantId = entity.TenantId, + CreatedOn = entity.CreatedOn, + ModifiedOn = entity.ModifiedOn, + DeletedOn = entity.DeletedOn + }; + } +} diff --git a/src/Core.Application/Actor/ActorGuard.cs b/src/Core.Application/Actor/ActorGuard.cs new file mode 100644 index 0000000..dbcde28 --- /dev/null +++ b/src/Core.Application/Actor/ActorGuard.cs @@ -0,0 +1,29 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public static class ActorGuard +{ + public static void GuardAgainstEmptyUserContext(IUserContext? userContext) + { + if (userContext == null || userContext.OwnerId == Guid.Empty || userContext.TenantId == Guid.Empty) + throw new CustomValidationException([ + new("UserContext", "A valid UserContext with OwnerId and TenantId is required to link an actor.") + ]); + } + + public static void GuardAgainstInvalidUserContext(IUserContext? userContext) + { + if (userContext is null) + { + throw new CustomValidationException([ + new("UserContext", "UserContext is required to save an actor") + ]); + } + + if (userContext.OwnerId == Guid.Empty) + { + throw new CustomValidationException([ + new("OwnerId", "A valid OwnerId is required in UserContext to save an actor") + ]); + } + } +} diff --git a/src/Core.Application/Actor/CreateOurActorCommand.cs b/src/Core.Application/Actor/CreateOurActorCommand.cs new file mode 100644 index 0000000..f7524f5 --- /dev/null +++ b/src/Core.Application/Actor/CreateOurActorCommand.cs @@ -0,0 +1,30 @@ +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class CreateOurActorCommand : UserScopedRequest, IRequest +{ + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? Email { get; set; } +} + +public class CreateOurActorCommandHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(CreateOurActorCommand request, CancellationToken cancellationToken) + { + ActorGuard.GuardAgainstEmptyUserContext(request.UserContext); + var actor = ActorEntity.Create( + ownerId: request.UserContext.OwnerId, + tenantId: request.UserContext.TenantId, + firstName: request.FirstName, + lastName: request.LastName, + email: request.Email + ); + _context.Actors.Add(actor); + await _context.SaveChangesAsync(cancellationToken); + return ActorDto.CreateFrom(actor); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/CreateOurActorCommandValidator.cs b/src/Core.Application/Actor/CreateOurActorCommandValidator.cs new file mode 100644 index 0000000..955f4c7 --- /dev/null +++ b/src/Core.Application/Actor/CreateOurActorCommandValidator.cs @@ -0,0 +1,16 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class CreateOurActorCommandValidator : SecuredValidator +{ + public CreateOurActorCommandValidator() + { + RuleFor(x => x.FirstName) + .NotEmpty(); + + RuleFor(x => x.LastName) + .NotEmpty(); + + RuleFor(x => x.Email) + .NotEmpty(); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs b/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs new file mode 100644 index 0000000..f58292c --- /dev/null +++ b/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs @@ -0,0 +1,26 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class DeleteActorByOwnerIdCommand : UserScopedRequest, IRequest +{ + public Guid OwnerId { get; set; } + +} + +public class DeleteActorByOwnerIdCommandHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(DeleteActorByOwnerIdCommand request, CancellationToken cancellationToken) + { + var actor = await _context.Actors.Where(x => x.OwnerId == request.OwnerId).FirstOrDefaultAsync(cancellationToken); + if (actor is null) + { + return CommandResult.NotFound(); + } + + _context.Actors.Remove(actor); + await _context.SaveChangesAsync(cancellationToken); + + return CommandResult.Success(); + } +} diff --git a/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs b/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs new file mode 100644 index 0000000..fbebddd --- /dev/null +++ b/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs @@ -0,0 +1,10 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class DeleteOurActorByOwnerIdCommandValidator : SecuredValidator +{ + public DeleteOurActorByOwnerIdCommandValidator() + { + RuleFor(x => x.OwnerId) + .NotEmpty(); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/DeleteOurActorCommand.cs b/src/Core.Application/Actor/DeleteOurActorCommand.cs new file mode 100644 index 0000000..3d2965c --- /dev/null +++ b/src/Core.Application/Actor/DeleteOurActorCommand.cs @@ -0,0 +1,26 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class DeleteOurActorCommand : UserScopedRequest, IRequest +{ + public Guid Id { get; set; } + +} + +public class DeleteActorCommandHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(DeleteOurActorCommand request, CancellationToken cancellationToken) + { + var actor = await _context.Actors.FindAsync([request.Id, cancellationToken], cancellationToken: cancellationToken); + if (actor is null) + { + return CommandResult.NotFound(); + } + + _context.Actors.Remove(actor); + await _context.SaveChangesAsync(cancellationToken); + + return CommandResult.Success(); + } +} diff --git a/src/Core.Application/Actor/DeleteOurActorCommandValidator.cs b/src/Core.Application/Actor/DeleteOurActorCommandValidator.cs new file mode 100644 index 0000000..d10b613 --- /dev/null +++ b/src/Core.Application/Actor/DeleteOurActorCommandValidator.cs @@ -0,0 +1,10 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class DeleteOurActorCommandValidator : SecuredValidator +{ + public DeleteOurActorCommandValidator() + { + RuleFor(x => x.Id) + .NotEmpty(); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetMyActorQuery.cs b/src/Core.Application/Actor/GetMyActorQuery.cs new file mode 100644 index 0000000..b6d95d7 --- /dev/null +++ b/src/Core.Application/Actor/GetMyActorQuery.cs @@ -0,0 +1,20 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetMyActorQuery : UserScopedRequest, IRequest +{ + public Guid OwnerId { get; set; } + +} + +public class GetActorByOwnerIdQueryHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(GetMyActorQuery request, CancellationToken cancellationToken) + { + var actor = await _context.Actors + .FirstOrDefaultAsync(x => x.OwnerId == request.UserContext.OwnerId && x.TenantId == request.UserContext.TenantId, cancellationToken: cancellationToken); + + return actor is null ? null : ActorDto.CreateFrom(actor); + } +} diff --git a/src/Core.Application/Actor/GetMyActorQueryValidator.cs b/src/Core.Application/Actor/GetMyActorQueryValidator.cs new file mode 100644 index 0000000..093d8cf --- /dev/null +++ b/src/Core.Application/Actor/GetMyActorQueryValidator.cs @@ -0,0 +1,9 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetMyActorQueryValidator : SecuredValidator +{ + public GetMyActorQueryValidator() + { + + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionQuery.cs b/src/Core.Application/Actor/GetOurActorChatSessionQuery.cs new file mode 100644 index 0000000..59dbb69 --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorChatSessionQuery.cs @@ -0,0 +1,23 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; + +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorChatSessionQuery : UserScopedRequest, IRequest +{ + public Guid ActorId { get; set; } + public Guid ChatSessionId { get; set; } + +} + +public class GetOurActorChatSessionQueryHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(GetOurActorChatSessionQuery request, CancellationToken cancellationToken) + { + var returnData = await _context.ChatSessions + .FirstOrDefaultAsync(x => x.Id == request.ChatSessionId && x.ActorId == request.ActorId && x.TenantId == request.UserContext.TenantId, cancellationToken: cancellationToken); + + return returnData is null ? null : ChatSessionDto.CreateFrom(returnData); + } +} diff --git a/src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs b/src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs new file mode 100644 index 0000000..edff521 --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs @@ -0,0 +1,10 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorChatSessionQueryValidator : SecuredValidator +{ + public GetOurActorChatSessionQueryValidator() + { + RuleFor(x => x.ActorId).NotEmpty(); + RuleFor(x => x.ChatSessionId).NotEmpty(); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs b/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs new file mode 100644 index 0000000..f57e5e0 --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs @@ -0,0 +1,32 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; + +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorChatSessionsPaginatedQuery : UserScopedRequest, IRequest> +{ + public Guid ActorId { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public int PageNumber { get; init; } = 1; + public int PageSize { get; init; } = 10; + +} + +public class GetOurActorChatSessionsPaginatedQueryHandler(IAgentFrameworkContext context) : IRequestHandler> +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task> Handle(GetOurActorChatSessionsPaginatedQuery request, CancellationToken cancellationToken) + { + var returnData = await _context.ChatSessions + .Include(x => x.Messages) + .OrderByDescending(x => x.Timestamp) + .Where(x => (request.StartDate == null || x.Timestamp > request.StartDate) + && (request.EndDate == null || x.Timestamp < request.EndDate)) + .Select(x => ChatSessionDto.CreateFrom(x)) + .PaginatedListAsync(request.PageNumber, request.PageSize); + + return returnData; + + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs b/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs new file mode 100644 index 0000000..dc76c6a --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs @@ -0,0 +1,22 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorChatSessionsPaginatedQueryValidator : SecuredValidator +{ + public GetOurActorChatSessionsPaginatedQueryValidator() + { + RuleFor(x => x.ActorId).NotEmpty(); + + RuleFor(v => v.StartDate).NotEmpty() + .When(v => v.EndDate != null) + .LessThanOrEqualTo(v => v.EndDate); + + RuleFor(v => v.EndDate) + .NotEmpty() + .When(v => v.StartDate != null) + .GreaterThanOrEqualTo(v => v.StartDate); + + RuleFor(x => x.PageNumber).NotEqual(0); + + RuleFor(x => x.PageSize).NotEqual(0); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs b/src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs new file mode 100644 index 0000000..83f6937 --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs @@ -0,0 +1,29 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; + +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorChatSessionsQuery : UserScopedRequest, IRequest> +{ + public Guid ActorId { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + +} + +public class GetOurActorChatSessionsQueryHandler(IAgentFrameworkContext context) : IRequestHandler> +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task> Handle(GetOurActorChatSessionsQuery request, CancellationToken cancellationToken) + { + var returnData = await _context.ChatSessions + .OrderByDescending(x => x.Timestamp) + .Where(x => x.ActorId == request.ActorId + && (request.StartDate == null || x.Timestamp > request.StartDate) + && (request.EndDate == null || x.Timestamp < request.EndDate)) + .Select(x => ChatSessionDto.CreateFrom(x)) + .ToListAsync(cancellationToken); + + return returnData; + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs b/src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs new file mode 100644 index 0000000..eb386bc --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs @@ -0,0 +1,18 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorChatSessionsQueryValidator : SecuredValidator +{ + public GetOurActorChatSessionsQueryValidator() + { + RuleFor(x => x.ActorId).NotEmpty(); + + RuleFor(v => v.StartDate).NotEmpty() + .When(v => v.EndDate != null) + .LessThanOrEqualTo(v => v.EndDate); + + RuleFor(v => v.EndDate) + .NotEmpty() + .When(v => v.StartDate != null) + .GreaterThanOrEqualTo(v => v.StartDate); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorQuery.cs b/src/Core.Application/Actor/GetOurActorQuery.cs new file mode 100644 index 0000000..6f9a5f4 --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorQuery.cs @@ -0,0 +1,19 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorQuery : UserScopedRequest, IRequest +{ + public Guid ActorId { get; set; } +} + +public class GetActorQueryHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(GetOurActorQuery request, CancellationToken cancellationToken) + { + var actor = await _context.Actors + .FirstOrDefaultAsync(x => x.Id == request.ActorId && x.TenantId == request.UserContext.TenantId, cancellationToken: cancellationToken); + + return actor is null ? null : ActorDto.CreateFrom(actor); + } +} diff --git a/src/Core.Application/Actor/GetOurActorQueryValidator.cs b/src/Core.Application/Actor/GetOurActorQueryValidator.cs new file mode 100644 index 0000000..aee4094 --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorQueryValidator.cs @@ -0,0 +1,9 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorQueryValidator : SecuredValidator +{ + public GetOurActorQueryValidator() + { + RuleFor(x => x.ActorId).NotEmpty(); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorsByNameQuery.cs b/src/Core.Application/Actor/GetOurActorsByNameQuery.cs new file mode 100644 index 0000000..1c4ef8d --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorsByNameQuery.cs @@ -0,0 +1,25 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorsByNameQuery : UserScopedRequest, IRequest> +{ + public string Name { get; set; } = string.Empty; +} + +public class GetOurActorsByNameQueryHandler(IAgentFrameworkContext context) : IRequestHandler> +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task> Handle(GetOurActorsByNameQuery request, CancellationToken cancellationToken) + { + var tenantId = request.UserContext.TenantId; + var normalizedInput = request.Name.Trim(); + + return await _context.Actors + .Where(x => x.TenantId == tenantId) + .Where(x => + (x.FirstName != null && x.FirstName.Contains(normalizedInput)) + || (x.LastName != null && x.LastName.Contains(normalizedInput))) + .Select(x => ActorDto.CreateFrom(x)) + .ToListAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs b/src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs new file mode 100644 index 0000000..7f13383 --- /dev/null +++ b/src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs @@ -0,0 +1,9 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class GetOurActorsByNameQueryValidator : SecuredValidator +{ + public GetOurActorsByNameQueryValidator() + { + RuleFor(x => x.Name).NotEmpty(); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/SaveMyActorCommand.cs b/src/Core.Application/Actor/SaveMyActorCommand.cs new file mode 100644 index 0000000..e36c28d --- /dev/null +++ b/src/Core.Application/Actor/SaveMyActorCommand.cs @@ -0,0 +1,44 @@ +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class SaveMyActorCommand : UserScopedRequest, IRequest +{ + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? Email { get; set; } + +} + +public class SaveMyActorCommandHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(SaveMyActorCommand request, CancellationToken cancellationToken) + { + ActorGuard.GuardAgainstInvalidUserContext(request?.UserContext); + + var actor = await _context.Actors + .Where(x => x.OwnerId == request!.UserContext.OwnerId && x.TenantId == request.UserContext.TenantId) + .FirstOrDefaultAsync(cancellationToken); + if (actor is not null) + { + actor.Update(request?.FirstName, request?.LastName, request?.Email); + _context.Actors.Update(actor); + } + else + { + actor = ActorEntity.Create( + ownerId: request!.UserContext.OwnerId, + tenantId: request.UserContext.TenantId, + firstName: request.FirstName, + lastName: request.LastName, + email: request.Email + ); + _context.Actors.Add(actor); + } + + await _context.SaveChangesAsync(cancellationToken); + return ActorDto.CreateFrom(actor); + } +} \ No newline at end of file diff --git a/src/Core.Application/Actor/SaveMyActorCommandValidator.cs b/src/Core.Application/Actor/SaveMyActorCommandValidator.cs new file mode 100644 index 0000000..f207656 --- /dev/null +++ b/src/Core.Application/Actor/SaveMyActorCommandValidator.cs @@ -0,0 +1,16 @@ +namespace Goodtocode.AgentFramework.Core.Application.Actors; + +public class SaveMyActorCommandValidator : SecuredValidator +{ + public SaveMyActorCommandValidator() + { + RuleFor(x => x.FirstName) + .NotEmpty(); + + RuleFor(x => x.LastName) + .NotEmpty(); + + RuleFor(x => x.Email) + .NotEmpty(); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/ChatGuard.cs b/src/Core.Application/Chat/ChatGuard.cs new file mode 100644 index 0000000..5f1e0fc --- /dev/null +++ b/src/Core.Application/Chat/ChatGuard.cs @@ -0,0 +1,89 @@ +using Goodtocode.AgentFramework.Core.Domain.Chats; +using Microsoft.Extensions.AI; + +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public static class ChatGuard +{ + public static void GuardAgainstEmptyMessage(string? message) + { + if (string.IsNullOrWhiteSpace(message)) + throw new CustomValidationException([ + new("Message", "A message is required as a prompt to get an AI response") + ]); + } + + public static void GuardAgainstIdExists(DbSet dbSet, Guid id) + { + if (dbSet.Any(x => x.Id == id)) + throw new CustomConflictException("Id already exists"); + } + + public static void GuardAgainstEmptyUser(IUserContext? userContext) + { + if (userContext == null || userContext.OwnerId == Guid.Empty || userContext.TenantId == Guid.Empty) + throw new CustomValidationException([ + new("UserContext", "User information is required to create a chat message") + ]); + } + + public static void GuardAgainstUnauthorized(ChatSessionEntity chatSession, IUserContext userContext) + { + if ((chatSession.OwnerId != userContext.OwnerId) && !(userContext.Roles?.Contains("Admin") ?? false)) + throw new CustomForbiddenAccessException("You do not have permission to access this ChatSession"); + } + + public static void GuardAgainstNullAgentResponse(ChatMessage? response) + { + if (response == null) + throw new CustomValidationException([ + new("ChatMessage", "Agent response cannot be null") + ]); + } + + public static void GuardAgainstNullAgentResponse(object? response) + { + if (response == null) + throw new CustomValidationException([ + new("AgentResponse", "Failed to get a response from the AI agent") + ]); + } + + public static void GuardAgainstUnauthorized(ChatMessageEntity chatMessage, IUserContext userInfo) + { + if (chatMessage.ChatSession?.OwnerId != userInfo.OwnerId) + throw new CustomForbiddenAccessException("ChatMessage", chatMessage.Id); + } + + public static void GuardAgainstEmptyUserForQuery(IUserContext? userContext) + { + if (userContext == null || userContext.OwnerId == Guid.Empty || userContext.TenantId == Guid.Empty) + throw new CustomValidationException([ + new("UserInfo", "User information is required to retrieve chat sessions") + ]); + } + + public static void GuardAgainstEmptyId(Guid? id) + { + if (id == Guid.Empty) + throw new CustomValidationException([ + new("Id", "A valid chat session ID is required") + ]); + } + + public static void GuardAgainstEmptyTitle(string title) + { + if (string.IsNullOrWhiteSpace(title)) + throw new CustomValidationException([ + new("Title", "Title cannot be empty") + ]); + } + + public static void GuardAgainstEmptyUserForPatch(IUserContext? userContext) + { + if (userContext == null || userContext.OwnerId == Guid.Empty || userContext.TenantId == Guid.Empty) + throw new CustomValidationException([ + new("UserContext", "User information is required to update a chat session") + ]); + } +} diff --git a/src/Core.Application/Chat/ChatMessageDto.cs b/src/Core.Application/Chat/ChatMessageDto.cs new file mode 100644 index 0000000..ae8f824 --- /dev/null +++ b/src/Core.Application/Chat/ChatMessageDto.cs @@ -0,0 +1,29 @@ +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class ChatMessageDto +{ + public Guid Id { get; set; } = Guid.Empty; + public Guid ChatSessionId { get; set; } = Guid.Empty; + public string Role { get; set; } = string.Empty; + public string Content { get; set; } = string.Empty; + public DateTimeOffset Timestamp { get; set; } + + public static ChatMessageDto CreateFrom(ChatMessageEntity? entity) + { + if (entity is null) + { + return null!; + } + + return new ChatMessageDto + { + Id = entity.Id, + ChatSessionId = entity.ChatSessionId, + Role = entity.Role.ToString(), + Content = entity.Content, + Timestamp = entity.Timestamp + }; + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/ChatSessionDto.cs b/src/Core.Application/Chat/ChatSessionDto.cs new file mode 100644 index 0000000..81ac784 --- /dev/null +++ b/src/Core.Application/Chat/ChatSessionDto.cs @@ -0,0 +1,29 @@ +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class ChatSessionDto +{ + public Guid Id { get; set; } = Guid.Empty; + public string Title { get; set; } = string.Empty; + public Guid ActorId { get; set; } = Guid.Empty; + public DateTimeOffset Timestamp { get; set; } + public ICollection? Messages { get; set; } + + public static ChatSessionDto CreateFrom(ChatSessionEntity? entity) + { + if (entity is null) + { + return null!; + } + + return new ChatSessionDto + { + Id = entity.Id, + Title = entity.Title ?? string.Empty, + ActorId = entity.ActorId, + Timestamp = entity.Timestamp, + Messages = entity.Messages?.Select(ChatMessageDto.CreateFrom).ToList() + }; + } +} diff --git a/src/Core.Application/Chat/CreateMyChatMessageCommand.cs b/src/Core.Application/Chat/CreateMyChatMessageCommand.cs new file mode 100644 index 0000000..ae60c1d --- /dev/null +++ b/src/Core.Application/Chat/CreateMyChatMessageCommand.cs @@ -0,0 +1,83 @@ +using Goodtocode.AgentFramework.Core.Domain.Chats; +using Goodtocode.AgentFramework.Core.Application.Governance; +using Microsoft.Agents.AI; +using Microsoft.Extensions.AI; + +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class CreateMyChatMessageCommand : UserScopedRequest, IRequest> +{ + public Guid ChatSessionId { get; set; } + public string? Message { get; set; } + +} + +public class CreateChatMessageCommandHandler(AIAgent agent, IAgentFrameworkContext context, ChatGovernanceGate governanceGate) : IRequestHandler> +{ + private readonly AIAgent _agent = agent; + private readonly IAgentFrameworkContext _context = context; + private readonly ChatGovernanceGate _governanceGate = governanceGate; + + public async Task> Handle(CreateMyChatMessageCommand request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyMessage(request?.Message); + ChatGuard.GuardAgainstEmptyUser(request?.UserContext); + + var chatSession = await _context.ChatSessions + .FirstOrDefaultAsync(x => x.Id == request!.ChatSessionId && x.OwnerId == request.UserContext.OwnerId && x.TenantId == request.UserContext.TenantId, cancellationToken); + if (chatSession is null) + { + return CommandResult.NotFound(); + } + + ChatGuard.GuardAgainstUnauthorized(chatSession, request!.UserContext!); + + var governed = _governanceGate.Enforce( + request.UserContext, + chatSession.Id, + request.Message!); + + var chatHistory = new List + { + new(ChatRole.System, governed.PromptContext.SystemInstruction) + }; + foreach (ChatMessageEntity message in chatSession.Messages) + { + chatHistory.Add(new ChatMessage( + role: message.Role == ChatMessageRole.user ? ChatRole.User : ChatRole.Assistant, + content: message.Content)); + } + chatHistory.Add(new ChatMessage(role: ChatRole.User, content: request!.Message!)); + + var agentResponse = await _agent.RunAsync(chatHistory, cancellationToken: cancellationToken); + var response = agentResponse.Messages.LastOrDefault(); + + ChatGuard.GuardAgainstNullAgentResponse(response); + + var chatMessage = ChatMessageEntity.Create( + ownerId: request.UserContext.OwnerId, + tenantId: request.UserContext.TenantId, + chatSessionId: chatSession.Id, + role: ChatMessageRole.user, + content: request.Message! + ); + chatSession.Messages.Add(chatMessage); + _context.ChatMessages.Add(chatMessage); + + var agentReply = (response?.Contents?.LastOrDefault()?.ToString()) ?? string.Empty; + + var chatMessageResponse = ChatMessageEntity.Create( + ownerId: request.UserContext.OwnerId, + tenantId: request.UserContext.TenantId, + chatSessionId: chatSession.Id, + role: ChatMessageRole.assistant, + content: agentReply + ); + chatSession.Messages.Add(chatMessageResponse); + _context.ChatMessages.Add(chatMessageResponse); + + await _context.SaveChangesAsync(cancellationToken); + + return CommandResult.Success(ChatMessageDto.CreateFrom(chatMessage)); + } +} diff --git a/src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs b/src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs new file mode 100644 index 0000000..5bb8a9b --- /dev/null +++ b/src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs @@ -0,0 +1,13 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class CreateMyChatMessageCommandValidator : SecuredValidator +{ + public CreateMyChatMessageCommandValidator() + { + RuleFor(x => x.ChatSessionId) + .NotEmpty("ChatSessionId is required"); + + RuleFor(x => x.Message) + .NotEmpty("Message is required"); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/CreateMyChatSessionCommand.cs b/src/Core.Application/Chat/CreateMyChatSessionCommand.cs new file mode 100644 index 0000000..0f8530e --- /dev/null +++ b/src/Core.Application/Chat/CreateMyChatSessionCommand.cs @@ -0,0 +1,97 @@ +using Goodtocode.AgentFramework.Core.Domain.Actors; +using Goodtocode.AgentFramework.Core.Domain.Chats; +using Goodtocode.AgentFramework.Core.Application.Governance; +using Microsoft.Agents.AI; +using Microsoft.Extensions.AI; + +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class CreateMyChatSessionCommand : UserScopedRequest, IRequest +{ + public string? Title { get; set; } + public string? Message { get; set; } + public Guid? PersonaId { get; set; } + public int? PersonaVersion { get; set; } + +} + +public class CreateMyChatSessionCommandHandler(AIAgent kernel, IAgentFrameworkContext context, ChatGovernanceGate governanceGate) : IRequestHandler +{ + private readonly AIAgent _agent = kernel; + private readonly IAgentFrameworkContext _context = context; + private readonly ChatGovernanceGate _governanceGate = governanceGate; + + public async Task Handle(CreateMyChatSessionCommand request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyMessage(request?.Message); + ChatGuard.GuardAgainstEmptyUser(request?.UserContext); + + var actor = await _context.Actors + .FirstOrDefaultAsync(a => a.OwnerId == request!.UserContext!.OwnerId + && a.TenantId == request.UserContext.TenantId, cancellationToken); + + if (actor == null) + { + actor = ActorEntity.Create( + ownerId: request!.UserContext.OwnerId, + tenantId: request.UserContext.TenantId, + firstName: request.UserContext.FirstName, + lastName: request.UserContext.LastName, + email: request.UserContext.Email + ); + _context.Actors.Add(actor); + await _context.SaveChangesAsync(cancellationToken); + } + + var governed = _governanceGate.Enforce( + request.UserContext, + Guid.Empty, + request.Message!); + + var chatHistory = new List + { + new(ChatRole.System, governed.PromptContext.SystemInstruction), + new(ChatRole.User, request!.Message!) + }; + + var agentResponse = await _agent.RunAsync(chatHistory, cancellationToken: cancellationToken); + var response = agentResponse.Messages.LastOrDefault(); + + ChatGuard.GuardAgainstNullAgentResponse(response); + + var title = request!.Title ?? $"{request!.Message![..(request.Message!.Length >= 25 ? 25 : request.Message!.Length)]}"; + + var chatSession = ChatSessionEntity.Create( + ownerId: request.UserContext.OwnerId, + tenantId: request.UserContext.TenantId, + actorId: actor.Id, + title: title, + personaId: request.PersonaId ?? Guid.Empty, + personaVersion: request.PersonaVersion ?? 0 + ); + _context.ChatSessions.Add(chatSession); + await _context.SaveChangesAsync(cancellationToken); + + var chatMessages = new List + { + ChatMessageEntity.Create( + ownerId: request.UserContext.OwnerId, + tenantId: request.UserContext.TenantId, + chatSessionId: chatSession.Id, + role: ChatMessageRole.user, + content: request!.Message! + ), + ChatMessageEntity.Create( + ownerId: request.UserContext.OwnerId, + tenantId: request.UserContext.TenantId, + chatSessionId: chatSession.Id, + role: ChatMessageRole.system, + content: response!.Text + ) + }; + _context.ChatMessages.AddRange(chatMessages); + await _context.SaveChangesAsync(cancellationToken); + + return ChatSessionDto.CreateFrom(chatSession); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs b/src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs new file mode 100644 index 0000000..d220a90 --- /dev/null +++ b/src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs @@ -0,0 +1,10 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class CreateMyChatSessionCommandValidator : SecuredValidator +{ + public CreateMyChatSessionCommandValidator() + { + RuleFor(x => x.Message) + .NotEmpty("Message is required"); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/DeleteMyChatSessionCommand.cs b/src/Core.Application/Chat/DeleteMyChatSessionCommand.cs new file mode 100644 index 0000000..7967db5 --- /dev/null +++ b/src/Core.Application/Chat/DeleteMyChatSessionCommand.cs @@ -0,0 +1,30 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class DeleteMyChatSessionCommand : UserScopedRequest, IRequest +{ + public Guid Id { get; set; } + +} + +public class DeleteMyChatSessionCommandHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(DeleteMyChatSessionCommand request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyUser(request?.UserContext); + + var chatSession = await _context.ChatSessions.FindAsync([request!.Id, cancellationToken], cancellationToken: cancellationToken); + if (chatSession is null) + { + return CommandResult.NotFound(); + } + + ChatGuard.GuardAgainstUnauthorized(chatSession, request.UserContext!); + + _context.ChatSessions.Remove(chatSession); + await _context.SaveChangesAsync(cancellationToken); + + return CommandResult.Success(); + } +} diff --git a/src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs b/src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs new file mode 100644 index 0000000..4529f80 --- /dev/null +++ b/src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs @@ -0,0 +1,10 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class DeleteMyChatSessionCommandValidator : SecuredValidator +{ + public DeleteMyChatSessionCommandValidator() + { + RuleFor(x => x.Id) + .NotEmpty("Id is required"); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatMessageQuery.cs b/src/Core.Application/Chat/GetMyChatMessageQuery.cs new file mode 100644 index 0000000..ef37d71 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatMessageQuery.cs @@ -0,0 +1,28 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatMessageQuery : UserScopedRequest, IRequest +{ + public Guid Id { get; set; } + +} + +public class GetMyChatMessageQueryHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(GetMyChatMessageQuery request, + CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyUser(request?.UserContext); + + var chatMessage = await _context.ChatMessages.FindAsync([request!.Id, cancellationToken], cancellationToken: cancellationToken); + if (chatMessage is null) + { + return null; + } + + ChatGuard.GuardAgainstUnauthorized(chatMessage, request.UserContext!); + + return ChatMessageDto.CreateFrom(chatMessage); + } +} diff --git a/src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs b/src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs new file mode 100644 index 0000000..ba69e39 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs @@ -0,0 +1,10 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatMessageQueryValidator : SecuredValidator +{ + public GetMyChatMessageQueryValidator() + { + RuleFor(x => x.Id) + .NotEmpty("Id is required"); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs b/src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs new file mode 100644 index 0000000..aa55939 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs @@ -0,0 +1,38 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatMessagesPaginatedQuery : UserScopedRequest, IRequest> +{ + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public int PageNumber { get; init; } = 1; + public int PageSize { get; init; } = 10; + +} + +public class GetMyChatMessagesPaginatedQueryHandler(IAgentFrameworkContext context) : IRequestHandler> +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task> Handle(GetMyChatMessagesPaginatedQuery request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyUserForQuery(request?.UserContext); + + var userContext = request!.UserContext!; + + var query = _context.ChatMessages + .Where(x => x.ChatSession != null && x.ChatSession.OwnerId == userContext.OwnerId && x.ChatSession.TenantId == userContext.TenantId); + + if (request.StartDate.HasValue) + query = query.Where(x => x.Timestamp > request.StartDate.Value); + + if (request.EndDate.HasValue) + query = query.Where(x => x.Timestamp < request.EndDate.Value); + + var returnData = await query + .OrderByDescending(x => x.Timestamp) + .Select(x => ChatMessageDto.CreateFrom(x)) + .PaginatedListAsync(request.PageNumber, request.PageSize); + + return returnData; + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs b/src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs new file mode 100644 index 0000000..29923b0 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs @@ -0,0 +1,23 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatMessagesPaginatedQueryValidator : SecuredValidator +{ + public GetMyChatMessagesPaginatedQueryValidator() + { + RuleFor(v => v.StartDate) + .NotEmpty("StartDate is required when EndDate is provided") + .When(v => v.EndDate != null) + .LessThanOrEqualTo(v => v.EndDate); + + RuleFor(v => v.EndDate) + .NotEmpty("EndDate is required when StartDate is provided") + .When(v => v.StartDate != null) + .GreaterThanOrEqualTo(v => v.StartDate); + + RuleFor(x => x.PageNumber) + .NotEqual(0, "PageNumber must be greater than 0"); + + RuleFor(x => x.PageSize) + .NotEqual(0, "PageSize must be greater than 0"); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs b/src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs new file mode 100644 index 0000000..90caa32 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs @@ -0,0 +1,26 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatSessionMessagesQuery : UserScopedRequest, IRequest> +{ + public Guid ChatSessionId { get; set; } +} + +public class GetMyChatSessionMessagesQueryHandler(IAgentFrameworkContext context) : IRequestHandler> +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task> Handle(GetMyChatSessionMessagesQuery request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyUserForQuery(request.UserContext); + ChatGuard.GuardAgainstEmptyId(request.ChatSessionId); + + var userContext = request.UserContext; + return await _context.ChatMessages + .Where(x => x.ChatSessionId == request.ChatSessionId + && x.OwnerId == userContext.OwnerId + && x.TenantId == userContext.TenantId) + .OrderBy(x => x.Timestamp) + .Select(x => ChatMessageDto.CreateFrom(x)) + .ToListAsync(cancellationToken); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs b/src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs new file mode 100644 index 0000000..3a4e485 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs @@ -0,0 +1,9 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatSessionMessagesQueryValidator : SecuredValidator +{ + public GetMyChatSessionMessagesQueryValidator() + { + RuleFor(x => x.ChatSessionId).NotEmpty(); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionQuery.cs b/src/Core.Application/Chat/GetMyChatSessionQuery.cs new file mode 100644 index 0000000..76dbcfd --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatSessionQuery.cs @@ -0,0 +1,30 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatSessionQuery : UserScopedRequest, IRequest +{ + public Guid Id { get; set; } + +} + +public class GetMyChatSessionQueryHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(GetMyChatSessionQuery request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyUserForQuery(request?.UserContext); + ChatGuard.GuardAgainstEmptyId(request?.Id); + + var chatSession = await _context.ChatSessions + .FirstOrDefaultAsync(x => x.Id == request!.Id && x.OwnerId == request.UserContext.OwnerId && x.TenantId == request.UserContext.TenantId, cancellationToken: cancellationToken); + + if (chatSession is null) + { + return null; + } + + ChatGuard.GuardAgainstUnauthorized(chatSession, request!.UserContext!); + + return ChatSessionDto.CreateFrom(chatSession); + } +} diff --git a/src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs b/src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs new file mode 100644 index 0000000..e2ba9b2 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs @@ -0,0 +1,10 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatSessionQueryValidator : SecuredValidator +{ + public GetMyChatSessionQueryValidator() + { + RuleFor(x => x.Id) + .NotEmpty("Id is required"); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs b/src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs new file mode 100644 index 0000000..c345b09 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs @@ -0,0 +1,32 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatSessionsPaginatedQuery : UserScopedRequest, IRequest> +{ + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public int PageNumber { get; init; } = 1; + public int PageSize { get; init; } = 10; + +} + +public class GetMyChatSessionsPaginatedQueryHandler(IAgentFrameworkContext context) : IRequestHandler> +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task> Handle(GetMyChatSessionsPaginatedQuery request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyUserForQuery(request?.UserContext); + var ownerId = request!.UserContext!.OwnerId; + + var returnData = await _context.ChatSessions + .Include(x => x.Messages) + .Where(x => x.OwnerId == ownerId) + .OrderByDescending(x => x.Timestamp) + .Where(x => (request.StartDate == null || x.Timestamp > request.StartDate) + && (request.EndDate == null || x.Timestamp < request.EndDate)) + .Select(x => ChatSessionDto.CreateFrom(x)) + .PaginatedListAsync(request.PageNumber, request.PageSize); + + return returnData; + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs b/src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs new file mode 100644 index 0000000..dcae49b --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs @@ -0,0 +1,23 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatSessionsPaginatedQueryValidator : SecuredValidator +{ + public GetMyChatSessionsPaginatedQueryValidator() + { + RuleFor(v => v.StartDate) + .NotEmpty("StartDate is required when EndDate is provided") + .When(v => v.EndDate != null) + .LessThanOrEqualTo(v => v.EndDate); + + RuleFor(v => v.EndDate) + .NotEmpty("EndDate is required when StartDate is provided") + .When(v => v.StartDate != null) + .GreaterThanOrEqualTo(v => v.StartDate); + + RuleFor(x => x.PageNumber) + .NotEqual(0, "PageNumber must be greater than 0"); + + RuleFor(x => x.PageSize) + .NotEqual(0, "PageSize must be greater than 0"); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionsQuery.cs b/src/Core.Application/Chat/GetMyChatSessionsQuery.cs new file mode 100644 index 0000000..55fa0e9 --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatSessionsQuery.cs @@ -0,0 +1,33 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatSessionsQuery : UserScopedRequest, IRequest> +{ + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + +} + +public class GetMyChatSessionsQueryHandler(IAgentFrameworkContext context) : IRequestHandler> +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task> Handle(GetMyChatSessionsQuery request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyUserForQuery(request?.UserContext); + + var startDate = request?.StartDate; + var endDate = request?.EndDate; + var userContext = request?.UserContext; + + var returnData = await _context.ChatSessions + .Where(x => userContext != null && x.OwnerId == userContext.OwnerId && x.TenantId == userContext.TenantId) + .OrderByDescending(x => x.Timestamp) + .Where(x => (startDate == null || x.Timestamp > startDate) + && (endDate == null || x.Timestamp < endDate)) + .Include(x => x.Messages) + .Select(x => ChatSessionDto.CreateFrom(x)) + .ToListAsync(cancellationToken); + + return returnData; + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs b/src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs new file mode 100644 index 0000000..82be05b --- /dev/null +++ b/src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs @@ -0,0 +1,17 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class GetMyChatSessionsQueryValidator : SecuredValidator +{ + public GetMyChatSessionsQueryValidator() + { + RuleFor(v => v.StartDate) + .NotEmpty("StartDate is required when EndDate is provided") + .When(v => v.EndDate != null) + .LessThanOrEqualTo(v => v.EndDate); + + RuleFor(v => v.EndDate) + .NotEmpty("EndDate is required when StartDate is provided") + .When(v => v.StartDate != null) + .GreaterThanOrEqualTo(v => v.StartDate); + } +} \ No newline at end of file diff --git a/src/Core.Application/Chat/PatchMyChatSessionCommand.cs b/src/Core.Application/Chat/PatchMyChatSessionCommand.cs new file mode 100644 index 0000000..998182b --- /dev/null +++ b/src/Core.Application/Chat/PatchMyChatSessionCommand.cs @@ -0,0 +1,34 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class PatchMyChatSessionCommand : UserScopedRequest, IRequest +{ + public Guid Id { get; set; } + public string Title { get; set; } = string.Empty; + +} + +public class PatchChatSessionCommandHandler(IAgentFrameworkContext context) : IRequestHandler +{ + private readonly IAgentFrameworkContext _context = context; + + public async Task Handle(PatchMyChatSessionCommand request, CancellationToken cancellationToken) + { + ChatGuard.GuardAgainstEmptyTitle(request.Title); + ChatGuard.GuardAgainstEmptyUserForPatch(request?.UserContext); + + var chatSession = await _context.ChatSessions.FindAsync([request!.Id, cancellationToken], cancellationToken: cancellationToken); + if (chatSession is null) + { + return CommandResult.NotFound(); + } + + ChatGuard.GuardAgainstUnauthorized(chatSession, request.UserContext!); + + chatSession.Update(request.Title); + + _context.ChatSessions.Update(chatSession); + await _context.SaveChangesAsync(cancellationToken); + + return CommandResult.Success(); + } +} diff --git a/src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs b/src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs new file mode 100644 index 0000000..97c72b2 --- /dev/null +++ b/src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs @@ -0,0 +1,13 @@ +namespace Goodtocode.AgentFramework.Core.Application.Chats; + +public class PatchMyChatSessionCommandValidator : SecuredValidator +{ + public PatchMyChatSessionCommandValidator() + { + RuleFor(x => x.Id) + .NotEmpty("Id is required"); + + RuleFor(x => x.Title) + .NotEmpty("Title is required"); + } +} \ No newline at end of file diff --git a/src/Core.Domain/Actor/ActorEntity.cs b/src/Core.Domain/Actor/ActorEntity.cs new file mode 100644 index 0000000..532ec3a --- /dev/null +++ b/src/Core.Domain/Actor/ActorEntity.cs @@ -0,0 +1,58 @@ +namespace Goodtocode.AgentFramework.Core.Domain.Actors; + +public class ActorEntity : SecuredEntity +{ + public string? FirstName { get; private set; } = string.Empty; + public string? LastName { get; private set; } = string.Empty; + public string? Email { get; private set; } = string.Empty; + + protected ActorEntity() : base() { } + + private ActorEntity( + Guid id, + string canonicalKey, + Guid ownerId, + Guid tenantId, + Guid createdBy, + DateTime createdOn, + DateTimeOffset timestamp, + string? firstName, + string? lastName, + string? email) + : base(id: id, partitionKey: tenantId.ToString(), rowKey: canonicalKey, + ownerId: ownerId, tenantId: tenantId, createdBy: createdBy, + createdOn: createdOn, timestamp: timestamp) + { + FirstName = firstName; + LastName = lastName; + Email = email; + } + + public static ActorEntity Create( + Guid ownerId, + Guid tenantId, + string? firstName, + string? lastName, + string? email) + { + return new ActorEntity( + id: Guid.NewGuid(), + canonicalKey: Guid.NewGuid().ToString(), + ownerId: ownerId, + tenantId: tenantId, + createdBy: ownerId, + createdOn: DateTime.UtcNow, + timestamp: DateTimeOffset.UtcNow, + firstName: firstName, + lastName: lastName, + email: email + ); + } + + public void Update(string? firstName, string? lastName, string? email) + { + FirstName = firstName ?? FirstName; + LastName = lastName ?? LastName; + Email = email ?? Email; + } +} diff --git a/src/Core.Domain/Chat/ChatMessageEntity.cs b/src/Core.Domain/Chat/ChatMessageEntity.cs new file mode 100644 index 0000000..c84ec9f --- /dev/null +++ b/src/Core.Domain/Chat/ChatMessageEntity.cs @@ -0,0 +1,52 @@ +namespace Goodtocode.AgentFramework.Core.Domain.Chats; + +public class ChatMessageEntity : SecuredEntity, IDomainEntity +{ + public Guid ChatSessionId { get; private set; } + public ChatMessageRole Role { get; private set; } + public string Content { get; private set; } = string.Empty; + public virtual ChatSessionEntity? ChatSession { get; private set; } + + protected ChatMessageEntity() : base() { } + + private ChatMessageEntity( + Guid id, + string canonicalKey, + Guid ownerId, + Guid tenantId, + Guid createdBy, + DateTime createdOn, + DateTimeOffset timestamp, + Guid chatSessionId, + ChatMessageRole role, + string content) + : base(id: id, partitionKey: tenantId.ToString(), rowKey: canonicalKey, + ownerId: ownerId, tenantId: tenantId, createdBy: createdBy, + createdOn: createdOn, timestamp: timestamp) + { + ChatSessionId = chatSessionId; + Role = role; + Content = content; + } + + public static ChatMessageEntity Create( + Guid ownerId, + Guid tenantId, + Guid chatSessionId, + ChatMessageRole role, + string content) + { + return new ChatMessageEntity( + id: Guid.NewGuid(), + canonicalKey: Guid.NewGuid().ToString(), + ownerId: ownerId, + tenantId: tenantId, + createdBy: ownerId, + createdOn: DateTime.UtcNow, + timestamp: DateTimeOffset.UtcNow, + chatSessionId: chatSessionId, + role: role, + content: content + ); + } +} diff --git a/src/Core.Domain/Chat/ChatMessageRoles.cs b/src/Core.Domain/Chat/ChatMessageRoles.cs new file mode 100644 index 0000000..b98a163 --- /dev/null +++ b/src/Core.Domain/Chat/ChatMessageRoles.cs @@ -0,0 +1,9 @@ +namespace Goodtocode.AgentFramework.Core.Domain.Chats; + +public enum ChatMessageRole +{ + system, + user, + assistant, + tool +} diff --git a/src/Core.Domain/Chat/ChatSessionEntity.cs b/src/Core.Domain/Chat/ChatSessionEntity.cs new file mode 100644 index 0000000..9b58c5a --- /dev/null +++ b/src/Core.Domain/Chat/ChatSessionEntity.cs @@ -0,0 +1,66 @@ +namespace Goodtocode.AgentFramework.Core.Domain.Chats; + +public class ChatSessionEntity : SecuredEntity +{ + public Guid ActorId { get; private set; } + public Guid PersonaId { get; private set; } + public int PersonaVersion { get; private set; } + public string? Title { get; private set; } = string.Empty; + public virtual ICollection Messages { get; private set; } = []; + + protected ChatSessionEntity() : base() { } + + private ChatSessionEntity( + Guid id, + string canonicalKey, + Guid ownerId, + Guid tenantId, + Guid createdBy, + DateTime createdOn, + DateTimeOffset timestamp, + Guid actorId, + Guid personaId, + int personaVersion, + string? title, + ICollection messages) + : base(id: id, partitionKey: tenantId.ToString(), rowKey: canonicalKey, + ownerId: ownerId, tenantId: tenantId, createdBy: createdBy, + createdOn: createdOn, timestamp: timestamp) + { + ActorId = actorId; + PersonaId = personaId; + PersonaVersion = personaVersion; + Title = title; + Messages = messages; + } + + public static ChatSessionEntity Create( + Guid ownerId, + Guid tenantId, + Guid actorId, + string? title, + ICollection? messages = null, + Guid? personaId = null, + int? personaVersion = null) + { + return new ChatSessionEntity( + id: Guid.NewGuid(), + canonicalKey: Guid.NewGuid().ToString(), + ownerId: ownerId, + tenantId: tenantId, + createdBy: ownerId, + createdOn: DateTime.UtcNow, + timestamp: DateTimeOffset.UtcNow, + actorId: actorId, + personaId: personaId ?? Guid.Empty, + personaVersion: personaVersion ?? 0, + title: title, + messages: messages ?? [] + ); + } + + public void Update(string? title) + { + Title = title ?? Title; + } +} diff --git a/src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs b/src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs new file mode 100644 index 0000000..8e7ce1d --- /dev/null +++ b/src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs @@ -0,0 +1,57 @@ +using Goodtocode.AgentFramework.Core.Application.Actors; + +namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Actor; + +/// +/// Maps identity actor endpoints. +/// +public static class MyActorEndpoints +{ + /// + /// Registers actor-related minimal API endpoints. + /// + /// The endpoint route builder. + /// The API version set that declares supported versions for this endpoint group, enabling Asp.Versioning to substitute the version token in the route template (e.g. api/v{version:apiVersion}api/v1) and generate correct OpenAPI paths. + /// The endpoint route builder. + public static IEndpointRouteBuilder MapMyActorEndpoints(this IEndpointRouteBuilder endpoints, ApiVersionSet versionSet) + { + var group = endpoints + .MapGroup("api/v{version:apiVersion}/my/actors") + .RequireAuthorization(); + group.WithApiVersionSet(versionSet).HasApiVersion(new ApiVersion(1, 0)); + + group.MapGet("{ownerId:guid}", GetMyActorProfile) + .WithName("GetMyActorProfile") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status500InternalServerError); + + group.MapPut("", SaveMyActor) + .WithName("SaveMyActor") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status500InternalServerError); + + return endpoints; + } + + private static async Task GetMyActorProfile(ISender sender, Guid ownerId) + { + var actor = await sender.Send(new GetMyActorQuery { OwnerId = ownerId }); + return ApiResponseMapper.SingleOrNotFound(actor); + } + + private static async Task SaveMyActor(HttpContext httpContext, ISender sender, SaveMyActorCommand command) + { + var response = await sender.Send(command); + var version = httpContext.Request.RouteValues["version"]?.ToString() ?? "1.0"; + + return TypedResults.CreatedAtRoute( + response, + "GetMyActorProfile", + new { version, ownerId = response.OwnerId }); + } +} diff --git a/src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs b/src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs new file mode 100644 index 0000000..25193b1 --- /dev/null +++ b/src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs @@ -0,0 +1,88 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; + +namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Chat; + +/// +/// Maps chat message endpoints. +/// +public static class MyChatMessageEndpoints +{ + /// + /// Registers chat message endpoint mappings. + /// + /// The endpoint route builder. + /// The API version set that declares supported versions for this endpoint group, enabling Asp.Versioning to substitute the version token in the route template (e.g. api/v{version:apiVersion}api/v1) and generate correct OpenAPI paths. + /// The endpoint route builder. + public static IEndpointRouteBuilder MapMyChatMessageEndpoints(this IEndpointRouteBuilder endpoints, ApiVersionSet versionSet) + { + var group = endpoints + .MapGroup("api/v{version:apiVersion}/my/messages") + .RequireAuthorization(); + group.WithApiVersionSet(versionSet).HasApiVersion(new ApiVersion(1, 0)); + + group.MapGet("{id:guid}", Get) + .WithName("GetMyChatMessage") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status500InternalServerError); + + group.MapGet("Paginated", GetPaginated) + .WithName("GetMyChatMessagesPaginated") + .Produces>(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status500InternalServerError); + + group.MapPost("", Post) + .WithName("CreateMyChatMessage") + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status500InternalServerError); + + group.MapPatch("{id:guid}", Patch) + .WithName("PatchMyChatSession") + .Produces(StatusCodes.Status204NoContent) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status500InternalServerError); + + return endpoints; + } + + private static async Task Get(ISender sender, Guid id) + { + var message = await sender.Send(new GetMyChatMessageQuery { Id = id }); + return ApiResponseMapper.SingleOrNotFound(message); + } + + private static async Task GetPaginated(ISender sender, [AsParameters] GetMyChatMessagesPaginatedQuery query) + { + var result = await sender.Send(query); + return TypedResults.Ok(result); + } + + private static async Task Post(HttpContext httpContext, ISender sender, CreateMyChatMessageCommand command) + { + var response = await sender.Send(command); + if (response.IsNotFound || response.Value is null) + { + return TypedResults.NotFound(); + } + + var version = httpContext.Request.RouteValues["version"]?.ToString() ?? "1.0"; + + return TypedResults.CreatedAtRoute( + response.Value, + "GetMyChatMessage", + new { version, id = response.Value.Id }); + } + + private static async Task Patch(ISender sender, Guid id, PatchMyChatSessionCommand command) + { + command.Id = id; + var result = await sender.Send(command); + return ApiResponseMapper.FromCommand(result); + } +} diff --git a/src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs b/src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs new file mode 100644 index 0000000..9b58d80 --- /dev/null +++ b/src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs @@ -0,0 +1,93 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; + +namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Chat; + +/// +/// Maps chat session endpoints. +/// +public static class MyChatSessionEndpoints +{ + /// + /// Registers chat session endpoint mappings. + /// + /// The endpoint route builder. + /// The API version set that declares supported versions for this endpoint group, enabling Asp.Versioning to substitute the version token in the route template (e.g. api/v{version:apiVersion}api/v1) and generate correct OpenAPI paths. + /// The endpoint route builder. + public static IEndpointRouteBuilder MapMyChatSessionEndpoints(this IEndpointRouteBuilder endpoints, ApiVersionSet versionSet) + { + var group = endpoints + .MapGroup("api/v{version:apiVersion}/my/chat") + .RequireAuthorization(); + group.WithApiVersionSet(versionSet).HasApiVersion(new ApiVersion(1, 0)); + + group.MapGet("ChatSessions", GetAll) + .WithName("GetMyChatSessions") + .Produces>(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status500InternalServerError); + + group.MapGet("Paginated", GetPaginated) + .WithName("GetMyChatSessionsPaginated") + .Produces>(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status500InternalServerError); + + group.MapGet("{id:guid}", Get) + .WithName("GetMyChatSession") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status500InternalServerError); + + group.MapPost("", Post) + .WithName("CreateMyChatSession") + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status500InternalServerError); + + return endpoints; + } + + private static async Task GetAll(ISender sender) + { + var sessions = await sender.Send(new GetMyChatSessionsQuery()); + return ApiResponseMapper.ListOrOk(sessions); + } + + private static async Task GetPaginated( + ISender sender, + DateTime? startDate, + DateTime? endDate, + int pageNumber = 1, + int pageSize = 10) + { + var query = new GetMyChatSessionsPaginatedQuery + { + StartDate = startDate, + EndDate = endDate, + PageNumber = pageNumber, + PageSize = pageSize + }; + + var result = await sender.Send(query); + return TypedResults.Ok(result); + } + + private static async Task Get(ISender sender, Guid id) + { + var session = await sender.Send(new GetMyChatSessionQuery { Id = id }); + return ApiResponseMapper.SingleOrNotFound(session); + } + + private static async Task Post(HttpContext httpContext, ISender sender, CreateMyChatSessionCommand command) + { + var response = await sender.Send(command); + var version = httpContext.Request.RouteValues["version"]?.ToString() ?? "1.0"; + + return TypedResults.CreatedAtRoute( + response, + "GetMyChatSession", + new { version, id = response.Id }); + } +} diff --git a/src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs b/src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs new file mode 100644 index 0000000..4460439 --- /dev/null +++ b/src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs @@ -0,0 +1,100 @@ +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Tests.Integration.Actor; + +[Binding] +[Scope(Tag = "createActorCommand")] +public class CreateActorCommandStepDefinitions : TestBase +{ + private string _name = string.Empty; + private Guid _id; + private bool _exists; + private Guid _ownerId = Guid.NewGuid(); + private readonly Guid _tenantId = Guid.NewGuid(); + private string _email = string.Empty; + + [Given(@"I have a def ""([^""]*)""")] + public void GivenIHaveADef(string def) + { + base.def = def; + } + + [Given(@"I have a name ""([^""]*)""")] + public void GivenIHaveAName(string name) + { + _name = name; + } + + [Given("I have a Email {string}")] + public void GivenIHaveAEmail(string email) + { + _email = email; + } + + [Given(@"I have a Actor id ""([^""]*)""")] + public void GivenIHaveAAuthorId(string id) + { + _id = Guid.Parse(id); + } + + [Given("I have a OwnerId {string}")] + public void GivenIHaveAExternalId(string ownerId) + { + _ownerId = Guid.Parse(ownerId); + } + + [Given(@"The Actor exists ""([^""]*)""")] + public void GivenTheAuthorExists(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [When(@"I create a actor")] + public async Task WhenICreateAAuthor() + { + if (_exists) + { + var actor = ActorEntity.Create( + firstName: "John", + lastName: "Doe", + email: "jdoe@goodtocode.com", + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId + ); + context.Actors.Add(actor); + await context.SaveChangesAsync(CancellationToken.None); + } + + var request = new CreateOurActorCommand() + { + FirstName = _name.Split(" ").FirstOrDefault(), + LastName = _name.Split(" ").LastOrDefault(), + Email = _email + }; + + try + { + var created = await Sender.Send(request, CancellationToken.None); + _id = created.Id; + responseType = CommandResponseType.Successful; + } + catch (Exception e) + { + HandleAssignResponseType(e); + } + } + + [Then(@"I see the Actor created with the initial response ""([^""]*)""")] + public void ThenISeeTheAuthorCreatedWithTheInitialResponse(string response) + { + HandleHasResponseType(response); + } + + [Then(@"if the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + +} \ No newline at end of file diff --git a/src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs b/src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs new file mode 100644 index 0000000..67eb3e7 --- /dev/null +++ b/src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs @@ -0,0 +1,78 @@ +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Tests.Integration.Actor +{ + [Binding] + [Scope(Tag = "deleteActorCommand")] + public class DeleteActorCommandStepDefinitions : TestBase + { + private bool _exists; + private Guid _id; + + [Given(@"I have a def ""([^""]*)""")] + public void GivenIHaveADef(string def) + { + base.def = def; + } + + [Given(@"I have a actor id""([^""]*)""")] + public void GivenIHaveAAuthorId(string id) + { + Guid.TryParse(id, out _id).ShouldBeTrue(); + } + + [Given(@"The actor exists ""([^""]*)""")] + public void GivenTheAuthorExists(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [When(@"I delete the actor")] + public async Task WhenIDeleteTheAuthor() + { + if (_exists) + { + var actor = ActorEntity.Create( + firstName: "John", + lastName: "Doe", + email: "jdoe@goodtocode.com", + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId + ); + context.Actors.Add(actor); + await context.SaveChangesAsync(CancellationToken.None); + _id = actor.OwnerId; + } + + var request = new DeleteActorByOwnerIdCommand() + { + OwnerId = _id == Guid.Empty ? rlsContext.OwnerId : _id + }; + + try + { + var result = await Sender.Send(request, CancellationToken.None); + responseType = result.IsNotFound + ? CommandResponseType.NotFound + : CommandResponseType.Successful; + } + catch (Exception e) + { + HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + } +} diff --git a/src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs b/src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs new file mode 100644 index 0000000..0e5293d --- /dev/null +++ b/src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs @@ -0,0 +1,86 @@ +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Tests.Integration.Actor; + +[Binding] +[Scope(Tag = "getAuthorByOwnerIdQuery")] +public class GetActorByOwnerIdQueryStepDefinitions : TestBase +{ + private bool _exists; + private ActorDto? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given("I have a Actor OwnerId")] + public void GivenIHaveAAuthorExternalId() + { + rlsContext.OwnerId.ShouldNotBeEmpty(); + } + + [Given(@"the Actor exists ""([^""]*)""")] + public void GivenITheAuthorExists(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [When(@"I get the Actor")] + public async Task WhenIGetAAuthor() + { + if (_exists) + { + var actor = ActorEntity.Create( + firstName: "John", + lastName: "Doe", + email: "jdoe@goodtocode.com", + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId + ); + context.Actors.Add(actor); + await context.SaveChangesAsync(CancellationToken.None); + } + + var request = new GetMyActorQuery() + { + }; + + try + { + _response = await Sender.Send(request, CancellationToken.None); + responseType = _response is null + ? CommandResponseType.NotFound + : CommandResponseType.Successful; + } + catch (Exception e) + { + responseType = HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"If the response is successful the response has a Id")] + public void ThenIfTheResponseIsSuccessfulTheResponseHasAKey() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.Id.ShouldNotBeEmpty(); + } +} diff --git a/src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs b/src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs new file mode 100644 index 0000000..9841d1f --- /dev/null +++ b/src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs @@ -0,0 +1,94 @@ +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Tests.Integration.Actor; + +[Binding] +[Scope(Tag = "getAuthorQuery")] +public class GetActorQueryStepDefinitions : TestBase +{ + private Guid _id; + private bool _exists; + private ActorDto? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given(@"I have a Actor id ""([^""]*)""")] + public void GivenIHaveAAuthorId(string actorId) + { + if (string.IsNullOrWhiteSpace(actorId)) + { + return; + } + + Guid.TryParse(actorId, out _id).ShouldBeTrue(); + } + + [Given(@"the Actor exists ""([^""]*)""")] + public void GivenITheAuthorExists(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [When(@"I get the Actor")] + public async Task WhenIGetAAuthor() + { + if (_exists) + { + var actor = ActorEntity.Create( + firstName: "John", + lastName: "Doe", + email: "jdoe@goodtocode.com", + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId + ); + context.Actors.Add(actor); + await context.SaveChangesAsync(CancellationToken.None); + _id = actor.Id; + } + + var request = new GetOurActorQuery() + { + ActorId = _id + }; + + try + { + _response = await Sender.Send(request, CancellationToken.None); + responseType = _response is null + ? CommandResponseType.NotFound + : CommandResponseType.Successful; + } + catch (Exception e) + { + responseType = HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"If the response is successful the response has a Id")] + public void ThenIfTheResponseIsSuccessfulTheResponseHasAKey() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.Id.ShouldNotBeEmpty(); + } +} diff --git a/src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs b/src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs new file mode 100644 index 0000000..3f9dd0b --- /dev/null +++ b/src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs @@ -0,0 +1,96 @@ +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Tests.Integration.Actor; + +[Binding] +[Scope(Tag = "getOurActorsByNameQuery")] +public class GetOurActorsByNameQueryStepDefinitions : TestBase +{ + private string _name = string.Empty; + private bool _exists; + private bool _otherTenantExists; + private ICollection? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given(@"I search for actor name ""([^""]*)""")] + public void GivenISearchForActorName(string name) + { + _name = name; + } + + [Given(@"matching actors in my tenant exist ""([^""]*)""")] + public void GivenMatchingActorsInMyTenantExist(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [Given(@"matching actors in another tenant exist ""([^""]*)""")] + public void GivenMatchingActorsInAnotherTenantExist(string exists) + { + bool.TryParse(exists, out _otherTenantExists).ShouldBeTrue(); + } + + [When(@"I get actors by name")] + public async Task WhenIGetActorsByName() + { + if (_exists) + { + context.Actors.Add(ActorEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + firstName: _name, + lastName: "CurrentTenant", + email: "current@example.test")); + } + + if (_otherTenantExists) + { + context.Actors.Add(ActorEntity.Create( + ownerId: Guid.NewGuid(), + tenantId: Guid.NewGuid(), + firstName: _name, + lastName: "OtherTenant", + email: "other@example.test")); + } + + await context.SaveChangesAsync(CancellationToken.None); + + try + { + _response = await Sender.Send(new GetOurActorsByNameQuery + { + Name = _name + }, CancellationToken.None); + responseType = CommandResponseType.Successful; + } + catch (Exception exception) + { + responseType = HandleAssignResponseType(exception); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string result) + { + HandleHasResponseType(result); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"The actor search response count is ""([^""]*)""")] + public void ThenTheActorSearchResponseCountIs(string count) + { + int.TryParse(count, out var expectedCount).ShouldBeTrue(); + _response?.Count.ShouldBe(expectedCount); + } +} \ No newline at end of file diff --git a/src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs b/src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs new file mode 100644 index 0000000..4aa1069 --- /dev/null +++ b/src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs @@ -0,0 +1,98 @@ +using Goodtocode.AgentFramework.Core.Application.Actors; +using Goodtocode.AgentFramework.Core.Domain.Actors; + +namespace Goodtocode.AgentFramework.Tests.Integration.Actor; + +[Binding] +[Scope(Tag = "saveActorCommand")] +public class SaveActorCommandStepDefinitions : TestBase +{ + private string _name = string.Empty; + private Guid _id; + private bool _exists; + private Guid _ownerId = Guid.NewGuid(); + private readonly Guid _tenantId = Guid.NewGuid(); + private string _email = string.Empty; + + [Given(@"I have a def ""([^""]*)""")] + public void GivenIHaveADef(string def) + { + base.def = def; + } + + [Given(@"I have a name ""([^""]*)""")] + public void GivenIHaveAName(string name) + { + _name = name; + } + + [Given("I have a Email {string}")] + public void GivenIHaveAEmail(string email) + { + _email = email; + } + + [Given(@"I have a Actor id ""([^""]*)""")] + public void GivenIHaveAAuthorId(string id) + { + _id = Guid.Parse(id); + } + + [Given("I have a OwnerId {string}")] + public void GivenIHaveAExternalId(string ownerId) + { + _ownerId = Guid.Parse(ownerId); + } + + [Given(@"The Actor exists ""([^""]*)""")] + public void GivenTheAuthorExists(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [When(@"I create a actor")] + public async Task WhenICreateAAuthor() + { + if (_exists) + { + var actor = ActorEntity.Create( + firstName: "John", + lastName: "Doe", + email: "jdoe@goodtocode.com", + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId + ); + context.Actors.Add(actor); + await context.SaveChangesAsync(CancellationToken.None); + } + + var request = new SaveMyActorCommand() + { + FirstName = _name.Split(" ").FirstOrDefault(), + LastName = _name.Split(" ").LastOrDefault(), + Email = _email + }; + + try + { + await Sender.Send(request, CancellationToken.None); + responseType = CommandResponseType.Successful; + } + catch (Exception e) + { + HandleAssignResponseType(e); + } + } + + [Then(@"I see the Actor created with the initial response ""([^""]*)""")] + public void ThenISeeTheAuthorCreatedWithTheInitialResponse(string response) + { + HandleHasResponseType(response); + } + + [Then(@"if the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } +} \ No newline at end of file diff --git a/src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs b/src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs new file mode 100644 index 0000000..16f6476 --- /dev/null +++ b/src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs @@ -0,0 +1,104 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Actors; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat; + +[Binding] +[Scope(Tag = "createChatMessageCommand")] +public class CreateChatMessageCommandStepDefinitions : TestBase +{ + private string _message = string.Empty; + private Guid _id; + private Guid _chatSessionId; + private bool _exists; + + [Given(@"I have a def ""([^""]*)""")] + public void GivenIHaveADef(string def) + { + base.def = def; + } + + [Given(@"I have a initial message ""([^""]*)""")] + public void GivenIHaveAInitialMessage(string message) + { + _message = message; + } + + [Given(@"I have a Chat Message id ""([^""]*)""")] + public void GivenIHaveAChatMessageKey(string id) + { + _id = Guid.Parse(id); + } + + [Given(@"The Chat Message exists ""([^""]*)""")] + public void GivenTheChatMessageExists(string exists) + { + _exists = bool.Parse(exists); + } + + [When(@"I create a Chat Message with the message")] + public async Task WhenICreateAChatMessageWithTheMessage() + { + if (_exists) + { + var actor = ActorEntity.Create( + firstName: "John", + lastName: "Doe", + email: "John.Doe@goodtocode.com", + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId + ); + context.Actors.Add(actor); + await context.SaveChangesAsync(CancellationToken.None); + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: actor.Id, + title: "Test Session" + ); + context.ChatSessions.Add(chatSession); + await context.SaveChangesAsync(CancellationToken.None); + _chatSessionId = chatSession.Id; + } + else + { + _chatSessionId = Guid.NewGuid(); + } + + var request = new CreateMyChatMessageCommand() + { + ChatSessionId = _chatSessionId, + Message = _message + }; + + try + { + var created = await Sender.Send(request, CancellationToken.None); + if (created.IsNotFound || created.Value is null) + { + responseType = CommandResponseType.NotFound; + return; + } + + _id = created.Value.Id; + responseType = CommandResponseType.Successful; + } + catch (Exception e) + { + HandleAssignResponseType(e); + } + } + + [Then(@"I see the Chat Message created with the initial response ""([^""]*)""")] + public void ThenISeeTheChatMessageCreatedWithTheInitialResponse(string response) + { + HandleHasResponseType(response); + } + + [Then(@"if the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } +} diff --git a/src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs new file mode 100644 index 0000000..80807c7 --- /dev/null +++ b/src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs @@ -0,0 +1,93 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Actors; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat; + +[Binding] +[Scope(Tag = "createChatSessionCommand")] +public class CreateChatSessionCommandStepDefinitions : TestBase +{ + private string _message = string.Empty; + private Guid _id; + private readonly Guid _actorId = Guid.NewGuid(); + private bool _exists; + + [Given(@"I have a def ""([^""]*)""")] + public void GivenIHaveADef(string def) + { + base.def = def; + } + + [Given(@"I have a initial message ""([^""]*)""")] + public void GivenIHaveAInitialMessage(string message) + { + _message = message; + } + + [Given(@"I have a chat session id ""([^""]*)""")] + public void GivenIHaveAChatSessionKey(string id) + { + _id = Guid.Parse(id); + } + + [Given(@"The chat session exists ""([^""]*)""")] + public void GivenTheChatSessionExists(string exists) + { + _exists = bool.Parse(exists); + } + + [When(@"I create a chat session with the message")] + public async Task WhenICreateAChatSessionWithTheMessage() + { + // Setup the database if want to test existing records + var actor = ActorEntity.Create( + firstName: "Test", + lastName: "Actor", + email: "actor@goodtocode.com", + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId + ); + context.Actors.Add(actor); + if (_exists) + { + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: _actorId, + title: "Test Session" + ); + context.ChatSessions.Add(chatSession); + } + await context.SaveChangesAsync(CancellationToken.None); + + var request = new CreateMyChatSessionCommand() + { + Title = def, + Message = _message + }; + + try + { + var created = await Sender.Send(request, CancellationToken.None); + _id = created.Id; + responseType = CommandResponseType.Successful; + } + catch (Exception e) + { + HandleAssignResponseType(e); + } + } + + [Then(@"I see the chat session created with the initial response ""([^""]*)""")] + public void ThenISeeTheChatSessionCreatedWithTheInitialResponse(string response) + { + HandleHasResponseType(response); + } + + [Then(@"if the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } +} diff --git a/src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs new file mode 100644 index 0000000..856b3a9 --- /dev/null +++ b/src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs @@ -0,0 +1,77 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat +{ + [Binding] + [Scope(Tag = "deleteChatSessionCommand")] + public class DeleteChatSessionCommandStepDefinitions : TestBase + { + private Guid _id; + private bool _exists; + + [Given(@"I have a def ""([^""]*)""")] + public void GivenIHaveADef(string def) + { + base.def = def; + } + + [Given(@"I have a chat session id""([^""]*)""")] + public void GivenIHaveAChatSessionKey(string id) + { + Guid.TryParse(id, out _id).ShouldBeTrue(); + } + + [Given(@"The chat session exists ""([^""]*)""")] + public void GivenTheChatSessionExists(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [When(@"I delete the chat session")] + public async Task WhenIDeleteTheChatSession() + { + if (_exists) + { + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Test Session" + ); + context.ChatSessions.Add(chatSession); + await context.SaveChangesAsync(CancellationToken.None); + _id = chatSession.Id; + } + + var request = new DeleteMyChatSessionCommand() + { + Id = _id + }; + + try + { + var result = await Sender.Send(request, CancellationToken.None); + responseType = result.IsNotFound + ? CommandResponseType.NotFound + : CommandResponseType.Successful; + } + catch (Exception e) + { + HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + } +} diff --git a/src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs new file mode 100644 index 0000000..e8b2ec2 --- /dev/null +++ b/src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs @@ -0,0 +1,108 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat; + +[Binding] +[Scope(Tag = "getChatMessageQuery")] +public class GetChatMessageQueryStepDefinitions : TestBase +{ + private Guid _id; + private bool _exists; + private readonly Guid _chatSessionId = Guid.NewGuid(); + private ChatMessageDto? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given(@"I have a Chat Message id ""([^""]*)""")] + public void GivenIHaveAChatMessageId(string ChatMessageKey) + { + if (string.IsNullOrWhiteSpace(ChatMessageKey)) + { + return; + } + + Guid.TryParse(ChatMessageKey, out _id).ShouldBeTrue(); + } + + [Given(@"The Chat Message exists ""([^""]*)""")] + public void GivenITheChatMessageExists(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [When(@"I get a Chat Message")] + public async Task WhenIGetAChatMessage() + { + if (_exists) + { + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Test Session" + ); + var chatMessage = ChatMessageEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + chatSessionId: chatSession.Id, + role: ChatMessageRole.user, + content: "Test Message Content" + ); + chatSession.Messages.Add(chatMessage); + context.ChatSessions.Add(chatSession); + await context.SaveChangesAsync(CancellationToken.None); + _id = chatMessage.Id; + } + + var request = new GetMyChatMessageQuery() + { + Id = _id + }; + + try + { + _response = await Sender.Send(request, CancellationToken.None); + responseType = _response is null + ? CommandResponseType.NotFound + : CommandResponseType.Successful; + } + catch (Exception e) + { + responseType = HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"If the response is successful the response has a Id")] + public void ThenIfTheResponseIsSuccessfulTheResponseHasAId() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.Id.ShouldNotBeEmpty(); + } + + [Then(@"If the response is successful the response has a count matching ""([^""]*)""")] + public void ThenIfTheResponseIsSuccessfulTheResponseHasACountMatching(string messageContent) + { + _response?.Content?.ShouldBe(messageContent); + } +} diff --git a/src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs new file mode 100644 index 0000000..cf8b853 --- /dev/null +++ b/src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs @@ -0,0 +1,197 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat; + +[Binding] +[Scope(Tag = "getChatMessagesPaginatedQuery")] +public class GetChatMessagesPaginatedQueryStepDefinitions : TestBase +{ + private bool _exists; + private readonly Guid _chatSessionId = Guid.NewGuid(); + private DateTime _startDate; + private DateTime _endDate; + private bool _withinDateRangeExists; + private int _pageNumber; + private int _pageSize; + private IPaginatedList? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given(@"Chat Messages exist ""([^""]*)""")] + public void GivenChatMessagesExist(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [Given(@"I have a start date ""([^""]*)""")] + public void GivenIHaveAStartDate(string startDate) + { + if (string.IsNullOrWhiteSpace(startDate)) + { + return; + } + + DateTime.TryParse(startDate, out _startDate).ShouldBeTrue(); + } + + [Given(@"I have a end date ""([^""]*)""")] + public void GivenIHaveAEndDate(string endDate) + { + if (string.IsNullOrWhiteSpace(endDate)) + { + return; + } + + DateTime.TryParse(endDate, out _endDate).ShouldBeTrue(); + } + + [Given(@"Chat Messages within the date range exists ""([^""]*)""")] + public void GivenChatMessagesWithinTheDateRangeExists(string withinDateRangeExists) + { + bool.TryParse(withinDateRangeExists, out _withinDateRangeExists).ShouldBeTrue(); + } + + [Given(@"I have a page number ""([^""]*)""")] + public void GivenIHaveAPageNumber(string pageNumber) + { + int.TryParse(pageNumber, out _pageNumber).ShouldBeTrue(); + } + + [Given(@"I have a page size ""([^""]*)""")] + public void GivenIHaveAPageSize(string pageSize) + { + int.TryParse(pageSize, out _pageSize).ShouldBeTrue(); ; + } + + [When(@"I get the Chat Messages paginated")] + public async Task WhenIGetTheChatMessagesPaginated() + { + if (_exists) + { + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Test Session" + ); + var chatMessage = ChatMessageEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + chatSessionId: chatSession.Id, + role: ChatMessageRole.user, + content: "Test Message Content" + ); + chatSession.Messages.Add(chatMessage); + context.ChatSessions.Add(chatSession); + await context.SaveChangesAsync(CancellationToken.None); + } + + var request = new GetMyChatMessagesPaginatedQuery() + { + PageNumber = _pageNumber, + PageSize = _pageSize, + StartDate = _startDate == default ? null : _startDate, + EndDate = _endDate == default ? null : _endDate + }; + + try + { + _response = await Sender.Send(request, CancellationToken.None); + responseType = CommandResponseType.Successful; + } + catch (Exception e) + { + responseType = HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"The response has a collection of Chat Messages")] + public void ThenTheResponseHasACollectionOfChatMessages() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.TotalCount.ShouldBe(_withinDateRangeExists == false ? 0 : _response.TotalCount); + } + + [Then(@"Each Chat Message has a Key")] + public void ThenEachChatMessageHasAKey() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.Items.FirstOrDefault(x => x.Id == default).ShouldBeNull(); + } + + [Then(@"Each Chat Message has a Date greater than start date")] + public void ThenEachChatMessageHasADateGreaterThanStartDate() + { + if (responseType == CommandResponseType.Successful && _withinDateRangeExists) + { + _response?.Items.FirstOrDefault(x => _startDate == default || x.Timestamp > _startDate).ShouldNotBeNull(); + } + } + + [Then(@"Each Chat Message has a Date less than end date")] + public void ThenEachChatMessageHasADateLessThanEndDate() + { + if (responseType == CommandResponseType.Successful && _withinDateRangeExists) + { + _response?.Items.FirstOrDefault(x => _endDate == default || x.Timestamp < _endDate).ShouldNotBeNull(); + } + } + + [Then(@"The response has a Page Number")] + public void ThenTheResponseHasAPageNumber() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.PageNumber.Should(); + } + + [Then(@"The response has a Total Pages")] + public void ThenTheResponseHasATotalPages() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.TotalPages.Should(); + } + + [Then(@"The response has a Total Count")] + public void ThenTheResponseHasATotalCount() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.TotalCount.Should(); + } +} diff --git a/src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs new file mode 100644 index 0000000..866a504 --- /dev/null +++ b/src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs @@ -0,0 +1,122 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat; + +[Binding] +[Scope(Tag = "getMyChatSessionMessagesQuery")] +public class GetMyChatSessionMessagesQueryStepDefinitions : TestBase +{ + private string _requestedSession = string.Empty; + private bool _exists; + private bool _otherOwnerExists; + private Guid _currentSessionId; + private Guid _otherSessionId; + private ICollection? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given(@"the requested session is ""([^""]*)""")] + public void GivenTheRequestedSessionIs(string requestedSession) + { + _requestedSession = requestedSession; + } + + [Given(@"messages in my chat session exist ""([^""]*)""")] + public void GivenMessagesInMyChatSessionExist(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [Given(@"messages in another owner's chat session exist ""([^""]*)""")] + public void GivenMessagesInAnotherOwnersChatSessionExist(string exists) + { + bool.TryParse(exists, out _otherOwnerExists).ShouldBeTrue(); + } + + [When(@"I get my chat session messages")] + public async Task WhenIGetMyChatSessionMessages() + { + if (_exists) + { + var session = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Current session"); + var message = ChatMessageEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + chatSessionId: session.Id, + role: ChatMessageRole.user, + content: "Current owner message"); + session.Messages.Add(message); + context.ChatSessions.Add(session); + _currentSessionId = session.Id; + } + + if (_otherOwnerExists) + { + var otherOwnerId = Guid.NewGuid(); + var session = ChatSessionEntity.Create( + ownerId: otherOwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Other owner session"); + var message = ChatMessageEntity.Create( + ownerId: otherOwnerId, + tenantId: rlsContext.TenantId, + chatSessionId: session.Id, + role: ChatMessageRole.user, + content: "Other owner message"); + session.Messages.Add(message); + context.ChatSessions.Add(session); + _otherSessionId = session.Id; + } + + await context.SaveChangesAsync(CancellationToken.None); + + var chatSessionId = _requestedSession switch + { + "current" => _currentSessionId, + "other" => _otherSessionId, + _ => Guid.Empty + }; + + try + { + _response = await Sender.Send(new GetMyChatSessionMessagesQuery + { + ChatSessionId = chatSessionId + }, CancellationToken.None); + responseType = CommandResponseType.Successful; + } + catch (Exception exception) + { + responseType = HandleAssignResponseType(exception); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string result) + { + HandleHasResponseType(result); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"The chat session message response count is ""([^""]*)""")] + public void ThenTheChatSessionMessageResponseCountIs(string count) + { + int.TryParse(count, out var expectedCount).ShouldBeTrue(); + _response?.Count.ShouldBe(expectedCount); + } +} \ No newline at end of file diff --git a/src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs new file mode 100644 index 0000000..44e4ef9 --- /dev/null +++ b/src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs @@ -0,0 +1,93 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat; + +[Binding] +[Scope(Tag = "getChatSessionQuery")] +public class GetMyChatSessionQueryStepDefinitions : TestBase +{ + private Guid _id; + private bool _exists; + private ChatSessionDto? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given(@"I have a chat session id ""([^""]*)""")] + public void GivenIHaveAChatSessionId(string chatSessionKey) + { + if (string.IsNullOrWhiteSpace(chatSessionKey)) + { + return; + } + + Guid.TryParse(chatSessionKey, out _id).ShouldBeTrue(); + } + + [Given(@"I the chat session exists ""([^""]*)""")] + public void GivenITheChatSessionExists(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [When(@"I get a chat session")] + public async Task WhenIGetAChatSession() + { + if (_exists) + { + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Test Session" + ); + context.ChatSessions.Add(chatSession); + await context.SaveChangesAsync(CancellationToken.None); + _id = chatSession.Id; + } + + var request = new GetMyChatSessionQuery() + { + Id = _id + }; + + try + { + _response = await Sender.Send(request, CancellationToken.None); + responseType = _response is null + ? CommandResponseType.NotFound + : CommandResponseType.Successful; + } + catch (Exception e) + { + responseType = HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"If the response is successful the response has a Id")] + public void ThenIfTheResponseIsSuccessfulTheResponseHasAId() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.Id.ShouldNotBeEmpty(); + } +} diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs new file mode 100644 index 0000000..ba83479 --- /dev/null +++ b/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs @@ -0,0 +1,188 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat; + +[Binding] +[Scope(Tag = "getChatSessionsPaginatedQuery")] +public class GetMyChatSessionsPaginatedQueryStepDefinitions : TestBase +{ + private bool _exists; + private DateTime _startDate; + private DateTime _endDate; + private bool _withinDateRangeExists; + private int _pageNumber; + private int _pageSize; + private IPaginatedList? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given(@"Chat Sessions exist ""([^""]*)""")] + public void GivenChatSessionsExist(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [Given(@"I have a start date ""([^""]*)""")] + public void GivenIHaveAStartDate(string startDate) + { + if (string.IsNullOrWhiteSpace(startDate)) + { + return; + } + + DateTime.TryParse(startDate, out _startDate).ShouldBeTrue(); + } + + [Given(@"I have a end date ""([^""]*)""")] + public void GivenIHaveAEndDate(string endDate) + { + if (string.IsNullOrWhiteSpace(endDate)) + { + return; + } + + DateTime.TryParse(endDate, out _endDate).ShouldBeTrue(); + } + + [Given(@"chat sessions within the date range exists ""([^""]*)""")] + public void GivenChatSessionsWithinTheDateRangeExists(string withinDateRangeExists) + { + bool.TryParse(withinDateRangeExists, out _withinDateRangeExists).ShouldBeTrue(); + } + + [Given(@"I have a page number ""([^""]*)""")] + public void GivenIHaveAPageNumber(string pageNumber) + { + int.TryParse(pageNumber, out _pageNumber).ShouldBeTrue(); + } + + [Given(@"I have a page size ""([^""]*)""")] + public void GivenIHaveAPageSize(string pageSize) + { + int.TryParse(pageSize, out _pageSize).ShouldBeTrue(); ; + } + + [When(@"I get the chat sessions paginated")] + public async Task WhenIGetTheChatSessionsPaginated() + { + if (_exists) + { + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Test Session" + ); + context.ChatSessions.Add(chatSession); + await context.SaveChangesAsync(CancellationToken.None); + } + + var request = new GetMyChatSessionsPaginatedQuery() + { + PageNumber = _pageNumber, + PageSize = _pageSize, + StartDate = _startDate == default ? null : _startDate, + EndDate = _endDate == default ? null : _endDate + }; + + try + { + _response = await Sender.Send(request, CancellationToken.None); + responseType = CommandResponseType.Successful; + } + catch (Exception e) + { + responseType = HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"The response has a collection of chat sessions")] + public void ThenTheResponseHasACollectionOfChatSessions() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.TotalCount.ShouldBe(_withinDateRangeExists == false ? 0 : _response.TotalCount); + } + + [Then(@"Each chat session has a Key")] + public void ThenEachChatSessionHasAKey() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.Items.FirstOrDefault(x => x.Id == default).ShouldBeNull(); + } + + [Then(@"Each chat session has a Date greater than start date")] + public void ThenEachChatSessionHasADateGreaterThanStartDate() + { + if (responseType == CommandResponseType.Successful && _withinDateRangeExists) + { + _response?.Items.FirstOrDefault(x => _startDate == default || x.Timestamp > _startDate).ShouldNotBeNull(); + } + } + + [Then(@"Each chat session has a Date less than end date")] + public void ThenEachChatSessionHasADateLessThanEndDate() + { + if (responseType == CommandResponseType.Successful && _withinDateRangeExists) + { + _response?.Items.FirstOrDefault(x => _endDate == default || x.Timestamp < _endDate).ShouldNotBeNull(); + } + } + + [Then(@"The response has a Page Number")] + public void ThenTheResponseHasAPageNumber() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.PageNumber.Should(); + } + + [Then(@"The response has a Total Pages")] + public void ThenTheResponseHasATotalPages() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.TotalPages.Should(); + } + + [Then(@"The response has a Total Count")] + public void ThenTheResponseHasATotalCount() + { + if (responseType != CommandResponseType.Successful) + { + return; + } + + _response?.TotalCount.Should(); + } +} diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs new file mode 100644 index 0000000..1f1606b --- /dev/null +++ b/src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs @@ -0,0 +1,130 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat; + +[Binding] +[Scope(Tag = "getChatSessionsQuery")] +public class GetMyChatSessionsQueryStepDefinitions : TestBase +{ + private bool _exists; + private bool _withinDateRangeExists; + private DateTime _endDate; + private DateTime _startDate; + private ICollection? _response; + + [Given(@"I have a definition ""([^""]*)""")] + public void GivenIHaveADefinition(string def) + { + base.def = def; + } + + [Given(@"Chat Sessions exist ""([^""]*)""")] + public void GivenChatSessionsExist(string exists) + { + bool.TryParse(exists, out _exists).ShouldBeTrue(); + } + + [Given(@"chat sessions within the date range exists ""([^""]*)""")] + public void GivenChatSessionsWithinTheDateRangeExists(string withinDateRangeExists) + { + bool.TryParse(withinDateRangeExists, out _withinDateRangeExists).ShouldBeTrue(); + } + + [Given(@"I have a start date ""([^""]*)""")] + public void GivenIHaveAStartDate(string startDate) + { + if (string.IsNullOrWhiteSpace(startDate)) + { + return; + } + + DateTime.TryParse(startDate, out _startDate).ShouldBeTrue(); + _startDate = DateTime.UtcNow.AddMinutes(_withinDateRangeExists ? -1 : 1); + } + + [Given(@"I have a end date ""([^""]*)""")] + public void GivenIHaveAEndDate(string endDate) + { + if (string.IsNullOrWhiteSpace(endDate)) + { + return; + } + + DateTime.TryParse(endDate, out _endDate).ShouldBeTrue(); + } + + [When(@"I get the chat sessions")] + public async Task WhenIGetTheChatSessions() + { + if (_exists) + { + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Test Session" + ); + context.ChatSessions.Add(chatSession); + await context.SaveChangesAsync(CancellationToken.None); + } + + var request = new GetMyChatSessionsQuery() + { + StartDate = _startDate == default ? null : _startDate, + EndDate = _endDate == default ? null : _endDate + }; + + try + { + _response = await Sender.Send(request, CancellationToken.None); + responseType = CommandResponseType.Successful; + } + catch (Exception e) + { + responseType = HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + + [Then(@"The response has a collection of chat sessions")] + public void ThenTheResponseHasACollectionOfChatSessions() + { + _response?.Count.ShouldBe(_withinDateRangeExists == false ? 0 : _response.Count); + } + + [Then(@"Each chat session has a Key")] + public void ThenEachChatSessionHasAKey() + { + _response?.FirstOrDefault(x => x.Id == default).ShouldBeNull(); + } + + [Then(@"Each chat session has a Date greater than start date")] + public void ThenEachChatSessionHasADateGreaterThanStartDate() + { + if (_withinDateRangeExists) + { + _response?.FirstOrDefault(x => _startDate == default || x.Timestamp > _startDate).ShouldNotBeNull(); + } + } + + [Then(@"Each chat session has a Date less than end date")] + public void ThenEachChatSessionHasADateLessThanEndDate() + { + if (_withinDateRangeExists) + { + _response?.FirstOrDefault(x => _endDate == default || x.Timestamp < _endDate).ShouldNotBeNull(); + } + } +} diff --git a/src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs new file mode 100644 index 0000000..7be8917 --- /dev/null +++ b/src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs @@ -0,0 +1,85 @@ +using Goodtocode.AgentFramework.Core.Application.Chats; +using Goodtocode.AgentFramework.Core.Domain.Chats; + +namespace Goodtocode.AgentFramework.Tests.Integration.Chat +{ + [Binding] + [Scope(Tag = "patchChatSessionCommand")] + public class PatchChatSessionCommandStepDefinitions : TestBase + { + private Guid _id; + private bool _exists; + private string _title = string.Empty; + + [Given(@"I have a def ""([^""]*)""")] + public void GivenIHaveADef(string def) + { + base.def = def; + } + + [Given(@"I have a chat session id ""([^""]*)""")] + public void GivenIHaveAChatSessionId(string id) + { + Guid.TryParse(id, out _id).ShouldBeTrue(); + } + + [Given(@"the chat session exists ""([^""]*)""")] + public void GivenTheChatSessionExists(string exists) + { + _exists = bool.Parse(exists); + } + + [Given(@"I have a new chat session title ""([^""]*)""")] + public void GivenIHaveANewChatSessionTitle(string title) + { + _title = title; + } + + [When(@"I patch the chatSession")] + public async Task WhenIPatchTheChatSession() + { + if (_exists) + { + var chatSession = ChatSessionEntity.Create( + ownerId: rlsContext.OwnerId, + tenantId: rlsContext.TenantId, + actorId: Guid.NewGuid(), + title: "Test Session" + ); + context.ChatSessions.Add(chatSession); + await context.SaveChangesAsync(CancellationToken.None); + _id = chatSession.Id; + } + + var request = new PatchMyChatSessionCommand() + { + Id = _id, + Title = _title + }; + + try + { + var result = await Sender.Send(request, CancellationToken.None); + responseType = result.IsNotFound + ? CommandResponseType.NotFound + : CommandResponseType.Successful; + } + catch (Exception e) + { + HandleAssignResponseType(e); + } + } + + [Then(@"The response is ""([^""]*)""")] + public void ThenTheResponseIs(string response) + { + HandleHasResponseType(response); + } + + [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] + public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) + { + HandleExpectedValidationErrorsAssertions(expectedErrors); + } + } +} From 680d2cc60b4c1ef1849fe4ac5819d1fa1182245a Mon Sep 17 00:00:00 2001 From: "Robert J. Good" Date: Sat, 29 Aug 2026 00:18:33 -0700 Subject: [PATCH 4/6] removed dups --- src/Core.Application/Actor/ActorDto.cs | 38 ---- src/Core.Application/Actor/ActorGuard.cs | 29 --- .../Actor/CreateOurActorCommand.cs | 30 --- .../Actor/CreateOurActorCommandValidator.cs | 16 -- .../Actor/DeleteOurActorByOwnerIdCommand.cs | 26 --- ...DeleteOurActorByOwnerIdCommandValidator.cs | 10 - .../Actor/DeleteOurActorCommand.cs | 26 --- .../Actor/DeleteOurActorCommandValidator.cs | 10 - src/Core.Application/Actor/GetMyActorQuery.cs | 20 -- .../Actor/GetMyActorQueryValidator.cs | 9 - .../Actor/GetOurActorChatSessionQuery.cs | 23 -- .../GetOurActorChatSessionQueryValidator.cs | 10 - .../GetOurActorChatSessionsPaginatedQuery.cs | 32 --- ...ctorChatSessionsPaginatedQueryValidator.cs | 22 -- .../Actor/GetOurActorChatSessionsQuery.cs | 29 --- .../GetOurActorChatSessionsQueryValidator.cs | 18 -- .../Actor/GetOurActorQuery.cs | 19 -- .../Actor/GetOurActorQueryValidator.cs | 9 - .../Actor/GetOurActorsByNameQuery.cs | 25 --- .../Actor/GetOurActorsByNameQueryValidator.cs | 9 - .../Actor/SaveMyActorCommand.cs | 44 ---- .../Actor/SaveMyActorCommandValidator.cs | 16 -- src/Core.Application/Chat/ChatGuard.cs | 89 -------- src/Core.Application/Chat/ChatMessageDto.cs | 29 --- src/Core.Application/Chat/ChatSessionDto.cs | 29 --- .../Chat/CreateMyChatMessageCommand.cs | 83 -------- .../CreateMyChatMessageCommandValidator.cs | 13 -- .../Chat/CreateMyChatSessionCommand.cs | 97 --------- .../CreateMyChatSessionCommandValidator.cs | 10 - .../Chat/DeleteMyChatSessionCommand.cs | 30 --- .../DeleteMyChatSessionCommandValidator.cs | 10 - .../Chat/GetMyChatMessageQuery.cs | 28 --- .../Chat/GetMyChatMessageQueryValidator.cs | 10 - .../Chat/GetMyChatMessagesPaginatedQuery.cs | 38 ---- ...etMyChatMessagesPaginatedQueryValidator.cs | 23 -- .../Chat/GetMyChatSessionMessagesQuery.cs | 26 --- .../GetMyChatSessionMessagesQueryValidator.cs | 9 - .../Chat/GetMyChatSessionQuery.cs | 30 --- .../Chat/GetMyChatSessionQueryValidator.cs | 10 - .../Chat/GetMyChatSessionsPaginatedQuery.cs | 32 --- ...etMyChatSessionsPaginatedQueryValidator.cs | 23 -- .../Chat/GetMyChatSessionsQuery.cs | 33 --- .../Chat/GetMyChatSessionsQueryValidator.cs | 17 -- .../Chat/PatchMyChatSessionCommand.cs | 34 --- .../PatchMyChatSessionCommandValidator.cs | 13 -- src/Core.Domain/Actor/ActorEntity.cs | 58 ------ src/Core.Domain/Chat/ChatMessageEntity.cs | 52 ----- src/Core.Domain/Chat/ChatMessageRoles.cs | 9 - src/Core.Domain/Chat/ChatSessionEntity.cs | 66 ------ .../Endpoints/Actor/MyActorEndpoints.cs | 57 ----- .../Endpoints/Chat/MyChatMessageEndpoints.cs | 88 -------- .../Endpoints/Chat/MyChatSessionEndpoints.cs | 93 --------- .../CreateActorCommandStepDefinitions.cs | 100 --------- .../DeleteActorCommandStepDefinitions.cs | 78 ------- .../GetActorByOwnerIdQueryStepDefinitions.cs | 86 -------- .../Actor/GetActorQueryStepDefinitions.cs | 94 --------- .../GetOurActorsByNameQueryStepDefinitions.cs | 96 --------- .../Actor/SaveActorCommandStepDefinitions.cs | 98 --------- ...CreateChatMessageCommandStepDefinitions.cs | 104 --------- ...CreateChatSessionCommandStepDefinitions.cs | 93 --------- ...DeleteChatSessionCommandStepDefinitions.cs | 77 ------- .../GetChatMessageQueryStepDefinitions.cs | 108 ---------- ...atMessagesPaginatedQueryStepDefinitions.cs | 197 ------------------ ...ChatSessionMessagesQueryStepDefinitions.cs | 122 ----------- .../GetMyChatSessionQueryStepDefinitions.cs | 93 --------- ...atSessionsPaginatedQueryStepDefinitions.cs | 188 ----------------- .../GetMyChatSessionsQueryStepDefinitions.cs | 130 ------------ .../PatchChatSessionCommandStepDefinitions.cs | 85 -------- 68 files changed, 3358 deletions(-) delete mode 100644 src/Core.Application/Actor/ActorDto.cs delete mode 100644 src/Core.Application/Actor/ActorGuard.cs delete mode 100644 src/Core.Application/Actor/CreateOurActorCommand.cs delete mode 100644 src/Core.Application/Actor/CreateOurActorCommandValidator.cs delete mode 100644 src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs delete mode 100644 src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs delete mode 100644 src/Core.Application/Actor/DeleteOurActorCommand.cs delete mode 100644 src/Core.Application/Actor/DeleteOurActorCommandValidator.cs delete mode 100644 src/Core.Application/Actor/GetMyActorQuery.cs delete mode 100644 src/Core.Application/Actor/GetMyActorQueryValidator.cs delete mode 100644 src/Core.Application/Actor/GetOurActorChatSessionQuery.cs delete mode 100644 src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs delete mode 100644 src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs delete mode 100644 src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs delete mode 100644 src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs delete mode 100644 src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs delete mode 100644 src/Core.Application/Actor/GetOurActorQuery.cs delete mode 100644 src/Core.Application/Actor/GetOurActorQueryValidator.cs delete mode 100644 src/Core.Application/Actor/GetOurActorsByNameQuery.cs delete mode 100644 src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs delete mode 100644 src/Core.Application/Actor/SaveMyActorCommand.cs delete mode 100644 src/Core.Application/Actor/SaveMyActorCommandValidator.cs delete mode 100644 src/Core.Application/Chat/ChatGuard.cs delete mode 100644 src/Core.Application/Chat/ChatMessageDto.cs delete mode 100644 src/Core.Application/Chat/ChatSessionDto.cs delete mode 100644 src/Core.Application/Chat/CreateMyChatMessageCommand.cs delete mode 100644 src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs delete mode 100644 src/Core.Application/Chat/CreateMyChatSessionCommand.cs delete mode 100644 src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs delete mode 100644 src/Core.Application/Chat/DeleteMyChatSessionCommand.cs delete mode 100644 src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs delete mode 100644 src/Core.Application/Chat/GetMyChatMessageQuery.cs delete mode 100644 src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs delete mode 100644 src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs delete mode 100644 src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs delete mode 100644 src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs delete mode 100644 src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs delete mode 100644 src/Core.Application/Chat/GetMyChatSessionQuery.cs delete mode 100644 src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs delete mode 100644 src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs delete mode 100644 src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs delete mode 100644 src/Core.Application/Chat/GetMyChatSessionsQuery.cs delete mode 100644 src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs delete mode 100644 src/Core.Application/Chat/PatchMyChatSessionCommand.cs delete mode 100644 src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs delete mode 100644 src/Core.Domain/Actor/ActorEntity.cs delete mode 100644 src/Core.Domain/Chat/ChatMessageEntity.cs delete mode 100644 src/Core.Domain/Chat/ChatMessageRoles.cs delete mode 100644 src/Core.Domain/Chat/ChatSessionEntity.cs delete mode 100644 src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs delete mode 100644 src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs delete mode 100644 src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs delete mode 100644 src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs delete mode 100644 src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs delete mode 100644 src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs delete mode 100644 src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs diff --git a/src/Core.Application/Actor/ActorDto.cs b/src/Core.Application/Actor/ActorDto.cs deleted file mode 100644 index 744a02c..0000000 --- a/src/Core.Application/Actor/ActorDto.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class ActorDto -{ - public Guid Id { get; set; } = Guid.Empty; - public string Name { get; set; } = string.Empty; - public string FirstName { get; set; } = string.Empty; - public string LastName { get; set; } = string.Empty; - public string Email { get; set; } = string.Empty; - public Guid OwnerId { get; set; } - public Guid TenantId { get; set; } - public DateTime CreatedOn { get; private set; } = DateTime.UtcNow; - public DateTime? ModifiedOn { get; private set; } - public DateTime? DeletedOn { get; private set; } - - public static ActorDto CreateFrom(ActorEntity? entity) - { - if (entity is null) - { - return null!; - } - - return new ActorDto - { - Id = entity.Id, - FirstName = entity.FirstName ?? string.Empty, - LastName = entity.LastName ?? string.Empty, - Email = entity.Email ?? string.Empty, - OwnerId = entity.OwnerId, - TenantId = entity.TenantId, - CreatedOn = entity.CreatedOn, - ModifiedOn = entity.ModifiedOn, - DeletedOn = entity.DeletedOn - }; - } -} diff --git a/src/Core.Application/Actor/ActorGuard.cs b/src/Core.Application/Actor/ActorGuard.cs deleted file mode 100644 index dbcde28..0000000 --- a/src/Core.Application/Actor/ActorGuard.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public static class ActorGuard -{ - public static void GuardAgainstEmptyUserContext(IUserContext? userContext) - { - if (userContext == null || userContext.OwnerId == Guid.Empty || userContext.TenantId == Guid.Empty) - throw new CustomValidationException([ - new("UserContext", "A valid UserContext with OwnerId and TenantId is required to link an actor.") - ]); - } - - public static void GuardAgainstInvalidUserContext(IUserContext? userContext) - { - if (userContext is null) - { - throw new CustomValidationException([ - new("UserContext", "UserContext is required to save an actor") - ]); - } - - if (userContext.OwnerId == Guid.Empty) - { - throw new CustomValidationException([ - new("OwnerId", "A valid OwnerId is required in UserContext to save an actor") - ]); - } - } -} diff --git a/src/Core.Application/Actor/CreateOurActorCommand.cs b/src/Core.Application/Actor/CreateOurActorCommand.cs deleted file mode 100644 index f7524f5..0000000 --- a/src/Core.Application/Actor/CreateOurActorCommand.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class CreateOurActorCommand : UserScopedRequest, IRequest -{ - public string? FirstName { get; set; } - public string? LastName { get; set; } - public string? Email { get; set; } -} - -public class CreateOurActorCommandHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(CreateOurActorCommand request, CancellationToken cancellationToken) - { - ActorGuard.GuardAgainstEmptyUserContext(request.UserContext); - var actor = ActorEntity.Create( - ownerId: request.UserContext.OwnerId, - tenantId: request.UserContext.TenantId, - firstName: request.FirstName, - lastName: request.LastName, - email: request.Email - ); - _context.Actors.Add(actor); - await _context.SaveChangesAsync(cancellationToken); - return ActorDto.CreateFrom(actor); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/CreateOurActorCommandValidator.cs b/src/Core.Application/Actor/CreateOurActorCommandValidator.cs deleted file mode 100644 index 955f4c7..0000000 --- a/src/Core.Application/Actor/CreateOurActorCommandValidator.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class CreateOurActorCommandValidator : SecuredValidator -{ - public CreateOurActorCommandValidator() - { - RuleFor(x => x.FirstName) - .NotEmpty(); - - RuleFor(x => x.LastName) - .NotEmpty(); - - RuleFor(x => x.Email) - .NotEmpty(); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs b/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs deleted file mode 100644 index f58292c..0000000 --- a/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommand.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class DeleteActorByOwnerIdCommand : UserScopedRequest, IRequest -{ - public Guid OwnerId { get; set; } - -} - -public class DeleteActorByOwnerIdCommandHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(DeleteActorByOwnerIdCommand request, CancellationToken cancellationToken) - { - var actor = await _context.Actors.Where(x => x.OwnerId == request.OwnerId).FirstOrDefaultAsync(cancellationToken); - if (actor is null) - { - return CommandResult.NotFound(); - } - - _context.Actors.Remove(actor); - await _context.SaveChangesAsync(cancellationToken); - - return CommandResult.Success(); - } -} diff --git a/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs b/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs deleted file mode 100644 index fbebddd..0000000 --- a/src/Core.Application/Actor/DeleteOurActorByOwnerIdCommandValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class DeleteOurActorByOwnerIdCommandValidator : SecuredValidator -{ - public DeleteOurActorByOwnerIdCommandValidator() - { - RuleFor(x => x.OwnerId) - .NotEmpty(); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/DeleteOurActorCommand.cs b/src/Core.Application/Actor/DeleteOurActorCommand.cs deleted file mode 100644 index 3d2965c..0000000 --- a/src/Core.Application/Actor/DeleteOurActorCommand.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class DeleteOurActorCommand : UserScopedRequest, IRequest -{ - public Guid Id { get; set; } - -} - -public class DeleteActorCommandHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(DeleteOurActorCommand request, CancellationToken cancellationToken) - { - var actor = await _context.Actors.FindAsync([request.Id, cancellationToken], cancellationToken: cancellationToken); - if (actor is null) - { - return CommandResult.NotFound(); - } - - _context.Actors.Remove(actor); - await _context.SaveChangesAsync(cancellationToken); - - return CommandResult.Success(); - } -} diff --git a/src/Core.Application/Actor/DeleteOurActorCommandValidator.cs b/src/Core.Application/Actor/DeleteOurActorCommandValidator.cs deleted file mode 100644 index d10b613..0000000 --- a/src/Core.Application/Actor/DeleteOurActorCommandValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class DeleteOurActorCommandValidator : SecuredValidator -{ - public DeleteOurActorCommandValidator() - { - RuleFor(x => x.Id) - .NotEmpty(); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetMyActorQuery.cs b/src/Core.Application/Actor/GetMyActorQuery.cs deleted file mode 100644 index b6d95d7..0000000 --- a/src/Core.Application/Actor/GetMyActorQuery.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetMyActorQuery : UserScopedRequest, IRequest -{ - public Guid OwnerId { get; set; } - -} - -public class GetActorByOwnerIdQueryHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(GetMyActorQuery request, CancellationToken cancellationToken) - { - var actor = await _context.Actors - .FirstOrDefaultAsync(x => x.OwnerId == request.UserContext.OwnerId && x.TenantId == request.UserContext.TenantId, cancellationToken: cancellationToken); - - return actor is null ? null : ActorDto.CreateFrom(actor); - } -} diff --git a/src/Core.Application/Actor/GetMyActorQueryValidator.cs b/src/Core.Application/Actor/GetMyActorQueryValidator.cs deleted file mode 100644 index 093d8cf..0000000 --- a/src/Core.Application/Actor/GetMyActorQueryValidator.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetMyActorQueryValidator : SecuredValidator -{ - public GetMyActorQueryValidator() - { - - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionQuery.cs b/src/Core.Application/Actor/GetOurActorChatSessionQuery.cs deleted file mode 100644 index 59dbb69..0000000 --- a/src/Core.Application/Actor/GetOurActorChatSessionQuery.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; - -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorChatSessionQuery : UserScopedRequest, IRequest -{ - public Guid ActorId { get; set; } - public Guid ChatSessionId { get; set; } - -} - -public class GetOurActorChatSessionQueryHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(GetOurActorChatSessionQuery request, CancellationToken cancellationToken) - { - var returnData = await _context.ChatSessions - .FirstOrDefaultAsync(x => x.Id == request.ChatSessionId && x.ActorId == request.ActorId && x.TenantId == request.UserContext.TenantId, cancellationToken: cancellationToken); - - return returnData is null ? null : ChatSessionDto.CreateFrom(returnData); - } -} diff --git a/src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs b/src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs deleted file mode 100644 index edff521..0000000 --- a/src/Core.Application/Actor/GetOurActorChatSessionQueryValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorChatSessionQueryValidator : SecuredValidator -{ - public GetOurActorChatSessionQueryValidator() - { - RuleFor(x => x.ActorId).NotEmpty(); - RuleFor(x => x.ChatSessionId).NotEmpty(); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs b/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs deleted file mode 100644 index f57e5e0..0000000 --- a/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQuery.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; - -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorChatSessionsPaginatedQuery : UserScopedRequest, IRequest> -{ - public Guid ActorId { get; set; } - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - public int PageNumber { get; init; } = 1; - public int PageSize { get; init; } = 10; - -} - -public class GetOurActorChatSessionsPaginatedQueryHandler(IAgentFrameworkContext context) : IRequestHandler> -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task> Handle(GetOurActorChatSessionsPaginatedQuery request, CancellationToken cancellationToken) - { - var returnData = await _context.ChatSessions - .Include(x => x.Messages) - .OrderByDescending(x => x.Timestamp) - .Where(x => (request.StartDate == null || x.Timestamp > request.StartDate) - && (request.EndDate == null || x.Timestamp < request.EndDate)) - .Select(x => ChatSessionDto.CreateFrom(x)) - .PaginatedListAsync(request.PageNumber, request.PageSize); - - return returnData; - - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs b/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs deleted file mode 100644 index dc76c6a..0000000 --- a/src/Core.Application/Actor/GetOurActorChatSessionsPaginatedQueryValidator.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorChatSessionsPaginatedQueryValidator : SecuredValidator -{ - public GetOurActorChatSessionsPaginatedQueryValidator() - { - RuleFor(x => x.ActorId).NotEmpty(); - - RuleFor(v => v.StartDate).NotEmpty() - .When(v => v.EndDate != null) - .LessThanOrEqualTo(v => v.EndDate); - - RuleFor(v => v.EndDate) - .NotEmpty() - .When(v => v.StartDate != null) - .GreaterThanOrEqualTo(v => v.StartDate); - - RuleFor(x => x.PageNumber).NotEqual(0); - - RuleFor(x => x.PageSize).NotEqual(0); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs b/src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs deleted file mode 100644 index 83f6937..0000000 --- a/src/Core.Application/Actor/GetOurActorChatSessionsQuery.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; - -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorChatSessionsQuery : UserScopedRequest, IRequest> -{ - public Guid ActorId { get; set; } - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - -} - -public class GetOurActorChatSessionsQueryHandler(IAgentFrameworkContext context) : IRequestHandler> -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task> Handle(GetOurActorChatSessionsQuery request, CancellationToken cancellationToken) - { - var returnData = await _context.ChatSessions - .OrderByDescending(x => x.Timestamp) - .Where(x => x.ActorId == request.ActorId - && (request.StartDate == null || x.Timestamp > request.StartDate) - && (request.EndDate == null || x.Timestamp < request.EndDate)) - .Select(x => ChatSessionDto.CreateFrom(x)) - .ToListAsync(cancellationToken); - - return returnData; - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs b/src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs deleted file mode 100644 index eb386bc..0000000 --- a/src/Core.Application/Actor/GetOurActorChatSessionsQueryValidator.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorChatSessionsQueryValidator : SecuredValidator -{ - public GetOurActorChatSessionsQueryValidator() - { - RuleFor(x => x.ActorId).NotEmpty(); - - RuleFor(v => v.StartDate).NotEmpty() - .When(v => v.EndDate != null) - .LessThanOrEqualTo(v => v.EndDate); - - RuleFor(v => v.EndDate) - .NotEmpty() - .When(v => v.StartDate != null) - .GreaterThanOrEqualTo(v => v.StartDate); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorQuery.cs b/src/Core.Application/Actor/GetOurActorQuery.cs deleted file mode 100644 index 6f9a5f4..0000000 --- a/src/Core.Application/Actor/GetOurActorQuery.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorQuery : UserScopedRequest, IRequest -{ - public Guid ActorId { get; set; } -} - -public class GetActorQueryHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(GetOurActorQuery request, CancellationToken cancellationToken) - { - var actor = await _context.Actors - .FirstOrDefaultAsync(x => x.Id == request.ActorId && x.TenantId == request.UserContext.TenantId, cancellationToken: cancellationToken); - - return actor is null ? null : ActorDto.CreateFrom(actor); - } -} diff --git a/src/Core.Application/Actor/GetOurActorQueryValidator.cs b/src/Core.Application/Actor/GetOurActorQueryValidator.cs deleted file mode 100644 index aee4094..0000000 --- a/src/Core.Application/Actor/GetOurActorQueryValidator.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorQueryValidator : SecuredValidator -{ - public GetOurActorQueryValidator() - { - RuleFor(x => x.ActorId).NotEmpty(); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorsByNameQuery.cs b/src/Core.Application/Actor/GetOurActorsByNameQuery.cs deleted file mode 100644 index 1c4ef8d..0000000 --- a/src/Core.Application/Actor/GetOurActorsByNameQuery.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorsByNameQuery : UserScopedRequest, IRequest> -{ - public string Name { get; set; } = string.Empty; -} - -public class GetOurActorsByNameQueryHandler(IAgentFrameworkContext context) : IRequestHandler> -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task> Handle(GetOurActorsByNameQuery request, CancellationToken cancellationToken) - { - var tenantId = request.UserContext.TenantId; - var normalizedInput = request.Name.Trim(); - - return await _context.Actors - .Where(x => x.TenantId == tenantId) - .Where(x => - (x.FirstName != null && x.FirstName.Contains(normalizedInput)) - || (x.LastName != null && x.LastName.Contains(normalizedInput))) - .Select(x => ActorDto.CreateFrom(x)) - .ToListAsync(cancellationToken); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs b/src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs deleted file mode 100644 index 7f13383..0000000 --- a/src/Core.Application/Actor/GetOurActorsByNameQueryValidator.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class GetOurActorsByNameQueryValidator : SecuredValidator -{ - public GetOurActorsByNameQueryValidator() - { - RuleFor(x => x.Name).NotEmpty(); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/SaveMyActorCommand.cs b/src/Core.Application/Actor/SaveMyActorCommand.cs deleted file mode 100644 index e36c28d..0000000 --- a/src/Core.Application/Actor/SaveMyActorCommand.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class SaveMyActorCommand : UserScopedRequest, IRequest -{ - public string? FirstName { get; set; } - public string? LastName { get; set; } - public string? Email { get; set; } - -} - -public class SaveMyActorCommandHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(SaveMyActorCommand request, CancellationToken cancellationToken) - { - ActorGuard.GuardAgainstInvalidUserContext(request?.UserContext); - - var actor = await _context.Actors - .Where(x => x.OwnerId == request!.UserContext.OwnerId && x.TenantId == request.UserContext.TenantId) - .FirstOrDefaultAsync(cancellationToken); - if (actor is not null) - { - actor.Update(request?.FirstName, request?.LastName, request?.Email); - _context.Actors.Update(actor); - } - else - { - actor = ActorEntity.Create( - ownerId: request!.UserContext.OwnerId, - tenantId: request.UserContext.TenantId, - firstName: request.FirstName, - lastName: request.LastName, - email: request.Email - ); - _context.Actors.Add(actor); - } - - await _context.SaveChangesAsync(cancellationToken); - return ActorDto.CreateFrom(actor); - } -} \ No newline at end of file diff --git a/src/Core.Application/Actor/SaveMyActorCommandValidator.cs b/src/Core.Application/Actor/SaveMyActorCommandValidator.cs deleted file mode 100644 index f207656..0000000 --- a/src/Core.Application/Actor/SaveMyActorCommandValidator.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Actors; - -public class SaveMyActorCommandValidator : SecuredValidator -{ - public SaveMyActorCommandValidator() - { - RuleFor(x => x.FirstName) - .NotEmpty(); - - RuleFor(x => x.LastName) - .NotEmpty(); - - RuleFor(x => x.Email) - .NotEmpty(); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/ChatGuard.cs b/src/Core.Application/Chat/ChatGuard.cs deleted file mode 100644 index 5f1e0fc..0000000 --- a/src/Core.Application/Chat/ChatGuard.cs +++ /dev/null @@ -1,89 +0,0 @@ -using Goodtocode.AgentFramework.Core.Domain.Chats; -using Microsoft.Extensions.AI; - -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public static class ChatGuard -{ - public static void GuardAgainstEmptyMessage(string? message) - { - if (string.IsNullOrWhiteSpace(message)) - throw new CustomValidationException([ - new("Message", "A message is required as a prompt to get an AI response") - ]); - } - - public static void GuardAgainstIdExists(DbSet dbSet, Guid id) - { - if (dbSet.Any(x => x.Id == id)) - throw new CustomConflictException("Id already exists"); - } - - public static void GuardAgainstEmptyUser(IUserContext? userContext) - { - if (userContext == null || userContext.OwnerId == Guid.Empty || userContext.TenantId == Guid.Empty) - throw new CustomValidationException([ - new("UserContext", "User information is required to create a chat message") - ]); - } - - public static void GuardAgainstUnauthorized(ChatSessionEntity chatSession, IUserContext userContext) - { - if ((chatSession.OwnerId != userContext.OwnerId) && !(userContext.Roles?.Contains("Admin") ?? false)) - throw new CustomForbiddenAccessException("You do not have permission to access this ChatSession"); - } - - public static void GuardAgainstNullAgentResponse(ChatMessage? response) - { - if (response == null) - throw new CustomValidationException([ - new("ChatMessage", "Agent response cannot be null") - ]); - } - - public static void GuardAgainstNullAgentResponse(object? response) - { - if (response == null) - throw new CustomValidationException([ - new("AgentResponse", "Failed to get a response from the AI agent") - ]); - } - - public static void GuardAgainstUnauthorized(ChatMessageEntity chatMessage, IUserContext userInfo) - { - if (chatMessage.ChatSession?.OwnerId != userInfo.OwnerId) - throw new CustomForbiddenAccessException("ChatMessage", chatMessage.Id); - } - - public static void GuardAgainstEmptyUserForQuery(IUserContext? userContext) - { - if (userContext == null || userContext.OwnerId == Guid.Empty || userContext.TenantId == Guid.Empty) - throw new CustomValidationException([ - new("UserInfo", "User information is required to retrieve chat sessions") - ]); - } - - public static void GuardAgainstEmptyId(Guid? id) - { - if (id == Guid.Empty) - throw new CustomValidationException([ - new("Id", "A valid chat session ID is required") - ]); - } - - public static void GuardAgainstEmptyTitle(string title) - { - if (string.IsNullOrWhiteSpace(title)) - throw new CustomValidationException([ - new("Title", "Title cannot be empty") - ]); - } - - public static void GuardAgainstEmptyUserForPatch(IUserContext? userContext) - { - if (userContext == null || userContext.OwnerId == Guid.Empty || userContext.TenantId == Guid.Empty) - throw new CustomValidationException([ - new("UserContext", "User information is required to update a chat session") - ]); - } -} diff --git a/src/Core.Application/Chat/ChatMessageDto.cs b/src/Core.Application/Chat/ChatMessageDto.cs deleted file mode 100644 index ae8f824..0000000 --- a/src/Core.Application/Chat/ChatMessageDto.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class ChatMessageDto -{ - public Guid Id { get; set; } = Guid.Empty; - public Guid ChatSessionId { get; set; } = Guid.Empty; - public string Role { get; set; } = string.Empty; - public string Content { get; set; } = string.Empty; - public DateTimeOffset Timestamp { get; set; } - - public static ChatMessageDto CreateFrom(ChatMessageEntity? entity) - { - if (entity is null) - { - return null!; - } - - return new ChatMessageDto - { - Id = entity.Id, - ChatSessionId = entity.ChatSessionId, - Role = entity.Role.ToString(), - Content = entity.Content, - Timestamp = entity.Timestamp - }; - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/ChatSessionDto.cs b/src/Core.Application/Chat/ChatSessionDto.cs deleted file mode 100644 index 81ac784..0000000 --- a/src/Core.Application/Chat/ChatSessionDto.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class ChatSessionDto -{ - public Guid Id { get; set; } = Guid.Empty; - public string Title { get; set; } = string.Empty; - public Guid ActorId { get; set; } = Guid.Empty; - public DateTimeOffset Timestamp { get; set; } - public ICollection? Messages { get; set; } - - public static ChatSessionDto CreateFrom(ChatSessionEntity? entity) - { - if (entity is null) - { - return null!; - } - - return new ChatSessionDto - { - Id = entity.Id, - Title = entity.Title ?? string.Empty, - ActorId = entity.ActorId, - Timestamp = entity.Timestamp, - Messages = entity.Messages?.Select(ChatMessageDto.CreateFrom).ToList() - }; - } -} diff --git a/src/Core.Application/Chat/CreateMyChatMessageCommand.cs b/src/Core.Application/Chat/CreateMyChatMessageCommand.cs deleted file mode 100644 index ae60c1d..0000000 --- a/src/Core.Application/Chat/CreateMyChatMessageCommand.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Goodtocode.AgentFramework.Core.Domain.Chats; -using Goodtocode.AgentFramework.Core.Application.Governance; -using Microsoft.Agents.AI; -using Microsoft.Extensions.AI; - -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class CreateMyChatMessageCommand : UserScopedRequest, IRequest> -{ - public Guid ChatSessionId { get; set; } - public string? Message { get; set; } - -} - -public class CreateChatMessageCommandHandler(AIAgent agent, IAgentFrameworkContext context, ChatGovernanceGate governanceGate) : IRequestHandler> -{ - private readonly AIAgent _agent = agent; - private readonly IAgentFrameworkContext _context = context; - private readonly ChatGovernanceGate _governanceGate = governanceGate; - - public async Task> Handle(CreateMyChatMessageCommand request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyMessage(request?.Message); - ChatGuard.GuardAgainstEmptyUser(request?.UserContext); - - var chatSession = await _context.ChatSessions - .FirstOrDefaultAsync(x => x.Id == request!.ChatSessionId && x.OwnerId == request.UserContext.OwnerId && x.TenantId == request.UserContext.TenantId, cancellationToken); - if (chatSession is null) - { - return CommandResult.NotFound(); - } - - ChatGuard.GuardAgainstUnauthorized(chatSession, request!.UserContext!); - - var governed = _governanceGate.Enforce( - request.UserContext, - chatSession.Id, - request.Message!); - - var chatHistory = new List - { - new(ChatRole.System, governed.PromptContext.SystemInstruction) - }; - foreach (ChatMessageEntity message in chatSession.Messages) - { - chatHistory.Add(new ChatMessage( - role: message.Role == ChatMessageRole.user ? ChatRole.User : ChatRole.Assistant, - content: message.Content)); - } - chatHistory.Add(new ChatMessage(role: ChatRole.User, content: request!.Message!)); - - var agentResponse = await _agent.RunAsync(chatHistory, cancellationToken: cancellationToken); - var response = agentResponse.Messages.LastOrDefault(); - - ChatGuard.GuardAgainstNullAgentResponse(response); - - var chatMessage = ChatMessageEntity.Create( - ownerId: request.UserContext.OwnerId, - tenantId: request.UserContext.TenantId, - chatSessionId: chatSession.Id, - role: ChatMessageRole.user, - content: request.Message! - ); - chatSession.Messages.Add(chatMessage); - _context.ChatMessages.Add(chatMessage); - - var agentReply = (response?.Contents?.LastOrDefault()?.ToString()) ?? string.Empty; - - var chatMessageResponse = ChatMessageEntity.Create( - ownerId: request.UserContext.OwnerId, - tenantId: request.UserContext.TenantId, - chatSessionId: chatSession.Id, - role: ChatMessageRole.assistant, - content: agentReply - ); - chatSession.Messages.Add(chatMessageResponse); - _context.ChatMessages.Add(chatMessageResponse); - - await _context.SaveChangesAsync(cancellationToken); - - return CommandResult.Success(ChatMessageDto.CreateFrom(chatMessage)); - } -} diff --git a/src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs b/src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs deleted file mode 100644 index 5bb8a9b..0000000 --- a/src/Core.Application/Chat/CreateMyChatMessageCommandValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class CreateMyChatMessageCommandValidator : SecuredValidator -{ - public CreateMyChatMessageCommandValidator() - { - RuleFor(x => x.ChatSessionId) - .NotEmpty("ChatSessionId is required"); - - RuleFor(x => x.Message) - .NotEmpty("Message is required"); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/CreateMyChatSessionCommand.cs b/src/Core.Application/Chat/CreateMyChatSessionCommand.cs deleted file mode 100644 index 0f8530e..0000000 --- a/src/Core.Application/Chat/CreateMyChatSessionCommand.cs +++ /dev/null @@ -1,97 +0,0 @@ -using Goodtocode.AgentFramework.Core.Domain.Actors; -using Goodtocode.AgentFramework.Core.Domain.Chats; -using Goodtocode.AgentFramework.Core.Application.Governance; -using Microsoft.Agents.AI; -using Microsoft.Extensions.AI; - -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class CreateMyChatSessionCommand : UserScopedRequest, IRequest -{ - public string? Title { get; set; } - public string? Message { get; set; } - public Guid? PersonaId { get; set; } - public int? PersonaVersion { get; set; } - -} - -public class CreateMyChatSessionCommandHandler(AIAgent kernel, IAgentFrameworkContext context, ChatGovernanceGate governanceGate) : IRequestHandler -{ - private readonly AIAgent _agent = kernel; - private readonly IAgentFrameworkContext _context = context; - private readonly ChatGovernanceGate _governanceGate = governanceGate; - - public async Task Handle(CreateMyChatSessionCommand request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyMessage(request?.Message); - ChatGuard.GuardAgainstEmptyUser(request?.UserContext); - - var actor = await _context.Actors - .FirstOrDefaultAsync(a => a.OwnerId == request!.UserContext!.OwnerId - && a.TenantId == request.UserContext.TenantId, cancellationToken); - - if (actor == null) - { - actor = ActorEntity.Create( - ownerId: request!.UserContext.OwnerId, - tenantId: request.UserContext.TenantId, - firstName: request.UserContext.FirstName, - lastName: request.UserContext.LastName, - email: request.UserContext.Email - ); - _context.Actors.Add(actor); - await _context.SaveChangesAsync(cancellationToken); - } - - var governed = _governanceGate.Enforce( - request.UserContext, - Guid.Empty, - request.Message!); - - var chatHistory = new List - { - new(ChatRole.System, governed.PromptContext.SystemInstruction), - new(ChatRole.User, request!.Message!) - }; - - var agentResponse = await _agent.RunAsync(chatHistory, cancellationToken: cancellationToken); - var response = agentResponse.Messages.LastOrDefault(); - - ChatGuard.GuardAgainstNullAgentResponse(response); - - var title = request!.Title ?? $"{request!.Message![..(request.Message!.Length >= 25 ? 25 : request.Message!.Length)]}"; - - var chatSession = ChatSessionEntity.Create( - ownerId: request.UserContext.OwnerId, - tenantId: request.UserContext.TenantId, - actorId: actor.Id, - title: title, - personaId: request.PersonaId ?? Guid.Empty, - personaVersion: request.PersonaVersion ?? 0 - ); - _context.ChatSessions.Add(chatSession); - await _context.SaveChangesAsync(cancellationToken); - - var chatMessages = new List - { - ChatMessageEntity.Create( - ownerId: request.UserContext.OwnerId, - tenantId: request.UserContext.TenantId, - chatSessionId: chatSession.Id, - role: ChatMessageRole.user, - content: request!.Message! - ), - ChatMessageEntity.Create( - ownerId: request.UserContext.OwnerId, - tenantId: request.UserContext.TenantId, - chatSessionId: chatSession.Id, - role: ChatMessageRole.system, - content: response!.Text - ) - }; - _context.ChatMessages.AddRange(chatMessages); - await _context.SaveChangesAsync(cancellationToken); - - return ChatSessionDto.CreateFrom(chatSession); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs b/src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs deleted file mode 100644 index d220a90..0000000 --- a/src/Core.Application/Chat/CreateMyChatSessionCommandValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class CreateMyChatSessionCommandValidator : SecuredValidator -{ - public CreateMyChatSessionCommandValidator() - { - RuleFor(x => x.Message) - .NotEmpty("Message is required"); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/DeleteMyChatSessionCommand.cs b/src/Core.Application/Chat/DeleteMyChatSessionCommand.cs deleted file mode 100644 index 7967db5..0000000 --- a/src/Core.Application/Chat/DeleteMyChatSessionCommand.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class DeleteMyChatSessionCommand : UserScopedRequest, IRequest -{ - public Guid Id { get; set; } - -} - -public class DeleteMyChatSessionCommandHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(DeleteMyChatSessionCommand request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyUser(request?.UserContext); - - var chatSession = await _context.ChatSessions.FindAsync([request!.Id, cancellationToken], cancellationToken: cancellationToken); - if (chatSession is null) - { - return CommandResult.NotFound(); - } - - ChatGuard.GuardAgainstUnauthorized(chatSession, request.UserContext!); - - _context.ChatSessions.Remove(chatSession); - await _context.SaveChangesAsync(cancellationToken); - - return CommandResult.Success(); - } -} diff --git a/src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs b/src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs deleted file mode 100644 index 4529f80..0000000 --- a/src/Core.Application/Chat/DeleteMyChatSessionCommandValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class DeleteMyChatSessionCommandValidator : SecuredValidator -{ - public DeleteMyChatSessionCommandValidator() - { - RuleFor(x => x.Id) - .NotEmpty("Id is required"); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatMessageQuery.cs b/src/Core.Application/Chat/GetMyChatMessageQuery.cs deleted file mode 100644 index ef37d71..0000000 --- a/src/Core.Application/Chat/GetMyChatMessageQuery.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatMessageQuery : UserScopedRequest, IRequest -{ - public Guid Id { get; set; } - -} - -public class GetMyChatMessageQueryHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(GetMyChatMessageQuery request, - CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyUser(request?.UserContext); - - var chatMessage = await _context.ChatMessages.FindAsync([request!.Id, cancellationToken], cancellationToken: cancellationToken); - if (chatMessage is null) - { - return null; - } - - ChatGuard.GuardAgainstUnauthorized(chatMessage, request.UserContext!); - - return ChatMessageDto.CreateFrom(chatMessage); - } -} diff --git a/src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs b/src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs deleted file mode 100644 index ba69e39..0000000 --- a/src/Core.Application/Chat/GetMyChatMessageQueryValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatMessageQueryValidator : SecuredValidator -{ - public GetMyChatMessageQueryValidator() - { - RuleFor(x => x.Id) - .NotEmpty("Id is required"); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs b/src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs deleted file mode 100644 index aa55939..0000000 --- a/src/Core.Application/Chat/GetMyChatMessagesPaginatedQuery.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatMessagesPaginatedQuery : UserScopedRequest, IRequest> -{ - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - public int PageNumber { get; init; } = 1; - public int PageSize { get; init; } = 10; - -} - -public class GetMyChatMessagesPaginatedQueryHandler(IAgentFrameworkContext context) : IRequestHandler> -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task> Handle(GetMyChatMessagesPaginatedQuery request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyUserForQuery(request?.UserContext); - - var userContext = request!.UserContext!; - - var query = _context.ChatMessages - .Where(x => x.ChatSession != null && x.ChatSession.OwnerId == userContext.OwnerId && x.ChatSession.TenantId == userContext.TenantId); - - if (request.StartDate.HasValue) - query = query.Where(x => x.Timestamp > request.StartDate.Value); - - if (request.EndDate.HasValue) - query = query.Where(x => x.Timestamp < request.EndDate.Value); - - var returnData = await query - .OrderByDescending(x => x.Timestamp) - .Select(x => ChatMessageDto.CreateFrom(x)) - .PaginatedListAsync(request.PageNumber, request.PageSize); - - return returnData; - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs b/src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs deleted file mode 100644 index 29923b0..0000000 --- a/src/Core.Application/Chat/GetMyChatMessagesPaginatedQueryValidator.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatMessagesPaginatedQueryValidator : SecuredValidator -{ - public GetMyChatMessagesPaginatedQueryValidator() - { - RuleFor(v => v.StartDate) - .NotEmpty("StartDate is required when EndDate is provided") - .When(v => v.EndDate != null) - .LessThanOrEqualTo(v => v.EndDate); - - RuleFor(v => v.EndDate) - .NotEmpty("EndDate is required when StartDate is provided") - .When(v => v.StartDate != null) - .GreaterThanOrEqualTo(v => v.StartDate); - - RuleFor(x => x.PageNumber) - .NotEqual(0, "PageNumber must be greater than 0"); - - RuleFor(x => x.PageSize) - .NotEqual(0, "PageSize must be greater than 0"); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs b/src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs deleted file mode 100644 index 90caa32..0000000 --- a/src/Core.Application/Chat/GetMyChatSessionMessagesQuery.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatSessionMessagesQuery : UserScopedRequest, IRequest> -{ - public Guid ChatSessionId { get; set; } -} - -public class GetMyChatSessionMessagesQueryHandler(IAgentFrameworkContext context) : IRequestHandler> -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task> Handle(GetMyChatSessionMessagesQuery request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyUserForQuery(request.UserContext); - ChatGuard.GuardAgainstEmptyId(request.ChatSessionId); - - var userContext = request.UserContext; - return await _context.ChatMessages - .Where(x => x.ChatSessionId == request.ChatSessionId - && x.OwnerId == userContext.OwnerId - && x.TenantId == userContext.TenantId) - .OrderBy(x => x.Timestamp) - .Select(x => ChatMessageDto.CreateFrom(x)) - .ToListAsync(cancellationToken); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs b/src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs deleted file mode 100644 index 3a4e485..0000000 --- a/src/Core.Application/Chat/GetMyChatSessionMessagesQueryValidator.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatSessionMessagesQueryValidator : SecuredValidator -{ - public GetMyChatSessionMessagesQueryValidator() - { - RuleFor(x => x.ChatSessionId).NotEmpty(); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionQuery.cs b/src/Core.Application/Chat/GetMyChatSessionQuery.cs deleted file mode 100644 index 76dbcfd..0000000 --- a/src/Core.Application/Chat/GetMyChatSessionQuery.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatSessionQuery : UserScopedRequest, IRequest -{ - public Guid Id { get; set; } - -} - -public class GetMyChatSessionQueryHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(GetMyChatSessionQuery request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyUserForQuery(request?.UserContext); - ChatGuard.GuardAgainstEmptyId(request?.Id); - - var chatSession = await _context.ChatSessions - .FirstOrDefaultAsync(x => x.Id == request!.Id && x.OwnerId == request.UserContext.OwnerId && x.TenantId == request.UserContext.TenantId, cancellationToken: cancellationToken); - - if (chatSession is null) - { - return null; - } - - ChatGuard.GuardAgainstUnauthorized(chatSession, request!.UserContext!); - - return ChatSessionDto.CreateFrom(chatSession); - } -} diff --git a/src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs b/src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs deleted file mode 100644 index e2ba9b2..0000000 --- a/src/Core.Application/Chat/GetMyChatSessionQueryValidator.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatSessionQueryValidator : SecuredValidator -{ - public GetMyChatSessionQueryValidator() - { - RuleFor(x => x.Id) - .NotEmpty("Id is required"); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs b/src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs deleted file mode 100644 index c345b09..0000000 --- a/src/Core.Application/Chat/GetMyChatSessionsPaginatedQuery.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatSessionsPaginatedQuery : UserScopedRequest, IRequest> -{ - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - public int PageNumber { get; init; } = 1; - public int PageSize { get; init; } = 10; - -} - -public class GetMyChatSessionsPaginatedQueryHandler(IAgentFrameworkContext context) : IRequestHandler> -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task> Handle(GetMyChatSessionsPaginatedQuery request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyUserForQuery(request?.UserContext); - var ownerId = request!.UserContext!.OwnerId; - - var returnData = await _context.ChatSessions - .Include(x => x.Messages) - .Where(x => x.OwnerId == ownerId) - .OrderByDescending(x => x.Timestamp) - .Where(x => (request.StartDate == null || x.Timestamp > request.StartDate) - && (request.EndDate == null || x.Timestamp < request.EndDate)) - .Select(x => ChatSessionDto.CreateFrom(x)) - .PaginatedListAsync(request.PageNumber, request.PageSize); - - return returnData; - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs b/src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs deleted file mode 100644 index dcae49b..0000000 --- a/src/Core.Application/Chat/GetMyChatSessionsPaginatedQueryValidator.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatSessionsPaginatedQueryValidator : SecuredValidator -{ - public GetMyChatSessionsPaginatedQueryValidator() - { - RuleFor(v => v.StartDate) - .NotEmpty("StartDate is required when EndDate is provided") - .When(v => v.EndDate != null) - .LessThanOrEqualTo(v => v.EndDate); - - RuleFor(v => v.EndDate) - .NotEmpty("EndDate is required when StartDate is provided") - .When(v => v.StartDate != null) - .GreaterThanOrEqualTo(v => v.StartDate); - - RuleFor(x => x.PageNumber) - .NotEqual(0, "PageNumber must be greater than 0"); - - RuleFor(x => x.PageSize) - .NotEqual(0, "PageSize must be greater than 0"); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionsQuery.cs b/src/Core.Application/Chat/GetMyChatSessionsQuery.cs deleted file mode 100644 index 55fa0e9..0000000 --- a/src/Core.Application/Chat/GetMyChatSessionsQuery.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatSessionsQuery : UserScopedRequest, IRequest> -{ - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - -} - -public class GetMyChatSessionsQueryHandler(IAgentFrameworkContext context) : IRequestHandler> -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task> Handle(GetMyChatSessionsQuery request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyUserForQuery(request?.UserContext); - - var startDate = request?.StartDate; - var endDate = request?.EndDate; - var userContext = request?.UserContext; - - var returnData = await _context.ChatSessions - .Where(x => userContext != null && x.OwnerId == userContext.OwnerId && x.TenantId == userContext.TenantId) - .OrderByDescending(x => x.Timestamp) - .Where(x => (startDate == null || x.Timestamp > startDate) - && (endDate == null || x.Timestamp < endDate)) - .Include(x => x.Messages) - .Select(x => ChatSessionDto.CreateFrom(x)) - .ToListAsync(cancellationToken); - - return returnData; - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs b/src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs deleted file mode 100644 index 82be05b..0000000 --- a/src/Core.Application/Chat/GetMyChatSessionsQueryValidator.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class GetMyChatSessionsQueryValidator : SecuredValidator -{ - public GetMyChatSessionsQueryValidator() - { - RuleFor(v => v.StartDate) - .NotEmpty("StartDate is required when EndDate is provided") - .When(v => v.EndDate != null) - .LessThanOrEqualTo(v => v.EndDate); - - RuleFor(v => v.EndDate) - .NotEmpty("EndDate is required when StartDate is provided") - .When(v => v.StartDate != null) - .GreaterThanOrEqualTo(v => v.StartDate); - } -} \ No newline at end of file diff --git a/src/Core.Application/Chat/PatchMyChatSessionCommand.cs b/src/Core.Application/Chat/PatchMyChatSessionCommand.cs deleted file mode 100644 index 998182b..0000000 --- a/src/Core.Application/Chat/PatchMyChatSessionCommand.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class PatchMyChatSessionCommand : UserScopedRequest, IRequest -{ - public Guid Id { get; set; } - public string Title { get; set; } = string.Empty; - -} - -public class PatchChatSessionCommandHandler(IAgentFrameworkContext context) : IRequestHandler -{ - private readonly IAgentFrameworkContext _context = context; - - public async Task Handle(PatchMyChatSessionCommand request, CancellationToken cancellationToken) - { - ChatGuard.GuardAgainstEmptyTitle(request.Title); - ChatGuard.GuardAgainstEmptyUserForPatch(request?.UserContext); - - var chatSession = await _context.ChatSessions.FindAsync([request!.Id, cancellationToken], cancellationToken: cancellationToken); - if (chatSession is null) - { - return CommandResult.NotFound(); - } - - ChatGuard.GuardAgainstUnauthorized(chatSession, request.UserContext!); - - chatSession.Update(request.Title); - - _context.ChatSessions.Update(chatSession); - await _context.SaveChangesAsync(cancellationToken); - - return CommandResult.Success(); - } -} diff --git a/src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs b/src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs deleted file mode 100644 index 97c72b2..0000000 --- a/src/Core.Application/Chat/PatchMyChatSessionCommandValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Application.Chats; - -public class PatchMyChatSessionCommandValidator : SecuredValidator -{ - public PatchMyChatSessionCommandValidator() - { - RuleFor(x => x.Id) - .NotEmpty("Id is required"); - - RuleFor(x => x.Title) - .NotEmpty("Title is required"); - } -} \ No newline at end of file diff --git a/src/Core.Domain/Actor/ActorEntity.cs b/src/Core.Domain/Actor/ActorEntity.cs deleted file mode 100644 index 532ec3a..0000000 --- a/src/Core.Domain/Actor/ActorEntity.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Domain.Actors; - -public class ActorEntity : SecuredEntity -{ - public string? FirstName { get; private set; } = string.Empty; - public string? LastName { get; private set; } = string.Empty; - public string? Email { get; private set; } = string.Empty; - - protected ActorEntity() : base() { } - - private ActorEntity( - Guid id, - string canonicalKey, - Guid ownerId, - Guid tenantId, - Guid createdBy, - DateTime createdOn, - DateTimeOffset timestamp, - string? firstName, - string? lastName, - string? email) - : base(id: id, partitionKey: tenantId.ToString(), rowKey: canonicalKey, - ownerId: ownerId, tenantId: tenantId, createdBy: createdBy, - createdOn: createdOn, timestamp: timestamp) - { - FirstName = firstName; - LastName = lastName; - Email = email; - } - - public static ActorEntity Create( - Guid ownerId, - Guid tenantId, - string? firstName, - string? lastName, - string? email) - { - return new ActorEntity( - id: Guid.NewGuid(), - canonicalKey: Guid.NewGuid().ToString(), - ownerId: ownerId, - tenantId: tenantId, - createdBy: ownerId, - createdOn: DateTime.UtcNow, - timestamp: DateTimeOffset.UtcNow, - firstName: firstName, - lastName: lastName, - email: email - ); - } - - public void Update(string? firstName, string? lastName, string? email) - { - FirstName = firstName ?? FirstName; - LastName = lastName ?? LastName; - Email = email ?? Email; - } -} diff --git a/src/Core.Domain/Chat/ChatMessageEntity.cs b/src/Core.Domain/Chat/ChatMessageEntity.cs deleted file mode 100644 index c84ec9f..0000000 --- a/src/Core.Domain/Chat/ChatMessageEntity.cs +++ /dev/null @@ -1,52 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Domain.Chats; - -public class ChatMessageEntity : SecuredEntity, IDomainEntity -{ - public Guid ChatSessionId { get; private set; } - public ChatMessageRole Role { get; private set; } - public string Content { get; private set; } = string.Empty; - public virtual ChatSessionEntity? ChatSession { get; private set; } - - protected ChatMessageEntity() : base() { } - - private ChatMessageEntity( - Guid id, - string canonicalKey, - Guid ownerId, - Guid tenantId, - Guid createdBy, - DateTime createdOn, - DateTimeOffset timestamp, - Guid chatSessionId, - ChatMessageRole role, - string content) - : base(id: id, partitionKey: tenantId.ToString(), rowKey: canonicalKey, - ownerId: ownerId, tenantId: tenantId, createdBy: createdBy, - createdOn: createdOn, timestamp: timestamp) - { - ChatSessionId = chatSessionId; - Role = role; - Content = content; - } - - public static ChatMessageEntity Create( - Guid ownerId, - Guid tenantId, - Guid chatSessionId, - ChatMessageRole role, - string content) - { - return new ChatMessageEntity( - id: Guid.NewGuid(), - canonicalKey: Guid.NewGuid().ToString(), - ownerId: ownerId, - tenantId: tenantId, - createdBy: ownerId, - createdOn: DateTime.UtcNow, - timestamp: DateTimeOffset.UtcNow, - chatSessionId: chatSessionId, - role: role, - content: content - ); - } -} diff --git a/src/Core.Domain/Chat/ChatMessageRoles.cs b/src/Core.Domain/Chat/ChatMessageRoles.cs deleted file mode 100644 index b98a163..0000000 --- a/src/Core.Domain/Chat/ChatMessageRoles.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Domain.Chats; - -public enum ChatMessageRole -{ - system, - user, - assistant, - tool -} diff --git a/src/Core.Domain/Chat/ChatSessionEntity.cs b/src/Core.Domain/Chat/ChatSessionEntity.cs deleted file mode 100644 index 9b58c5a..0000000 --- a/src/Core.Domain/Chat/ChatSessionEntity.cs +++ /dev/null @@ -1,66 +0,0 @@ -namespace Goodtocode.AgentFramework.Core.Domain.Chats; - -public class ChatSessionEntity : SecuredEntity -{ - public Guid ActorId { get; private set; } - public Guid PersonaId { get; private set; } - public int PersonaVersion { get; private set; } - public string? Title { get; private set; } = string.Empty; - public virtual ICollection Messages { get; private set; } = []; - - protected ChatSessionEntity() : base() { } - - private ChatSessionEntity( - Guid id, - string canonicalKey, - Guid ownerId, - Guid tenantId, - Guid createdBy, - DateTime createdOn, - DateTimeOffset timestamp, - Guid actorId, - Guid personaId, - int personaVersion, - string? title, - ICollection messages) - : base(id: id, partitionKey: tenantId.ToString(), rowKey: canonicalKey, - ownerId: ownerId, tenantId: tenantId, createdBy: createdBy, - createdOn: createdOn, timestamp: timestamp) - { - ActorId = actorId; - PersonaId = personaId; - PersonaVersion = personaVersion; - Title = title; - Messages = messages; - } - - public static ChatSessionEntity Create( - Guid ownerId, - Guid tenantId, - Guid actorId, - string? title, - ICollection? messages = null, - Guid? personaId = null, - int? personaVersion = null) - { - return new ChatSessionEntity( - id: Guid.NewGuid(), - canonicalKey: Guid.NewGuid().ToString(), - ownerId: ownerId, - tenantId: tenantId, - createdBy: ownerId, - createdOn: DateTime.UtcNow, - timestamp: DateTimeOffset.UtcNow, - actorId: actorId, - personaId: personaId ?? Guid.Empty, - personaVersion: personaVersion ?? 0, - title: title, - messages: messages ?? [] - ); - } - - public void Update(string? title) - { - Title = title ?? Title; - } -} diff --git a/src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs b/src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs deleted file mode 100644 index 8e7ce1d..0000000 --- a/src/Presentation.Api/Endpoints/Actor/MyActorEndpoints.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Actors; - -namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Actor; - -/// -/// Maps identity actor endpoints. -/// -public static class MyActorEndpoints -{ - /// - /// Registers actor-related minimal API endpoints. - /// - /// The endpoint route builder. - /// The API version set that declares supported versions for this endpoint group, enabling Asp.Versioning to substitute the version token in the route template (e.g. api/v{version:apiVersion}api/v1) and generate correct OpenAPI paths. - /// The endpoint route builder. - public static IEndpointRouteBuilder MapMyActorEndpoints(this IEndpointRouteBuilder endpoints, ApiVersionSet versionSet) - { - var group = endpoints - .MapGroup("api/v{version:apiVersion}/my/actors") - .RequireAuthorization(); - group.WithApiVersionSet(versionSet).HasApiVersion(new ApiVersion(1, 0)); - - group.MapGet("{ownerId:guid}", GetMyActorProfile) - .WithName("GetMyActorProfile") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status404NotFound) - .Produces(StatusCodes.Status500InternalServerError); - - group.MapPut("", SaveMyActor) - .WithName("SaveMyActor") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status400BadRequest) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status500InternalServerError); - - return endpoints; - } - - private static async Task GetMyActorProfile(ISender sender, Guid ownerId) - { - var actor = await sender.Send(new GetMyActorQuery { OwnerId = ownerId }); - return ApiResponseMapper.SingleOrNotFound(actor); - } - - private static async Task SaveMyActor(HttpContext httpContext, ISender sender, SaveMyActorCommand command) - { - var response = await sender.Send(command); - var version = httpContext.Request.RouteValues["version"]?.ToString() ?? "1.0"; - - return TypedResults.CreatedAtRoute( - response, - "GetMyActorProfile", - new { version, ownerId = response.OwnerId }); - } -} diff --git a/src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs b/src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs deleted file mode 100644 index 25193b1..0000000 --- a/src/Presentation.Api/Endpoints/Chat/MyChatMessageEndpoints.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; - -namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Chat; - -/// -/// Maps chat message endpoints. -/// -public static class MyChatMessageEndpoints -{ - /// - /// Registers chat message endpoint mappings. - /// - /// The endpoint route builder. - /// The API version set that declares supported versions for this endpoint group, enabling Asp.Versioning to substitute the version token in the route template (e.g. api/v{version:apiVersion}api/v1) and generate correct OpenAPI paths. - /// The endpoint route builder. - public static IEndpointRouteBuilder MapMyChatMessageEndpoints(this IEndpointRouteBuilder endpoints, ApiVersionSet versionSet) - { - var group = endpoints - .MapGroup("api/v{version:apiVersion}/my/messages") - .RequireAuthorization(); - group.WithApiVersionSet(versionSet).HasApiVersion(new ApiVersion(1, 0)); - - group.MapGet("{id:guid}", Get) - .WithName("GetMyChatMessage") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status404NotFound) - .Produces(StatusCodes.Status500InternalServerError); - - group.MapGet("Paginated", GetPaginated) - .WithName("GetMyChatMessagesPaginated") - .Produces>(StatusCodes.Status200OK) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status500InternalServerError); - - group.MapPost("", Post) - .WithName("CreateMyChatMessage") - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status400BadRequest) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status404NotFound) - .Produces(StatusCodes.Status500InternalServerError); - - group.MapPatch("{id:guid}", Patch) - .WithName("PatchMyChatSession") - .Produces(StatusCodes.Status204NoContent) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status404NotFound) - .Produces(StatusCodes.Status500InternalServerError); - - return endpoints; - } - - private static async Task Get(ISender sender, Guid id) - { - var message = await sender.Send(new GetMyChatMessageQuery { Id = id }); - return ApiResponseMapper.SingleOrNotFound(message); - } - - private static async Task GetPaginated(ISender sender, [AsParameters] GetMyChatMessagesPaginatedQuery query) - { - var result = await sender.Send(query); - return TypedResults.Ok(result); - } - - private static async Task Post(HttpContext httpContext, ISender sender, CreateMyChatMessageCommand command) - { - var response = await sender.Send(command); - if (response.IsNotFound || response.Value is null) - { - return TypedResults.NotFound(); - } - - var version = httpContext.Request.RouteValues["version"]?.ToString() ?? "1.0"; - - return TypedResults.CreatedAtRoute( - response.Value, - "GetMyChatMessage", - new { version, id = response.Value.Id }); - } - - private static async Task Patch(ISender sender, Guid id, PatchMyChatSessionCommand command) - { - command.Id = id; - var result = await sender.Send(command); - return ApiResponseMapper.FromCommand(result); - } -} diff --git a/src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs b/src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs deleted file mode 100644 index 9b58d80..0000000 --- a/src/Presentation.Api/Endpoints/Chat/MyChatSessionEndpoints.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; - -namespace Goodtocode.AgentFramework.Presentation.Api.Endpoints.Chat; - -/// -/// Maps chat session endpoints. -/// -public static class MyChatSessionEndpoints -{ - /// - /// Registers chat session endpoint mappings. - /// - /// The endpoint route builder. - /// The API version set that declares supported versions for this endpoint group, enabling Asp.Versioning to substitute the version token in the route template (e.g. api/v{version:apiVersion}api/v1) and generate correct OpenAPI paths. - /// The endpoint route builder. - public static IEndpointRouteBuilder MapMyChatSessionEndpoints(this IEndpointRouteBuilder endpoints, ApiVersionSet versionSet) - { - var group = endpoints - .MapGroup("api/v{version:apiVersion}/my/chat") - .RequireAuthorization(); - group.WithApiVersionSet(versionSet).HasApiVersion(new ApiVersion(1, 0)); - - group.MapGet("ChatSessions", GetAll) - .WithName("GetMyChatSessions") - .Produces>(StatusCodes.Status200OK) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status500InternalServerError); - - group.MapGet("Paginated", GetPaginated) - .WithName("GetMyChatSessionsPaginated") - .Produces>(StatusCodes.Status200OK) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status500InternalServerError); - - group.MapGet("{id:guid}", Get) - .WithName("GetMyChatSession") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status404NotFound) - .Produces(StatusCodes.Status500InternalServerError); - - group.MapPost("", Post) - .WithName("CreateMyChatSession") - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status400BadRequest) - .Produces(StatusCodes.Status401Unauthorized) - .Produces(StatusCodes.Status500InternalServerError); - - return endpoints; - } - - private static async Task GetAll(ISender sender) - { - var sessions = await sender.Send(new GetMyChatSessionsQuery()); - return ApiResponseMapper.ListOrOk(sessions); - } - - private static async Task GetPaginated( - ISender sender, - DateTime? startDate, - DateTime? endDate, - int pageNumber = 1, - int pageSize = 10) - { - var query = new GetMyChatSessionsPaginatedQuery - { - StartDate = startDate, - EndDate = endDate, - PageNumber = pageNumber, - PageSize = pageSize - }; - - var result = await sender.Send(query); - return TypedResults.Ok(result); - } - - private static async Task Get(ISender sender, Guid id) - { - var session = await sender.Send(new GetMyChatSessionQuery { Id = id }); - return ApiResponseMapper.SingleOrNotFound(session); - } - - private static async Task Post(HttpContext httpContext, ISender sender, CreateMyChatSessionCommand command) - { - var response = await sender.Send(command); - var version = httpContext.Request.RouteValues["version"]?.ToString() ?? "1.0"; - - return TypedResults.CreatedAtRoute( - response, - "GetMyChatSession", - new { version, id = response.Id }); - } -} diff --git a/src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs b/src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs deleted file mode 100644 index 4460439..0000000 --- a/src/Tests.Integration/Actor/CreateActorCommandStepDefinitions.cs +++ /dev/null @@ -1,100 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Actors; -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Tests.Integration.Actor; - -[Binding] -[Scope(Tag = "createActorCommand")] -public class CreateActorCommandStepDefinitions : TestBase -{ - private string _name = string.Empty; - private Guid _id; - private bool _exists; - private Guid _ownerId = Guid.NewGuid(); - private readonly Guid _tenantId = Guid.NewGuid(); - private string _email = string.Empty; - - [Given(@"I have a def ""([^""]*)""")] - public void GivenIHaveADef(string def) - { - base.def = def; - } - - [Given(@"I have a name ""([^""]*)""")] - public void GivenIHaveAName(string name) - { - _name = name; - } - - [Given("I have a Email {string}")] - public void GivenIHaveAEmail(string email) - { - _email = email; - } - - [Given(@"I have a Actor id ""([^""]*)""")] - public void GivenIHaveAAuthorId(string id) - { - _id = Guid.Parse(id); - } - - [Given("I have a OwnerId {string}")] - public void GivenIHaveAExternalId(string ownerId) - { - _ownerId = Guid.Parse(ownerId); - } - - [Given(@"The Actor exists ""([^""]*)""")] - public void GivenTheAuthorExists(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [When(@"I create a actor")] - public async Task WhenICreateAAuthor() - { - if (_exists) - { - var actor = ActorEntity.Create( - firstName: "John", - lastName: "Doe", - email: "jdoe@goodtocode.com", - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId - ); - context.Actors.Add(actor); - await context.SaveChangesAsync(CancellationToken.None); - } - - var request = new CreateOurActorCommand() - { - FirstName = _name.Split(" ").FirstOrDefault(), - LastName = _name.Split(" ").LastOrDefault(), - Email = _email - }; - - try - { - var created = await Sender.Send(request, CancellationToken.None); - _id = created.Id; - responseType = CommandResponseType.Successful; - } - catch (Exception e) - { - HandleAssignResponseType(e); - } - } - - [Then(@"I see the Actor created with the initial response ""([^""]*)""")] - public void ThenISeeTheAuthorCreatedWithTheInitialResponse(string response) - { - HandleHasResponseType(response); - } - - [Then(@"if the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - -} \ No newline at end of file diff --git a/src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs b/src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs deleted file mode 100644 index 67eb3e7..0000000 --- a/src/Tests.Integration/Actor/DeleteActorCommandStepDefinitions.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Actors; -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Tests.Integration.Actor -{ - [Binding] - [Scope(Tag = "deleteActorCommand")] - public class DeleteActorCommandStepDefinitions : TestBase - { - private bool _exists; - private Guid _id; - - [Given(@"I have a def ""([^""]*)""")] - public void GivenIHaveADef(string def) - { - base.def = def; - } - - [Given(@"I have a actor id""([^""]*)""")] - public void GivenIHaveAAuthorId(string id) - { - Guid.TryParse(id, out _id).ShouldBeTrue(); - } - - [Given(@"The actor exists ""([^""]*)""")] - public void GivenTheAuthorExists(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [When(@"I delete the actor")] - public async Task WhenIDeleteTheAuthor() - { - if (_exists) - { - var actor = ActorEntity.Create( - firstName: "John", - lastName: "Doe", - email: "jdoe@goodtocode.com", - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId - ); - context.Actors.Add(actor); - await context.SaveChangesAsync(CancellationToken.None); - _id = actor.OwnerId; - } - - var request = new DeleteActorByOwnerIdCommand() - { - OwnerId = _id == Guid.Empty ? rlsContext.OwnerId : _id - }; - - try - { - var result = await Sender.Send(request, CancellationToken.None); - responseType = result.IsNotFound - ? CommandResponseType.NotFound - : CommandResponseType.Successful; - } - catch (Exception e) - { - HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - } -} diff --git a/src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs b/src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs deleted file mode 100644 index 0e5293d..0000000 --- a/src/Tests.Integration/Actor/GetActorByOwnerIdQueryStepDefinitions.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Actors; -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Tests.Integration.Actor; - -[Binding] -[Scope(Tag = "getAuthorByOwnerIdQuery")] -public class GetActorByOwnerIdQueryStepDefinitions : TestBase -{ - private bool _exists; - private ActorDto? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given("I have a Actor OwnerId")] - public void GivenIHaveAAuthorExternalId() - { - rlsContext.OwnerId.ShouldNotBeEmpty(); - } - - [Given(@"the Actor exists ""([^""]*)""")] - public void GivenITheAuthorExists(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [When(@"I get the Actor")] - public async Task WhenIGetAAuthor() - { - if (_exists) - { - var actor = ActorEntity.Create( - firstName: "John", - lastName: "Doe", - email: "jdoe@goodtocode.com", - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId - ); - context.Actors.Add(actor); - await context.SaveChangesAsync(CancellationToken.None); - } - - var request = new GetMyActorQuery() - { - }; - - try - { - _response = await Sender.Send(request, CancellationToken.None); - responseType = _response is null - ? CommandResponseType.NotFound - : CommandResponseType.Successful; - } - catch (Exception e) - { - responseType = HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"If the response is successful the response has a Id")] - public void ThenIfTheResponseIsSuccessfulTheResponseHasAKey() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.Id.ShouldNotBeEmpty(); - } -} diff --git a/src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs b/src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs deleted file mode 100644 index 9841d1f..0000000 --- a/src/Tests.Integration/Actor/GetActorQueryStepDefinitions.cs +++ /dev/null @@ -1,94 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Actors; -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Tests.Integration.Actor; - -[Binding] -[Scope(Tag = "getAuthorQuery")] -public class GetActorQueryStepDefinitions : TestBase -{ - private Guid _id; - private bool _exists; - private ActorDto? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given(@"I have a Actor id ""([^""]*)""")] - public void GivenIHaveAAuthorId(string actorId) - { - if (string.IsNullOrWhiteSpace(actorId)) - { - return; - } - - Guid.TryParse(actorId, out _id).ShouldBeTrue(); - } - - [Given(@"the Actor exists ""([^""]*)""")] - public void GivenITheAuthorExists(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [When(@"I get the Actor")] - public async Task WhenIGetAAuthor() - { - if (_exists) - { - var actor = ActorEntity.Create( - firstName: "John", - lastName: "Doe", - email: "jdoe@goodtocode.com", - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId - ); - context.Actors.Add(actor); - await context.SaveChangesAsync(CancellationToken.None); - _id = actor.Id; - } - - var request = new GetOurActorQuery() - { - ActorId = _id - }; - - try - { - _response = await Sender.Send(request, CancellationToken.None); - responseType = _response is null - ? CommandResponseType.NotFound - : CommandResponseType.Successful; - } - catch (Exception e) - { - responseType = HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"If the response is successful the response has a Id")] - public void ThenIfTheResponseIsSuccessfulTheResponseHasAKey() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.Id.ShouldNotBeEmpty(); - } -} diff --git a/src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs b/src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs deleted file mode 100644 index 3f9dd0b..0000000 --- a/src/Tests.Integration/Actor/GetOurActorsByNameQueryStepDefinitions.cs +++ /dev/null @@ -1,96 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Actors; -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Tests.Integration.Actor; - -[Binding] -[Scope(Tag = "getOurActorsByNameQuery")] -public class GetOurActorsByNameQueryStepDefinitions : TestBase -{ - private string _name = string.Empty; - private bool _exists; - private bool _otherTenantExists; - private ICollection? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given(@"I search for actor name ""([^""]*)""")] - public void GivenISearchForActorName(string name) - { - _name = name; - } - - [Given(@"matching actors in my tenant exist ""([^""]*)""")] - public void GivenMatchingActorsInMyTenantExist(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [Given(@"matching actors in another tenant exist ""([^""]*)""")] - public void GivenMatchingActorsInAnotherTenantExist(string exists) - { - bool.TryParse(exists, out _otherTenantExists).ShouldBeTrue(); - } - - [When(@"I get actors by name")] - public async Task WhenIGetActorsByName() - { - if (_exists) - { - context.Actors.Add(ActorEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - firstName: _name, - lastName: "CurrentTenant", - email: "current@example.test")); - } - - if (_otherTenantExists) - { - context.Actors.Add(ActorEntity.Create( - ownerId: Guid.NewGuid(), - tenantId: Guid.NewGuid(), - firstName: _name, - lastName: "OtherTenant", - email: "other@example.test")); - } - - await context.SaveChangesAsync(CancellationToken.None); - - try - { - _response = await Sender.Send(new GetOurActorsByNameQuery - { - Name = _name - }, CancellationToken.None); - responseType = CommandResponseType.Successful; - } - catch (Exception exception) - { - responseType = HandleAssignResponseType(exception); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string result) - { - HandleHasResponseType(result); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"The actor search response count is ""([^""]*)""")] - public void ThenTheActorSearchResponseCountIs(string count) - { - int.TryParse(count, out var expectedCount).ShouldBeTrue(); - _response?.Count.ShouldBe(expectedCount); - } -} \ No newline at end of file diff --git a/src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs b/src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs deleted file mode 100644 index 4aa1069..0000000 --- a/src/Tests.Integration/Actor/SaveActorCommandStepDefinitions.cs +++ /dev/null @@ -1,98 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Actors; -using Goodtocode.AgentFramework.Core.Domain.Actors; - -namespace Goodtocode.AgentFramework.Tests.Integration.Actor; - -[Binding] -[Scope(Tag = "saveActorCommand")] -public class SaveActorCommandStepDefinitions : TestBase -{ - private string _name = string.Empty; - private Guid _id; - private bool _exists; - private Guid _ownerId = Guid.NewGuid(); - private readonly Guid _tenantId = Guid.NewGuid(); - private string _email = string.Empty; - - [Given(@"I have a def ""([^""]*)""")] - public void GivenIHaveADef(string def) - { - base.def = def; - } - - [Given(@"I have a name ""([^""]*)""")] - public void GivenIHaveAName(string name) - { - _name = name; - } - - [Given("I have a Email {string}")] - public void GivenIHaveAEmail(string email) - { - _email = email; - } - - [Given(@"I have a Actor id ""([^""]*)""")] - public void GivenIHaveAAuthorId(string id) - { - _id = Guid.Parse(id); - } - - [Given("I have a OwnerId {string}")] - public void GivenIHaveAExternalId(string ownerId) - { - _ownerId = Guid.Parse(ownerId); - } - - [Given(@"The Actor exists ""([^""]*)""")] - public void GivenTheAuthorExists(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [When(@"I create a actor")] - public async Task WhenICreateAAuthor() - { - if (_exists) - { - var actor = ActorEntity.Create( - firstName: "John", - lastName: "Doe", - email: "jdoe@goodtocode.com", - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId - ); - context.Actors.Add(actor); - await context.SaveChangesAsync(CancellationToken.None); - } - - var request = new SaveMyActorCommand() - { - FirstName = _name.Split(" ").FirstOrDefault(), - LastName = _name.Split(" ").LastOrDefault(), - Email = _email - }; - - try - { - await Sender.Send(request, CancellationToken.None); - responseType = CommandResponseType.Successful; - } - catch (Exception e) - { - HandleAssignResponseType(e); - } - } - - [Then(@"I see the Actor created with the initial response ""([^""]*)""")] - public void ThenISeeTheAuthorCreatedWithTheInitialResponse(string response) - { - HandleHasResponseType(response); - } - - [Then(@"if the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } -} \ No newline at end of file diff --git a/src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs b/src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs deleted file mode 100644 index 16f6476..0000000 --- a/src/Tests.Integration/Chat/CreateChatMessageCommandStepDefinitions.cs +++ /dev/null @@ -1,104 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Actors; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat; - -[Binding] -[Scope(Tag = "createChatMessageCommand")] -public class CreateChatMessageCommandStepDefinitions : TestBase -{ - private string _message = string.Empty; - private Guid _id; - private Guid _chatSessionId; - private bool _exists; - - [Given(@"I have a def ""([^""]*)""")] - public void GivenIHaveADef(string def) - { - base.def = def; - } - - [Given(@"I have a initial message ""([^""]*)""")] - public void GivenIHaveAInitialMessage(string message) - { - _message = message; - } - - [Given(@"I have a Chat Message id ""([^""]*)""")] - public void GivenIHaveAChatMessageKey(string id) - { - _id = Guid.Parse(id); - } - - [Given(@"The Chat Message exists ""([^""]*)""")] - public void GivenTheChatMessageExists(string exists) - { - _exists = bool.Parse(exists); - } - - [When(@"I create a Chat Message with the message")] - public async Task WhenICreateAChatMessageWithTheMessage() - { - if (_exists) - { - var actor = ActorEntity.Create( - firstName: "John", - lastName: "Doe", - email: "John.Doe@goodtocode.com", - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId - ); - context.Actors.Add(actor); - await context.SaveChangesAsync(CancellationToken.None); - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: actor.Id, - title: "Test Session" - ); - context.ChatSessions.Add(chatSession); - await context.SaveChangesAsync(CancellationToken.None); - _chatSessionId = chatSession.Id; - } - else - { - _chatSessionId = Guid.NewGuid(); - } - - var request = new CreateMyChatMessageCommand() - { - ChatSessionId = _chatSessionId, - Message = _message - }; - - try - { - var created = await Sender.Send(request, CancellationToken.None); - if (created.IsNotFound || created.Value is null) - { - responseType = CommandResponseType.NotFound; - return; - } - - _id = created.Value.Id; - responseType = CommandResponseType.Successful; - } - catch (Exception e) - { - HandleAssignResponseType(e); - } - } - - [Then(@"I see the Chat Message created with the initial response ""([^""]*)""")] - public void ThenISeeTheChatMessageCreatedWithTheInitialResponse(string response) - { - HandleHasResponseType(response); - } - - [Then(@"if the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } -} diff --git a/src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs deleted file mode 100644 index 80807c7..0000000 --- a/src/Tests.Integration/Chat/CreateChatSessionCommandStepDefinitions.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Actors; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat; - -[Binding] -[Scope(Tag = "createChatSessionCommand")] -public class CreateChatSessionCommandStepDefinitions : TestBase -{ - private string _message = string.Empty; - private Guid _id; - private readonly Guid _actorId = Guid.NewGuid(); - private bool _exists; - - [Given(@"I have a def ""([^""]*)""")] - public void GivenIHaveADef(string def) - { - base.def = def; - } - - [Given(@"I have a initial message ""([^""]*)""")] - public void GivenIHaveAInitialMessage(string message) - { - _message = message; - } - - [Given(@"I have a chat session id ""([^""]*)""")] - public void GivenIHaveAChatSessionKey(string id) - { - _id = Guid.Parse(id); - } - - [Given(@"The chat session exists ""([^""]*)""")] - public void GivenTheChatSessionExists(string exists) - { - _exists = bool.Parse(exists); - } - - [When(@"I create a chat session with the message")] - public async Task WhenICreateAChatSessionWithTheMessage() - { - // Setup the database if want to test existing records - var actor = ActorEntity.Create( - firstName: "Test", - lastName: "Actor", - email: "actor@goodtocode.com", - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId - ); - context.Actors.Add(actor); - if (_exists) - { - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: _actorId, - title: "Test Session" - ); - context.ChatSessions.Add(chatSession); - } - await context.SaveChangesAsync(CancellationToken.None); - - var request = new CreateMyChatSessionCommand() - { - Title = def, - Message = _message - }; - - try - { - var created = await Sender.Send(request, CancellationToken.None); - _id = created.Id; - responseType = CommandResponseType.Successful; - } - catch (Exception e) - { - HandleAssignResponseType(e); - } - } - - [Then(@"I see the chat session created with the initial response ""([^""]*)""")] - public void ThenISeeTheChatSessionCreatedWithTheInitialResponse(string response) - { - HandleHasResponseType(response); - } - - [Then(@"if the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } -} diff --git a/src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs deleted file mode 100644 index 856b3a9..0000000 --- a/src/Tests.Integration/Chat/DeleteChatSessionCommandStepDefinitions.cs +++ /dev/null @@ -1,77 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat -{ - [Binding] - [Scope(Tag = "deleteChatSessionCommand")] - public class DeleteChatSessionCommandStepDefinitions : TestBase - { - private Guid _id; - private bool _exists; - - [Given(@"I have a def ""([^""]*)""")] - public void GivenIHaveADef(string def) - { - base.def = def; - } - - [Given(@"I have a chat session id""([^""]*)""")] - public void GivenIHaveAChatSessionKey(string id) - { - Guid.TryParse(id, out _id).ShouldBeTrue(); - } - - [Given(@"The chat session exists ""([^""]*)""")] - public void GivenTheChatSessionExists(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [When(@"I delete the chat session")] - public async Task WhenIDeleteTheChatSession() - { - if (_exists) - { - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Test Session" - ); - context.ChatSessions.Add(chatSession); - await context.SaveChangesAsync(CancellationToken.None); - _id = chatSession.Id; - } - - var request = new DeleteMyChatSessionCommand() - { - Id = _id - }; - - try - { - var result = await Sender.Send(request, CancellationToken.None); - responseType = result.IsNotFound - ? CommandResponseType.NotFound - : CommandResponseType.Successful; - } - catch (Exception e) - { - HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - } -} diff --git a/src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs deleted file mode 100644 index e8b2ec2..0000000 --- a/src/Tests.Integration/Chat/GetChatMessageQueryStepDefinitions.cs +++ /dev/null @@ -1,108 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat; - -[Binding] -[Scope(Tag = "getChatMessageQuery")] -public class GetChatMessageQueryStepDefinitions : TestBase -{ - private Guid _id; - private bool _exists; - private readonly Guid _chatSessionId = Guid.NewGuid(); - private ChatMessageDto? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given(@"I have a Chat Message id ""([^""]*)""")] - public void GivenIHaveAChatMessageId(string ChatMessageKey) - { - if (string.IsNullOrWhiteSpace(ChatMessageKey)) - { - return; - } - - Guid.TryParse(ChatMessageKey, out _id).ShouldBeTrue(); - } - - [Given(@"The Chat Message exists ""([^""]*)""")] - public void GivenITheChatMessageExists(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [When(@"I get a Chat Message")] - public async Task WhenIGetAChatMessage() - { - if (_exists) - { - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Test Session" - ); - var chatMessage = ChatMessageEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - chatSessionId: chatSession.Id, - role: ChatMessageRole.user, - content: "Test Message Content" - ); - chatSession.Messages.Add(chatMessage); - context.ChatSessions.Add(chatSession); - await context.SaveChangesAsync(CancellationToken.None); - _id = chatMessage.Id; - } - - var request = new GetMyChatMessageQuery() - { - Id = _id - }; - - try - { - _response = await Sender.Send(request, CancellationToken.None); - responseType = _response is null - ? CommandResponseType.NotFound - : CommandResponseType.Successful; - } - catch (Exception e) - { - responseType = HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"If the response is successful the response has a Id")] - public void ThenIfTheResponseIsSuccessfulTheResponseHasAId() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.Id.ShouldNotBeEmpty(); - } - - [Then(@"If the response is successful the response has a count matching ""([^""]*)""")] - public void ThenIfTheResponseIsSuccessfulTheResponseHasACountMatching(string messageContent) - { - _response?.Content?.ShouldBe(messageContent); - } -} diff --git a/src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs deleted file mode 100644 index cf8b853..0000000 --- a/src/Tests.Integration/Chat/GetChatMessagesPaginatedQueryStepDefinitions.cs +++ /dev/null @@ -1,197 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat; - -[Binding] -[Scope(Tag = "getChatMessagesPaginatedQuery")] -public class GetChatMessagesPaginatedQueryStepDefinitions : TestBase -{ - private bool _exists; - private readonly Guid _chatSessionId = Guid.NewGuid(); - private DateTime _startDate; - private DateTime _endDate; - private bool _withinDateRangeExists; - private int _pageNumber; - private int _pageSize; - private IPaginatedList? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given(@"Chat Messages exist ""([^""]*)""")] - public void GivenChatMessagesExist(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [Given(@"I have a start date ""([^""]*)""")] - public void GivenIHaveAStartDate(string startDate) - { - if (string.IsNullOrWhiteSpace(startDate)) - { - return; - } - - DateTime.TryParse(startDate, out _startDate).ShouldBeTrue(); - } - - [Given(@"I have a end date ""([^""]*)""")] - public void GivenIHaveAEndDate(string endDate) - { - if (string.IsNullOrWhiteSpace(endDate)) - { - return; - } - - DateTime.TryParse(endDate, out _endDate).ShouldBeTrue(); - } - - [Given(@"Chat Messages within the date range exists ""([^""]*)""")] - public void GivenChatMessagesWithinTheDateRangeExists(string withinDateRangeExists) - { - bool.TryParse(withinDateRangeExists, out _withinDateRangeExists).ShouldBeTrue(); - } - - [Given(@"I have a page number ""([^""]*)""")] - public void GivenIHaveAPageNumber(string pageNumber) - { - int.TryParse(pageNumber, out _pageNumber).ShouldBeTrue(); - } - - [Given(@"I have a page size ""([^""]*)""")] - public void GivenIHaveAPageSize(string pageSize) - { - int.TryParse(pageSize, out _pageSize).ShouldBeTrue(); ; - } - - [When(@"I get the Chat Messages paginated")] - public async Task WhenIGetTheChatMessagesPaginated() - { - if (_exists) - { - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Test Session" - ); - var chatMessage = ChatMessageEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - chatSessionId: chatSession.Id, - role: ChatMessageRole.user, - content: "Test Message Content" - ); - chatSession.Messages.Add(chatMessage); - context.ChatSessions.Add(chatSession); - await context.SaveChangesAsync(CancellationToken.None); - } - - var request = new GetMyChatMessagesPaginatedQuery() - { - PageNumber = _pageNumber, - PageSize = _pageSize, - StartDate = _startDate == default ? null : _startDate, - EndDate = _endDate == default ? null : _endDate - }; - - try - { - _response = await Sender.Send(request, CancellationToken.None); - responseType = CommandResponseType.Successful; - } - catch (Exception e) - { - responseType = HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"The response has a collection of Chat Messages")] - public void ThenTheResponseHasACollectionOfChatMessages() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.TotalCount.ShouldBe(_withinDateRangeExists == false ? 0 : _response.TotalCount); - } - - [Then(@"Each Chat Message has a Key")] - public void ThenEachChatMessageHasAKey() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.Items.FirstOrDefault(x => x.Id == default).ShouldBeNull(); - } - - [Then(@"Each Chat Message has a Date greater than start date")] - public void ThenEachChatMessageHasADateGreaterThanStartDate() - { - if (responseType == CommandResponseType.Successful && _withinDateRangeExists) - { - _response?.Items.FirstOrDefault(x => _startDate == default || x.Timestamp > _startDate).ShouldNotBeNull(); - } - } - - [Then(@"Each Chat Message has a Date less than end date")] - public void ThenEachChatMessageHasADateLessThanEndDate() - { - if (responseType == CommandResponseType.Successful && _withinDateRangeExists) - { - _response?.Items.FirstOrDefault(x => _endDate == default || x.Timestamp < _endDate).ShouldNotBeNull(); - } - } - - [Then(@"The response has a Page Number")] - public void ThenTheResponseHasAPageNumber() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.PageNumber.Should(); - } - - [Then(@"The response has a Total Pages")] - public void ThenTheResponseHasATotalPages() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.TotalPages.Should(); - } - - [Then(@"The response has a Total Count")] - public void ThenTheResponseHasATotalCount() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.TotalCount.Should(); - } -} diff --git a/src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs deleted file mode 100644 index 866a504..0000000 --- a/src/Tests.Integration/Chat/GetMyChatSessionMessagesQueryStepDefinitions.cs +++ /dev/null @@ -1,122 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat; - -[Binding] -[Scope(Tag = "getMyChatSessionMessagesQuery")] -public class GetMyChatSessionMessagesQueryStepDefinitions : TestBase -{ - private string _requestedSession = string.Empty; - private bool _exists; - private bool _otherOwnerExists; - private Guid _currentSessionId; - private Guid _otherSessionId; - private ICollection? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given(@"the requested session is ""([^""]*)""")] - public void GivenTheRequestedSessionIs(string requestedSession) - { - _requestedSession = requestedSession; - } - - [Given(@"messages in my chat session exist ""([^""]*)""")] - public void GivenMessagesInMyChatSessionExist(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [Given(@"messages in another owner's chat session exist ""([^""]*)""")] - public void GivenMessagesInAnotherOwnersChatSessionExist(string exists) - { - bool.TryParse(exists, out _otherOwnerExists).ShouldBeTrue(); - } - - [When(@"I get my chat session messages")] - public async Task WhenIGetMyChatSessionMessages() - { - if (_exists) - { - var session = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Current session"); - var message = ChatMessageEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - chatSessionId: session.Id, - role: ChatMessageRole.user, - content: "Current owner message"); - session.Messages.Add(message); - context.ChatSessions.Add(session); - _currentSessionId = session.Id; - } - - if (_otherOwnerExists) - { - var otherOwnerId = Guid.NewGuid(); - var session = ChatSessionEntity.Create( - ownerId: otherOwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Other owner session"); - var message = ChatMessageEntity.Create( - ownerId: otherOwnerId, - tenantId: rlsContext.TenantId, - chatSessionId: session.Id, - role: ChatMessageRole.user, - content: "Other owner message"); - session.Messages.Add(message); - context.ChatSessions.Add(session); - _otherSessionId = session.Id; - } - - await context.SaveChangesAsync(CancellationToken.None); - - var chatSessionId = _requestedSession switch - { - "current" => _currentSessionId, - "other" => _otherSessionId, - _ => Guid.Empty - }; - - try - { - _response = await Sender.Send(new GetMyChatSessionMessagesQuery - { - ChatSessionId = chatSessionId - }, CancellationToken.None); - responseType = CommandResponseType.Successful; - } - catch (Exception exception) - { - responseType = HandleAssignResponseType(exception); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string result) - { - HandleHasResponseType(result); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"The chat session message response count is ""([^""]*)""")] - public void ThenTheChatSessionMessageResponseCountIs(string count) - { - int.TryParse(count, out var expectedCount).ShouldBeTrue(); - _response?.Count.ShouldBe(expectedCount); - } -} \ No newline at end of file diff --git a/src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs deleted file mode 100644 index 44e4ef9..0000000 --- a/src/Tests.Integration/Chat/GetMyChatSessionQueryStepDefinitions.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat; - -[Binding] -[Scope(Tag = "getChatSessionQuery")] -public class GetMyChatSessionQueryStepDefinitions : TestBase -{ - private Guid _id; - private bool _exists; - private ChatSessionDto? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given(@"I have a chat session id ""([^""]*)""")] - public void GivenIHaveAChatSessionId(string chatSessionKey) - { - if (string.IsNullOrWhiteSpace(chatSessionKey)) - { - return; - } - - Guid.TryParse(chatSessionKey, out _id).ShouldBeTrue(); - } - - [Given(@"I the chat session exists ""([^""]*)""")] - public void GivenITheChatSessionExists(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [When(@"I get a chat session")] - public async Task WhenIGetAChatSession() - { - if (_exists) - { - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Test Session" - ); - context.ChatSessions.Add(chatSession); - await context.SaveChangesAsync(CancellationToken.None); - _id = chatSession.Id; - } - - var request = new GetMyChatSessionQuery() - { - Id = _id - }; - - try - { - _response = await Sender.Send(request, CancellationToken.None); - responseType = _response is null - ? CommandResponseType.NotFound - : CommandResponseType.Successful; - } - catch (Exception e) - { - responseType = HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"If the response is successful the response has a Id")] - public void ThenIfTheResponseIsSuccessfulTheResponseHasAId() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.Id.ShouldNotBeEmpty(); - } -} diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs deleted file mode 100644 index ba83479..0000000 --- a/src/Tests.Integration/Chat/GetMyChatSessionsPaginatedQueryStepDefinitions.cs +++ /dev/null @@ -1,188 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat; - -[Binding] -[Scope(Tag = "getChatSessionsPaginatedQuery")] -public class GetMyChatSessionsPaginatedQueryStepDefinitions : TestBase -{ - private bool _exists; - private DateTime _startDate; - private DateTime _endDate; - private bool _withinDateRangeExists; - private int _pageNumber; - private int _pageSize; - private IPaginatedList? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given(@"Chat Sessions exist ""([^""]*)""")] - public void GivenChatSessionsExist(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [Given(@"I have a start date ""([^""]*)""")] - public void GivenIHaveAStartDate(string startDate) - { - if (string.IsNullOrWhiteSpace(startDate)) - { - return; - } - - DateTime.TryParse(startDate, out _startDate).ShouldBeTrue(); - } - - [Given(@"I have a end date ""([^""]*)""")] - public void GivenIHaveAEndDate(string endDate) - { - if (string.IsNullOrWhiteSpace(endDate)) - { - return; - } - - DateTime.TryParse(endDate, out _endDate).ShouldBeTrue(); - } - - [Given(@"chat sessions within the date range exists ""([^""]*)""")] - public void GivenChatSessionsWithinTheDateRangeExists(string withinDateRangeExists) - { - bool.TryParse(withinDateRangeExists, out _withinDateRangeExists).ShouldBeTrue(); - } - - [Given(@"I have a page number ""([^""]*)""")] - public void GivenIHaveAPageNumber(string pageNumber) - { - int.TryParse(pageNumber, out _pageNumber).ShouldBeTrue(); - } - - [Given(@"I have a page size ""([^""]*)""")] - public void GivenIHaveAPageSize(string pageSize) - { - int.TryParse(pageSize, out _pageSize).ShouldBeTrue(); ; - } - - [When(@"I get the chat sessions paginated")] - public async Task WhenIGetTheChatSessionsPaginated() - { - if (_exists) - { - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Test Session" - ); - context.ChatSessions.Add(chatSession); - await context.SaveChangesAsync(CancellationToken.None); - } - - var request = new GetMyChatSessionsPaginatedQuery() - { - PageNumber = _pageNumber, - PageSize = _pageSize, - StartDate = _startDate == default ? null : _startDate, - EndDate = _endDate == default ? null : _endDate - }; - - try - { - _response = await Sender.Send(request, CancellationToken.None); - responseType = CommandResponseType.Successful; - } - catch (Exception e) - { - responseType = HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"The response has a collection of chat sessions")] - public void ThenTheResponseHasACollectionOfChatSessions() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.TotalCount.ShouldBe(_withinDateRangeExists == false ? 0 : _response.TotalCount); - } - - [Then(@"Each chat session has a Key")] - public void ThenEachChatSessionHasAKey() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.Items.FirstOrDefault(x => x.Id == default).ShouldBeNull(); - } - - [Then(@"Each chat session has a Date greater than start date")] - public void ThenEachChatSessionHasADateGreaterThanStartDate() - { - if (responseType == CommandResponseType.Successful && _withinDateRangeExists) - { - _response?.Items.FirstOrDefault(x => _startDate == default || x.Timestamp > _startDate).ShouldNotBeNull(); - } - } - - [Then(@"Each chat session has a Date less than end date")] - public void ThenEachChatSessionHasADateLessThanEndDate() - { - if (responseType == CommandResponseType.Successful && _withinDateRangeExists) - { - _response?.Items.FirstOrDefault(x => _endDate == default || x.Timestamp < _endDate).ShouldNotBeNull(); - } - } - - [Then(@"The response has a Page Number")] - public void ThenTheResponseHasAPageNumber() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.PageNumber.Should(); - } - - [Then(@"The response has a Total Pages")] - public void ThenTheResponseHasATotalPages() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.TotalPages.Should(); - } - - [Then(@"The response has a Total Count")] - public void ThenTheResponseHasATotalCount() - { - if (responseType != CommandResponseType.Successful) - { - return; - } - - _response?.TotalCount.Should(); - } -} diff --git a/src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs b/src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs deleted file mode 100644 index 1f1606b..0000000 --- a/src/Tests.Integration/Chat/GetMyChatSessionsQueryStepDefinitions.cs +++ /dev/null @@ -1,130 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat; - -[Binding] -[Scope(Tag = "getChatSessionsQuery")] -public class GetMyChatSessionsQueryStepDefinitions : TestBase -{ - private bool _exists; - private bool _withinDateRangeExists; - private DateTime _endDate; - private DateTime _startDate; - private ICollection? _response; - - [Given(@"I have a definition ""([^""]*)""")] - public void GivenIHaveADefinition(string def) - { - base.def = def; - } - - [Given(@"Chat Sessions exist ""([^""]*)""")] - public void GivenChatSessionsExist(string exists) - { - bool.TryParse(exists, out _exists).ShouldBeTrue(); - } - - [Given(@"chat sessions within the date range exists ""([^""]*)""")] - public void GivenChatSessionsWithinTheDateRangeExists(string withinDateRangeExists) - { - bool.TryParse(withinDateRangeExists, out _withinDateRangeExists).ShouldBeTrue(); - } - - [Given(@"I have a start date ""([^""]*)""")] - public void GivenIHaveAStartDate(string startDate) - { - if (string.IsNullOrWhiteSpace(startDate)) - { - return; - } - - DateTime.TryParse(startDate, out _startDate).ShouldBeTrue(); - _startDate = DateTime.UtcNow.AddMinutes(_withinDateRangeExists ? -1 : 1); - } - - [Given(@"I have a end date ""([^""]*)""")] - public void GivenIHaveAEndDate(string endDate) - { - if (string.IsNullOrWhiteSpace(endDate)) - { - return; - } - - DateTime.TryParse(endDate, out _endDate).ShouldBeTrue(); - } - - [When(@"I get the chat sessions")] - public async Task WhenIGetTheChatSessions() - { - if (_exists) - { - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Test Session" - ); - context.ChatSessions.Add(chatSession); - await context.SaveChangesAsync(CancellationToken.None); - } - - var request = new GetMyChatSessionsQuery() - { - StartDate = _startDate == default ? null : _startDate, - EndDate = _endDate == default ? null : _endDate - }; - - try - { - _response = await Sender.Send(request, CancellationToken.None); - responseType = CommandResponseType.Successful; - } - catch (Exception e) - { - responseType = HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - - [Then(@"The response has a collection of chat sessions")] - public void ThenTheResponseHasACollectionOfChatSessions() - { - _response?.Count.ShouldBe(_withinDateRangeExists == false ? 0 : _response.Count); - } - - [Then(@"Each chat session has a Key")] - public void ThenEachChatSessionHasAKey() - { - _response?.FirstOrDefault(x => x.Id == default).ShouldBeNull(); - } - - [Then(@"Each chat session has a Date greater than start date")] - public void ThenEachChatSessionHasADateGreaterThanStartDate() - { - if (_withinDateRangeExists) - { - _response?.FirstOrDefault(x => _startDate == default || x.Timestamp > _startDate).ShouldNotBeNull(); - } - } - - [Then(@"Each chat session has a Date less than end date")] - public void ThenEachChatSessionHasADateLessThanEndDate() - { - if (_withinDateRangeExists) - { - _response?.FirstOrDefault(x => _endDate == default || x.Timestamp < _endDate).ShouldNotBeNull(); - } - } -} diff --git a/src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs b/src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs deleted file mode 100644 index 7be8917..0000000 --- a/src/Tests.Integration/Chat/PatchChatSessionCommandStepDefinitions.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Goodtocode.AgentFramework.Core.Application.Chats; -using Goodtocode.AgentFramework.Core.Domain.Chats; - -namespace Goodtocode.AgentFramework.Tests.Integration.Chat -{ - [Binding] - [Scope(Tag = "patchChatSessionCommand")] - public class PatchChatSessionCommandStepDefinitions : TestBase - { - private Guid _id; - private bool _exists; - private string _title = string.Empty; - - [Given(@"I have a def ""([^""]*)""")] - public void GivenIHaveADef(string def) - { - base.def = def; - } - - [Given(@"I have a chat session id ""([^""]*)""")] - public void GivenIHaveAChatSessionId(string id) - { - Guid.TryParse(id, out _id).ShouldBeTrue(); - } - - [Given(@"the chat session exists ""([^""]*)""")] - public void GivenTheChatSessionExists(string exists) - { - _exists = bool.Parse(exists); - } - - [Given(@"I have a new chat session title ""([^""]*)""")] - public void GivenIHaveANewChatSessionTitle(string title) - { - _title = title; - } - - [When(@"I patch the chatSession")] - public async Task WhenIPatchTheChatSession() - { - if (_exists) - { - var chatSession = ChatSessionEntity.Create( - ownerId: rlsContext.OwnerId, - tenantId: rlsContext.TenantId, - actorId: Guid.NewGuid(), - title: "Test Session" - ); - context.ChatSessions.Add(chatSession); - await context.SaveChangesAsync(CancellationToken.None); - _id = chatSession.Id; - } - - var request = new PatchMyChatSessionCommand() - { - Id = _id, - Title = _title - }; - - try - { - var result = await Sender.Send(request, CancellationToken.None); - responseType = result.IsNotFound - ? CommandResponseType.NotFound - : CommandResponseType.Successful; - } - catch (Exception e) - { - HandleAssignResponseType(e); - } - } - - [Then(@"The response is ""([^""]*)""")] - public void ThenTheResponseIs(string response) - { - HandleHasResponseType(response); - } - - [Then(@"If the response has validation issues I see the ""([^""]*)"" in the response")] - public void ThenIfTheResponseHasValidationIssuesISeeTheInTheResponse(string expectedErrors) - { - HandleExpectedValidationErrorsAssertions(expectedErrors); - } - } -} From 9909e739b0288bfc5da16e22244d01c73c6a7ed3 Mon Sep 17 00:00:00 2001 From: "Robert J. Good" Date: Sat, 29 Aug 2026 07:39:53 -0700 Subject: [PATCH 5/6] fixed chat to chats route --- src/Presentation.Web/Features/Chats/ChatPage.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Presentation.Web/Features/Chats/ChatPage.razor b/src/Presentation.Web/Features/Chats/ChatPage.razor index 53dd56c..f9cd293 100644 --- a/src/Presentation.Web/Features/Chats/ChatPage.razor +++ b/src/Presentation.Web/Features/Chats/ChatPage.razor @@ -227,7 +227,7 @@ { if (firstRender) { - chatPageJsModule = await JSRuntime.InvokeAsync("import", "./Features/Chat/ChatPage.razor.js"); + chatPageJsModule = await JSRuntime.InvokeAsync("import", "./Features/Chats/ChatPage.razor.js"); shouldScrollToBottom = true; } From 4ce23469de035d655643470c33377f105fc6aa37 Mon Sep 17 00:00:00 2001 From: "Robert J. Good" Date: Sat, 29 Aug 2026 07:40:13 -0700 Subject: [PATCH 6/6] Stop AI from violating SOLID --- .github/copilot-instructions.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0879914..3f18ab7 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -41,4 +41,7 @@ - Apply the matching file-scoped rule in `.github/instructions/` when editing Application, Domain, Infrastructure, Presentation.Web, or Presentation.Api. - Use `docs/governance/` for detailed architecture, coding, tool, governance, runtime-observability, and administrative UX guidance. - Use `docs/product/` for product intent, ontology, user flows, feature definitions, and completion criteria. -- Follow existing patterns in the local folder before adding a new abstraction or dependency. \ No newline at end of file +- Follow existing patterns in the local folder before adding a new abstraction or dependency. + +## Command and Query Guidelines +- Commands and queries in Core.Application must remain presentation/infrastructure-agnostic; formatting and response shaping for agent/tool interactions belong in Infrastructure.AgentFramework tools/adapters, not in application handlers. \ No newline at end of file