using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Domain.Entities.Members; namespace Domain.Entities.Developers; /// /// 개인 Access Token (PAT). /// 회원이 자기 자신을 대신해 API 호출용 — OAuth2 client_credentials 보다 간단한 인증. /// public class ApiPersonalAccessToken { [ForeignKey(nameof(OwnerMemberID))] public virtual Member? Owner { get; private set; } [Key] public long ID { get; private set; } public int OwnerMemberID { get; private set; } public string Name { get; private set; } = default!; public string TokenHash { get; private set; } = default!; public string TokenHint { get; private set; } = default!; public string ScopesCsv { get; private set; } = string.Empty; public DateTime CreatedAt { get; private set; } = DateTime.UtcNow; public DateTime? ExpiresAt { get; private set; } public DateTime? LastUsedAt { get; private set; } public DateTime? RevokedAt { get; private set; } private ApiPersonalAccessToken() { } public static ApiPersonalAccessToken Create( int ownerMemberID, string name, string tokenHash, string tokenHint, string scopesCsv, DateTime? expiresAt ) { return new ApiPersonalAccessToken { OwnerMemberID = ownerMemberID, Name = name, TokenHash = tokenHash, TokenHint = tokenHint, ScopesCsv = scopesCsv, ExpiresAt = expiresAt }; } public void Revoke() { RevokedAt = DateTime.UtcNow; } public void TouchLastUsed() { LastUsedAt = DateTime.UtcNow; } public bool IsRevoked => RevokedAt != null; public bool IsExpired => ExpiresAt.HasValue && DateTime.UtcNow >= ExpiresAt.Value; public bool IsActive => !IsRevoked && !IsExpired; }