Files
apskel-pos-backend/internal/repository/customer_auth_repository.go
T
efrilmandClaude Opus 5.5 a3cb7dd5fd fix(customer-auth): register customers into the app's organization
Registration put every new customer into a hardcoded organization id,
which does not exist in staging, so set-password failed on the
fk_customers_organization foreign key with a 500.

POST /customer-auth/register/start now takes organization_id, the
organization the app is built for. It must be a UUID of an existing
organization, checked before the OTP is sent; it is kept in the OTP
session and set-password creates the customer there. A registration
started before this change has no organization in its session and is asked
to start again.

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

93 lines
3.4 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)
}
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
}