159 lines
6.7 KiB
C#
159 lines
6.7 KiB
C#
using PlotLine.Data;
|
|
using PlotLine.Models;
|
|
|
|
namespace PlotLine.Services;
|
|
|
|
public interface IStoryIntelligencePipelineStateService
|
|
{
|
|
Task<StoryIntelligenceBookPipelineState?> GetForBookAsync(int bookId, int userId);
|
|
Task<IReadOnlyList<StoryIntelligenceBookPipelineState>> ListForUserAsync(int userId);
|
|
Task<StoryIntelligenceBookPipelineState?> EnsureForBookAsync(int bookId, int userId);
|
|
Task RecordSceneImportAsync(int projectId, int bookId, int runId);
|
|
Task RecordCharacterImportAsync(int projectId, int bookId);
|
|
Task RecordLocationImportAsync(int projectId, int bookId);
|
|
Task RecordAssetImportAsync(int projectId, int bookId);
|
|
Task RecordRelationshipImportAsync(int projectId, int bookId);
|
|
Task RecordKnowledgeImportAsync(int projectId, int bookId);
|
|
Task<IReadOnlyList<StoryIntelligenceCommittedRunSummary>> ListCommittedRunsByBookAsync(int bookId, int userId);
|
|
}
|
|
|
|
public sealed class StoryIntelligencePipelineStateService(
|
|
IStoryIntelligencePipelineRepository pipelines,
|
|
ILogger<StoryIntelligencePipelineStateService> logger) : IStoryIntelligencePipelineStateService
|
|
{
|
|
public async Task<StoryIntelligenceBookPipelineState?> GetForBookAsync(int bookId, int userId)
|
|
=> await pipelines.GetByBookForUserAsync(bookId, userId)
|
|
?? await EnsureForBookAsync(bookId, userId);
|
|
|
|
public Task<IReadOnlyList<StoryIntelligenceBookPipelineState>> ListForUserAsync(int userId)
|
|
=> pipelines.ListForUserAsync(userId);
|
|
|
|
public async Task<StoryIntelligenceBookPipelineState?> EnsureForBookAsync(int bookId, int userId)
|
|
{
|
|
var existing = await pipelines.GetByBookForUserAsync(bookId, userId);
|
|
if (existing is not null)
|
|
{
|
|
return existing;
|
|
}
|
|
|
|
var committedRuns = await pipelines.ListCommittedRunsByBookAsync(bookId, userId);
|
|
if (committedRuns.Count == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var latestRun = committedRuns.OrderByDescending(run => run.StoryIntelligenceRunID).First();
|
|
var created = await pipelines.UpsertAsync(new StoryIntelligenceBookPipelineSaveRequest
|
|
{
|
|
ProjectID = latestRun.ProjectID,
|
|
BookID = latestRun.BookID,
|
|
CurrentStage = StoryIntelligencePipelineStages.CharacterReview,
|
|
LastCompletedStage = StoryIntelligencePipelineStages.SceneImport,
|
|
CurrentReviewStage = StoryIntelligencePipelineStages.CharacterReview,
|
|
Status = StoryIntelligencePipelineStatuses.NeedsReview,
|
|
CompletedUtc = null,
|
|
LastRunID = latestRun.StoryIntelligenceRunID
|
|
});
|
|
|
|
logger.LogInformation(
|
|
"Created Story Intelligence pipeline state for existing imported book {BookID}. ProjectID={ProjectID} CurrentStage={CurrentStage}",
|
|
bookId,
|
|
created.ProjectID,
|
|
created.CurrentStage);
|
|
return created;
|
|
}
|
|
|
|
public async Task RecordSceneImportAsync(int projectId, int bookId, int runId)
|
|
{
|
|
await pipelines.UpsertAsync(new StoryIntelligenceBookPipelineSaveRequest
|
|
{
|
|
ProjectID = projectId,
|
|
BookID = bookId,
|
|
CurrentStage = StoryIntelligencePipelineStages.CharacterReview,
|
|
LastCompletedStage = StoryIntelligencePipelineStages.SceneImport,
|
|
CurrentReviewStage = StoryIntelligencePipelineStages.CharacterReview,
|
|
Status = StoryIntelligencePipelineStatuses.NeedsReview,
|
|
CompletedUtc = null,
|
|
LastRunID = runId
|
|
});
|
|
}
|
|
|
|
public async Task RecordCharacterImportAsync(int projectId, int bookId)
|
|
{
|
|
await pipelines.UpsertAsync(new StoryIntelligenceBookPipelineSaveRequest
|
|
{
|
|
ProjectID = projectId,
|
|
BookID = bookId,
|
|
CurrentStage = StoryIntelligencePipelineStages.LocationReview,
|
|
LastCompletedStage = StoryIntelligencePipelineStages.CharacterImport,
|
|
CurrentReviewStage = StoryIntelligencePipelineStages.LocationReview,
|
|
Status = StoryIntelligencePipelineStatuses.NeedsReview,
|
|
CompletedUtc = null,
|
|
LastRunID = null
|
|
});
|
|
}
|
|
|
|
public async Task RecordLocationImportAsync(int projectId, int bookId)
|
|
{
|
|
await pipelines.UpsertAsync(new StoryIntelligenceBookPipelineSaveRequest
|
|
{
|
|
ProjectID = projectId,
|
|
BookID = bookId,
|
|
CurrentStage = StoryIntelligencePipelineStages.AssetReview,
|
|
LastCompletedStage = StoryIntelligencePipelineStages.LocationImport,
|
|
CurrentReviewStage = StoryIntelligencePipelineStages.AssetReview,
|
|
Status = StoryIntelligencePipelineStatuses.NeedsReview,
|
|
CompletedUtc = null,
|
|
LastRunID = null
|
|
});
|
|
}
|
|
|
|
public async Task RecordAssetImportAsync(int projectId, int bookId)
|
|
{
|
|
await pipelines.UpsertAsync(new StoryIntelligenceBookPipelineSaveRequest
|
|
{
|
|
ProjectID = projectId,
|
|
BookID = bookId,
|
|
CurrentStage = StoryIntelligencePipelineStages.RelationshipReview,
|
|
LastCompletedStage = StoryIntelligencePipelineStages.AssetImport,
|
|
CurrentReviewStage = StoryIntelligencePipelineStages.RelationshipReview,
|
|
Status = StoryIntelligencePipelineStatuses.NeedsReview,
|
|
CompletedUtc = null,
|
|
LastRunID = null
|
|
});
|
|
}
|
|
|
|
public async Task RecordRelationshipImportAsync(int projectId, int bookId)
|
|
{
|
|
await pipelines.UpsertAsync(new StoryIntelligenceBookPipelineSaveRequest
|
|
{
|
|
ProjectID = projectId,
|
|
BookID = bookId,
|
|
CurrentStage = StoryIntelligencePipelineStages.KnowledgeReview,
|
|
LastCompletedStage = StoryIntelligencePipelineStages.RelationshipImport,
|
|
CurrentReviewStage = StoryIntelligencePipelineStages.KnowledgeReview,
|
|
Status = StoryIntelligencePipelineStatuses.NeedsReview,
|
|
CompletedUtc = null,
|
|
LastRunID = null
|
|
});
|
|
}
|
|
|
|
public async Task RecordKnowledgeImportAsync(int projectId, int bookId)
|
|
{
|
|
await pipelines.UpsertAsync(new StoryIntelligenceBookPipelineSaveRequest
|
|
{
|
|
ProjectID = projectId,
|
|
BookID = bookId,
|
|
CurrentStage = StoryIntelligencePipelineStages.Complete,
|
|
LastCompletedStage = StoryIntelligencePipelineStages.KnowledgeImport,
|
|
CurrentReviewStage = null,
|
|
Status = StoryIntelligencePipelineStatuses.Complete,
|
|
CompletedUtc = DateTime.UtcNow,
|
|
LastRunID = null
|
|
});
|
|
}
|
|
|
|
public Task<IReadOnlyList<StoryIntelligenceCommittedRunSummary>> ListCommittedRunsByBookAsync(int bookId, int userId)
|
|
=> pipelines.ListCommittedRunsByBookAsync(bookId, userId);
|
|
}
|