Documentation
¶
Overview ¶
Package user provides user domain models and repository interfaces.
Index ¶
- Variables
- func ValidRole(r Role) bool
- type CreateUserInput
- type PostgresRepository
- func (r *PostgresRepository) Count(ctx context.Context) (int, error)
- func (r *PostgresRepository) Create(ctx context.Context, input *CreateUserInput, passwordHash string) (*User, error)
- func (r *PostgresRepository) Delete(ctx context.Context, id uuid.UUID) error
- func (r *PostgresRepository) GetByEmail(ctx context.Context, email string) (*User, error)
- func (r *PostgresRepository) GetByID(ctx context.Context, id uuid.UUID) (*User, error)
- func (r *PostgresRepository) List(ctx context.Context, limit, offset int) ([]*User, error)
- func (r *PostgresRepository) ListByEmail(ctx context.Context, email string) ([]*User, error)
- func (r *PostgresRepository) RecordFailedLogin(ctx context.Context, id uuid.UUID, maxAttempts int, lockFor time.Duration) error
- func (r *PostgresRepository) ResetFailedLogins(ctx context.Context, id uuid.UUID) error
- func (r *PostgresRepository) SetPassword(ctx context.Context, id uuid.UUID, passwordHash string) error
- func (r *PostgresRepository) Update(ctx context.Context, id uuid.UUID, input *UpdateUserInput) (*User, error)
- func (r *PostgresRepository) UpdateLastLogin(ctx context.Context, id uuid.UUID) error
- type Repository
- type Role
- type UpdateUserInput
- type User
Constants ¶
This section is empty.
Variables ¶
var ( ErrUserNotFound = errors.New("user not found") ErrEmailAlreadyExists = errors.New("email already exists") ErrInvalidRole = errors.New("invalid role") // ErrLastOwner is returned when a change would leave the site without an owner. ErrLastOwner = errors.New("cannot remove or demote the last owner") )
Common errors.
Functions ¶
Types ¶
type CreateUserInput ¶
CreateUserInput represents input for creating a new user.
type PostgresRepository ¶
type PostgresRepository struct {
// contains filtered or unexported fields
}
PostgresRepository implements Repository using PostgreSQL.
func NewPostgresRepository ¶
func NewPostgresRepository(db *database.DB) *PostgresRepository
NewPostgresRepository creates a new PostgreSQL user repository.
func (*PostgresRepository) Count ¶
func (r *PostgresRepository) Count(ctx context.Context) (int, error)
Count returns the total number of users.
Path B PR 2b/3: dropped the tenantID parameter (see List).
func (*PostgresRepository) Create ¶
func (r *PostgresRepository) Create(ctx context.Context, input *CreateUserInput, passwordHash string) (*User, error)
Create inserts a new user into the database. Multi-tenancy was removed in Path B; hatamoto_users has no tenant_id column and the User model has no TenantID field.
func (*PostgresRepository) GetByEmail ¶
GetByEmail retrieves a user by email address.
func (*PostgresRepository) List ¶
List retrieves users with pagination.
Path B PR 2b/3: dropped the tenantID parameter — there's a single tenant so per-tenant filtering is meaningless. Callers must update their call sites accordingly.
func (*PostgresRepository) ListByEmail ¶
ListByEmail retrieves all users with the given email. Pre-Path-B this scanned across tenants for the multi-tenant cross-account login feature; post-strip the result set is at most 1 row but the API contract stays the same so callers (auth.Service) don't need adjusting.
func (*PostgresRepository) RecordFailedLogin ¶
func (r *PostgresRepository) RecordFailedLogin(ctx context.Context, id uuid.UUID, maxAttempts int, lockFor time.Duration) error
RecordFailedLogin increments the failure counter and locks the account once the threshold is reached, in a single statement.
func (*PostgresRepository) ResetFailedLogins ¶
ResetFailedLogins clears the failure counter and unlocks the account.
func (*PostgresRepository) SetPassword ¶
func (r *PostgresRepository) SetPassword(ctx context.Context, id uuid.UUID, passwordHash string) error
SetPassword replaces a user's password hash and clears any login lockout.
func (*PostgresRepository) Update ¶
func (r *PostgresRepository) Update(ctx context.Context, id uuid.UUID, input *UpdateUserInput) (*User, error)
Update modifies a user's information.
func (*PostgresRepository) UpdateLastLogin ¶
UpdateLastLogin updates the user's last login timestamp.
type Repository ¶
type Repository interface {
Create(ctx context.Context, input *CreateUserInput, passwordHash string) (*User, error)
GetByID(ctx context.Context, id uuid.UUID) (*User, error)
GetByEmail(ctx context.Context, email string) (*User, error)
ListByEmail(ctx context.Context, email string) ([]*User, error)
Update(ctx context.Context, id uuid.UUID, input *UpdateUserInput) (*User, error)
UpdateLastLogin(ctx context.Context, id uuid.UUID) error
// RecordFailedLogin increments the consecutive-failure counter and, once it
// reaches maxAttempts, sets locked_until to now()+lockFor.
RecordFailedLogin(ctx context.Context, id uuid.UUID, maxAttempts int, lockFor time.Duration) error
// ResetFailedLogins clears the failure counter and any lock (called on a
// successful login).
ResetFailedLogins(ctx context.Context, id uuid.UUID) error
Delete(ctx context.Context, id uuid.UUID) error
List(ctx context.Context, limit, offset int) ([]*User, error)
Count(ctx context.Context) (int, error)
}
Repository defines the interface for user data operations.
Path B PR 2b/3: List and Count no longer take a tenantID — there is only one tenant. The signature change forces callers off the legacy code path rather than silently ignoring the argument.
type UpdateUserInput ¶
UpdateUserInput represents input for updating a user.
type User ¶
type User struct {
ID uuid.UUID `json:"id"`
Email string `json:"email"`
PasswordHash string `json:"-"` // Never expose
Role Role `json:"role"`
Name *string `json:"name,omitempty"`
AvatarURL *string `json:"avatar_url,omitempty"`
LastLoginAt *time.Time `json:"last_login_at,omitempty"`
// Login-lockout state (migration 004). Never serialized to clients.
FailedLoginAttempts int `json:"-"`
LockedUntil *time.Time `json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
User represents a tenant user.