Phase 20AP.1 – Asset Intelligence Review and Import

This commit is contained in:
Nick Beckley 2026-07-09 21:09:48 +01:00
parent 11de81abed
commit d44217162c
4 changed files with 66 additions and 28 deletions

View File

@ -60,7 +60,9 @@ public sealed class StoryIntelligenceBookPipelineState
public DateTime CreatedUtc { get; init; }
public DateTime UpdatedUtc { get; init; }
public bool IsComplete => string.Equals(Status, StoryIntelligencePipelineStatuses.Complete, StringComparison.OrdinalIgnoreCase);
public bool IsComplete
=> string.Equals(Status, StoryIntelligencePipelineStatuses.Complete, StringComparison.OrdinalIgnoreCase)
&& string.Equals(LastCompletedStage, StoryIntelligencePipelineStages.AssetImport, StringComparison.OrdinalIgnoreCase);
}
public sealed class StoryIntelligenceBookPipelineSaveRequest

View File

@ -525,31 +525,32 @@ public sealed class OnboardingStoryIntelligenceService(
.ToList()
};
if (state.IsComplete)
{
batch.CharacterStageComplete = true;
batch.LocationStageComplete = true;
batch.AssetStageComplete = true;
}
else if (state.CurrentStage is StoryIntelligencePipelineStages.AssetReview or StoryIntelligencePipelineStages.AssetImport)
{
batch.CharacterStageComplete = true;
batch.LocationStageComplete = true;
}
else if (state.CurrentStage is StoryIntelligencePipelineStages.LocationReview or StoryIntelligencePipelineStages.LocationImport)
{
batch.CharacterStageComplete = true;
}
var characterStageComplete = HasCompletedStage(state, StoryIntelligencePipelineStages.CharacterImport)
|| state.CurrentStage is StoryIntelligencePipelineStages.LocationReview
or StoryIntelligencePipelineStages.LocationImport
or StoryIntelligencePipelineStages.AssetReview
or StoryIntelligencePipelineStages.AssetImport
or StoryIntelligencePipelineStages.Complete;
var locationStageComplete = HasCompletedStage(state, StoryIntelligencePipelineStages.LocationImport)
|| state.CurrentStage is StoryIntelligencePipelineStages.AssetReview
or StoryIntelligencePipelineStages.AssetImport
or StoryIntelligencePipelineStages.Complete;
var assetStageComplete = HasCompletedStage(state, StoryIntelligencePipelineStages.AssetImport);
batch.CharacterStageComplete = characterStageComplete;
batch.LocationStageComplete = locationStageComplete;
batch.AssetStageComplete = assetStageComplete;
await batchStore.SaveAsync(batch);
var route = state.CurrentStage switch
var route = assetStageComplete
? StoryIntelligenceResumeRoutes.Complete
: locationStageComplete
? StoryIntelligenceResumeRoutes.Assets
: characterStageComplete
? StoryIntelligenceResumeRoutes.Locations
: state.CurrentStage switch
{
StoryIntelligencePipelineStages.Complete => StoryIntelligenceResumeRoutes.Complete,
StoryIntelligencePipelineStages.AssetReview => StoryIntelligenceResumeRoutes.Assets,
StoryIntelligencePipelineStages.AssetImport => StoryIntelligenceResumeRoutes.Assets,
StoryIntelligencePipelineStages.LocationReview => StoryIntelligenceResumeRoutes.Locations,
StoryIntelligencePipelineStages.LocationImport => StoryIntelligenceResumeRoutes.Locations,
StoryIntelligencePipelineStages.CharacterReview => StoryIntelligenceResumeRoutes.Characters,
StoryIntelligencePipelineStages.CharacterImport => StoryIntelligenceResumeRoutes.Characters,
StoryIntelligencePipelineStages.SceneReview => StoryIntelligenceResumeRoutes.SceneReview,
@ -560,6 +561,9 @@ public sealed class OnboardingStoryIntelligenceService(
return new OnboardingStoryIntelligenceResumeTarget(batch.BatchID, route);
}
private static bool HasCompletedStage(StoryIntelligenceBookPipelineState state, string stage)
=> string.Equals(state.LastCompletedStage, stage, StringComparison.OrdinalIgnoreCase);
private async Task<(UserOnboardingState State, ManuscriptScanPreview Preview, ManuscriptScanReviewDecision Review, OnboardingManuscriptBuildResult? Build, OnboardingWizardViewModel Wizard)?> GetContextAsync(int userId)
{
var state = await onboardingRepository.GetAsync(userId);

View File

@ -269,8 +269,12 @@ public sealed class StoryIntelligenceService(
return state.CurrentReviewStage switch
{
StoryIntelligencePipelineStages.AssetReview => "Waiting for Asset Review",
StoryIntelligencePipelineStages.LocationReview => "Waiting for Location Review",
StoryIntelligencePipelineStages.CharacterReview => "Waiting for Character Review",
StoryIntelligencePipelineStages.SceneReview => "Needs Scene Review",
_ when StoryIntelligenceReadyForAssets(state) => "Waiting for Asset Review",
_ when StoryIntelligenceReadyForLocations(state) => "Waiting for Location Review",
_ => string.Equals(state.Status, StoryIntelligencePipelineStatuses.InProgress, StringComparison.OrdinalIgnoreCase)
? "Story Intelligence In Progress"
: "Story Intelligence Needs Review"
@ -282,11 +286,25 @@ public sealed class StoryIntelligenceService(
? "All currently available Story Intelligence stages are complete."
: state.CurrentReviewStage switch
{
StoryIntelligencePipelineStages.AssetReview => "Review detected assets and decide what to create or link.",
StoryIntelligencePipelineStages.LocationReview => "Review detected locations and decide what to create or link.",
StoryIntelligencePipelineStages.CharacterReview => "Review detected characters and decide what to create or link.",
StoryIntelligencePipelineStages.SceneReview => "Review prepared scenes before creating them.",
_ when StoryIntelligenceReadyForAssets(state) => "Review detected assets and decide what to create or link.",
_ when StoryIntelligenceReadyForLocations(state) => "Review detected locations and decide what to create or link.",
_ => "Continue from the next Story Intelligence stage."
};
private static bool StoryIntelligenceReadyForAssets(StoryIntelligenceBookPipelineState state)
=> string.Equals(state.LastCompletedStage, StoryIntelligencePipelineStages.LocationImport, StringComparison.OrdinalIgnoreCase)
|| state.CurrentStage is StoryIntelligencePipelineStages.AssetReview or StoryIntelligencePipelineStages.AssetImport
|| (string.Equals(state.CurrentStage, StoryIntelligencePipelineStages.Complete, StringComparison.OrdinalIgnoreCase)
&& !string.Equals(state.LastCompletedStage, StoryIntelligencePipelineStages.AssetImport, StringComparison.OrdinalIgnoreCase));
private static bool StoryIntelligenceReadyForLocations(StoryIntelligenceBookPipelineState state)
=> string.Equals(state.LastCompletedStage, StoryIntelligencePipelineStages.CharacterImport, StringComparison.OrdinalIgnoreCase)
|| state.CurrentStage is StoryIntelligencePipelineStages.LocationReview or StoryIntelligencePipelineStages.LocationImport;
private static string FormatElapsed(TimeSpan elapsed)
=> elapsed.TotalMinutes < 1
? $"{Math.Max(0, (int)elapsed.TotalSeconds)} sec"

View File

@ -200,9 +200,23 @@
return pipeline.CurrentReviewStage switch
{
StoryIntelligencePipelineStages.AssetReview => "Review detected assets and decide what to create or link.",
StoryIntelligencePipelineStages.LocationReview => "Review detected locations and decide what to create or link.",
StoryIntelligencePipelineStages.CharacterReview => "Scene creation is complete. Review detected characters to continue building the story database.",
StoryIntelligencePipelineStages.SceneReview => "Review prepared scenes before creating them in PlotDirector.",
_ when StoryIntelligenceReadyForAssets(pipeline) => "Review detected assets and decide what to create or link.",
_ when StoryIntelligenceReadyForLocations(pipeline) => "Review detected locations and decide what to create or link.",
_ => "PlotDirector will resume from the next Story Intelligence stage."
};
}
private static bool StoryIntelligenceReadyForAssets(StoryIntelligenceBookPipelineState pipeline)
=> string.Equals(pipeline.LastCompletedStage, StoryIntelligencePipelineStages.LocationImport, StringComparison.OrdinalIgnoreCase)
|| pipeline.CurrentStage is StoryIntelligencePipelineStages.AssetReview or StoryIntelligencePipelineStages.AssetImport
|| (string.Equals(pipeline.CurrentStage, StoryIntelligencePipelineStages.Complete, StringComparison.OrdinalIgnoreCase)
&& !string.Equals(pipeline.LastCompletedStage, StoryIntelligencePipelineStages.AssetImport, StringComparison.OrdinalIgnoreCase));
private static bool StoryIntelligenceReadyForLocations(StoryIntelligenceBookPipelineState pipeline)
=> string.Equals(pipeline.LastCompletedStage, StoryIntelligencePipelineStages.CharacterImport, StringComparison.OrdinalIgnoreCase)
|| pipeline.CurrentStage is StoryIntelligencePipelineStages.LocationReview or StoryIntelligencePipelineStages.LocationImport;
}