// Package domain contém as entidades e estados centrais. Não depende de // nenhum outro pacote do projeto. package domain import "time" type UserStatus string const ( UserPending UserStatus = "pending" UserActive UserStatus = "active" UserDisabled UserStatus = "disabled" ) // PauseReason explica por que os lembretes de um usuário estão desligados (/status). type PauseReason string const ( PauseManual PauseReason = "manual" PauseAPIFailures PauseReason = "api_failures" PauseAdmin PauseReason = "admin" PauseUserDisabled PauseReason = "user_disabled" ) const DefaultTimezone = "America/Sao_Paulo" type User struct { ID int64 TelegramChatID int64 DisplayName string Status UserStatus IsBotAdmin bool NotificationsEnabled bool PausedReason *PauseReason Timezone string CreatedAt time.Time UpdatedAt time.Time } func (u User) IsActive() bool { return u.Status == UserActive } // IsActiveBotAdmin indica quem pode usar os comandos administrativos do Telegram. func (u User) IsActiveBotAdmin() bool { return u.IsActive() && u.IsBotAdmin } // Location devolve o fuso do usuário; um valor inválido cai no fuso padrão. func (u User) Location() *time.Location { return LoadLocation(u.Timezone) } var fallbackLocation = func() *time.Location { loc, err := time.LoadLocation(DefaultTimezone) if err != nil { return time.UTC } return loc }() func LoadLocation(name string) *time.Location { if name == "" { return fallbackLocation } loc, err := time.LoadLocation(name) if err != nil { return fallbackLocation } return loc } // LocalDay devolve a data (AAAA-MM-DD) de t no fuso informado. func LocalDay(t time.Time, loc *time.Location) string { return t.In(loc).Format(DateLayout) } const DateLayout = "2006-01-02"