Files
skybridge/user/internal/domain/models.go
2025-09-01 18:26:44 -04:00

295 lines
14 KiB
Go

package domain
import (
"time"
"github.com/google/uuid"
)
// UserStatus represents the status of a user account
type UserStatus string
const (
UserStatusActive UserStatus = "active"
UserStatusInactive UserStatus = "inactive"
UserStatusSuspended UserStatus = "suspended"
UserStatusPending UserStatus = "pending"
)
// UserRole represents the role of a user
type UserRole string
const (
UserRoleAdmin UserRole = "admin"
UserRoleUser UserRole = "user"
UserRoleModerator UserRole = "moderator"
UserRoleViewer UserRole = "viewer"
)
// User represents a user in the system
type User struct {
ID uuid.UUID `json:"id" db:"id"`
Email string `json:"email" validate:"required,email,max=255" db:"email"`
FirstName string `json:"first_name" validate:"required,min=1,max=100" db:"first_name"`
LastName string `json:"last_name" validate:"required,min=1,max=100" db:"last_name"`
DisplayName *string `json:"display_name,omitempty" validate:"omitempty,max=200" db:"display_name"`
Avatar *string `json:"avatar,omitempty" validate:"omitempty,url,max=500" db:"avatar"`
Role UserRole `json:"role" validate:"required,oneof=admin user moderator viewer" db:"role"`
Status UserStatus `json:"status" validate:"required,oneof=active inactive suspended pending" db:"status"`
LastLoginAt *time.Time `json:"last_login_at,omitempty" db:"last_login_at"`
// Security fields
PasswordHash string `json:"-" db:"password_hash"` // Hidden from JSON
PasswordSalt string `json:"-" db:"password_salt"` // Hidden from JSON
EmailVerified bool `json:"email_verified" db:"email_verified"`
EmailVerificationToken *string `json:"-" db:"email_verification_token"` // Hidden from JSON
EmailVerificationExpiresAt *time.Time `json:"-" db:"email_verification_expires_at"` // Hidden from JSON
PasswordResetToken *string `json:"-" db:"password_reset_token"` // Hidden from JSON
PasswordResetExpiresAt *time.Time `json:"-" db:"password_reset_expires_at"` // Hidden from JSON
FailedLoginAttempts int `json:"-" db:"failed_login_attempts"` // Hidden from JSON
LockedUntil *time.Time `json:"-" db:"locked_until"` // Hidden from JSON
TwoFactorEnabled bool `json:"two_factor_enabled" db:"two_factor_enabled"`
TwoFactorSecret *string `json:"-" db:"two_factor_secret"` // Hidden from JSON
TwoFactorBackupCodes []string `json:"-" db:"two_factor_backup_codes"` // Hidden from JSON
LastPasswordChange *time.Time `json:"last_password_change,omitempty" db:"last_password_change"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
CreatedBy string `json:"created_by" validate:"required" db:"created_by"`
UpdatedBy string `json:"updated_by" validate:"required" db:"updated_by"`
}
// UserProfile represents extended user profile information
type UserProfile struct {
UserID uuid.UUID `json:"user_id" db:"user_id"`
Bio string `json:"bio,omitempty" validate:"omitempty,max=1000" db:"bio"`
Location string `json:"location,omitempty" validate:"omitempty,max=200" db:"location"`
Website string `json:"website,omitempty" validate:"omitempty,url,max=500" db:"website"`
Timezone string `json:"timezone,omitempty" validate:"omitempty,max=50" db:"timezone"`
Language string `json:"language,omitempty" validate:"omitempty,max=10" db:"language"`
Preferences map[string]interface{} `json:"preferences,omitempty" db:"preferences"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
// UserSession represents a user session
type UserSession struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" validate:"required" db:"user_id"`
Token string `json:"-" db:"token"` // Hidden from JSON
IPAddress string `json:"ip_address" validate:"required" db:"ip_address"`
UserAgent string `json:"user_agent" validate:"required" db:"user_agent"`
ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
LastUsedAt time.Time `json:"last_used_at" db:"last_used_at"`
}
// CreateUserRequest represents a request to create a new user
type CreateUserRequest struct {
Email string `json:"email" validate:"required,email,max=255"`
FirstName string `json:"first_name" validate:"required,min=1,max=100"`
LastName string `json:"last_name" validate:"required,min=1,max=100"`
DisplayName *string `json:"display_name,omitempty" validate:"omitempty,max=200"`
Avatar *string `json:"avatar,omitempty" validate:"omitempty,url,max=500"`
Role UserRole `json:"role" validate:"required,oneof=admin user moderator viewer"`
Status UserStatus `json:"status" validate:"omitempty,oneof=active inactive suspended pending"`
Password *string `json:"password,omitempty" validate:"omitempty,min=8,max=128"`
SendWelcomeEmail bool `json:"send_welcome_email" validate:"omitempty"`
}
// UpdateUserRequest represents a request to update an existing user
type UpdateUserRequest struct {
Email *string `json:"email,omitempty" validate:"omitempty,email,max=255"`
FirstName *string `json:"first_name,omitempty" validate:"omitempty,min=1,max=100"`
LastName *string `json:"last_name,omitempty" validate:"omitempty,min=1,max=100"`
DisplayName *string `json:"display_name,omitempty" validate:"omitempty,max=200"`
Avatar *string `json:"avatar,omitempty" validate:"omitempty,url,max=500"`
Role *UserRole `json:"role,omitempty" validate:"omitempty,oneof=admin user moderator viewer"`
Status *UserStatus `json:"status,omitempty" validate:"omitempty,oneof=active inactive suspended pending"`
}
// UpdateUserProfileRequest represents a request to update user profile
type UpdateUserProfileRequest struct {
Bio *string `json:"bio,omitempty" validate:"omitempty,max=1000"`
Location *string `json:"location,omitempty" validate:"omitempty,max=200"`
Website *string `json:"website,omitempty" validate:"omitempty,url,max=500"`
Timezone *string `json:"timezone,omitempty" validate:"omitempty,max=50"`
Language *string `json:"language,omitempty" validate:"omitempty,max=10"`
Preferences *map[string]interface{} `json:"preferences,omitempty"`
}
// ListUsersRequest represents a request to list users with filters
type ListUsersRequest struct {
Status *UserStatus `json:"status,omitempty" validate:"omitempty,oneof=active inactive suspended pending"`
Role *UserRole `json:"role,omitempty" validate:"omitempty,oneof=admin user moderator viewer"`
Search string `json:"search,omitempty" validate:"omitempty,max=255"`
Limit int `json:"limit,omitempty" validate:"omitempty,min=1,max=100"`
Offset int `json:"offset,omitempty" validate:"omitempty,min=0"`
OrderBy string `json:"order_by,omitempty" validate:"omitempty,oneof=created_at updated_at email first_name last_name"`
OrderDir string `json:"order_dir,omitempty" validate:"omitempty,oneof=asc desc"`
}
// ListUsersResponse represents a response for listing users
type ListUsersResponse struct {
Users []User `json:"users"`
Total int `json:"total"`
Limit int `json:"limit"`
Offset int `json:"offset"`
HasMore bool `json:"has_more"`
}
// PasswordResetToken represents a password reset token
type PasswordResetToken struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
Token string `json:"-" db:"token"` // Hidden from JSON
ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
UsedAt *time.Time `json:"used_at,omitempty" db:"used_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
IPAddress *string `json:"ip_address,omitempty" db:"ip_address"`
UserAgent *string `json:"user_agent,omitempty" db:"user_agent"`
}
// EmailVerificationToken represents an email verification token
type EmailVerificationToken struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
Token string `json:"-" db:"token"` // Hidden from JSON
Email string `json:"email" db:"email"`
ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
UsedAt *time.Time `json:"used_at,omitempty" db:"used_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
IPAddress *string `json:"ip_address,omitempty" db:"ip_address"`
UserAgent *string `json:"user_agent,omitempty" db:"user_agent"`
}
// LoginAttempt represents a login attempt record
type LoginAttempt struct {
ID uuid.UUID `json:"id" db:"id"`
Email string `json:"email" db:"email"`
IPAddress string `json:"ip_address" db:"ip_address"`
UserAgent *string `json:"user_agent,omitempty" db:"user_agent"`
Success bool `json:"success" db:"success"`
FailureReason *string `json:"failure_reason,omitempty" db:"failure_reason"`
AttemptedAt time.Time `json:"attempted_at" db:"attempted_at"`
SessionID *string `json:"session_id,omitempty" db:"session_id"`
}
// TwoFactorRecoveryCode represents a 2FA recovery code
type TwoFactorRecoveryCode struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
CodeHash string `json:"-" db:"code_hash"` // Hidden from JSON
UsedAt *time.Time `json:"used_at,omitempty" db:"used_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
// AuthContext represents the authentication context for a request
type AuthContext struct {
UserID string `json:"user_id"`
Email string `json:"email"`
Role UserRole `json:"role"`
Permissions []string `json:"permissions"`
Claims map[string]string `json:"claims"`
}
// Authentication Request/Response Types
// LoginRequest represents a login request
type LoginRequest struct {
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required"`
TwoFactorCode *string `json:"two_factor_code,omitempty" validate:"omitempty,len=6"`
RememberMe bool `json:"remember_me"`
}
// LoginResponse represents a login response
type LoginResponse struct {
User *User `json:"user,omitempty"`
Token string `json:"token"`
ExpiresAt time.Time `json:"expires_at"`
RequiresTwoFactor bool `json:"requires_two_factor"`
TwoFactorTempToken *string `json:"two_factor_temp_token,omitempty"`
}
// RegisterRequest represents a user registration request
type RegisterRequest struct {
Email string `json:"email" validate:"required,email,max=255"`
Password string `json:"password" validate:"required,min=8,max=128"`
FirstName string `json:"first_name" validate:"required,min=1,max=100"`
LastName string `json:"last_name" validate:"required,min=1,max=100"`
DisplayName *string `json:"display_name,omitempty" validate:"omitempty,max=200"`
}
// RegisterResponse represents a registration response
type RegisterResponse struct {
User *User `json:"user"`
Message string `json:"message"`
}
// ForgotPasswordRequest represents a forgot password request
type ForgotPasswordRequest struct {
Email string `json:"email" validate:"required,email"`
}
// ResetPasswordRequest represents a reset password request
type ResetPasswordRequest struct {
Token string `json:"token" validate:"required"`
Password string `json:"password" validate:"required,min=8,max=128"`
}
// ChangePasswordRequest represents a change password request
type ChangePasswordRequest struct {
CurrentPassword string `json:"current_password" validate:"required"`
NewPassword string `json:"new_password" validate:"required,min=8,max=128"`
}
// VerifyEmailRequest represents an email verification request
type VerifyEmailRequest struct {
Token string `json:"token" validate:"required"`
}
// ResendVerificationRequest represents a resend verification request
type ResendVerificationRequest struct {
Email string `json:"email" validate:"required,email"`
}
// SetupTwoFactorResponse represents the response when setting up 2FA
type SetupTwoFactorResponse struct {
Secret string `json:"secret"`
QRCodeURL string `json:"qr_code_url"`
BackupCodes []string `json:"backup_codes"`
}
// EnableTwoFactorRequest represents a request to enable 2FA
type EnableTwoFactorRequest struct {
Code string `json:"code" validate:"required,len=6"`
}
// DisableTwoFactorRequest represents a request to disable 2FA
type DisableTwoFactorRequest struct {
Password string `json:"password" validate:"required"`
Code *string `json:"code,omitempty" validate:"omitempty,len=6"`
}
// ValidateTwoFactorRequest represents a 2FA validation request
type ValidateTwoFactorRequest struct {
TempToken string `json:"temp_token" validate:"required"`
Code string `json:"code" validate:"required,len=6"`
}
// SessionInfo represents session information
type SessionInfo struct {
ID uuid.UUID `json:"id"`
IPAddress string `json:"ip_address"`
UserAgent string `json:"user_agent"`
CreatedAt time.Time `json:"created_at"`
LastUsedAt time.Time `json:"last_used_at"`
ExpiresAt time.Time `json:"expires_at"`
IsCurrent bool `json:"is_current"`
}
// ListSessionsResponse represents a list of user sessions
type ListSessionsResponse struct {
Sessions []SessionInfo `json:"sessions"`
}