PlotDirector/PlotLine/Sql/002_Phase1B_WorkspaceMetrics.sql
2026-06-01 09:03:59 +01:00

259 lines
11 KiB
Transact-SQL

SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF OBJECT_ID(N'dbo.SceneMetricTypes', N'U') IS NULL
BEGIN
CREATE TABLE dbo.SceneMetricTypes
(
MetricTypeID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SceneMetricTypes PRIMARY KEY,
ProjectID int NULL,
MetricName nvarchar(100) NOT NULL,
Description nvarchar(500) NULL,
MinValue int NOT NULL CONSTRAINT DF_SceneMetricTypes_MinValue DEFAULT 1,
MaxValue int NOT NULL CONSTRAINT DF_SceneMetricTypes_MaxValue DEFAULT 10,
DefaultValue int NOT NULL CONSTRAINT DF_SceneMetricTypes_DefaultValue DEFAULT 5,
SortOrder int NOT NULL,
IsActive bit NOT NULL CONSTRAINT DF_SceneMetricTypes_IsActive DEFAULT 1,
CONSTRAINT FK_SceneMetricTypes_Projects FOREIGN KEY (ProjectID) REFERENCES dbo.Projects(ProjectID),
CONSTRAINT CK_SceneMetricTypes_Range CHECK (MinValue < MaxValue AND DefaultValue BETWEEN MinValue AND MaxValue)
);
END;
GO
IF OBJECT_ID(N'dbo.SceneMetricValues', N'U') IS NULL
BEGIN
CREATE TABLE dbo.SceneMetricValues
(
SceneID int NOT NULL,
MetricTypeID int NOT NULL,
Value int NOT NULL,
Notes nvarchar(500) NULL,
CONSTRAINT PK_SceneMetricValues PRIMARY KEY (SceneID, MetricTypeID),
CONSTRAINT FK_SceneMetricValues_Scenes FOREIGN KEY (SceneID) REFERENCES dbo.Scenes(SceneID),
CONSTRAINT FK_SceneMetricValues_SceneMetricTypes FOREIGN KEY (MetricTypeID) REFERENCES dbo.SceneMetricTypes(MetricTypeID),
CONSTRAINT CK_SceneMetricValues_Value CHECK (Value BETWEEN 1 AND 10)
);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneMetricTypes_ProjectID_SortOrder' AND object_id = OBJECT_ID(N'dbo.SceneMetricTypes'))
CREATE INDEX IX_SceneMetricTypes_ProjectID_SortOrder ON dbo.SceneMetricTypes(ProjectID, IsActive, SortOrder);
GO
MERGE dbo.SceneMetricTypes AS target
USING (VALUES
(N'Overall Intensity', N'General dramatic intensity for the scene.', 1, 10, 5, 10),
(N'Tension', N'Pressure, suspense, uncertainty, or conflict.', 1, 10, 5, 20),
(N'Emotional Weight', N'Emotional load carried by the scene.', 1, 10, 5, 30),
(N'Action', N'Physical action, movement, or event energy.', 1, 10, 3, 40),
(N'Darkness', N'Darkness, bleakness, fear, or threat.', 1, 10, 3, 50),
(N'Romance', N'Romantic focus or intimacy.', 1, 10, 1, 60),
(N'Sexual Charge', N'Sexual tension or sensual charge.', 1, 10, 1, 70),
(N'Violence', N'Violent action, injury, or threat.', 1, 10, 1, 80),
(N'Hope / Lightness', N'Hope, relief, warmth, or tonal lightness.', 1, 10, 4, 90),
(N'Comedy', N'Humour or comic relief.', 1, 10, 1, 100),
(N'Mystery', N'Questions, clue energy, and mystery pressure.', 1, 10, 5, 110)
) AS source (MetricName, Description, MinValue, MaxValue, DefaultValue, SortOrder)
ON target.ProjectID IS NULL AND target.MetricName = source.MetricName
WHEN NOT MATCHED THEN
INSERT (ProjectID, MetricName, Description, MinValue, MaxValue, DefaultValue, SortOrder, IsActive)
VALUES (NULL, source.MetricName, source.Description, source.MinValue, source.MaxValue, source.DefaultValue, source.SortOrder, 1);
GO
CREATE OR ALTER PROCEDURE dbo.SceneMetricType_List
@ProjectID int = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT MetricTypeID, ProjectID, MetricName, Description, MinValue, MaxValue, DefaultValue, SortOrder, IsActive
FROM dbo.SceneMetricTypes
WHERE IsActive = 1 AND (ProjectID IS NULL OR ProjectID = @ProjectID)
ORDER BY SortOrder, MetricName;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneMetric_EnsureDefaults
@SceneID int
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ProjectID int;
SELECT @ProjectID = b.ProjectID
FROM dbo.Scenes s
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
INNER JOIN dbo.Books b ON b.BookID = c.BookID
WHERE s.SceneID = @SceneID;
INSERT dbo.SceneMetricValues (SceneID, MetricTypeID, Value, Notes)
SELECT @SceneID, mt.MetricTypeID, mt.DefaultValue, NULL
FROM dbo.SceneMetricTypes mt
WHERE mt.IsActive = 1
AND (mt.ProjectID IS NULL OR mt.ProjectID = @ProjectID)
AND NOT EXISTS
(
SELECT 1
FROM dbo.SceneMetricValues smv
WHERE smv.SceneID = @SceneID AND smv.MetricTypeID = mt.MetricTypeID
);
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneMetric_ListByScene
@SceneID int
AS
BEGIN
SET NOCOUNT ON;
EXEC dbo.SceneMetric_EnsureDefaults @SceneID = @SceneID;
SELECT mt.MetricTypeID, mt.ProjectID, mt.MetricName, mt.Description, mt.MinValue, mt.MaxValue,
mt.DefaultValue, mt.SortOrder, mt.IsActive, smv.SceneID, smv.Value, smv.Notes
FROM dbo.SceneMetricTypes mt
INNER JOIN dbo.SceneMetricValues smv ON smv.MetricTypeID = mt.MetricTypeID AND smv.SceneID = @SceneID
WHERE mt.IsActive = 1
ORDER BY mt.SortOrder, mt.MetricName;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneMetric_SaveValue
@SceneID int,
@MetricTypeID int,
@Value int,
@Notes nvarchar(500) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @MinValue int;
DECLARE @MaxValue int;
SELECT @MinValue = MinValue, @MaxValue = MaxValue
FROM dbo.SceneMetricTypes
WHERE MetricTypeID = @MetricTypeID AND IsActive = 1;
IF @MinValue IS NULL
THROW 50001, 'Metric type does not exist.', 1;
IF @Value < @MinValue OR @Value > @MaxValue
THROW 50002, 'Metric value is outside the configured range.', 1;
MERGE dbo.SceneMetricValues AS target
USING (SELECT @SceneID AS SceneID, @MetricTypeID AS MetricTypeID) AS source
ON target.SceneID = source.SceneID AND target.MetricTypeID = source.MetricTypeID
WHEN MATCHED THEN
UPDATE SET Value = @Value, Notes = @Notes
WHEN NOT MATCHED THEN
INSERT (SceneID, MetricTypeID, Value, Notes)
VALUES (@SceneID, @MetricTypeID, @Value, @Notes);
END;
GO
CREATE OR ALTER PROCEDURE dbo.Scene_Get
@SceneID int
AS
BEGIN
SET NOCOUNT ON;
EXEC dbo.SceneMetric_EnsureDefaults @SceneID = @SceneID;
SELECT s.SceneID, s.ChapterID, s.SceneNumber, s.SceneTitle, s.Summary, s.POVCharacterID,
s.PrimaryLocationID, s.SortOrder, s.TimeModeID, tm.TimeModeName, s.StartDateTime,
s.EndDateTime, s.DurationAmount, s.DurationUnitID, du.DurationUnitName, s.RelativeTimeText,
s.TimeConfidenceID, tc.TimeConfidenceName, s.ScenePurposeNotes, s.SceneOutcomeNotes,
s.RevisionStatusID, rs.StatusName AS RevisionStatusName, s.CreatedDate, s.UpdatedDate, s.IsArchived
FROM dbo.Scenes s
INNER JOIN dbo.TimeModes tm ON tm.TimeModeID = s.TimeModeID
LEFT JOIN dbo.DurationUnits du ON du.DurationUnitID = s.DurationUnitID
INNER JOIN dbo.TimeConfidences tc ON tc.TimeConfidenceID = s.TimeConfidenceID
INNER JOIN dbo.RevisionStatuses rs ON rs.RevisionStatusID = s.RevisionStatusID
WHERE s.SceneID = @SceneID AND s.IsArchived = 0;
SELECT sp.ScenePurposeTypeID
FROM dbo.ScenePurposes sp
WHERE sp.SceneID = @SceneID;
SELECT mt.MetricTypeID, mt.ProjectID, mt.MetricName, mt.Description, mt.MinValue, mt.MaxValue,
mt.DefaultValue, mt.SortOrder, mt.IsActive, smv.SceneID, smv.Value, smv.Notes
FROM dbo.SceneMetricTypes mt
INNER JOIN dbo.SceneMetricValues smv ON smv.MetricTypeID = mt.MetricTypeID AND smv.SceneID = @SceneID
WHERE mt.IsActive = 1
ORDER BY mt.SortOrder, mt.MetricName;
END;
GO
CREATE OR ALTER PROCEDURE dbo.Timeline_GetByProject
@ProjectID int,
@BookID int = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT ProjectID, ProjectName, Description, CreatedDate, UpdatedDate, IsArchived
FROM dbo.Projects
WHERE ProjectID = @ProjectID AND IsArchived = 0;
SELECT BookID, ProjectID, BookTitle, BookNumber, Description, SortOrder, CreatedDate, UpdatedDate, IsArchived
FROM dbo.Books
WHERE ProjectID = @ProjectID AND IsArchived = 0 AND (@BookID IS NULL OR BookID = @BookID)
ORDER BY SortOrder, BookNumber;
SELECT c.ChapterID, c.BookID, c.ChapterNumber, c.ChapterTitle, c.POVCharacterID, c.Summary,
c.SortOrder, c.RevisionStatusID, rs.StatusName AS RevisionStatusName,
c.CreatedDate, c.UpdatedDate, c.IsArchived
FROM dbo.Chapters c
INNER JOIN dbo.Books b ON b.BookID = c.BookID
INNER JOIN dbo.RevisionStatuses rs ON rs.RevisionStatusID = c.RevisionStatusID
WHERE b.ProjectID = @ProjectID AND b.IsArchived = 0 AND c.IsArchived = 0 AND (@BookID IS NULL OR b.BookID = @BookID)
ORDER BY b.SortOrder, c.SortOrder, c.ChapterNumber;
SELECT s.SceneID, s.ChapterID, s.SceneNumber, s.SceneTitle, s.Summary, s.POVCharacterID,
s.PrimaryLocationID, s.SortOrder, s.TimeModeID, tm.TimeModeName, s.StartDateTime,
s.EndDateTime, s.DurationAmount, s.DurationUnitID, du.DurationUnitName, s.RelativeTimeText,
s.TimeConfidenceID, tc.TimeConfidenceName, s.ScenePurposeNotes, s.SceneOutcomeNotes,
s.RevisionStatusID, rs.StatusName AS RevisionStatusName, s.CreatedDate, s.UpdatedDate, s.IsArchived
FROM dbo.Scenes s
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
INNER JOIN dbo.Books b ON b.BookID = c.BookID
INNER JOIN dbo.TimeModes tm ON tm.TimeModeID = s.TimeModeID
LEFT JOIN dbo.DurationUnits du ON du.DurationUnitID = s.DurationUnitID
INNER JOIN dbo.TimeConfidences tc ON tc.TimeConfidenceID = s.TimeConfidenceID
INNER JOIN dbo.RevisionStatuses rs ON rs.RevisionStatusID = s.RevisionStatusID
WHERE b.ProjectID = @ProjectID AND b.IsArchived = 0 AND c.IsArchived = 0 AND s.IsArchived = 0 AND (@BookID IS NULL OR b.BookID = @BookID)
ORDER BY b.SortOrder, c.SortOrder, s.SortOrder, s.SceneNumber;
SELECT sp.SceneID, spt.ScenePurposeTypeID, spt.PurposeName, spt.SortOrder
FROM dbo.ScenePurposes sp
INNER JOIN dbo.ScenePurposeTypes spt ON spt.ScenePurposeTypeID = sp.ScenePurposeTypeID
INNER JOIN dbo.Scenes s ON s.SceneID = sp.SceneID
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
INNER JOIN dbo.Books b ON b.BookID = c.BookID
WHERE b.ProjectID = @ProjectID AND b.IsArchived = 0 AND c.IsArchived = 0 AND s.IsArchived = 0 AND (@BookID IS NULL OR b.BookID = @BookID)
ORDER BY sp.SceneID, spt.SortOrder;
SELECT MetricTypeID, ProjectID, MetricName, Description, MinValue, MaxValue, DefaultValue, SortOrder, IsActive
FROM dbo.SceneMetricTypes
WHERE IsActive = 1 AND (ProjectID IS NULL OR ProjectID = @ProjectID)
ORDER BY SortOrder, MetricName;
SELECT s.SceneID, mt.MetricTypeID, mt.MetricName, COALESCE(smv.Value, mt.DefaultValue) AS Value, smv.Notes
FROM dbo.Scenes s
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
INNER JOIN dbo.Books b ON b.BookID = c.BookID
CROSS JOIN dbo.SceneMetricTypes mt
LEFT JOIN dbo.SceneMetricValues smv ON smv.SceneID = s.SceneID AND smv.MetricTypeID = mt.MetricTypeID
WHERE b.ProjectID = @ProjectID
AND b.IsArchived = 0
AND c.IsArchived = 0
AND s.IsArchived = 0
AND mt.IsActive = 1
AND (mt.ProjectID IS NULL OR mt.ProjectID = @ProjectID)
AND (@BookID IS NULL OR b.BookID = @BookID)
ORDER BY b.SortOrder, c.SortOrder, s.SortOrder, mt.SortOrder;
END;
GO