IF OBJECT_ID(N'dbo.StoryIntelligenceNarrativeCandidateEvidence', N'U') IS NULL BEGIN CREATE TABLE dbo.StoryIntelligenceNarrativeCandidateEvidence ( NarrativeCandidateEvidenceID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_StoryIntelligenceNarrativeCandidateEvidence PRIMARY KEY, NarrativeCandidateID int NOT NULL, SceneID int NOT NULL, ContributionType nvarchar(40) NULL, Evidence nvarchar(1000) NULL, SortOrder int NOT NULL CONSTRAINT DF_StoryIntelligenceNarrativeCandidateEvidence_SortOrder DEFAULT 0, CreatedUtc datetime2 NOT NULL CONSTRAINT DF_StoryIntelligenceNarrativeCandidateEvidence_CreatedUtc DEFAULT SYSUTCDATETIME() ); END; IF OBJECT_ID(N'dbo.StoryIntelligenceNarrativeCandidates', N'U') IS NULL BEGIN CREATE TABLE dbo.StoryIntelligenceNarrativeCandidates ( NarrativeCandidateID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_StoryIntelligenceNarrativeCandidates PRIMARY KEY, ProjectID int NOT NULL, BookID int NOT NULL, CandidateType nvarchar(20) NOT NULL, CandidateKey nvarchar(220) NOT NULL, ProposedTitle nvarchar(200) NOT NULL, ProposedDescription nvarchar(1000) NULL, Category nvarchar(80) NULL, InferredState nvarchar(40) NULL, ExistingPlotLineID int NULL, ExistingPlotThreadID int NULL, RelatedPlotLineID int NULL, Confidence decimal(5,4) NULL, Status nvarchar(20) NOT NULL CONSTRAINT DF_StoryIntelligenceNarrativeCandidates_Status DEFAULT N'Pending', ReviewAction nvarchar(40) NULL, AcceptedPlotLineID int NULL, AcceptedPlotThreadID int NULL, ReviewedByUserID int NULL, ReviewedUtc datetime2 NULL, CreatedUtc datetime2 NOT NULL CONSTRAINT DF_StoryIntelligenceNarrativeCandidates_CreatedUtc DEFAULT SYSUTCDATETIME(), UpdatedUtc datetime2 NOT NULL CONSTRAINT DF_StoryIntelligenceNarrativeCandidates_UpdatedUtc DEFAULT SYSUTCDATETIME(), CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_Projects FOREIGN KEY (ProjectID) REFERENCES dbo.Projects(ProjectID), CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_Books FOREIGN KEY (BookID) REFERENCES dbo.Books(BookID), CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_ExistingPlotLines FOREIGN KEY (ExistingPlotLineID) REFERENCES dbo.PlotLines(PlotLineID), CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_RelatedPlotLines FOREIGN KEY (RelatedPlotLineID) REFERENCES dbo.PlotLines(PlotLineID), CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_AcceptedPlotLines FOREIGN KEY (AcceptedPlotLineID) REFERENCES dbo.PlotLines(PlotLineID), CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_ExistingPlotThreads FOREIGN KEY (ExistingPlotThreadID) REFERENCES dbo.PlotThreads(PlotThreadID), CONSTRAINT FK_StoryIntelligenceNarrativeCandidates_AcceptedPlotThreads FOREIGN KEY (AcceptedPlotThreadID) REFERENCES dbo.PlotThreads(PlotThreadID) ); END; IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_StoryIntelligenceNarrativeCandidateEvidence_Candidates') BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidateEvidence ADD CONSTRAINT FK_StoryIntelligenceNarrativeCandidateEvidence_Candidates FOREIGN KEY (NarrativeCandidateID) REFERENCES dbo.StoryIntelligenceNarrativeCandidates(NarrativeCandidateID) ON DELETE CASCADE; END; IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_StoryIntelligenceNarrativeCandidateEvidence_Scenes') BEGIN ALTER TABLE dbo.StoryIntelligenceNarrativeCandidateEvidence ADD CONSTRAINT FK_StoryIntelligenceNarrativeCandidateEvidence_Scenes FOREIGN KEY (SceneID) REFERENCES dbo.Scenes(SceneID); END; IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_StoryIntelligenceNarrativeCandidates_BookTypeKey' AND object_id = OBJECT_ID(N'dbo.StoryIntelligenceNarrativeCandidates')) CREATE UNIQUE INDEX UX_StoryIntelligenceNarrativeCandidates_BookTypeKey ON dbo.StoryIntelligenceNarrativeCandidates(BookID, CandidateType, CandidateKey); IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_StoryIntelligenceNarrativeCandidates_Status' AND object_id = OBJECT_ID(N'dbo.StoryIntelligenceNarrativeCandidates')) CREATE INDEX IX_StoryIntelligenceNarrativeCandidates_Status ON dbo.StoryIntelligenceNarrativeCandidates(BookID, Status, CandidateType); IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_StoryIntelligenceNarrativeCandidateEvidence_Candidate' AND object_id = OBJECT_ID(N'dbo.StoryIntelligenceNarrativeCandidateEvidence')) CREATE INDEX IX_StoryIntelligenceNarrativeCandidateEvidence_Candidate ON dbo.StoryIntelligenceNarrativeCandidateEvidence(NarrativeCandidateID, SceneID); 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, @ExistingPlotLineID int = NULL, @ExistingPlotThreadID int = NULL, @RelatedPlotLineID 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 @NarrativeCandidateID IS NULL BEGIN INSERT dbo.StoryIntelligenceNarrativeCandidates (ProjectID, BookID, CandidateType, CandidateKey, ProposedTitle, ProposedDescription, Category, InferredState, ExistingPlotLineID, ExistingPlotThreadID, RelatedPlotLineID, Confidence) VALUES (@ProjectID, @BookID, @CandidateType, @CandidateKey, @ProposedTitle, @ProposedDescription, @Category, @InferredState, @ExistingPlotLineID, @ExistingPlotThreadID, @RelatedPlotLineID, @Confidence); SET @NarrativeCandidateID = CAST(SCOPE_IDENTITY() AS int); END ELSE BEGIN UPDATE dbo.StoryIntelligenceNarrativeCandidates SET ProposedTitle = @ProposedTitle, ProposedDescription = @ProposedDescription, Category = @Category, InferredState = @InferredState, ExistingPlotLineID = @ExistingPlotLineID, ExistingPlotThreadID = @ExistingPlotThreadID, RelatedPlotLineID = @RelatedPlotLineID, Confidence = @Confidence, UpdatedUtc = SYSUTCDATETIME() WHERE NarrativeCandidateID = @NarrativeCandidateID AND Status = N'Pending'; END; SELECT @NarrativeCandidateID; END; GO CREATE OR ALTER PROCEDURE dbo.StoryIntelligenceNarrativeCandidateEvidence_Save @NarrativeCandidateID int, @SceneID int, @ContributionType nvarchar(40) = NULL, @Evidence nvarchar(1000) = NULL, @SortOrder int = 0 AS BEGIN SET NOCOUNT ON; IF NOT EXISTS ( SELECT 1 FROM dbo.StoryIntelligenceNarrativeCandidateEvidence WHERE NarrativeCandidateID = @NarrativeCandidateID AND SceneID = @SceneID AND ISNULL(Evidence, N'') = ISNULL(@Evidence, N'') ) BEGIN INSERT dbo.StoryIntelligenceNarrativeCandidateEvidence (NarrativeCandidateID, SceneID, ContributionType, Evidence, SortOrder) VALUES (@NarrativeCandidateID, @SceneID, @ContributionType, @Evidence, @SortOrder); END; 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.ExistingPlotLineID, epl.PlotLineName AS ExistingPlotLineName, nc.ExistingPlotThreadID, ept.ThreadTitle AS ExistingPlotThreadTitle, nc.RelatedPlotLineID, rpl.PlotLineName AS RelatedPlotLineName, 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.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, 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 AS BEGIN SET NOCOUNT ON; UPDATE dbo.StoryIntelligenceNarrativeCandidates SET Status = @Status, ReviewAction = @ReviewAction, ReviewedByUserID = @ReviewedByUserID, ReviewedUtc = SYSUTCDATETIME(), AcceptedPlotLineID = @AcceptedPlotLineID, AcceptedPlotThreadID = @AcceptedPlotThreadID, UpdatedUtc = SYSUTCDATETIME() WHERE NarrativeCandidateID = @NarrativeCandidateID; END; GO