IF COL_LENGTH(N'dbo.StoryIntelligenceNarrativeCandidates', N'ChangeType') IS NULL BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidates ADD ChangeType nvarchar(40) NULL; END; GO IF COL_LENGTH(N'dbo.StoryIntelligenceNarrativeCandidates', N'Significance') IS NULL BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidates ADD Significance nvarchar(20) NULL; END; GO IF COL_LENGTH(N'dbo.StoryIntelligenceNarrativeCandidates', N'ParentCandidateKey') IS NULL BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidates ADD ParentCandidateKey nvarchar(220) NULL; END; GO IF COL_LENGTH(N'dbo.StoryIntelligenceNarrativeCandidates', N'ParentNarrativeCandidateID') IS NULL BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidates ADD ParentNarrativeCandidateID int NULL; END; GO IF COL_LENGTH(N'dbo.StoryIntelligenceNarrativeCandidates', N'MergeTargetNarrativeCandidateID') IS NULL BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidates ADD MergeTargetNarrativeCandidateID int NULL; END; GO IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_StoryIntelligenceNarrativeCandidates_ParentCandidate') BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidates ADD CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_ParentCandidate FOREIGN KEY (ParentNarrativeCandidateID) REFERENCES dbo.StoryIntelligenceNarrativeCandidates(NarrativeCandidateID); END; GO IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_StoryIntelligenceNarrativeCandidates_MergeTarget') BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidates ADD CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_MergeTarget FOREIGN KEY (MergeTargetNarrativeCandidateID) REFERENCES dbo.StoryIntelligenceNarrativeCandidates(NarrativeCandidateID); END; GO IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_StoryIntelligenceNarrativeCandidates_Parent' AND object_id = OBJECT_ID(N'dbo.StoryIntelligenceNarrativeCandidates')) CREATE INDEX IX_StoryIntelligenceNarrativeCandidates_Parent ON dbo.StoryIntelligenceNarrativeCandidates(BookID, ParentNarrativeCandidateID, CandidateType); GO CREATE OR ALTER PROCEDURE dbo.StoryIntelligenceNarrativeCandidate_Save @ProjectID int, @BookID int, @CandidateType nvarchar(20), @CandidateKey nvarchar(220), @ProposedTitle nvarchar(200), @ProposedDescription nvarchar(1000) = NULL, @Category nvarchar(80) = NULL, @InferredState nvarchar(40) = NULL, @ChangeType nvarchar(40) = NULL, @Significance nvarchar(20) = NULL, @ExistingPlotLineID int = NULL, @ExistingPlotThreadID int = NULL, @RelatedPlotLineID int = NULL, @ParentCandidateKey nvarchar(220) = NULL, @ParentNarrativeCandidateID int = NULL, @Confidence decimal(5,4) = NULL AS BEGIN SET NOCOUNT ON; DECLARE @NarrativeCandidateID int; SELECT @NarrativeCandidateID = NarrativeCandidateID FROM dbo.StoryIntelligenceNarrativeCandidates WHERE BookID = @BookID AND CandidateType = @CandidateType AND CandidateKey = @CandidateKey; IF @ParentNarrativeCandidateID IS NULL AND @ParentCandidateKey IS NOT NULL BEGIN SELECT @ParentNarrativeCandidateID = NarrativeCandidateID FROM dbo.StoryIntelligenceNarrativeCandidates WHERE BookID = @BookID AND CandidateType = N'PlotLine' AND CandidateKey = @ParentCandidateKey; END; IF @NarrativeCandidateID IS NULL BEGIN INSERT dbo.StoryIntelligenceNarrativeCandidates (ProjectID, BookID, CandidateType, CandidateKey, ProposedTitle, ProposedDescription, Category, InferredState, ChangeType, Significance, ExistingPlotLineID, ExistingPlotThreadID, RelatedPlotLineID, ParentCandidateKey, ParentNarrativeCandidateID, Confidence) VALUES (@ProjectID, @BookID, @CandidateType, @CandidateKey, @ProposedTitle, @ProposedDescription, @Category, @InferredState, @ChangeType, @Significance, @ExistingPlotLineID, @ExistingPlotThreadID, @RelatedPlotLineID, @ParentCandidateKey, @ParentNarrativeCandidateID, @Confidence); SET @NarrativeCandidateID = CAST(SCOPE_IDENTITY() AS int); END ELSE BEGIN UPDATE dbo.StoryIntelligenceNarrativeCandidates SET ProposedTitle = @ProposedTitle, ProposedDescription = @ProposedDescription, Category = @Category, InferredState = @InferredState, ChangeType = @ChangeType, Significance = @Significance, ExistingPlotLineID = @ExistingPlotLineID, ExistingPlotThreadID = @ExistingPlotThreadID, RelatedPlotLineID = @RelatedPlotLineID, ParentCandidateKey = @ParentCandidateKey, ParentNarrativeCandidateID = @ParentNarrativeCandidateID, Confidence = @Confidence, UpdatedUtc = SYSUTCDATETIME() WHERE NarrativeCandidateID = @NarrativeCandidateID AND Status = N'Pending'; END; SELECT @NarrativeCandidateID; END; GO CREATE OR ALTER PROCEDURE dbo.StoryIntelligenceNarrativeCandidate_ListByBook @BookID int AS BEGIN SET NOCOUNT ON; SELECT nc.NarrativeCandidateID, nc.ProjectID, nc.BookID, nc.CandidateType, nc.CandidateKey, nc.ProposedTitle, nc.ProposedDescription, nc.Category, nc.InferredState, nc.ChangeType, nc.Significance, nc.ExistingPlotLineID, epl.PlotLineName AS ExistingPlotLineName, nc.ExistingPlotThreadID, ept.ThreadTitle AS ExistingPlotThreadTitle, nc.RelatedPlotLineID, rpl.PlotLineName AS RelatedPlotLineName, nc.ParentCandidateKey, nc.ParentNarrativeCandidateID, parent.ProposedTitle AS ParentCandidateTitle, nc.MergeTargetNarrativeCandidateID, nc.Confidence, nc.Status, nc.ReviewAction, nc.AcceptedPlotLineID, apl.PlotLineName AS AcceptedPlotLineName, nc.AcceptedPlotThreadID, apt.ThreadTitle AS AcceptedPlotThreadTitle, nc.ReviewedByUserID, nc.ReviewedUtc, nc.CreatedUtc, nc.UpdatedUtc FROM dbo.StoryIntelligenceNarrativeCandidates nc LEFT JOIN dbo.PlotLines epl ON epl.PlotLineID = nc.ExistingPlotLineID LEFT JOIN dbo.PlotThreads ept ON ept.PlotThreadID = nc.ExistingPlotThreadID LEFT JOIN dbo.PlotLines rpl ON rpl.PlotLineID = nc.RelatedPlotLineID LEFT JOIN dbo.StoryIntelligenceNarrativeCandidates parent ON parent.NarrativeCandidateID = nc.ParentNarrativeCandidateID LEFT JOIN dbo.PlotLines apl ON apl.PlotLineID = nc.AcceptedPlotLineID LEFT JOIN dbo.PlotThreads apt ON apt.PlotThreadID = nc.AcceptedPlotThreadID WHERE nc.BookID = @BookID ORDER BY CASE nc.Status WHEN N'Pending' THEN 0 ELSE 1 END, CASE nc.CandidateType WHEN N'PlotLine' THEN 0 ELSE 1 END, COALESCE(parent.ProposedTitle, nc.ProposedTitle), nc.CandidateType, nc.ProposedTitle; SELECT e.NarrativeCandidateEvidenceID, e.NarrativeCandidateID, e.SceneID, s.SceneNumber, s.SceneTitle, c.ChapterNumber, c.ChapterTitle, e.ContributionType, e.Evidence, e.SortOrder, e.CreatedUtc FROM dbo.StoryIntelligenceNarrativeCandidateEvidence e INNER JOIN dbo.StoryIntelligenceNarrativeCandidates nc ON nc.NarrativeCandidateID = e.NarrativeCandidateID INNER JOIN dbo.Scenes s ON s.SceneID = e.SceneID INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID WHERE nc.BookID = @BookID ORDER BY e.NarrativeCandidateID, c.SortOrder, s.SortOrder, e.SortOrder; END; GO CREATE OR ALTER PROCEDURE dbo.StoryIntelligenceNarrativeCandidate_MarkReviewed @NarrativeCandidateID int, @Status nvarchar(20), @ReviewAction nvarchar(40), @ReviewedByUserID int, @AcceptedPlotLineID int = NULL, @AcceptedPlotThreadID int = NULL, @MergeTargetNarrativeCandidateID int = NULL AS BEGIN SET NOCOUNT ON; UPDATE dbo.StoryIntelligenceNarrativeCandidates SET Status = @Status, ReviewAction = @ReviewAction, ReviewedByUserID = @ReviewedByUserID, ReviewedUtc = SYSUTCDATETIME(), AcceptedPlotLineID = @AcceptedPlotLineID, AcceptedPlotThreadID = @AcceptedPlotThreadID, MergeTargetNarrativeCandidateID = @MergeTargetNarrativeCandidateID, UpdatedUtc = SYSUTCDATETIME() WHERE NarrativeCandidateID = @NarrativeCandidateID; END; GO