Skip to content

Commit

Permalink
Code(API::GetChatSession): Implement GetChatSession feature
Browse files Browse the repository at this point in the history
  • Loading branch information
ktutak1337 committed Mar 30, 2024
1 parent c312ac3 commit 98f0da8
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using StellarChat.Shared.Abstractions.Exceptions;

namespace StellarChat.Server.Api.DAL.Mongo.Exceptions.Chat;

internal sealed class ChatSessionNotFoundException : StellarChatException
{
public Guid Id { get; }
public string? Title { get; }

public ChatSessionNotFoundException(Guid id)
: base(
message: $"Chat session with ID: {id} not found.",
userMessage: $"The requested chat session could not be found.")
=> Id = id;

public ChatSessionNotFoundException(string title)
: base(
message: $"Chat session with title: {title} not found.",
userMessage: $"The chat session with the title '{title}' could not be found.")
=> Title = title;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace StellarChat.Server.Api.Domain.Chat.Repositories;

internal interface IChatSessionRepository
public interface IChatSessionRepository
{
ValueTask<ChatSession?> GetAsync(Guid id);
ValueTask<ChatSession?> GetByTitleAsync(string title);
Expand Down
5 changes: 5 additions & 0 deletions src/Server/StellarChat.Server.Api/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ public static void AddInfrastructure(this WebApplicationBuilder builder)
.AddScoped<IChatSessionRepository, ChatSessionRepository>()
.AddMongoRepository<ChatMessageDocument, Guid>("messages")
.AddMongoRepository<ChatSessionDocument, Guid>("chat-sessions");

builder.Services.AddMediator(options =>
{
options.ServiceLifetime = ServiceLifetime.Scoped;
});
}

public static WebApplication UseInfrastructure(this WebApplication app)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Mediator;
using StellarChat.Shared.Abstractions.Contracts.Chat;

namespace StellarChat.Server.Api.Features.Chat.GetChatSession;

internal sealed record GetChatSession : IQuery<ChatSessionResponse>
{
public Guid Id { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Mediator;
using StellarChat.Shared.Abstractions.API.Endpoints;
using StellarChat.Shared.Abstractions.Contracts.Chat;

namespace StellarChat.Server.Api.Features.Chat.GetChatSession;

internal sealed class GetChatSessionEndpoint : IEndpoint
{
public void Expose(IEndpointRouteBuilder endpoints)
{
var chatHistory = endpoints.MapGroup("/chat-history").WithTags("Chat history");

chatHistory.MapGet("/sessions/{chatId:guid}", async (Guid chatId, IMediator mediator) => IEndpoint.Select(await mediator.Send(new GetChatSession { Id = chatId })))
.Produces<ChatSessionResponse>(StatusCodes.Status200OK)
.Produces(StatusCodes.Status404NotFound)
.WithName("GetChatSession")
.WithOpenApi(operation => new(operation)
{
Summary = "Retrieves a single chat session by 'chatId'."
});
}

public void Register(IServiceCollection services, IConfiguration configuration) { }

public void Use(IApplicationBuilder app) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Mapster;
using Mediator;
using StellarChat.Server.Api.DAL.Mongo.Exceptions.Chat;
using StellarChat.Server.Api.Domain.Chat.Repositories;
using StellarChat.Shared.Abstractions.Contracts.Chat;

namespace StellarChat.Server.Api.Features.Chat.GetChatSession;

internal sealed class GetChatSessionHandler : IQueryHandler<GetChatSession, ChatSessionResponse>
{
private readonly IChatSessionRepository _chatSessionRepository;

public GetChatSessionHandler(IChatSessionRepository chatSessionRepository)
=> _chatSessionRepository = chatSessionRepository;

public async ValueTask<ChatSessionResponse> Handle(GetChatSession query, CancellationToken cancellationToken)
=> (await _chatSessionRepository.GetAsync(query.Id))
.Adapt<ChatSessionResponse>() ?? throw new ChatSessionNotFoundException(query.Id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
<ItemGroup>
<PackageReference Include="Mapster" Version="7.4.1-pre01" />
<PackageReference Include="Mapster.DependencyInjection" Version="1.0.2-pre01" />
<PackageReference Include="Mediator.Abstractions" Version="3.0.0-preview.24" />
<PackageReference Include="Mediator.SourceGenerator" Version="3.0.0-preview.24">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace StellarChat.Shared.Abstractions.Contracts.Chat;

public record ChatSessionResponse(Guid Id, string Title, string Metaprompt, HashSet<string> ActivePlugins, DateTimeOffset CreatedAt, DateTimeOffset UpdatedAt);
7 changes: 3 additions & 4 deletions src/Shared/StellarChat.Shared.Infrastructure/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ public static WebApplicationBuilder AddSharedInfrastructure(this WebApplicationB
.AddCorsPolicy(builder.Configuration)
.AddMongo(builder.Configuration)
.RegisterEndpoints(builder.Configuration)
.AddSemanticKernel(builder.Configuration)
.AddMediator();
.AddSemanticKernel(builder.Configuration);

return builder;
}
Expand Down Expand Up @@ -62,7 +61,7 @@ public static string ToSnakeCase(this string input)
Regex.Replace(
Regex.Replace(input, @"([\p{Lu}]+)([\p{Lu}][\p{Ll}])", "$1_$2"), @"([\p{Ll}\d])([\p{Lu}])", "$1_$2"), @"[-\s]", "_").ToLower();

public static bool IsEmpty(this string value)
public static bool IsEmpty(this string value)
=> string.IsNullOrWhiteSpace(value);

public static bool IsNotEmpty(this string value)
Expand Down Expand Up @@ -99,7 +98,7 @@ public static string GetUserIpAddress(this HttpContext context)
if (context.Request.Headers.TryGetValue("x-forwarded-for", out var forwardedFor))
{
var ipAddresses = forwardedFor.ToString().Split(",", StringSplitOptions.RemoveEmptyEntries);

if (ipAddresses.Any())
{
ipAddress = ipAddresses[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Mediator.Abstractions" Version="3.0.0-preview.24" />
<PackageReference Include="Mediator.SourceGenerator" Version="3.0.0-preview.24">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SemanticKernel" Version="1.6.3" />
<PackageReference Include="MongoDB.Driver" Version="2.24.0" />
<PackageReference Include="Serilog" Version="4.0.0-dev-02113" />
Expand Down

0 comments on commit 98f0da8

Please sign in to comment.