PlotDirector/PlotLine/Data/ProjectBackupRepository.cs
2026-06-05 21:14:53 +01:00

134 lines
7.1 KiB
C#

using System.Data;
using Dapper;
using PlotLine.Models;
namespace PlotLine.Data;
public interface IProjectBackupRepository
{
Task<ProjectBackupExport?> GetProjectBackupAsync(int projectId);
}
public sealed class ProjectBackupRepository(ISqlConnectionFactory connectionFactory) : IProjectBackupRepository
{
public async Task<ProjectBackupExport?> GetProjectBackupAsync(int projectId)
{
using var connection = connectionFactory.CreateConnection();
using var result = await connection.QueryMultipleAsync(
"dbo.ProjectBackup_Export",
new { ProjectID = projectId },
commandType: CommandType.StoredProcedure);
var project = await result.ReadSingleOrDefaultAsync<Project>();
var data = new ProjectBackupData
{
Books = (await result.ReadAsync<Book>()).ToList(),
Chapters = (await result.ReadAsync<Chapter>()).ToList(),
Scenes = (await result.ReadAsync<Scene>()).ToList(),
ScenePurposes = (await result.ReadAsync<ProjectBackupScenePurpose>()).ToList(),
SceneOutcomes = (await result.ReadAsync<ProjectBackupSceneOutcome>()).ToList(),
SceneMetricTypes = (await result.ReadAsync<SceneMetricType>()).ToList(),
SceneMetricValues = (await result.ReadAsync<SceneMetricValue>()).ToList(),
TimelineSettings = (await result.ReadAsync<ProjectTimelineSettings>()).ToList(),
TimelineMetricSettings = (await result.ReadAsync<ProjectTimelineMetricSetting>()).ToList(),
TimelineViewPresets = (await result.ReadAsync<TimelineViewPreset>()).ToList(),
PlotLines = (await result.ReadAsync<PlotLineItem>()).ToList(),
PlotThreads = (await result.ReadAsync<PlotThread>()).ToList(),
ThreadEvents = (await result.ReadAsync<ThreadEvent>()).ToList(),
StoryAssets = (await result.ReadAsync<StoryAsset>()).ToList(),
AssetStates = (await result.ReadAsync<AssetState>()).ToList(),
AssetEvents = (await result.ReadAsync<AssetEvent>()).ToList(),
AssetDependencies = (await result.ReadAsync<AssetDependency>()).ToList(),
AssetCustodyEvents = (await result.ReadAsync<AssetCustodyEvent>()).ToList(),
AssetCustodyCharacters = (await result.ReadAsync<ProjectBackupAssetCustodyCharacter>()).ToList(),
Characters = (await result.ReadAsync<Character>()).ToList(),
SceneCharacters = (await result.ReadAsync<SceneCharacter>()).ToList(),
CharacterAttributeTypes = (await result.ReadAsync<CharacterAttributeType>()).ToList(),
CharacterAttributeEvents = (await result.ReadAsync<CharacterAttributeEvent>()).ToList(),
CharacterKnowledge = (await result.ReadAsync<CharacterKnowledgeItem>()).ToList(),
CharacterRelationships = (await result.ReadAsync<CharacterRelationship>()).ToList(),
RelationshipEvents = (await result.ReadAsync<RelationshipEvent>()).ToList(),
Locations = (await result.ReadAsync<LocationItem>()).ToList(),
LocationRelationships = (await result.ReadAsync<LocationRelationship>()).ToList(),
SceneAssetLocations = (await result.ReadAsync<SceneAssetLocation>()).ToList(),
SceneDependencies = (await result.ReadAsync<SceneDependency>()).ToList(),
ValidationRuns = (await result.ReadAsync<ProjectBackupValidationRun>()).ToList(),
ContinuityWarnings = (await result.ReadAsync<ContinuityWarning>()).ToList(),
SceneNotes = (await result.ReadAsync<SceneNote>()).ToList(),
SceneWorkflow = (await result.ReadAsync<SceneWorkflow>()).ToList(),
SceneChecklistItems = (await result.ReadAsync<SceneChecklistItem>()).ToList(),
SceneAttachments = (await result.ReadAsync<SceneAttachment>()).ToList(),
ChapterGoals = (await result.ReadAsync<ChapterGoal>()).ToList(),
Scenarios = (await result.ReadAsync<Scenario>()).ToList(),
ScenarioSceneOrder = (await result.ReadAsync<ProjectBackupScenarioSceneOrder>()).ToList(),
ScenarioValidationRuns = (await result.ReadAsync<ProjectBackupScenarioValidationRun>()).ToList(),
ScenarioWarnings = (await result.ReadAsync<ScenarioWarning>()).ToList(),
GenreMetricPresets = (await result.ReadAsync<GenreMetricPreset>()).ToList(),
GenreMetricPresetMetrics = (await result.ReadAsync<ProjectBackupGenreMetricPresetMetric>()).ToList()
};
if (project is null)
{
return null;
}
return new ProjectBackupExport
{
ExportedAtUtc = DateTime.UtcNow,
Project = project,
Data = data,
Diagnostics = new ProjectBackupDiagnostics
{
ProjectId = projectId,
IncludedEntitySets =
[
nameof(data.Books),
nameof(data.Chapters),
nameof(data.Scenes),
nameof(data.ScenePurposes),
nameof(data.SceneOutcomes),
nameof(data.SceneMetricTypes),
nameof(data.SceneMetricValues),
nameof(data.TimelineSettings),
nameof(data.TimelineMetricSettings),
nameof(data.TimelineViewPresets),
nameof(data.PlotLines),
nameof(data.PlotThreads),
nameof(data.ThreadEvents),
nameof(data.StoryAssets),
nameof(data.AssetStates),
nameof(data.AssetEvents),
nameof(data.AssetDependencies),
nameof(data.AssetCustodyEvents),
nameof(data.AssetCustodyCharacters),
nameof(data.Characters),
nameof(data.SceneCharacters),
nameof(data.CharacterAttributeTypes),
nameof(data.CharacterAttributeEvents),
nameof(data.CharacterKnowledge),
nameof(data.CharacterRelationships),
nameof(data.RelationshipEvents),
nameof(data.Locations),
nameof(data.LocationRelationships),
nameof(data.SceneAssetLocations),
nameof(data.SceneDependencies),
nameof(data.ValidationRuns),
nameof(data.ContinuityWarnings),
nameof(data.SceneNotes),
nameof(data.SceneWorkflow),
nameof(data.SceneChecklistItems),
nameof(data.SceneAttachments),
nameof(data.ChapterGoals),
nameof(data.Scenarios),
nameof(data.ScenarioSceneOrder),
nameof(data.ScenarioValidationRuns),
nameof(data.ScenarioWarnings),
nameof(data.GenreMetricPresets),
nameof(data.GenreMetricPresetMetrics)
],
Note = "Original database IDs are included for diagnostics. Future import/restore should map by logical project structure and names where practical."
}
};
}
}