using System; using System.Collections.Generic; namespace AutopilotMonitor.Shared.Models { /// /// Human-entered per-session verdict + free-text note, role-separated into lanes /// (one row per session + lane, editable in place). Stored in the /// SessionAnnotations table: PK = tenantId, RK = {sessionId}_{lane}. /// The globaladmin lane is platform-internal and never returned to tenant /// callers. Author fields are stamped server-side from the JWT, never from the body. /// public class SessionAnnotation { /// Maximum length of (matches the feedback comment cap). public const int MaxNoteLength = 4096; public string TenantId { get; set; } = string.Empty; public string SessionId { get; set; } = string.Empty; /// One of . public string Lane { get; set; } = string.Empty; /// One of , or null (note-only annotation). public string? Verdict { get; set; } /// Free text, ≤ , or null (verdict-only annotation). public string? Note { get; set; } /// UPN of the last editor. Server-stamped. public string AuthorUpn { get; set; } = string.Empty; /// Display name of the last editor. Server-stamped. public string AuthorDisplayName { get; set; } = string.Empty; /// UPN of the first writer. Immutable across edits. public string CreatedByUpn { get; set; } = string.Empty; public DateTime CreatedAtUtc { get; set; } public DateTime UpdatedAtUtc { get; set; } /// /// Snapshot of the rule ids that had fired for the session at write time /// (denormalized so rule-quality evaluation needs no join against RuleResults). /// public List RuleIds { get; set; } = new(); } /// Lane discriminators — the RowKey suffix and the write-permission axis. public static class AnnotationLanes { public const string Operator = "operator"; public const string TenantAdmin = "tenantadmin"; public const string GlobalAdmin = "globaladmin"; public static readonly string[] All = { Operator, TenantAdmin, GlobalAdmin }; } /// Structured verdict vocabulary. A verdict is always optional. public static class AnnotationVerdicts { public const string RootCauseConfirmed = "root_cause_confirmed"; public const string AnalysisWrong = "analysis_wrong"; public const string DifferentProblem = "different_problem"; public const string Inconclusive = "inconclusive"; public static readonly string[] All = { RootCauseConfirmed, AnalysisWrong, DifferentProblem, Inconclusive, }; } }