package domain import "time" // Role é o papel de uma conta do painel (ARQUITETURA.md 9.6). type Role string const ( RoleViewer Role = "viewer" RoleAdmin Role = "admin" RoleOwner Role = "owner" ) func (r Role) rank() int { switch r { case RoleOwner: return 3 case RoleAdmin: return 2 case RoleViewer: return 1 } return 0 } func (r Role) Valid() bool { return r.rank() > 0 } // AtLeast indica se o papel tem pelo menos as permissões de min. func (r Role) AtLeast(min Role) bool { return r.rank() >= min.rank() && r.Valid() } type WebAccount struct { ID int64 Username string PasswordHash string Role Role UserID *int64 FailedLoginCount int LockedUntil *time.Time DisabledAt *time.Time LastLoginAt *time.Time CreatedAt time.Time } func (a WebAccount) IsDisabled() bool { return a.DisabledAt != nil } func (a WebAccount) IsLocked(now time.Time) bool { return a.LockedUntil != nil && now.Before(*a.LockedUntil) } type WebSession struct { ID int64 AccountID int64 CSRFTokenHash []byte ExpiresAt time.Time LastSeenAt time.Time RevokedAt *time.Time Account WebAccount }