package customer import ( "context" "errors" "strings" ) var errCompanyNotAssigned = errors.New("company is not assigned to customer") func normalizeAssignedCompanyIDs(assigned []string) []string { normalized := make([]string, 0, len(assigned)) seen := make(map[string]struct{}, len(assigned)) for _, id := range assigned { clean := strings.TrimSpace(id) if clean == "" { continue } if _, ok := seen[clean]; ok { continue } seen[clean] = struct{}{} normalized = append(normalized, clean) } return normalized } // pickActiveCompanyID chooses the company context for a customer request. // When requestedCompanyID is set it must be in assigned; otherwise a still-valid // token company is kept; if the token company was removed, the first assignment is used. func pickActiveCompanyID(assigned []string, tokenCompanyID, requestedCompanyID string) (string, error) { assigned = normalizeAssignedCompanyIDs(assigned) if len(assigned) == 0 { return "", nil } requested := strings.TrimSpace(requestedCompanyID) if requested != "" { for _, id := range assigned { if id == requested { return requested, nil } } return "", errCompanyNotAssigned } token := strings.TrimSpace(tokenCompanyID) if token != "" { for _, id := range assigned { if id == token { return token, nil } } } return assigned[0], nil } // ResolveCompanyContext resolves the active company and assigned companies for an authenticated customer. func (s *customerService) ResolveCompanyContext(ctx context.Context, customerID, tokenCompanyID, requestedCompanyID string) (string, []string, error) { customer, err := s.repository.GetByID(ctx, customerID) if err != nil { return "", nil, errors.New("customer not found") } assigned := normalizeAssignedCompanyIDs(customer.Companies) companyID, err := pickActiveCompanyID(assigned, tokenCompanyID, requestedCompanyID) if err != nil { return "", nil, err } return companyID, assigned, nil } // ResolveActiveCompanyID resolves the active company for an authenticated customer. func (s *customerService) ResolveActiveCompanyID(ctx context.Context, customerID, tokenCompanyID, requestedCompanyID string) (string, error) { companyID, _, err := s.ResolveCompanyContext(ctx, customerID, tokenCompanyID, requestedCompanyID) return companyID, err }