package repository import ( "context" "fmt" "apskel-pos-be/internal/entities" "github.com/google/uuid" "gorm.io/gorm" ) type CustomerAuthRepository interface { GetCustomerByPhoneNumber(ctx context.Context, phoneNumber string) (*entities.Customer, error) GetCustomerByID(ctx context.Context, id string) (*entities.Customer, error) CreateCustomer(ctx context.Context, customer *entities.Customer) error UpdateCustomer(ctx context.Context, customer *entities.Customer) error CheckPhoneNumberExists(ctx context.Context, phoneNumber string) (bool, error) SetCustomerPassword(ctx context.Context, customerID string, passwordHash string) error // OrganizationExists reports whether an organization with this id exists. OrganizationExists(ctx context.Context, organizationID uuid.UUID) (bool, error) // OrganizationIDs returns up to limit organization ids. OrganizationIDs(ctx context.Context, limit int) ([]uuid.UUID, error) } type customerAuthRepository struct { db *gorm.DB } func NewCustomerAuthRepository(db *gorm.DB) CustomerAuthRepository { return &customerAuthRepository{ db: db, } } func (r *customerAuthRepository) GetCustomerByPhoneNumber(ctx context.Context, phoneNumber string) (*entities.Customer, error) { var customer entities.Customer if err := r.db.WithContext(ctx).Where("phone_number = ?", phoneNumber).First(&customer).Error; err != nil { if err == gorm.ErrRecordNotFound { return nil, nil // Customer not found, not an error } return nil, fmt.Errorf("failed to get customer by phone number: %w", err) } return &customer, nil } func (r *customerAuthRepository) GetCustomerByID(ctx context.Context, id string) (*entities.Customer, error) { var customer entities.Customer if err := r.db.WithContext(ctx).Where("id = ?", id).First(&customer).Error; err != nil { if err == gorm.ErrRecordNotFound { return nil, fmt.Errorf("customer not found") } return nil, fmt.Errorf("failed to get customer by ID: %w", err) } return &customer, nil } func (r *customerAuthRepository) CreateCustomer(ctx context.Context, customer *entities.Customer) error { if err := r.db.WithContext(ctx).Create(customer).Error; err != nil { return fmt.Errorf("failed to create customer: %w", err) } return nil } func (r *customerAuthRepository) UpdateCustomer(ctx context.Context, customer *entities.Customer) error { if err := r.db.WithContext(ctx).Save(customer).Error; err != nil { return fmt.Errorf("failed to update customer: %w", err) } return nil } func (r *customerAuthRepository) CheckPhoneNumberExists(ctx context.Context, phoneNumber string) (bool, error) { var count int64 if err := r.db.WithContext(ctx).Model(&entities.Customer{}).Where("phone_number = ?", phoneNumber).Count(&count).Error; err != nil { return false, fmt.Errorf("failed to check phone number existence: %w", err) } return count > 0, nil } func (r *customerAuthRepository) SetCustomerPassword(ctx context.Context, customerID string, passwordHash string) error { if err := r.db.WithContext(ctx).Model(&entities.Customer{}).Where("id = ?", customerID).Update("password_hash", passwordHash).Error; err != nil { return fmt.Errorf("failed to set customer password: %w", err) } return nil } func (r *customerAuthRepository) OrganizationExists(ctx context.Context, organizationID uuid.UUID) (bool, error) { var count int64 err := r.db.WithContext(ctx).Table("organizations").Where("id = ?", organizationID).Count(&count).Error if err != nil { return false, fmt.Errorf("failed to check organization: %w", err) } return count > 0, nil } func (r *customerAuthRepository) OrganizationIDs(ctx context.Context, limit int) ([]uuid.UUID, error) { var ids []uuid.UUID err := r.db.WithContext(ctx).Table("organizations").Order("created_at").Limit(limit).Pluck("id", &ids).Error if err != nil { return nil, fmt.Errorf("failed to list organizations: %w", err) } return ids, nil }