Expose critical curation and source image APIs

This commit is contained in:
2026-03-17 22:28:50 +01:00
parent 57fe9d217d
commit 9d25304a27
11 changed files with 323 additions and 2 deletions

View File

@@ -9,7 +9,9 @@ using SharedParsing = RolemasterDb.CriticalParsing;
namespace RolemasterDb.App.Features;
public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbContextFactory)
public sealed class LookupService(
IDbContextFactory<RolemasterDbContext> dbContextFactory,
CriticalImportArtifactLocator? artifactLocator = null)
{
public async Task<LookupReferenceData> GetReferenceDataAsync(CancellationToken cancellationToken = default)
{
@@ -245,6 +247,7 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
result.CriticalColumn.Role,
result.CriticalGroup?.GroupKey,
result.CriticalGroup?.Label,
result.IsCurated,
result.DescriptionText,
result.Effects
.OrderBy(effect => effect.Id)
@@ -300,6 +303,28 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
return CreateCellEditorResponse(result, currentState, generatedContent.ValidationErrors, CreateComparisonState(generatedContent));
}
public async Task<string?> GetCriticalSourceImagePathAsync(string slug, int resultId, CancellationToken cancellationToken = default)
{
if (artifactLocator is null)
{
return null;
}
await using var dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
var normalizedSlug = NormalizeSlug(slug);
var relativePath = await dbContext.CriticalResults
.AsNoTracking()
.Where(item => item.Id == resultId && item.CriticalTable.Slug == normalizedSlug)
.Select(item => item.SourceImagePath)
.SingleOrDefaultAsync(cancellationToken);
var fullPath = artifactLocator.ResolveStoredPath(relativePath);
return fullPath is not null && File.Exists(fullPath)
? fullPath
: null;
}
public async Task<CriticalCellEditorResponse?> ReparseCriticalCellAsync(
string slug,
int resultId,
@@ -363,6 +388,7 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
result.RawAffixText = NormalizeOptionalText(request.RawAffixText);
result.ParseStatus = request.ParseStatus.Trim();
result.ParsedJson = CriticalCellEditorSnapshot.FromRequest(request).ToJson();
result.IsCurated = request.IsCurated;
ReplaceBaseEffects(dbContext, result, request.Effects);
ReplaceBranches(dbContext, result, request.Branches);
@@ -450,6 +476,9 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
result.CriticalColumn.ColumnKey,
result.CriticalColumn.Label,
result.CriticalColumn.Role,
state.IsCurated,
result.SourcePageNumber,
CreateSourceImageUrl(result),
state.RawCellText,
state.QuickParseInput,
state.DescriptionText,
@@ -596,6 +625,7 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
result.RawAffixText,
result.ParseStatus,
result.ParsedJson,
result.IsCurated,
snapshot.IsDescriptionOverridden,
snapshot.IsRawAffixTextOverridden,
snapshot.AreEffectsOverridden,
@@ -620,6 +650,7 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
result.RawAffixText,
result.ParseStatus,
result.ParsedJson,
result.IsCurated,
false,
false,
false,
@@ -645,6 +676,7 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
RawAffixText: content.RawAffixText,
ParseStatus: ResolveParseStatus(content.Effects, content.Branches),
ParsedJson: SerializeParsedEffects(content.Effects),
IsCurated: false,
IsDescriptionOverridden: false,
IsRawAffixTextOverridden: false,
AreEffectsOverridden: false,
@@ -663,6 +695,7 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
currentState.IsRawAffixTextOverridden ? currentState.RawAffixText : generatedState.RawAffixText,
generatedState.ParseStatus,
generatedState.ParsedJson,
currentState.IsCurated,
currentState.IsDescriptionOverridden,
currentState.IsRawAffixTextOverridden,
currentState.AreEffectsOverridden,
@@ -992,4 +1025,9 @@ public sealed class LookupService(IDbContextFactory<RolemasterDbContext> dbConte
private static string NormalizeSlug(string value) =>
value.Trim().Replace(' ', '_').ToLowerInvariant();
private static string? CreateSourceImageUrl(CriticalResult result) =>
string.IsNullOrWhiteSpace(result.SourceImagePath)
? null
: $"/api/tables/critical/{result.CriticalTable.Slug}/cells/{result.Id}/source-image";
}