Fix Story Intelligence knowledge recovery transition

This commit is contained in:
Nick Beckley 2026-08-25 15:38:48 +00:00
parent 1b8b2a984a
commit c8148245c9
3 changed files with 57 additions and 3 deletions

View File

@ -2643,11 +2643,15 @@ static void StoryIntelligenceNarrativeStageFollowsKnowledge()
var onboarding = File.ReadAllText(Path.Combine(root, "Services/OnboardingStoryIntelligenceService.cs"));
var controller = File.ReadAllText(Path.Combine(root, "Controllers/OnboardingController.cs"));
var knowledgeComplete = File.ReadAllText(Path.Combine(root, "Views/Onboarding/StoryIntelligenceKnowledgeComplete.cshtml"));
var pipelineConstraint = File.ReadAllText(Path.Combine(root, "Sql/156_Phase25A_NarrativeReviewPipelineConstraint.sql"));
var knowledgeImport = File.ReadAllText(Path.Combine(root, "Services/StoryIntelligenceKnowledgeImportService.cs"));
Assert(stages.Contains("NarrativeReview", StringComparison.Ordinal) && stages.Contains("NarrativeImport", StringComparison.Ordinal), "Pipeline stages should include narrative review/import.");
Assert(stages.Contains("LastCompletedStage, StoryIntelligencePipelineStages.NarrativeImport", StringComparison.Ordinal), "Pipeline completion should require narrative import.");
Assert(pipeline.Contains("CurrentStage = StoryIntelligencePipelineStages.NarrativeReview", StringComparison.Ordinal), "Knowledge import should lead to narrative review.");
Assert(pipeline.Contains("RecordNarrativeImportAsync", StringComparison.Ordinal), "Narrative import should mark the pipeline complete.");
Assert(pipelineConstraint.Contains("N'NarrativeReview'", StringComparison.Ordinal) && pipelineConstraint.Contains("N'NarrativeImport'", StringComparison.Ordinal), "Database pipeline constraint should allow narrative stages.");
Assert(knowledgeImport.Contains("hasUndecidedCandidates", StringComparison.Ordinal), "Knowledge review should be able to advance when prior decisions already imported every candidate.");
Assert(onboarding.Contains("StoryIntelligenceResumeRoutes.Narrative", StringComparison.Ordinal), "Resume logic should route to narrative review.");
Assert(controller.Contains("StoryIntelligenceNarrative", StringComparison.Ordinal), "Onboarding controller should expose the narrative review stage.");
Assert(knowledgeComplete.Contains("Review Plot Lines & Threads", StringComparison.Ordinal), "Knowledge completion should lead to narrative review.");

View File

@ -79,15 +79,23 @@ public sealed class StoryIntelligenceKnowledgeImportService(
SaveKnowledgeSelections(batch, choices.Values);
if (choices.Count == 0)
{
if (data.Candidates.Count == 0)
var decidedKeys = batch.KnowledgeDecisions.Select(decision => decision.Key).ToHashSet(StringComparer.OrdinalIgnoreCase);
var hasUndecidedCandidates = data.Candidates.Any(candidate => !decidedKeys.Contains(candidate.Key));
if (!hasUndecidedCandidates)
{
batch.KnowledgeStageComplete = true;
batch.LastKnowledgeImportResult = new StoryIntelligenceKnowledgeImportBatchResult();
batch.LastKnowledgeImportResult ??= new StoryIntelligenceKnowledgeImportBatchResult
{
KnowledgeCreated = batch.KnowledgeDecisions.Count(decision => string.Equals(decision.Action, StoryIntelligenceKnowledgeImportActions.CreateNew, StringComparison.OrdinalIgnoreCase)),
KnowledgeLinked = batch.KnowledgeDecisions.Count(decision => string.Equals(decision.Action, StoryIntelligenceKnowledgeImportActions.LinkExisting, StringComparison.OrdinalIgnoreCase)),
KnowledgeMerged = batch.KnowledgeDecisions.Count(decision => string.Equals(decision.Action, StoryIntelligenceKnowledgeImportActions.Alias, StringComparison.OrdinalIgnoreCase)),
KnowledgeIgnored = batch.KnowledgeDecisions.Count(decision => string.Equals(decision.Action, StoryIntelligenceKnowledgeImportActions.Ignore, StringComparison.OrdinalIgnoreCase))
};
await pipelineState.RecordKnowledgeImportAsync(batch.ProjectID, batch.BookID);
return new StoryIntelligenceImportCommitResult
{
Success = true,
Message = "Knowledge review completed. No knowledge decisions were waiting."
Message = "Knowledge review completed. No knowledge decisions are waiting."
};
}

View File

@ -0,0 +1,42 @@
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF OBJECT_ID(N'dbo.StoryIntelligenceBookPipelines', N'U') IS NOT NULL
BEGIN
IF EXISTS
(
SELECT 1
FROM sys.check_constraints
WHERE name = N'CK_StoryIntelligenceBookPipelines_CurrentStage'
AND parent_object_id = OBJECT_ID(N'dbo.StoryIntelligenceBookPipelines')
)
BEGIN
ALTER TABLE dbo.StoryIntelligenceBookPipelines
DROP CONSTRAINT CK_StoryIntelligenceBookPipelines_CurrentStage;
END;
ALTER TABLE dbo.StoryIntelligenceBookPipelines
ADD CONSTRAINT CK_StoryIntelligenceBookPipelines_CurrentStage
CHECK (CurrentStage IN
(
N'Chapters',
N'SceneReview',
N'SceneImport',
N'CharacterReview',
N'CharacterImport',
N'LocationReview',
N'LocationImport',
N'AssetReview',
N'AssetImport',
N'RelationshipReview',
N'RelationshipImport',
N'KnowledgeReview',
N'KnowledgeImport',
N'NarrativeReview',
N'NarrativeImport',
N'Complete'
));
END;
GO