Files
apskel-pos-backend/internal/repository/customer_auth_repository.go
efrilmandClaude Opus 5.5 8bf2fe5585 fix(customer-auth): make organization_id optional at registration
Requiring organization_id broke the current app, which does not send it.
When it is left out and the database has exactly one organization, the
customer now joins that one, so the app works unchanged. A sent
organization_id must still exist, and with several organizations and none
sent registration is refused with a clear message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 18:16:31 +07:00

104 lines
3.8 KiB
Go

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
}