Files
2026-05-06 10:14:55 +03:00

44 lines
1.4 KiB
Go

package geo
import (
"context"
"errors"
"fmt"
"galaxy/backend/internal/postgres/jet/backend/table"
"github.com/go-jet/jet/v2/postgres"
"github.com/google/uuid"
)
// SetDeclaredCountryAtRegistration writes the geoip-derived country to
// `accounts.declared_country` for userID, and only when the column is
// currently NULL. The semantics match PLAN.md §5.8: declared_country is
// captured at first registration and never updated thereafter, so
// repeated calls on the same account are no-ops.
//
// The geoip lookup itself is best-effort: a missing or invalid country
// returns nil (no UPDATE executed) and never blocks the auth flow. Errors
// from the database UPDATE itself surface to the caller so the auth
// service can decide whether to log or escalate.
func (s *Service) SetDeclaredCountryAtRegistration(ctx context.Context, userID uuid.UUID, sourceIP string) error {
if s == nil {
return errors.New("geo: nil service")
}
country := s.LookupCountry(sourceIP)
if country == "" {
return nil
}
stmt := table.Accounts.UPDATE(table.Accounts.DeclaredCountry, table.Accounts.UpdatedAt).
SET(postgres.String(country), postgres.NOW()).
WHERE(
table.Accounts.UserID.EQ(postgres.UUID(userID)).
AND(table.Accounts.DeclaredCountry.IS_NULL()).
AND(table.Accounts.DeletedAt.IS_NULL()),
)
if _, err := stmt.ExecContext(ctx, s.db); err != nil {
return fmt.Errorf("geo: set declared_country for %s: %w", userID, err)
}
return nil
}