SET ANSI_NULLS ON; GO SET QUOTED_IDENTIFIER ON; GO CREATE OR ALTER PROCEDURE dbo.StoryIntelligenceBookPipeline_FindNextReadySceneAnalysis AS BEGIN SET NOCOUNT ON; ;WITH CandidatePipelines AS ( SELECT pipeline.StoryIntelligenceBookPipelineID, pipeline.ProjectID, pipeline.BookID, latest.UserID, latest.StoryIntelligenceRunID AS LastRunID, latest.CreatedUtc AS LastRunCreatedUtc, ( SELECT COUNT(1) FROM dbo.Scenes scene INNER JOIN dbo.Chapters chapter ON chapter.ChapterID = scene.ChapterID AND chapter.BookID = pipeline.BookID AND chapter.IsArchived = 0 WHERE scene.IsArchived = 0 ) AS TotalExpectedScenes FROM dbo.StoryIntelligenceBookPipelines pipeline CROSS APPLY ( SELECT TOP (1) run.StoryIntelligenceRunID, run.UserID, run.CreatedUtc FROM dbo.StoryIntelligenceRuns run WHERE run.BookID = pipeline.BookID AND run.ProjectID = pipeline.ProjectID ORDER BY run.CreatedUtc DESC, run.StoryIntelligenceRunID DESC ) latest WHERE pipeline.Status = N'InProgress' AND pipeline.CurrentStage = N'Chapters' ), CandidateRunCounts AS ( SELECT candidate.StoryIntelligenceBookPipelineID, candidate.ProjectID, candidate.BookID, candidate.UserID, candidate.LastRunID, candidate.TotalExpectedScenes, COUNT(run.StoryIntelligenceRunID) AS RunCount, SUM(ISNULL(run.CompletedScenes, 0)) AS CompletedScenes, SUM(ISNULL(run.FailedScenes, 0)) AS FailedScenes, SUM(CASE WHEN run.Status IN (N'Pending', N'Running') THEN 1 ELSE 0 END) AS ActiveRunCount, SUM(CASE WHEN run.Status IN (N'Failed', N'Cancelled') THEN 1 ELSE 0 END) AS FailedRunCount FROM CandidatePipelines candidate INNER JOIN dbo.StoryIntelligenceRuns run ON run.BookID = candidate.BookID AND run.ProjectID = candidate.ProjectID AND run.UserID = candidate.UserID AND run.CreatedUtc >= DATEADD(minute, -30, candidate.LastRunCreatedUtc) GROUP BY candidate.StoryIntelligenceBookPipelineID, candidate.ProjectID, candidate.BookID, candidate.UserID, candidate.LastRunID, candidate.TotalExpectedScenes ) SELECT TOP (1) StoryIntelligenceBookPipelineID, ProjectID, BookID, UserID, LastRunID, RunCount, TotalExpectedScenes, CompletedScenes, FailedScenes FROM CandidateRunCounts WHERE RunCount > 0 AND ActiveRunCount = 0 AND FailedRunCount = 0 AND TotalExpectedScenes > 0 AND CompletedScenes + FailedScenes >= TotalExpectedScenes ORDER BY StoryIntelligenceBookPipelineID; END; GO