Phase 20Z2 – Final Blocker Fix: Story Intelligence Commit Failures + Archived Project Delete
This commit is contained in:
parent
11841f5674
commit
aefa9aaadc
@ -404,6 +404,7 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
|
|
||||||
var scenesCreated = 0;
|
var scenesCreated = 0;
|
||||||
var metricsCreated = 0;
|
var metricsCreated = 0;
|
||||||
|
var commitWarnings = new List<string>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var alreadyCommitted = await connection.QuerySingleAsync<bool>(
|
var alreadyCommitted = await connection.QuerySingleAsync<bool>(
|
||||||
@ -440,10 +441,23 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
for (var index = 0; index < orderedScenes.Count; index++)
|
for (var index = 0; index < orderedScenes.Count; index++)
|
||||||
{
|
{
|
||||||
var item = orderedScenes[index];
|
var item = orderedScenes[index];
|
||||||
|
var operation = "preparing scene";
|
||||||
var replacePlaceholder = readiness.HasUntouchedDefaultPlaceholder
|
var replacePlaceholder = readiness.HasUntouchedDefaultPlaceholder
|
||||||
&& readiness.PlaceholderSceneID.HasValue
|
&& readiness.PlaceholderSceneID.HasValue
|
||||||
&& index == 0;
|
&& index == 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
operation = "saving scene";
|
||||||
|
var relativeTimeText = TrimOptionalText(
|
||||||
|
item.ParsedScene.Setting?.DateOrTimeReference ?? item.ParsedScene.Setting?.TimeOfDay,
|
||||||
|
200,
|
||||||
|
$"Scene {item.TemporarySceneNumber:N0} relative time",
|
||||||
|
commitWarnings);
|
||||||
|
|
||||||
|
var sceneTitle = TrimOptionalText(item.SceneTitle, 200, $"Scene {item.TemporarySceneNumber:N0} title", commitWarnings)
|
||||||
|
?? $"Scene {item.TemporarySceneNumber:N0}";
|
||||||
|
|
||||||
var sceneId = await connection.QuerySingleAsync<int>(
|
var sceneId = await connection.QuerySingleAsync<int>(
|
||||||
"dbo.Scene_Save",
|
"dbo.Scene_Save",
|
||||||
new
|
new
|
||||||
@ -451,14 +465,14 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
SceneID = replacePlaceholder ? readiness.PlaceholderSceneID : null,
|
SceneID = replacePlaceholder ? readiness.PlaceholderSceneID : null,
|
||||||
ChapterID = request.ChapterID,
|
ChapterID = request.ChapterID,
|
||||||
SceneNumber = Convert.ToDecimal(item.TemporarySceneNumber),
|
SceneNumber = Convert.ToDecimal(item.TemporarySceneNumber),
|
||||||
SceneTitle = item.SceneTitle,
|
SceneTitle = sceneTitle,
|
||||||
Summary = item.Summary,
|
Summary = item.Summary,
|
||||||
TimeModeID = request.TimeModeID,
|
TimeModeID = request.TimeModeID,
|
||||||
StartDateTime = (DateTime?)null,
|
StartDateTime = (DateTime?)null,
|
||||||
EndDateTime = (DateTime?)null,
|
EndDateTime = (DateTime?)null,
|
||||||
DurationAmount = (decimal?)null,
|
DurationAmount = (decimal?)null,
|
||||||
DurationUnitID = (int?)null,
|
DurationUnitID = (int?)null,
|
||||||
RelativeTimeText = item.ParsedScene.Setting?.DateOrTimeReference ?? item.ParsedScene.Setting?.TimeOfDay,
|
RelativeTimeText = relativeTimeText,
|
||||||
TimeConfidenceID = request.TimeConfidenceID,
|
TimeConfidenceID = request.TimeConfidenceID,
|
||||||
ScenePurposeNotes = item.PurposeNotes,
|
ScenePurposeNotes = item.PurposeNotes,
|
||||||
SceneOutcomeNotes = item.OutcomeNotes,
|
SceneOutcomeNotes = item.OutcomeNotes,
|
||||||
@ -470,6 +484,7 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
transaction,
|
transaction,
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
|
operation = "saving source tracking";
|
||||||
await connection.ExecuteAsync(
|
await connection.ExecuteAsync(
|
||||||
"dbo.StoryIntelligenceSceneSource_Save",
|
"dbo.StoryIntelligenceSceneSource_Save",
|
||||||
new
|
new
|
||||||
@ -485,35 +500,66 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
|
|
||||||
if (item.PovCharacterID.HasValue)
|
if (item.PovCharacterID.HasValue)
|
||||||
{
|
{
|
||||||
await connection.ExecuteAsync(
|
operation = "linking POV character";
|
||||||
|
await TryOptionalSceneOperationAsync(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
item.TemporarySceneNumber,
|
||||||
|
operation,
|
||||||
|
commitWarnings,
|
||||||
|
() => connection.ExecuteAsync(
|
||||||
"dbo.Scene_UpdatePovCharacter",
|
"dbo.Scene_UpdatePovCharacter",
|
||||||
new { SceneID = sceneId, POVCharacterID = item.PovCharacterID },
|
new { SceneID = sceneId, POVCharacterID = item.PovCharacterID },
|
||||||
transaction,
|
transaction,
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.PurposeTypeIDs.Count > 0)
|
if (item.PurposeTypeIDs.Count > 0)
|
||||||
{
|
{
|
||||||
await connection.ExecuteAsync(
|
operation = "linking purpose labels";
|
||||||
|
await TryOptionalSceneOperationAsync(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
item.TemporarySceneNumber,
|
||||||
|
operation,
|
||||||
|
commitWarnings,
|
||||||
|
() => connection.ExecuteAsync(
|
||||||
"dbo.Scene_SavePurposes",
|
"dbo.Scene_SavePurposes",
|
||||||
new { SceneID = sceneId, PurposeIds = string.Join(',', item.PurposeTypeIDs.Distinct()) },
|
new { SceneID = sceneId, PurposeIds = string.Join(',', item.PurposeTypeIDs.Distinct()) },
|
||||||
transaction,
|
transaction,
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var metric in item.Metrics)
|
foreach (var metric in item.Metrics)
|
||||||
{
|
{
|
||||||
await connection.ExecuteAsync(
|
operation = $"saving metric '{metric.MetricName}'";
|
||||||
|
var saved = await TryOptionalSceneOperationAsync(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
item.TemporarySceneNumber,
|
||||||
|
operation,
|
||||||
|
commitWarnings,
|
||||||
|
() => connection.ExecuteAsync(
|
||||||
"dbo.SceneMetric_SaveValue",
|
"dbo.SceneMetric_SaveValue",
|
||||||
new { SceneID = sceneId, metric.MetricTypeID, metric.Value, metric.Notes },
|
new { SceneID = sceneId, metric.MetricTypeID, metric.Value, metric.Notes },
|
||||||
transaction,
|
transaction,
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure));
|
||||||
|
if (saved)
|
||||||
|
{
|
||||||
metricsCreated++;
|
metricsCreated++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (request.TimelineNoteTypeID.HasValue && !string.IsNullOrWhiteSpace(item.ImportNoteText))
|
if (request.TimelineNoteTypeID.HasValue && !string.IsNullOrWhiteSpace(item.ImportNoteText))
|
||||||
{
|
{
|
||||||
await connection.ExecuteAsync(
|
operation = "saving import note";
|
||||||
|
await TryOptionalSceneOperationAsync(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
item.TemporarySceneNumber,
|
||||||
|
operation,
|
||||||
|
commitWarnings,
|
||||||
|
() => connection.ExecuteAsync(
|
||||||
"dbo.SceneNote_Save",
|
"dbo.SceneNote_Save",
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
@ -527,17 +573,25 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
IsResolved = false
|
IsResolved = false
|
||||||
},
|
},
|
||||||
transaction,
|
transaction,
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure));
|
||||||
}
|
}
|
||||||
|
|
||||||
scenesCreated++;
|
scenesCreated++;
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
$"Scene {item.TemporarySceneNumber:N0} failed during {operation}: {ex.Message}",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var notes = new List<string>();
|
var notes = new List<string>();
|
||||||
notes.Add(readiness.HasUntouchedDefaultPlaceholder
|
notes.Add(readiness.HasUntouchedDefaultPlaceholder
|
||||||
? "Replaced untouched default placeholder scene."
|
? "Replaced untouched default placeholder scene."
|
||||||
: "Committed into empty chapter.");
|
: "Committed into empty chapter.");
|
||||||
notes.AddRange(request.Warnings.Where(warning => !string.IsNullOrWhiteSpace(warning)));
|
notes.AddRange(request.Warnings.Where(warning => !string.IsNullOrWhiteSpace(warning)));
|
||||||
|
notes.AddRange(commitWarnings.Where(warning => !string.IsNullOrWhiteSpace(warning)));
|
||||||
|
|
||||||
var commitId = await connection.QuerySingleAsync<int>(
|
var commitId = await connection.QuerySingleAsync<int>(
|
||||||
"dbo.StoryIntelligenceImportCommit_RecordCompleted",
|
"dbo.StoryIntelligenceImportCommit_RecordCompleted",
|
||||||
@ -568,7 +622,7 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
transaction.Rollback();
|
transaction.Rollback();
|
||||||
await RecordFailedCommitAsync(request, scenesCreated, metricsCreated, ex);
|
await RecordFailedCommitAsync(request, 0, 0, ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -591,4 +645,41 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
},
|
},
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<bool> TryOptionalSceneOperationAsync(
|
||||||
|
IDbConnection connection,
|
||||||
|
IDbTransaction transaction,
|
||||||
|
int sceneNumber,
|
||||||
|
string operation,
|
||||||
|
ICollection<string> warnings,
|
||||||
|
Func<Task<int>> action)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await action();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
warnings.Add($"Scene {sceneNumber:N0}: skipped optional {operation} because the database rejected it: {ex.Message}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? TrimOptionalText(string? value, int maxLength, string label, ICollection<string> warnings)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var trimmed = value.Trim();
|
||||||
|
if (trimmed.Length <= maxLength)
|
||||||
|
{
|
||||||
|
return trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
warnings.Add($"{label} was truncated to {maxLength:N0} characters for the database field limit.");
|
||||||
|
return trimmed[..maxLength].TrimEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,416 @@
|
|||||||
|
SET ANSI_NULLS ON;
|
||||||
|
GO
|
||||||
|
SET QUOTED_IDENTIFIER ON;
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.ProjectHardDelete_ForOwner
|
||||||
|
@ProjectID int,
|
||||||
|
@UserID int
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
SET XACT_ABORT ON;
|
||||||
|
|
||||||
|
IF NOT EXISTS
|
||||||
|
(
|
||||||
|
SELECT 1
|
||||||
|
FROM dbo.Projects p
|
||||||
|
INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID
|
||||||
|
WHERE p.ProjectID = @ProjectID
|
||||||
|
AND pua.UserID = @UserID
|
||||||
|
AND pua.AccessRole = N'Owner'
|
||||||
|
AND pua.IsActive = 1
|
||||||
|
)
|
||||||
|
THROW 52001, 'Project was not found for this owner.', 1;
|
||||||
|
|
||||||
|
IF EXISTS (SELECT 1 FROM dbo.Projects WHERE ProjectID = @ProjectID AND IsArchived = 0)
|
||||||
|
THROW 52002, 'Only archived projects can be permanently deleted.', 1;
|
||||||
|
|
||||||
|
BEGIN TRY
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
DECLARE @BookIDs TABLE (BookID int NOT NULL PRIMARY KEY);
|
||||||
|
DECLARE @ChapterIDs TABLE (ChapterID int NOT NULL PRIMARY KEY);
|
||||||
|
DECLARE @SceneIDs TABLE (SceneID int NOT NULL PRIMARY KEY);
|
||||||
|
DECLARE @StoryIntelligenceRunIDs TABLE (StoryIntelligenceRunID int NOT NULL PRIMARY KEY);
|
||||||
|
DECLARE @StoryIntelligenceChapterResultIDs TABLE (ChapterResultID int NOT NULL PRIMARY KEY);
|
||||||
|
|
||||||
|
INSERT @BookIDs (BookID)
|
||||||
|
SELECT BookID FROM dbo.Books WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
INSERT @ChapterIDs (ChapterID)
|
||||||
|
SELECT c.ChapterID
|
||||||
|
FROM dbo.Chapters c
|
||||||
|
INNER JOIN @BookIDs b ON b.BookID = c.BookID;
|
||||||
|
|
||||||
|
INSERT @SceneIDs (SceneID)
|
||||||
|
SELECT s.SceneID
|
||||||
|
FROM dbo.Scenes s
|
||||||
|
INNER JOIN @ChapterIDs c ON c.ChapterID = s.ChapterID;
|
||||||
|
|
||||||
|
INSERT @StoryIntelligenceRunIDs (StoryIntelligenceRunID)
|
||||||
|
SELECT DISTINCT r.StoryIntelligenceRunID
|
||||||
|
FROM dbo.StoryIntelligenceRuns r
|
||||||
|
WHERE r.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = r.BookID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @ChapterIDs c WHERE c.ChapterID = r.ChapterID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @SceneIDs s INNER JOIN dbo.Scenes scene ON scene.SceneID = s.SceneID WHERE scene.ImportRunID = r.StoryIntelligenceRunID);
|
||||||
|
|
||||||
|
INSERT @StoryIntelligenceChapterResultIDs (ChapterResultID)
|
||||||
|
SELECT DISTINCT cr.ChapterResultID
|
||||||
|
FROM dbo.StoryIntelligenceChapterResults cr
|
||||||
|
WHERE cr.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @StoryIntelligenceRunIDs r WHERE r.StoryIntelligenceRunID = cr.StoryIntelligenceRunID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = cr.BookID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @ChapterIDs c WHERE c.ChapterID = cr.ChapterID);
|
||||||
|
|
||||||
|
DELETE sr
|
||||||
|
FROM dbo.StoryIntelligenceSceneResults sr
|
||||||
|
WHERE sr.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @StoryIntelligenceRunIDs r WHERE r.StoryIntelligenceRunID = sr.StoryIntelligenceRunID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @StoryIntelligenceChapterResultIDs cr WHERE cr.ChapterResultID = sr.ChapterResultID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = sr.BookID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @ChapterIDs c WHERE c.ChapterID = sr.ChapterID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @SceneIDs s WHERE s.SceneID = sr.SceneID);
|
||||||
|
|
||||||
|
DELETE cr
|
||||||
|
FROM dbo.StoryIntelligenceChapterResults cr
|
||||||
|
WHERE cr.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @StoryIntelligenceRunIDs r WHERE r.StoryIntelligenceRunID = cr.StoryIntelligenceRunID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @StoryIntelligenceChapterResultIDs result WHERE result.ChapterResultID = cr.ChapterResultID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = cr.BookID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @ChapterIDs c WHERE c.ChapterID = cr.ChapterID);
|
||||||
|
|
||||||
|
DELETE commitRows
|
||||||
|
FROM dbo.StoryIntelligenceImportCommits commitRows
|
||||||
|
WHERE commitRows.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @StoryIntelligenceRunIDs r WHERE r.StoryIntelligenceRunID = commitRows.StoryIntelligenceRunID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = commitRows.BookID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @ChapterIDs c WHERE c.ChapterID = commitRows.ChapterID);
|
||||||
|
|
||||||
|
UPDATE scene
|
||||||
|
SET ImportRunID = NULL
|
||||||
|
FROM dbo.Scenes scene
|
||||||
|
INNER JOIN @SceneIDs s ON s.SceneID = scene.SceneID
|
||||||
|
WHERE scene.ImportRunID IS NOT NULL;
|
||||||
|
|
||||||
|
DELETE r
|
||||||
|
FROM dbo.StoryIntelligenceRuns r
|
||||||
|
WHERE EXISTS (SELECT 1 FROM @StoryIntelligenceRunIDs runIDs WHERE runIDs.StoryIntelligenceRunID = r.StoryIntelligenceRunID);
|
||||||
|
|
||||||
|
DELETE job
|
||||||
|
FROM dbo.StoryIntelligenceJobs job
|
||||||
|
LEFT JOIN dbo.StoryIntelligenceConsents consent ON consent.StoryIntelligenceConsentID = job.StoryIntelligenceConsentID
|
||||||
|
WHERE job.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = job.BookID)
|
||||||
|
OR consent.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = consent.BookID);
|
||||||
|
|
||||||
|
DELETE consent
|
||||||
|
FROM dbo.StoryIntelligenceConsents consent
|
||||||
|
WHERE consent.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = consent.BookID);
|
||||||
|
|
||||||
|
DELETE FROM dbo.ProjectActivity WHERE ProjectID = @ProjectID;
|
||||||
|
DELETE prh
|
||||||
|
FROM dbo.ProjectRestoreHistory prh
|
||||||
|
LEFT JOIN dbo.ProjectRestorePoints sourcePoint ON sourcePoint.ProjectRestorePointID = prh.SourceRestorePointID
|
||||||
|
LEFT JOIN dbo.ProjectRestorePoints safetyPoint ON safetyPoint.ProjectRestorePointID = prh.SafetyRestorePointID
|
||||||
|
WHERE prh.ProjectID = @ProjectID
|
||||||
|
OR sourcePoint.ProjectID = @ProjectID
|
||||||
|
OR safetyPoint.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.ProjectRestorePoints WHERE ProjectID = @ProjectID;
|
||||||
|
DELETE FROM dbo.ProjectInvitation WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE uf
|
||||||
|
FROM dbo.UserFile uf
|
||||||
|
WHERE uf.ProjectID = @ProjectID
|
||||||
|
OR EXISTS
|
||||||
|
(
|
||||||
|
SELECT 1
|
||||||
|
FROM dbo.SceneAttachments sa
|
||||||
|
INNER JOIN @SceneIDs s ON s.SceneID = sa.SceneID
|
||||||
|
WHERE sa.FilePath = uf.StoragePath
|
||||||
|
);
|
||||||
|
|
||||||
|
DELETE wsi
|
||||||
|
FROM dbo.WritingScheduleItems wsi
|
||||||
|
INNER JOIN dbo.WritingPlans wp ON wp.WritingPlanID = wsi.WritingPlanID
|
||||||
|
WHERE wp.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE wsi
|
||||||
|
FROM dbo.WritingScheduleItems wsi
|
||||||
|
INNER JOIN @SceneIDs s ON s.SceneID = wsi.SceneID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.WritingPlans WHERE ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = dbo.WritingPlans.BookID);
|
||||||
|
|
||||||
|
UPDATE dbo.UserOnboardingState
|
||||||
|
SET ProjectID = NULL,
|
||||||
|
BookID = NULL
|
||||||
|
WHERE ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = dbo.UserOnboardingState.BookID);
|
||||||
|
|
||||||
|
DELETE ombsm FROM dbo.OnboardingManuscriptBuildSceneMap ombsm INNER JOIN @SceneIDs scene ON scene.SceneID = ombsm.SceneID;
|
||||||
|
DELETE ombcm FROM dbo.OnboardingManuscriptBuildChapterMap ombcm INNER JOIN @ChapterIDs chapter ON chapter.ChapterID = ombcm.ChapterID;
|
||||||
|
DELETE ombcm
|
||||||
|
FROM dbo.OnboardingManuscriptBuildChapterMap ombcm
|
||||||
|
INNER JOIN dbo.OnboardingManuscriptBuilds build ON build.OnboardingManuscriptBuildID = ombcm.OnboardingManuscriptBuildID
|
||||||
|
WHERE build.ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = build.BookID);
|
||||||
|
DELETE ombsm
|
||||||
|
FROM dbo.OnboardingManuscriptBuildSceneMap ombsm
|
||||||
|
INNER JOIN dbo.OnboardingManuscriptBuilds build ON build.OnboardingManuscriptBuildID = ombsm.OnboardingManuscriptBuildID
|
||||||
|
WHERE build.ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = build.BookID);
|
||||||
|
DELETE ombcharm
|
||||||
|
FROM dbo.OnboardingManuscriptBuildCharacterMap ombcharm
|
||||||
|
INNER JOIN dbo.OnboardingManuscriptBuilds build ON build.OnboardingManuscriptBuildID = ombcharm.OnboardingManuscriptBuildID
|
||||||
|
WHERE build.ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = build.BookID);
|
||||||
|
DELETE FROM dbo.OnboardingManuscriptBuilds WHERE ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = dbo.OnboardingManuscriptBuilds.BookID);
|
||||||
|
|
||||||
|
DELETE sw
|
||||||
|
FROM dbo.ScenarioWarnings sw
|
||||||
|
INNER JOIN dbo.Scenarios sc ON sc.ScenarioID = sw.ScenarioID
|
||||||
|
WHERE sc.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE svr
|
||||||
|
FROM dbo.ScenarioValidationRuns svr
|
||||||
|
INNER JOIN dbo.Scenarios sc ON sc.ScenarioID = svr.ScenarioID
|
||||||
|
WHERE sc.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE sso
|
||||||
|
FROM dbo.ScenarioSceneOrder sso
|
||||||
|
INNER JOIN dbo.Scenarios sc ON sc.ScenarioID = sso.ScenarioID
|
||||||
|
WHERE sc.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE sso
|
||||||
|
FROM dbo.ScenarioSceneOrder sso
|
||||||
|
WHERE EXISTS (SELECT 1 FROM @SceneIDs scene WHERE scene.SceneID = sso.SceneID)
|
||||||
|
OR EXISTS (SELECT 1 FROM @ChapterIDs chapter WHERE chapter.ChapterID = sso.ProposedChapterID);
|
||||||
|
|
||||||
|
DELETE FROM dbo.Scenarios WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE cwa
|
||||||
|
FROM dbo.ContinuityWarningAcknowledgements cwa
|
||||||
|
WHERE cwa.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @SceneIDs scene WHERE scene.SceneID = cwa.SceneID);
|
||||||
|
|
||||||
|
DELETE FROM dbo.ContinuityWarnings WHERE ProjectID = @ProjectID;
|
||||||
|
DELETE FROM dbo.ValidationRuns WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE sfpo FROM dbo.SceneFloorPlanOccupancy sfpo INNER JOIN @SceneIDs s ON s.SceneID = sfpo.SceneID;
|
||||||
|
DELETE sa FROM dbo.SceneAttachments sa INNER JOIN @SceneIDs s ON s.SceneID = sa.SceneID;
|
||||||
|
DELETE sci FROM dbo.SceneChecklistItems sci INNER JOIN @SceneIDs s ON s.SceneID = sci.SceneID;
|
||||||
|
DELETE sw FROM dbo.SceneWorkflow sw INNER JOIN @SceneIDs s ON s.SceneID = sw.SceneID;
|
||||||
|
DELETE sn FROM dbo.SceneNotes sn INNER JOIN @SceneIDs s ON s.SceneID = sn.SceneID;
|
||||||
|
DELETE cg FROM dbo.ChapterGoals cg INNER JOIN @ChapterIDs c ON c.ChapterID = cg.ChapterID;
|
||||||
|
|
||||||
|
DELETE sd
|
||||||
|
FROM dbo.SceneDependencies sd
|
||||||
|
LEFT JOIN @SceneIDs ss ON ss.SceneID = sd.SourceSceneID
|
||||||
|
LEFT JOIN @SceneIDs ts ON ts.SceneID = sd.TargetSceneID
|
||||||
|
WHERE sd.ProjectID = @ProjectID
|
||||||
|
OR ss.SceneID IS NOT NULL
|
||||||
|
OR ts.SceneID IS NOT NULL;
|
||||||
|
|
||||||
|
DELETE re
|
||||||
|
FROM dbo.RelationshipEvents re
|
||||||
|
INNER JOIN dbo.CharacterRelationships cr ON cr.CharacterRelationshipID = re.CharacterRelationshipID
|
||||||
|
WHERE cr.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE re FROM dbo.RelationshipEvents re INNER JOIN @SceneIDs scene ON scene.SceneID = re.SceneID;
|
||||||
|
DELETE FROM dbo.CharacterRelationships WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE ck
|
||||||
|
FROM dbo.CharacterKnowledge ck
|
||||||
|
LEFT JOIN dbo.Characters ch ON ch.CharacterID = ck.CharacterID
|
||||||
|
LEFT JOIN @SceneIDs scene ON scene.SceneID = ck.SceneID
|
||||||
|
LEFT JOIN dbo.StoryAssets sa ON sa.StoryAssetID = ck.StoryAssetID
|
||||||
|
LEFT JOIN dbo.PlotThreads pt ON pt.PlotThreadID = ck.PlotThreadID
|
||||||
|
LEFT JOIN dbo.PlotLines pl ON pl.PlotLineID = pt.PlotLineID
|
||||||
|
WHERE ch.ProjectID = @ProjectID
|
||||||
|
OR scene.SceneID IS NOT NULL
|
||||||
|
OR sa.ProjectID = @ProjectID
|
||||||
|
OR pl.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE cae
|
||||||
|
FROM dbo.CharacterAttributeEvents cae
|
||||||
|
LEFT JOIN dbo.Characters ch ON ch.CharacterID = cae.CharacterID
|
||||||
|
LEFT JOIN @SceneIDs scene ON scene.SceneID = cae.SceneID
|
||||||
|
WHERE ch.ProjectID = @ProjectID
|
||||||
|
OR scene.SceneID IS NOT NULL;
|
||||||
|
|
||||||
|
DELETE sc
|
||||||
|
FROM dbo.SceneCharacters sc
|
||||||
|
LEFT JOIN dbo.Characters ch ON ch.CharacterID = sc.CharacterID
|
||||||
|
LEFT JOIN @SceneIDs scene ON scene.SceneID = sc.SceneID
|
||||||
|
WHERE ch.ProjectID = @ProjectID
|
||||||
|
OR scene.SceneID IS NOT NULL;
|
||||||
|
|
||||||
|
DELETE acec
|
||||||
|
FROM dbo.AssetCustodyEventCharacters acec
|
||||||
|
INNER JOIN dbo.AssetCustodyEvents ace ON ace.AssetCustodyEventID = acec.AssetCustodyEventID
|
||||||
|
INNER JOIN dbo.StoryAssets sa ON sa.StoryAssetID = ace.StoryAssetID
|
||||||
|
WHERE sa.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE acec
|
||||||
|
FROM dbo.AssetCustodyEventCharacters acec
|
||||||
|
INNER JOIN dbo.AssetCustodyEvents ace ON ace.AssetCustodyEventID = acec.AssetCustodyEventID
|
||||||
|
INNER JOIN @SceneIDs scene ON scene.SceneID = ace.SceneID;
|
||||||
|
|
||||||
|
DELETE ace
|
||||||
|
FROM dbo.AssetCustodyEvents ace
|
||||||
|
LEFT JOIN dbo.StoryAssets sa ON sa.StoryAssetID = ace.StoryAssetID
|
||||||
|
LEFT JOIN @SceneIDs scene ON scene.SceneID = ace.SceneID
|
||||||
|
WHERE sa.ProjectID = @ProjectID
|
||||||
|
OR scene.SceneID IS NOT NULL;
|
||||||
|
|
||||||
|
DELETE ad
|
||||||
|
FROM dbo.AssetDependencies ad
|
||||||
|
INNER JOIN dbo.StoryAssets sourceAsset ON sourceAsset.StoryAssetID = ad.SourceAssetID
|
||||||
|
INNER JOIN dbo.StoryAssets targetAsset ON targetAsset.StoryAssetID = ad.TargetAssetID
|
||||||
|
WHERE sourceAsset.ProjectID = @ProjectID
|
||||||
|
OR targetAsset.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE ae
|
||||||
|
FROM dbo.AssetEvents ae
|
||||||
|
LEFT JOIN dbo.StoryAssets sa ON sa.StoryAssetID = ae.StoryAssetID
|
||||||
|
LEFT JOIN @SceneIDs scene ON scene.SceneID = ae.SceneID
|
||||||
|
WHERE sa.ProjectID = @ProjectID
|
||||||
|
OR scene.SceneID IS NOT NULL;
|
||||||
|
|
||||||
|
DELETE sal
|
||||||
|
FROM dbo.SceneAssetLocations sal
|
||||||
|
LEFT JOIN dbo.StoryAssets sa ON sa.StoryAssetID = sal.StoryAssetID
|
||||||
|
LEFT JOIN @SceneIDs scene ON scene.SceneID = sal.SceneID
|
||||||
|
WHERE sa.ProjectID = @ProjectID
|
||||||
|
OR scene.SceneID IS NOT NULL;
|
||||||
|
|
||||||
|
DELETE petpl
|
||||||
|
FROM dbo.PlotEventTargetPlotLines petpl
|
||||||
|
LEFT JOIN dbo.ThreadEvents te ON te.ThreadEventID = petpl.PlotEventID
|
||||||
|
LEFT JOIN dbo.PlotThreads pt ON pt.PlotThreadID = te.PlotThreadID
|
||||||
|
LEFT JOIN dbo.PlotLines eventPlotLine ON eventPlotLine.PlotLineID = pt.PlotLineID
|
||||||
|
LEFT JOIN dbo.PlotLines targetPlotLine ON targetPlotLine.PlotLineID = petpl.PlotLineID
|
||||||
|
WHERE eventPlotLine.ProjectID = @ProjectID
|
||||||
|
OR targetPlotLine.ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @SceneIDs scene WHERE scene.SceneID = te.SceneID);
|
||||||
|
|
||||||
|
DELETE te
|
||||||
|
FROM dbo.ThreadEvents te
|
||||||
|
LEFT JOIN dbo.PlotThreads pt ON pt.PlotThreadID = te.PlotThreadID
|
||||||
|
LEFT JOIN dbo.PlotLines pl ON pl.PlotLineID = pt.PlotLineID
|
||||||
|
LEFT JOIN dbo.PlotLines target ON target.PlotLineID = te.TargetPlotLineID
|
||||||
|
LEFT JOIN @SceneIDs scene ON scene.SceneID = te.SceneID
|
||||||
|
WHERE pl.ProjectID = @ProjectID
|
||||||
|
OR target.ProjectID = @ProjectID
|
||||||
|
OR scene.SceneID IS NOT NULL;
|
||||||
|
|
||||||
|
DELETE pt
|
||||||
|
FROM dbo.PlotThreads pt
|
||||||
|
INNER JOIN dbo.PlotLines pl ON pl.PlotLineID = pt.PlotLineID
|
||||||
|
WHERE pl.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
UPDATE dbo.PlotLines
|
||||||
|
SET ParentPlotLineID = NULL,
|
||||||
|
EmergesFromPlotLineID = NULL
|
||||||
|
WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.PlotLines WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.TimelineViewPresets WHERE ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = dbo.TimelineViewPresets.BookID);
|
||||||
|
DELETE FROM dbo.ProjectTimelineMetricSettings WHERE ProjectID = @ProjectID;
|
||||||
|
DELETE FROM dbo.ProjectTimelineSettings WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE smv FROM dbo.SceneMetricValues smv INNER JOIN @SceneIDs s ON s.SceneID = smv.SceneID;
|
||||||
|
DELETE sp FROM dbo.ScenePurposes sp INNER JOIN @SceneIDs s ON s.SceneID = sp.SceneID;
|
||||||
|
DELETE so FROM dbo.SceneOutcomes so INNER JOIN @SceneIDs s ON s.SceneID = so.SceneID;
|
||||||
|
|
||||||
|
UPDATE dbo.Characters
|
||||||
|
SET AgeReferenceSceneID = NULL
|
||||||
|
WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
UPDATE s
|
||||||
|
SET PrimaryLocationID = NULL,
|
||||||
|
FloorPlanID = NULL,
|
||||||
|
InitialFloorPlanFloorID = NULL,
|
||||||
|
ManuscriptDocumentID = NULL
|
||||||
|
FROM dbo.Scenes s
|
||||||
|
INNER JOIN @SceneIDs scene ON scene.SceneID = s.SceneID;
|
||||||
|
|
||||||
|
UPDATE c
|
||||||
|
SET ManuscriptDocumentID = NULL
|
||||||
|
FROM dbo.Chapters c
|
||||||
|
INNER JOIN @ChapterIDs chapter ON chapter.ChapterID = c.ChapterID;
|
||||||
|
|
||||||
|
UPDATE dbo.StoryAssets
|
||||||
|
SET CurrentLocationID = NULL
|
||||||
|
WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE fpt
|
||||||
|
FROM dbo.FloorPlanTransitions fpt
|
||||||
|
INNER JOIN dbo.FloorPlanFloors fpf ON fpf.FloorPlanFloorID = fpt.FloorPlanFloorID
|
||||||
|
INNER JOIN dbo.FloorPlans fp ON fp.FloorPlanID = fpf.FloorPlanID
|
||||||
|
WHERE fp.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE fpb
|
||||||
|
FROM dbo.FloorPlanBlocks fpb
|
||||||
|
INNER JOIN dbo.FloorPlanFloors fpf ON fpf.FloorPlanFloorID = fpb.FloorPlanFloorID
|
||||||
|
INNER JOIN dbo.FloorPlans fp ON fp.FloorPlanID = fpf.FloorPlanID
|
||||||
|
WHERE fp.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE fpf
|
||||||
|
FROM dbo.FloorPlanFloors fpf
|
||||||
|
INNER JOIN dbo.FloorPlans fp ON fp.FloorPlanID = fpf.FloorPlanID
|
||||||
|
WHERE fp.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.FloorPlans WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.StoryAssets WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
UPDATE dbo.Locations
|
||||||
|
SET ParentLocationID = NULL
|
||||||
|
WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE lr
|
||||||
|
FROM dbo.LocationRelationships lr
|
||||||
|
INNER JOIN dbo.Locations fromLocation ON fromLocation.LocationID = lr.FromLocationID
|
||||||
|
INNER JOIN dbo.Locations toLocation ON toLocation.LocationID = lr.ToLocationID
|
||||||
|
WHERE fromLocation.ProjectID = @ProjectID
|
||||||
|
OR toLocation.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.Locations WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE s FROM dbo.Scenes s INNER JOIN @SceneIDs scene ON scene.SceneID = s.SceneID;
|
||||||
|
DELETE c FROM dbo.Chapters c INNER JOIN @ChapterIDs chapter ON chapter.ChapterID = c.ChapterID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.ManuscriptDocuments
|
||||||
|
WHERE ProjectID = @ProjectID
|
||||||
|
OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = dbo.ManuscriptDocuments.BookID);
|
||||||
|
|
||||||
|
DELETE FROM dbo.Books WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.CharacterImages WHERE ProjectID = @ProjectID;
|
||||||
|
DELETE FROM dbo.Characters WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE gpmm
|
||||||
|
FROM dbo.GenreMetricPresetMetrics gpmm
|
||||||
|
INNER JOIN dbo.SceneMetricTypes mt ON mt.MetricTypeID = gpmm.MetricTypeID
|
||||||
|
WHERE mt.ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.SceneMetricTypes WHERE ProjectID = @ProjectID;
|
||||||
|
DELETE FROM dbo.CharacterAttributeTypes WHERE ProjectID = @ProjectID;
|
||||||
|
DELETE FROM dbo.AssetStates WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.ProjectUserAccess WHERE ProjectID = @ProjectID;
|
||||||
|
DELETE FROM dbo.Projects WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
COMMIT TRANSACTION;
|
||||||
|
END TRY
|
||||||
|
BEGIN CATCH
|
||||||
|
IF @@TRANCOUNT > 0
|
||||||
|
ROLLBACK TRANSACTION;
|
||||||
|
|
||||||
|
THROW;
|
||||||
|
END CATCH
|
||||||
|
END;
|
||||||
|
GO
|
||||||
Loading…
x
Reference in New Issue
Block a user