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