namespace JobTrackerApi.Models; // Phase 5 Milestone 2 — the application checklist. // // A workflow GUIDANCE layer, not a new store of truth. It duplicates nothing: the CV lives in // CvVariant, documents in Attachment, history in JobEvent, follow-up in JobApplication.FollowUpAt. // A checklist item only records "is this step done, and does the user still want it". // // System items carry a stable SystemKey and (usually) an AutoSignal: the same readiness signal the // /readiness endpoint already computes. When the signal is satisfied the item auto-completes, so the // checklist and readiness can never disagree — readiness became the calculation, this is the surface. // docs/architecture/application-workspace.md. public sealed class ApplicationChecklistItem { public int Id { get; set; } public string OwnerUserId { get; set; } = string.Empty; public int JobApplicationId { get; set; } public JobApplication? JobApplication { get; set; } // Stable identifier for system items ("prepare-cv", ...). Null for user-created items, so re-seeding // is idempotent and a system item can be recognised across renames. public string? SystemKey { get; set; } // Which readiness signal completes this item automatically. Null = manual only. public string? AutoSignal { get; set; } public string Title { get; set; } = string.Empty; public string? Description { get; set; } // preparation | submission | follow-up | interview | custom. Drives grouping and next-action priority. public string Category { get; set; } = ChecklistCategories.Custom; // pending | done | dismissed. "dismissed" is the user opting out — not every item fits every role. public string Status { get; set; } = ChecklistStatuses.Pending; // Workspace section this step is done in, so the checklist can link straight to the work. public string? Section { get; set; } public int SortOrder { get; set; } public bool IsSystemGenerated { get; set; } // Set when the auto-signal completed the item, so the sync may reopen it if the signal reverts. // A manual tick clears this and therefore sticks. public bool IsAutoCompleted { get; set; } public DateTimeOffset? CompletedAt { get; set; } public DateTimeOffset CreatedAtUtc { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset UpdatedAtUtc { get; set; } = DateTimeOffset.UtcNow; } public static class ChecklistStatuses { public const string Pending = "pending"; public const string Done = "done"; public const string Dismissed = "dismissed"; public static bool IsValid(string? value) => value is Pending or Done or Dismissed; } public static class ChecklistCategories { public const string Preparation = "preparation"; public const string Submission = "submission"; public const string FollowUp = "follow-up"; public const string Interview = "interview"; public const string Custom = "custom"; // Next-action priority: critical preparation, then submission, then chasing, then interview prep, // then whatever the user added themselves. public static readonly string[] Order = { Preparation, Submission, FollowUp, Interview, Custom }; public static int Rank(string? category) { var index = Array.IndexOf(Order, category ?? Custom); return index < 0 ? Order.Length : index; } public static bool IsValid(string? value) => Array.IndexOf(Order, value ?? string.Empty) >= 0; }