namespace PlotLine.Models; public static class StoryIntelligenceJobStatuses { public const string Pending = "Pending"; public const string Preparing = "Preparing"; public const string ReadingScenes = "ReadingScenes"; public const string AnalysingCharacters = "AnalysingCharacters"; public const string AnalysingRelationships = "AnalysingRelationships"; public const string AnalysingLocations = "AnalysingLocations"; public const string AnalysingAssets = "AnalysingAssets"; public const string AnalysingTimeline = "AnalysingTimeline"; public const string Finalising = "Finalising"; public const string Completed = "Completed"; public const string Cancelled = "Cancelled"; public const string Failed = "Failed"; } public sealed class StoryIntelligenceJob { public Guid JobID { get; init; } public int ConsentID { get; init; } public int UserID { get; init; } public int ProjectID { get; init; } public int BookID { get; init; } public string Status { get; init; } = StoryIntelligenceJobStatuses.Pending; public DateTime CreatedUtc { get; init; } public DateTime? StartedUtc { get; init; } public DateTime? CompletedUtc { get; init; } public DateTime? CancelledUtc { get; init; } public int ProgressPercent { get; init; } public string CurrentStage { get; init; } = StoryIntelligenceJobStatuses.Pending; public string CurrentMessage { get; init; } = "Story Intelligence is queued."; public string? EstimatedRemaining { get; init; } public string? ErrorMessage { get; init; } public DateTime UpdatedUtc { get; init; } public bool IsActive => Status is StoryIntelligenceJobStatuses.Pending or StoryIntelligenceJobStatuses.Preparing or StoryIntelligenceJobStatuses.ReadingScenes or StoryIntelligenceJobStatuses.AnalysingCharacters or StoryIntelligenceJobStatuses.AnalysingRelationships or StoryIntelligenceJobStatuses.AnalysingLocations or StoryIntelligenceJobStatuses.AnalysingAssets or StoryIntelligenceJobStatuses.AnalysingTimeline or StoryIntelligenceJobStatuses.Finalising; public bool IsCompleted => string.Equals(Status, StoryIntelligenceJobStatuses.Completed, StringComparison.Ordinal); public bool IsCancelled => string.Equals(Status, StoryIntelligenceJobStatuses.Cancelled, StringComparison.Ordinal); } public sealed class StoryIntelligenceJobProgress { public Guid JobID { get; init; } public int UserID { get; init; } public int ProjectID { get; init; } public int BookID { get; init; } public string Status { get; init; } = StoryIntelligenceJobStatuses.Pending; public string CurrentStage { get; init; } = StoryIntelligenceJobStatuses.Pending; public string CurrentMessage { get; init; } = "Story Intelligence is queued."; public int ProgressPercent { get; init; } public string? EstimatedRemaining { get; init; } public string ElapsedTime { get; init; } = "0 min"; public string? ErrorMessage { get; init; } public DateTime UpdatedUtc { get; init; } public bool IsActive { get; init; } public bool IsCompleted { get; init; } }