using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Domain.Entities.Developers.ValueObject; namespace Domain.Entities.Developers; /// /// OAuth2 Client Credentials (ClientID + SecretHash). /// Secret 회전을 위해 한 앱이 여러 credential 을 가질 수 있고 구 credential 은 Revoked 처리. /// public class ApiCredential { [ForeignKey(nameof(ApplicationID))] public virtual ApiApplication? Application { get; private set; } [Key] public int ID { get; private set; } public int ApplicationID { get; private set; } public string ClientID { get; private set; } = default!; public string SecretHash { get; private set; } = default!; public string SecretHint { get; private set; } = default!; public CredentialStatus Status { get; private set; } = CredentialStatus.Active; public DateTime CreatedAt { get; private set; } = DateTime.UtcNow; public DateTime? LastUsedAt { get; private set; } public DateTime? RevokedAt { get; private set; } private ApiCredential() { } public static ApiCredential Create(int applicationID, string clientID, string secretHash, string secretHint) { return new ApiCredential { ApplicationID = applicationID, ClientID = clientID, SecretHash = secretHash, SecretHint = secretHint }; } public void Revoke() { Status = CredentialStatus.Revoked; RevokedAt = DateTime.UtcNow; } public void TouchLastUsed() { LastUsedAt = DateTime.UtcNow; } public bool IsActive => Status == CredentialStatus.Active && RevokedAt == null; }