namespace ROLAC.API.Entities; /// /// A single-use, expiring invitation that lets a member set their own password and log in for /// the first time — without an admin-generated temporary password. The raw token is e-mailed / /// copied to the member; only its SHA-256 hash is stored here (same scheme as RefreshToken). /// public class UserInvitation { public int Id { get; set; } public string UserId { get; set; } = null!; public AppUser User { get; set; } = null!; /// SHA-256 hex of the raw invitation token. Never store raw tokens. public string TokenHash { get; set; } = null!; public DateTime ExpiresAt { get; set; } public DateTime CreatedAt { get; set; } /// Id of the admin who generated the link. public string CreatedBy { get; set; } = null!; /// Set when the member consumes the link to set their password (single-use). public DateTime? UsedAt { get; set; } /// Set when superseded by a newer invitation for the same user (re-issue). public DateTime? RevokedAt { get; set; } // Computed helpers — NOT mapped to DB columns (ignored in OnModelCreating) public bool IsExpired => DateTime.UtcNow >= ExpiresAt; public bool IsUsed => UsedAt.HasValue; public bool IsRevoked => RevokedAt.HasValue; public bool IsActive => !IsUsed && !IsRevoked && !IsExpired; }