Skip to content
Merged

Dev #2775

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.IO;
using System.Threading.Tasks;

namespace Unity.AI.Attachments;

public sealed class AttachmentContentStream(Stream content, string contentType) : IDisposable, IAsyncDisposable
{
public Stream Content { get; } = content ?? throw new ArgumentNullException(nameof(content));

public string ContentType { get; } =
string.IsNullOrWhiteSpace(contentType) ? "application/octet-stream" : contentType;

public static AttachmentContentStream Empty { get; } =
new(Stream.Null, "application/octet-stream");

public void Dispose() => Content.Dispose();

public ValueTask DisposeAsync() => Content.DisposeAsync();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Unity.GrantManager.Attachments;
namespace Unity.AI.Attachments;

public class AttachmentSummaryResultDto
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;
using System.Threading.Tasks;

namespace Unity.AI.Attachments;

public interface IAttachmentContentProvider
{
Task<AttachmentContentStream> OpenAttachmentAsync(Guid submissionId, Guid fileId, string name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Unity.AI.Generation;

public static class AIGenerationOperationKeyHelper
{
public const string AttachmentSummaryOperationType = "attachment-summary";
public const string ApplicationAnalysisOperationType = "application-analysis";
public const string ApplicationScoringOperationType = "application-scoring";
public const string FormMappingOperationType = "form-mapping";
public const string FormWorksheetOperationType = "form-worksheet";
public const string FormScoresheetOperationType = "form-scoresheet";

public static string? ResolveOperationName(string operationType)
{
return operationType switch
{
ApplicationAnalysisOperationType => "ApplicationAnalysis",
AttachmentSummaryOperationType => "AttachmentSummary",
ApplicationScoringOperationType => "ApplicationScoring",
FormMappingOperationType => "FormMapping",
FormWorksheetOperationType => "FormWorksheet",
FormScoresheetOperationType => "FormScoresheet",
_ => null
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;
using System.Threading.Tasks;

namespace Unity.AI.Generation;

public interface IAIGenerationStatusReader
{
Task<AIGenerationRequestDto?> GetLatestAsync(Guid applicationId, string operationType, Guid? tenantId = null);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Unity.GrantManager.GrantApplications;
namespace Unity.AI.GrantApplications;

public class ApplicationAnalysisResultDto
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Unity.GrantManager.GrantApplications;
namespace Unity.AI.GrantApplications;

public class ApplicationContentResultDto
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Unity.GrantManager.GrantApplications;
namespace Unity.AI.GrantApplications;

public class ApplicationScoringResultDto
{
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
using System.Threading;
using System.Threading.Tasks;
using Unity.AI.Extraction;
using Unity.AI.Attachments;
using Unity.AI.Localization;
using Unity.AI.Requests;
using Unity.GrantManager.Intakes;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
Expand All @@ -18,7 +18,7 @@ namespace Unity.AI.Operations;

public class AttachmentSummaryService(
IAttachmentSummaryDataProvider attachmentSummaryDataProvider,
IChefsFileAttachmentStreamProvider chefsFileAttachmentStreamProvider,
IAttachmentContentProvider attachmentContentProvider,
ITextExtractionService textExtractionService,
IAIService aiService,
IAIGenerationPrerequisiteValidator aiGenerationPrerequisiteValidator,
Expand Down Expand Up @@ -149,7 +149,7 @@ private async Task WithUnitOfWorkAsync(Func<Task> operation)
await uow.CompleteAsync();
}

private async Task<ChefsFileAttachmentStream> OpenAttachmentStreamAsync(
private async Task<AttachmentContentStream> OpenAttachmentStreamAsync(
AttachmentSummarySource attachment,
string fileName,
CancellationToken cancellationToken)
Expand All @@ -160,14 +160,13 @@ private async Task<ChefsFileAttachmentStream> OpenAttachmentStreamAsync(
logger.LogWarning(
"Attachment {AttachmentId} has invalid CHEFS IDs. Falling back to metadata-only summary generation.",
attachment.Id);
return ChefsFileAttachmentStream.Empty;
return AttachmentContentStream.Empty;
}

try
{
cancellationToken.ThrowIfCancellationRequested();
var stream = await chefsFileAttachmentStreamProvider.OpenAsync(submissionId, fileId, fileName);
return stream ?? ChefsFileAttachmentStream.Empty;
return await attachmentContentProvider.OpenAttachmentAsync(submissionId, fileId, fileName);
}
catch (OperationCanceledException)
{
Expand All @@ -179,7 +178,7 @@ private async Task<ChefsFileAttachmentStream> OpenAttachmentStreamAsync(
ex,
"Failed retrieving CHEFS content for attachment {AttachmentId}. Falling back to metadata-only summary generation.",
attachment.Id);
return ChefsFileAttachmentStream.Empty;
return AttachmentContentStream.Empty;
}
}

Expand All @@ -197,7 +196,7 @@ private static bool IsSupportedOfficeOrPdf(string fileName)
private void LogEmptyExtraction(
Guid attachmentId,
string fileName,
ChefsFileAttachmentStream attachmentStream)
AttachmentContentStream attachmentStream)
{
logger.LogWarning(
"No text extracted for supported attachment {AttachmentId} ({FileName}). Skipping AI summary generation. ContentType: {ContentType}; StreamCanSeek: {StreamCanSeek}; StreamLength: {StreamLength}.",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Unity.Flex;
using Unity.GrantManager;
using Volo.Abp.Application;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Mapperly;
Expand All @@ -16,8 +15,7 @@ namespace Unity.AI;
typeof(AbpDddApplicationModule),
typeof(AbpMapperlyModule),
typeof(AbpTenantManagementDomainModule),
typeof(FlexApplicationModule),
typeof(GrantManagerDomainModule)
typeof(FlexApplicationModule)
)]
public class AIApplicationModule : AbpModule
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Unity.AI.Operations;
using Unity.AI.Domain;
using Unity.AI.Prompts;
using Unity.GrantManager.GrantApplications;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
using Unity.AI.Operations;
using Unity.AI.Permissions;
using Unity.AI.Settings;
using Unity.GrantManager.Attachments;
using Unity.GrantManager.GrantApplications;
using Unity.GrantManager.GrantApplications.Automation;
using Volo.Abp.MultiTenancy;
using Volo.Abp;
using Volo.Abp.Features;
Expand All @@ -19,7 +16,7 @@ namespace Unity.AI.Generation;
[Route("api/app/ai/generation")]
public class AIGenerationAppService(
IApplicationGenerationQueue aiGenerationQueue,
IAIGenerationStatusAppService aiGenerationStatusAppService,
IAIGenerationStatusReader aiGenerationStatusReader,
AIFeatureGuard featureGuard,
ICurrentTenant currentTenant)
: AIAppService, IAIGenerationAppService
Expand Down Expand Up @@ -105,7 +102,7 @@ public virtual async Task<AIGenerationStatusDto> GetStatusAsync(Guid application
{
await EnsureStatusAccessAsync(operationType);

var request = await aiGenerationStatusAppService.GetLatestAsync(applicationId, operationType, currentTenant.Id);
var request = await aiGenerationStatusReader.GetLatestAsync(applicationId, operationType, currentTenant.Id);
if (request == null)
{
return new AIGenerationStatusDto();
Expand Down Expand Up @@ -141,12 +138,12 @@ private async Task EnsureStatusAccessAsync(string operationType)
{
var permission = operationType switch
{
AIGenerationRequestKeyHelper.ApplicationAnalysisOperationType => AIPermissions.Analysis.ViewApplicationAnalysis,
AIGenerationRequestKeyHelper.AttachmentSummaryOperationType => AIPermissions.Analysis.ViewAttachmentSummary,
AIGenerationRequestKeyHelper.ApplicationScoringOperationType => AIPermissions.Analysis.ViewScoringResult,
AIGenerationRequestKeyHelper.FormMappingOperationType => AIPermissions.Analysis.ViewFormMapping,
AIGenerationRequestKeyHelper.FormWorksheetOperationType => AIPermissions.Analysis.ViewFormWorksheet,
AIGenerationRequestKeyHelper.FormScoresheetOperationType => AIPermissions.Analysis.ViewFormScoresheet,
AIGenerationOperationKeyHelper.ApplicationAnalysisOperationType => AIPermissions.Analysis.ViewApplicationAnalysis,
AIGenerationOperationKeyHelper.AttachmentSummaryOperationType => AIPermissions.Analysis.ViewAttachmentSummary,
AIGenerationOperationKeyHelper.ApplicationScoringOperationType => AIPermissions.Analysis.ViewScoringResult,
AIGenerationOperationKeyHelper.FormMappingOperationType => AIPermissions.Analysis.ViewFormMapping,
AIGenerationOperationKeyHelper.FormWorksheetOperationType => AIPermissions.Analysis.ViewFormWorksheet,
AIGenerationOperationKeyHelper.FormScoresheetOperationType => AIPermissions.Analysis.ViewFormScoresheet,
_ => throw new UserFriendlyException($"Unsupported AI generation operation type: {operationType}")
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
<!-- Explicit reference to fix vulnerable transitive dependency -->
<PackageReference Include="System.Security.Cryptography.Xml" Version="10.0.10" />
<ProjectReference Include="..\..\..\..\modules\Unity.Flex\src\Unity.Flex.Application\Unity.Flex.Application.csproj" />
<ProjectReference Include="..\..\..\..\src\Unity.GrantManager.Application.Contracts\Unity.GrantManager.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\..\src\Unity.GrantManager.Domain\Unity.GrantManager.Domain.csproj" />
<ProjectReference Include="..\..\..\Unity.SharedKernel\Unity.SharedKernel.csproj" />
<ProjectReference Include="..\Unity.AI.Application.Contracts\Unity.AI.Application.Contracts.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,26 @@ function initializeDataTable(options) {
}
},
stateLoadParams: function (settings, data) {
// Discard stale state when column count has changed so defaultVisibleColumns applies cleanly
if (data?.columns && data.columns.length !== settings.aoColumns.length) {
return false;
// Remap saved column state onto the live column list by name, rather than
// applying it positionally, so that state (including named "Saved Views")
// saved before columns were added/removed/reordered can still be loaded
// correctly. Always remapped (not just on a length mismatch) since a
// same-count reorder or rename would otherwise still be misapplied by
// position. Columns with no matching saved name fall back to the table's
// configured default visibility (defaultVisibleColumns).
if (data?.columns) {
const savedColumnsByName = new Map(
data.columns.map(function (col) { return [col.name, col]; })
);
data.columns = settings.aoColumns.map(function (col) {
const saved = savedColumnsByName.get(col.name);
if (saved) return saved;
return {
name: col.name,
visible: col.bVisible,
search: { search: '', smart: true, regex: false, caseInsensitive: true, return: false }
};
});
}

if (data?.externalSearch) {
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
using Microsoft.Extensions.Localization;
using System;
using System.Linq;
using System.Threading.Tasks;
using Unity.Flex.Domain.Scoresheets;
using Microsoft.Extensions.Localization;
using Unity.AI.Localization;
using Unity.AI.Operations;
using Unity.Flex.Domain.Scoresheets;
using Unity.GrantManager.Applications;
using Unity.Modules.Shared.Correlation;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Linq;

namespace Unity.AI.Operations;
namespace Unity.GrantManager.GrantApplications.Automation;

public class AIGenerationPrerequisiteValidator(
IApplicationRepository applicationRepository,
Expand Down
Loading
Loading