namespace Nexus.Api.Data; public enum OperationalStatus { Online, Degraded, Offline, Unknown } /// /// Strongly-typed task lifecycle states. /// String values (e.g. "In progress") are preserved for API compatibility /// via ; the WorkTask entity continues to store /// state as a string in the database. /// public enum TaskState { Backlog, InProgress, Blocked, Done } public static class TaskStateHelper { private static readonly Dictionary StateToString = new() { [TaskState.Backlog] = "Backlog", [TaskState.InProgress] = "In progress", [TaskState.Blocked] = "Blocked", [TaskState.Done] = "Done" }; private static readonly Dictionary StringToState = new(StringComparer.OrdinalIgnoreCase) { ["Backlog"] = TaskState.Backlog, ["In progress"] = TaskState.InProgress, ["Blocked"] = TaskState.Blocked, ["Done"] = TaskState.Done }; /// Valid task-state string values for API validation. public static readonly string[] AllStates = ["Backlog", "In progress", "Blocked", "Done"]; /// Convert a TaskState enum to its API string representation. public static string ToStateString(this TaskState state) => StateToString[state]; /// Parse a string to TaskState; defaults to Backlog for unrecognized input. public static TaskState ToTaskState(this string state) => StringToState.TryGetValue(state, out var result) ? result : TaskState.Backlog; /// Returns true if the string is a recognized task state (case-insensitive). public static bool IsValidState(string? state) => !string.IsNullOrWhiteSpace(state) && StringToState.ContainsKey(state); public static bool IsInProgressOrBlocked(string? state) => string.Equals(state, "In progress", StringComparison.OrdinalIgnoreCase) || string.Equals(state, "Blocked", StringComparison.OrdinalIgnoreCase); public static bool IsDoneOrBacklog(string? state) => string.Equals(state, "Done", StringComparison.OrdinalIgnoreCase) || string.Equals(state, "Backlog", StringComparison.OrdinalIgnoreCase); } public sealed class Project { public Guid Id { get; init; } = Guid.NewGuid(); public required string Name { get; set; } public string Description { get; set; } = string.Empty; public int Progress { get; set; } public OperationalStatus Status { get; set; } = OperationalStatus.Unknown; public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class WorkTask { public Guid Id { get; init; } = Guid.NewGuid(); public required string Title { get; set; } public string? Detail { get; set; } public string State { get; set; } = "Backlog"; public string Priority { get; set; } = "Normal"; public string Source { get; set; } = "bao"; public string? AssignedTo { get; set; } public Guid? ProjectId { get; set; } public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; } public sealed class ActivityEvent { public long Id { get; init; } public required string Type { get; set; } public required string Message { get; set; } public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; }