fix usage of Enrichers and Dto Structures ...

This commit is contained in:
2026-08-08 09:42:28 +03:30
parent 17bbe401ae
commit 000408ae3f
12 changed files with 408 additions and 37 deletions
+2
View File
@@ -49,5 +49,7 @@ namespace xAiModels.Constants
public const string DefaultXAiProjectTitleResourceID = "XAiPrjT"; public const string DefaultXAiProjectTitleResourceID = "XAiPrjT";
public const string DefaultXAiConversationTitleResourceID = "XAiCnvT"; public const string DefaultXAiConversationTitleResourceID = "XAiCnvT";
public const string DefaultXAiProjectDescriptionResourceID = "XAiPrjD"; public const string DefaultXAiProjectDescriptionResourceID = "XAiPrjD";
//
} }
} }
+12
View File
@@ -431,6 +431,12 @@ namespace xAiModels.DI
services.Add( services.Add(
new ServiceDescriptor(typeof(IXAiMessageRepositoryProvider), typeof(XAiMessageRepositoryProvider), lifeTime) new ServiceDescriptor(typeof(IXAiMessageRepositoryProvider), typeof(XAiMessageRepositoryProvider), lifeTime)
); );
//
// Enrichers ...
services.Add(
new ServiceDescriptor(typeof(IXAiMessageEnricher), typeof(XAiMessageEnricher), lifeTime)
);
#endregion #endregion
// //
@@ -454,6 +460,12 @@ namespace xAiModels.DI
services.Add( services.Add(
new ServiceDescriptor(typeof(IXAiProjectDescriptionResourceProvider), typeof(XAiProjectDescriptionResourceProvider), lifeTime) new ServiceDescriptor(typeof(IXAiProjectDescriptionResourceProvider), typeof(XAiProjectDescriptionResourceProvider), lifeTime)
); );
//
// Enrichers ...
services.Add(
new ServiceDescriptor(typeof(IXAiProjectEnricher), typeof(XAiProjectEnricher), lifeTime)
);
#endregion #endregion
// //
@@ -1,22 +1,11 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using xAiModels.Models.Dtos; using xAiModels.Models.Dtos;
using xDataService.Interfaces;
namespace xAiModels.Interfaces.Enrichers namespace xAiModels.Interfaces.Enrichers
{ {
public interface IXAiConversationEnricher /// <summary>
{ /// Ai Conversation Enricher ...
Task EnrichAsync( /// </summary>
XAiConversationDto source, public interface IXAiConversationEnricher : IXBaseEnricher<XAiConversationDto, XAiConversationDto>
XAiConversationDto destination, { }
CancellationToken cancellationToken = default
);
Task<IEnumerable<XAiConversationDto>> EnrichRangeAsync(
IEnumerable<XAiConversationDto> sources,
IEnumerable<XAiConversationDto> destinations,
CancellationToken cancellationToken = default
);
}
} }
@@ -0,0 +1,8 @@
using xAiModels.Models.Dtos;
using xDataService.Interfaces;
namespace xAiModels.Interfaces.Enrichers
{
public interface IXAiMessageEnricher : IXBaseEnricher<XAiMessageDto, XAiMessageDto>
{ }
}
@@ -0,0 +1,8 @@
using xAiModels.Models.Dtos;
using xDataService.Interfaces;
namespace xAiModels.Interfaces.Enrichers
{
public interface IXAiProjectEnricher : IXBaseEnricher<XAiProjectDto, XAiProjectDto>
{ }
}
+3 -3
View File
@@ -28,7 +28,7 @@ namespace xAiModels.Models.Dtos
/// <summary> /// <summary>
/// All Exists Title Locale Resources ... /// All Exists Title Locale Resources ...
/// </summary> /// </summary>
public virtual XLocaleResourceDto[] TitleLocales { get; set; } public virtual XResourceDto TitleResource { get; set; }
/// <summary> /// <summary>
/// Created Time ... /// Created Time ...
@@ -58,11 +58,11 @@ namespace xAiModels.Models.Dtos
/// <summary> /// <summary>
/// Project Title Locale Resources ... /// Project Title Locale Resources ...
/// </summary> /// </summary>
public virtual XLocaleResourceDto[] ProjectTitleLocales { get; set; } public virtual XResourceDto ProjectTitleResource { get; set; }
/// <summary> /// <summary>
/// Project Description Locale Resources ... /// Project Description Locale Resources ...
/// </summary> /// </summary>
public virtual XLocaleResourceDto[] ProjectDescriptionLocales { get; set; } public virtual XResourceDto ProjectDescriptionResource { get; set; }
} }
} }
+4 -1
View File
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using xAiModels.Constants; using xAiModels.Constants;
using xCommons.Extensions; using xCommons.Extensions;
using xModels.Base; using xModels.Base;
@@ -48,7 +49,8 @@ namespace xAiModels.Models.Dtos
/// <summary> /// <summary>
/// Conversation Info ... /// Conversation Info ...
/// </summary> /// </summary>
public virtual XAiConversationDto Conversation { get; set; } = null; public virtual string ConversationTitle { get; set; } = null;
public virtual XResourceDto ConversationTitleResouce { get; set; } = null;
// //
#region Meta Data Property ... #region Meta Data Property ...
@@ -57,6 +59,7 @@ namespace xAiModels.Models.Dtos
/// <summary> /// <summary>
/// Meta Data of Message ... /// Meta Data of Message ...
/// </summary> /// </summary>
[NotMapped]
public IDictionary<string, object> Metadata { get; private set; } = null; public IDictionary<string, object> Metadata { get; private set; } = null;
/// <summary> /// <summary>
+2 -2
View File
@@ -29,7 +29,7 @@ namespace xAiModels.Models.Dtos
/// <summary> /// <summary>
/// All Exists Title Locale Resources ... /// All Exists Title Locale Resources ...
/// </summary> /// </summary>
public virtual XLocaleResourceDto[] TitleLocales { get; set; } public virtual XResourceDto TitleResource { get; set; }
/// <summary> /// <summary>
/// Description of Project ... /// Description of Project ...
@@ -39,7 +39,7 @@ namespace xAiModels.Models.Dtos
/// <summary> /// <summary>
/// All Exists Description Locale Resources ... /// All Exists Description Locale Resources ...
/// </summary> /// </summary>
public virtual XLocaleResourceDto[] DescriptionLocales { get; set; } public virtual XResourceDto DescriptionResource { get; set; }
/// <summary> /// <summary>
/// a Prompt for Project Start ... /// a Prompt for Project Start ...
+7 -12
View File
@@ -6,7 +6,6 @@ using xAiModels.Interfaces;
using xAiModels.Interfaces.Dtos; using xAiModels.Interfaces.Dtos;
using xAiModels.Interfaces.Enrichers; using xAiModels.Interfaces.Enrichers;
using xAiModels.Models.Dtos; using xAiModels.Models.Dtos;
using xAiModels.Models.Entities;
using xCommons.Extensions; using xCommons.Extensions;
using xIdentityService.Interfaces; using xIdentityService.Interfaces;
using xIdentityService.Extensions; using xIdentityService.Extensions;
@@ -58,14 +57,14 @@ namespace xAiModels.Providers.Enrichers
// //
// Attached Resolved Info to Destination ... // Attached Resolved Info to Destination ...
destination.Owner = ownerTask.Result; destination.Owner = ownerTask.Result;
destination.TitleLocales = titleLocalesTask.Result; destination.TitleResource = titleLocalesTask.Result;
var project = projectTask.Result; var project = projectTask.Result;
if (!project.IsNullOrDefault()) if (!project.IsNullOrDefault())
{ {
destination.ProjectTitle = project.Title; destination.ProjectTitle = project.Title;
destination.ProjectDescription = project.Description; destination.ProjectDescription = project.Description;
destination.ProjectTitleLocales = project.TitleLocales; destination.ProjectTitleResource = project.TitleResource;
destination.ProjectDescriptionLocales = project.DescriptionLocales; destination.ProjectDescriptionResource = project.DescriptionResource;
} }
} }
@@ -76,7 +75,7 @@ namespace xAiModels.Providers.Enrichers
/// <param name="destinations"></param> /// <param name="destinations"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
public async Task<IEnumerable<XAiConversationDto>> EnrichRangeAsync( public async Task EnrichRangeAsync(
IEnumerable<XAiConversationDto> sources, IEnumerable<XAiConversationDto> sources,
IEnumerable<XAiConversationDto> destinations, IEnumerable<XAiConversationDto> destinations,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
@@ -90,9 +89,6 @@ namespace xAiModels.Providers.Enrichers
// //
await Task.WhenAll(tasks); await Task.WhenAll(tasks);
//
return destinations;
} }
// //
@@ -137,24 +133,23 @@ namespace xAiModels.Providers.Enrichers
/// <param name="title"></param> /// <param name="title"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
private async Task<XLocaleResourceDto[]> ResolveTitleLocalesAsync( private async Task<XResourceDto> ResolveTitleLocalesAsync(
string title, string title,
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
) )
{ {
// //
XLocaleResourceDto[] result = []; XResourceDto result = null;
if (title.IsNullOrEmpty()) if (title.IsNullOrEmpty())
{ {
return result; return result;
} }
// //
var locales = await conversationTitleResourceProvider.GetLocales( result = await conversationTitleResourceProvider.GetResource(
identifier: title, identifier: title,
cancellationToken: cancellationToken cancellationToken: cancellationToken
); );
result = [.. locales];
// //
return result; return result;
+143
View File
@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using xAiModels.Interfaces.Enrichers;
using xAiModels.Models.Dtos;
using xCommons.Extensions;
using xIdentityService.Interfaces;
using xIdentityService.Extensions;
using xModels.Dtos;
using System.Linq;
using xAiModels.Interfaces.Dtos;
namespace xAiModels.Providers.Enrichers
{
public class XAiMessageEnricher : IXAiMessageEnricher
{
private readonly IXIdentityProvider identityProvider;
private readonly IXAiConversationRepositoryService conversationRepositoryService;
public XAiMessageEnricher(
IXIdentityProvider identityProvider,
IXAiConversationRepositoryService conversationRepositoryService
)
{
this.identityProvider = identityProvider;
this.conversationRepositoryService = conversationRepositoryService;
}
public async Task EnrichAsync(
XAiMessageDto source,
XAiMessageDto destination,
CancellationToken cancellationToken = default
)
{
//
// Run independent async operations concurrently
var ownerTask = ResolveOwnerAsync(source.OwnerId, cancellationToken);
var conversationTask = ResolveConversationAsync(source.ConversationId, cancellationToken);
//
// wait until All Tasks Resolved ...
await Task.WhenAll(ownerTask, conversationTask);
//
// Attached Resolved Info to Destination ...
destination.Owner = ownerTask.Result;
if (!conversationTask.Result.IsNullOrDefault())
{
//
destination.ConversationTitle = conversationTask.Result.Title;
destination.ConversationTitleResouce = conversationTask.Result.TitleResource;
}
}
public async Task EnrichRangeAsync(
IEnumerable<XAiMessageDto> sources,
IEnumerable<XAiMessageDto> destinations,
CancellationToken cancellationToken = default
)
{
//
// Make Tasks Ready ...
var tasks = sources.Zip(destinations, (src, dst) =>
EnrichAsync(src, dst, cancellationToken)
);
//
await Task.WhenAll(tasks);
}
//
#region Private ...
/// <summary>
/// Reading Owner User Info ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<XPersonDto> ResolveOwnerAsync(
string ownerId,
CancellationToken cancellationToken = default
)
{
//
XPersonDto result = null;
//
// Validate ...
if (ownerId.IsNullOrEmpty())
{
return result;
}
//
// Try to Retrieve User Info ...
var device = identityProvider.GetDevice();
var userInfo = await identityProvider.GetUserInfo(
device: device,
userSelectByParam: ownerId
);
result = userInfo.ToXPersonDto();
//
return result;
}
/// <summary>
/// Reading Conversation ...
/// </summary>
/// <param name="conversationId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<XAiConversationDto> ResolveConversationAsync(
Guid conversationId,
CancellationToken cancellationToken = default
)
{
//
XAiConversationDto result = null;
//
// Validate ...
if (conversationId.IsNull() ||
conversationId.IsDefaultGuid()
)
{
return result;
}
//
result = await conversationRepositoryService.GetAsync(
id: conversationId,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
//
return result;
}
#endregion
}
}
+191
View File
@@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using xAiModels.Interfaces.Enrichers;
using xAiModels.Models.Dtos;
using xCommons.Extensions;
using xIdentityService.Interfaces;
using xIdentityService.Extensions;
using xModels.Dtos;
using xAiModels.Interfaces;
using xAiModels.Interfaces.Dtos;
namespace xAiModels.Providers.Enrichers
{
public class XAiProjectEnricher : IXAiProjectEnricher
{
private readonly IXIdentityProvider identityProvider;
private readonly IXAiProjectTitleResourceProvider projectTitleResourceProvider;
private readonly IXAiConversationRepositoryService conversationRepositoryService;
private readonly IXAiProjectDescriptionResourceProvider projectDescriptionResourceProvider;
public XAiProjectEnricher(
IXIdentityProvider identityProvider,
IXAiProjectTitleResourceProvider projectTitleResourceProvider,
IXAiConversationRepositoryService conversationRepositoryService,
IXAiProjectDescriptionResourceProvider projectDescriptionResourceProvider
)
{
this.identityProvider = identityProvider;
this.projectTitleResourceProvider = projectTitleResourceProvider;
this.conversationRepositoryService = conversationRepositoryService;
this.projectDescriptionResourceProvider = projectDescriptionResourceProvider;
}
public Task EnrichAsync(
XAiProjectDto source,
XAiProjectDto destination,
CancellationToken cancellationToken = default
)
{
throw new NotImplementedException();
}
public Task EnrichRangeAsync(
IEnumerable<XAiProjectDto> sources,
IEnumerable<XAiProjectDto> destinations,
CancellationToken cancellationToken = default
)
{
throw new NotImplementedException();
}
//
#region Private ...
/// <summary>
/// Reading Owner User Info ...
/// </summary>
/// <param name="ownerId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<XPersonDto> ResolveOwnerAsync(
string ownerId,
CancellationToken cancellationToken = default
)
{
//
XPersonDto result = null;
//
// Validate ...
if (ownerId.IsNullOrEmpty())
{
return result;
}
//
// Try to Retrieve User Info ...
var device = identityProvider.GetDevice();
var userInfo = await identityProvider.GetUserInfo(
device: device,
userSelectByParam: ownerId
);
result = userInfo.ToXPersonDto();
//
return result;
}
/// <summary>
/// Retrieve Title Resource ...
/// </summary>
/// <param name="identifier"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<XResourceDto> ResolveTitleAsync(
string identifier,
CancellationToken cancellationToken = default
)
{
//
XResourceDto result = null;
//
// Validate ...
if (identifier.IsNullOrEmpty())
{
return result;
}
//
result = await projectTitleResourceProvider.GetResource(
identifier: identifier,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Retrieve Description Resource ...
/// </summary>
/// <param name="identifier"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<XResourceDto> ResolveDescriptionAsync(
string identifier,
CancellationToken cancellationToken = default
)
{
//
XResourceDto result = null;
//
// Validate ...
if (identifier.IsNullOrEmpty())
{
return result;
}
//
result = await projectDescriptionResourceProvider.GetResource(
identifier: identifier,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Retrieve Project Conversations ...
/// </summary>
/// <param name="projectId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<List<XAiConversationDto>> ResolveConversationsAsync(
Guid projectId,
CancellationToken cancellationToken = default
)
{
//
List<XAiConversationDto> result = [];
//
// Validate ...
if (projectId.IsNull() ||
projectId.IsDefaultGuid()
)
{
return result;
}
//
var items = await conversationRepositoryService.FindManyAsync(
orderBuilder: null,
includeBuilder: null,
ignoreSoftDeleteds: true,
predicate: x => x.Id == projectId,
cancellationToken: cancellationToken
);
result = [.. items];
//
return result;
}
#endregion
}
}
+20
View File
@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using xAiModels.Interfaces; using xAiModels.Interfaces;
using xAiModels.Interfaces.Entities; using xAiModels.Interfaces.Entities;
@@ -53,6 +54,25 @@ namespace xAiModels.Providers
this.projectDescriptionResourceProvider = projectDescriptionResourceProvider; this.projectDescriptionResourceProvider = projectDescriptionResourceProvider;
} }
//
#region Actions ...
#endregion
//
#region Private ...
/// <summary>
/// Handle Default Project for Specified Owner ...
/// </summary>
/// <param name="ownerId"></param>
/// <returns></returns>
private async Task HandleDefaultProject(string ownerId) { }
/// <summary>
/// Handle Default Project's Default Conversation for Specified Owner ...
/// </summary>
/// <param name="ownerId"></param>
/// <returns></returns>
private async Task HandleDefaultConversation(string ownerId) { }
#endregion
} }
} }