Refactor Customer Entity and Forms to Use 'Companies' Field
- Updated the Customer entity to replace 'CompanyIDs' with 'Companies' for improved clarity and consistency. - Modified CreateCustomerForm and UpdateCustomerForm to reflect the change from 'CompanyIDs' to 'Companies', ensuring proper validation and structured responses. - Adjusted service methods to handle the new 'Companies' field, including registration and company assignment logic, enhancing the overall data model and API usability.
This commit is contained in:
@@ -44,7 +44,7 @@ type Customer struct {
|
|||||||
Type CustomerType `bson:"type"`
|
Type CustomerType `bson:"type"`
|
||||||
Role CustomerRole `bson:"role"`
|
Role CustomerRole `bson:"role"`
|
||||||
Phone *string `bson:"phone"`
|
Phone *string `bson:"phone"`
|
||||||
CompanyIDs []string `bson:"company_ids"`
|
Companies []string `bson:"companies"`
|
||||||
DeviceToken []string `bson:"device_token"`
|
DeviceToken []string `bson:"device_token"`
|
||||||
LastLoginAt *int64 `bson:"last_login_at"`
|
LastLoginAt *int64 `bson:"last_login_at"`
|
||||||
UpdatedAt int64 `bson:"updated_at"`
|
UpdatedAt int64 `bson:"updated_at"`
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type CreateCustomerForm struct {
|
|||||||
FullName *string `json:"full_name,omitempty" valid:"optional,length(2|100)" example:"User"`
|
FullName *string `json:"full_name,omitempty" valid:"optional,length(2|100)" example:"User"`
|
||||||
Type string `json:"type" valid:"required,in(individual|company|government)" example:"individual"`
|
Type string `json:"type" valid:"required,in(individual|company|government)" example:"individual"`
|
||||||
Role string `json:"role" valid:"required,in(admin|analyst)" example:"analyst"`
|
Role string `json:"role" valid:"required,in(admin|analyst)" example:"analyst"`
|
||||||
CompanyIDs []string `json:"company_ids,omitempty" valid:"optional"`
|
Companies []string `json:"companies,omitempty" valid:"optional"`
|
||||||
Username string `json:"username" valid:"required,alphanum,length(3|30)" example:"user"`
|
Username string `json:"username" valid:"required,alphanum,length(3|30)" example:"user"`
|
||||||
Email string `json:"email" valid:"required,email" example:"user@opplens.com"`
|
Email string `json:"email" valid:"required,email" example:"user@opplens.com"`
|
||||||
Password string `json:"password" valid:"required,length(8|128)" example:"User!1234"`
|
Password string `json:"password" valid:"required,length(8|128)" example:"User!1234"`
|
||||||
@@ -19,7 +19,7 @@ type UpdateCustomerForm struct {
|
|||||||
FullName *string `json:"full_name,omitempty" valid:"optional,length(2|100)" example:"User"`
|
FullName *string `json:"full_name,omitempty" valid:"optional,length(2|100)" example:"User"`
|
||||||
Type string `json:"type" valid:"required,in(individual|company|government)" example:"individual"`
|
Type string `json:"type" valid:"required,in(individual|company|government)" example:"individual"`
|
||||||
Role string `json:"role" valid:"required,in(admin|analyst)" example:"analyst"`
|
Role string `json:"role" valid:"required,in(admin|analyst)" example:"analyst"`
|
||||||
CompanyIDs []string `json:"company_ids,omitempty" valid:"optional"`
|
Companies []string `json:"companies,omitempty" valid:"optional"`
|
||||||
Username string `json:"username" valid:"required,alphanum,length(3|30)" example:"user"`
|
Username string `json:"username" valid:"required,alphanum,length(3|30)" example:"user"`
|
||||||
Email string `json:"email" valid:"required,email" example:"user@opplens.com"`
|
Email string `json:"email" valid:"required,email" example:"user@opplens.com"`
|
||||||
Password string `json:"password" valid:"required,length(8|128)" example:"User!1234"`
|
Password string `json:"password" valid:"required,length(8|128)" example:"User!1234"`
|
||||||
@@ -56,7 +56,6 @@ type CustomerResponse struct {
|
|||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
Phone *string `json:"phone"`
|
Phone *string `json:"phone"`
|
||||||
CompanyIDs []string `json:"company_ids"`
|
|
||||||
UpdatedAt int64 `json:"updated_at"`
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
CreatedAt int64 `json:"created_at"`
|
CreatedAt int64 `json:"created_at"`
|
||||||
LastLoginAt *int64 `json:"last_login_at"`
|
LastLoginAt *int64 `json:"last_login_at"`
|
||||||
@@ -74,7 +73,6 @@ func (c *Customer) ToResponse(companies []*CompanySummary) *CustomerResponse {
|
|||||||
Status: string(c.Status),
|
Status: string(c.Status),
|
||||||
Role: string(c.Role),
|
Role: string(c.Role),
|
||||||
Phone: c.Phone,
|
Phone: c.Phone,
|
||||||
CompanyIDs: c.CompanyIDs,
|
|
||||||
UpdatedAt: c.UpdatedAt,
|
UpdatedAt: c.UpdatedAt,
|
||||||
CreatedAt: c.CreatedAt,
|
CreatedAt: c.CreatedAt,
|
||||||
LastLoginAt: c.LastLoginAt,
|
LastLoginAt: c.LastLoginAt,
|
||||||
@@ -117,11 +115,11 @@ type AuthResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AssignCompaniesForm struct {
|
type AssignCompaniesForm struct {
|
||||||
CompanyIDs []string `json:"company_ids" valid:"required"`
|
Companies []string `json:"companies" valid:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RemoveCompaniesForm struct {
|
type RemoveCompaniesForm struct {
|
||||||
CompanyIDs []string `json:"company_ids" valid:"required"`
|
Companies []string `json:"companies" valid:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestResetPasswordForm represents the form for requesting password reset
|
// RequestResetPasswordForm represents the form for requesting password reset
|
||||||
|
|||||||
@@ -79,9 +79,9 @@ func (s *customerService) Register(ctx context.Context, form *CreateCustomerForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify that all company IDs exist
|
// Verify that all company IDs exist
|
||||||
var companyIDs []string
|
var Companies []string
|
||||||
if len(form.CompanyIDs) > 0 {
|
if len(form.Companies) > 0 {
|
||||||
for _, companyID := range form.CompanyIDs {
|
for _, companyID := range form.Companies {
|
||||||
_, err := s.companyService.GetByID(ctx, companyID)
|
_, err := s.companyService.GetByID(ctx, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Invalid company ID provided", map[string]interface{}{
|
s.logger.Error("Invalid company ID provided", map[string]interface{}{
|
||||||
@@ -91,7 +91,7 @@ func (s *customerService) Register(ctx context.Context, form *CreateCustomerForm
|
|||||||
return nil, errors.New("invalid company ID: " + companyID)
|
return nil, errors.New("invalid company ID: " + companyID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
companyIDs = form.CompanyIDs
|
Companies = form.Companies
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash password
|
// Hash password
|
||||||
@@ -108,7 +108,7 @@ func (s *customerService) Register(ctx context.Context, form *CreateCustomerForm
|
|||||||
Type: CustomerType(form.Type),
|
Type: CustomerType(form.Type),
|
||||||
Role: CustomerRole(form.Role),
|
Role: CustomerRole(form.Role),
|
||||||
Status: CustomerStatusActive,
|
Status: CustomerStatusActive,
|
||||||
CompanyIDs: companyIDs,
|
Companies: Companies,
|
||||||
FullName: form.FullName,
|
FullName: form.FullName,
|
||||||
Username: form.Username,
|
Username: form.Username,
|
||||||
Email: form.Email,
|
Email: form.Email,
|
||||||
@@ -131,7 +131,7 @@ func (s *customerService) Register(ctx context.Context, form *CreateCustomerForm
|
|||||||
"customer_id": customer.ID,
|
"customer_id": customer.ID,
|
||||||
"email": customer.Email,
|
"email": customer.Email,
|
||||||
"type": customer.Type,
|
"type": customer.Type,
|
||||||
"company_ids": companyIDs,
|
"company_ids": Companies,
|
||||||
})
|
})
|
||||||
|
|
||||||
go s.notification.SendEmail(ctx, customer.Email, fmt.Sprintf("Welcome to Tender Management\nUsername: %s\nPassword: %s", customer.Username, form.Password), customer.ID.Hex())
|
go s.notification.SendEmail(ctx, customer.Email, fmt.Sprintf("Welcome to Tender Management\nUsername: %s\nPassword: %s", customer.Username, form.Password), customer.ID.Hex())
|
||||||
@@ -151,7 +151,7 @@ func (s *customerService) GetByID(ctx context.Context, id string) (*CustomerResp
|
|||||||
}
|
}
|
||||||
|
|
||||||
var companies []*CompanySummary
|
var companies []*CompanySummary
|
||||||
if len(customer.CompanyIDs) > 0 {
|
if len(customer.Companies) > 0 {
|
||||||
companies, err = s.loadCompaniesForCustomer(ctx, customer)
|
companies, err = s.loadCompaniesForCustomer(ctx, customer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to load companies for customer", map[string]interface{}{
|
s.logger.Error("Failed to load companies for customer", map[string]interface{}{
|
||||||
@@ -229,10 +229,10 @@ func (s *customerService) Update(ctx context.Context, id string, form *UpdateCus
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle company assignments
|
// Handle company assignments
|
||||||
if len(form.CompanyIDs) > 0 {
|
if len(form.Companies) > 0 {
|
||||||
// Verify that all company IDs exist
|
// Verify that all company IDs exist
|
||||||
var validCompanyIDs []string
|
var validCompanies []string
|
||||||
for _, companyID := range form.CompanyIDs {
|
for _, companyID := range form.Companies {
|
||||||
_, err := s.companyService.GetByID(ctx, companyID)
|
_, err := s.companyService.GetByID(ctx, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Invalid company ID provided in update", map[string]interface{}{
|
s.logger.Error("Invalid company ID provided in update", map[string]interface{}{
|
||||||
@@ -241,9 +241,9 @@ func (s *customerService) Update(ctx context.Context, id string, form *UpdateCus
|
|||||||
})
|
})
|
||||||
return nil, errors.New("invalid company ID: " + companyID)
|
return nil, errors.New("invalid company ID: " + companyID)
|
||||||
}
|
}
|
||||||
validCompanyIDs = append(validCompanyIDs, companyID)
|
validCompanies = append(validCompanies, companyID)
|
||||||
}
|
}
|
||||||
customer.CompanyIDs = validCompanyIDs
|
customer.Companies = validCompanies
|
||||||
}
|
}
|
||||||
|
|
||||||
if form.FullName != nil {
|
if form.FullName != nil {
|
||||||
@@ -337,7 +337,7 @@ func (s *customerService) UpdateStatus(ctx context.Context, id string, form *Upd
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AssignCompanies assigns companies to a customer
|
// AssignCompanies assigns companies to a customer
|
||||||
func (s *customerService) AssignCompanies(ctx context.Context, customerID string, companyIDs []string) error {
|
func (s *customerService) AssignCompanies(ctx context.Context, customerID string, Companies []string) error {
|
||||||
// Get customer to check if exists
|
// Get customer to check if exists
|
||||||
customer, err := s.repository.GetByID(ctx, customerID)
|
customer, err := s.repository.GetByID(ctx, customerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -345,8 +345,8 @@ func (s *customerService) AssignCompanies(ctx context.Context, customerID string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify companies exist and update customer's company IDs
|
// Verify companies exist and update customer's company IDs
|
||||||
var validCompanyIDs []string
|
var validCompanies []string
|
||||||
for _, companyID := range companyIDs {
|
for _, companyID := range Companies {
|
||||||
_, err = s.companyService.GetByID(ctx, companyID)
|
_, err = s.companyService.GetByID(ctx, companyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Company not found during assignment", map[string]interface{}{
|
s.logger.Error("Company not found during assignment", map[string]interface{}{
|
||||||
@@ -356,11 +356,11 @@ func (s *customerService) AssignCompanies(ctx context.Context, customerID string
|
|||||||
})
|
})
|
||||||
continue // Skip invalid company IDs
|
continue // Skip invalid company IDs
|
||||||
}
|
}
|
||||||
validCompanyIDs = append(validCompanyIDs, companyID)
|
validCompanies = append(validCompanies, companyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update customer's company IDs
|
// Update customer's company IDs
|
||||||
customer.CompanyIDs = append(customer.CompanyIDs, validCompanyIDs...)
|
customer.Companies = append(customer.Companies, validCompanies...)
|
||||||
customer.UpdatedAt = time.Now().Unix()
|
customer.UpdatedAt = time.Now().Unix()
|
||||||
|
|
||||||
err = s.repository.Update(ctx, customer)
|
err = s.repository.Update(ctx, customer)
|
||||||
@@ -374,14 +374,14 @@ func (s *customerService) AssignCompanies(ctx context.Context, customerID string
|
|||||||
|
|
||||||
s.logger.Info("Companies assigned to customer successfully", map[string]interface{}{
|
s.logger.Info("Companies assigned to customer successfully", map[string]interface{}{
|
||||||
"customer_id": customerID,
|
"customer_id": customerID,
|
||||||
"company_ids": validCompanyIDs,
|
"company_ids": validCompanies,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveCompaniesFromCustomer removes companies from a customer
|
// RemoveCompaniesFromCustomer removes companies from a customer
|
||||||
func (s *customerService) RemoveCompanies(ctx context.Context, customerID string, companyIDs []string) error {
|
func (s *customerService) RemoveCompanies(ctx context.Context, customerID string, Companies []string) error {
|
||||||
// Get customer to check if exists
|
// Get customer to check if exists
|
||||||
customer, err := s.repository.GetByID(ctx, customerID)
|
customer, err := s.repository.GetByID(ctx, customerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -389,22 +389,22 @@ func (s *customerService) RemoveCompanies(ctx context.Context, customerID string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove company IDs from customer's list
|
// Remove company IDs from customer's list
|
||||||
var updatedCompanyIDs []string
|
var updatedCompanies []string
|
||||||
for _, existingID := range customer.CompanyIDs {
|
for _, existingID := range customer.Companies {
|
||||||
shouldRemove := false
|
shouldRemove := false
|
||||||
for _, removeID := range companyIDs {
|
for _, removeID := range Companies {
|
||||||
if existingID == removeID {
|
if existingID == removeID {
|
||||||
shouldRemove = true
|
shouldRemove = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !shouldRemove {
|
if !shouldRemove {
|
||||||
updatedCompanyIDs = append(updatedCompanyIDs, existingID)
|
updatedCompanies = append(updatedCompanies, existingID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update customer's company IDs
|
// Update customer's company IDs
|
||||||
customer.CompanyIDs = updatedCompanyIDs
|
customer.Companies = updatedCompanies
|
||||||
customer.UpdatedAt = time.Now().Unix()
|
customer.UpdatedAt = time.Now().Unix()
|
||||||
|
|
||||||
err = s.repository.Update(ctx, customer)
|
err = s.repository.Update(ctx, customer)
|
||||||
@@ -418,7 +418,7 @@ func (s *customerService) RemoveCompanies(ctx context.Context, customerID string
|
|||||||
|
|
||||||
s.logger.Info("Companies removed from customer successfully", map[string]interface{}{
|
s.logger.Info("Companies removed from customer successfully", map[string]interface{}{
|
||||||
"customer_id": customerID,
|
"customer_id": customerID,
|
||||||
"company_ids": companyIDs,
|
"company_ids": Companies,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -512,8 +512,8 @@ func (s *customerService) Login(ctx context.Context, form *LoginForm) (*AuthResp
|
|||||||
|
|
||||||
// Generate JWT tokens using authorization service
|
// Generate JWT tokens using authorization service
|
||||||
companyID := ""
|
companyID := ""
|
||||||
if len(customer.CompanyIDs) > 0 {
|
if len(customer.Companies) > 0 {
|
||||||
companyID = customer.CompanyIDs[0] // Use first company ID for JWT token
|
companyID = customer.Companies[0] // Use first company ID for JWT token
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenPair, err := s.authService.GenerateTokenPair(
|
tokenPair, err := s.authService.GenerateTokenPair(
|
||||||
@@ -1038,17 +1038,17 @@ func (s *customerService) isValidPassword(password string) bool {
|
|||||||
|
|
||||||
// loadCompaniesForCustomer loads company summaries for a customer
|
// loadCompaniesForCustomer loads company summaries for a customer
|
||||||
func (s *customerService) loadCompaniesForCustomer(ctx context.Context, customer *Customer) ([]*CompanySummary, error) {
|
func (s *customerService) loadCompaniesForCustomer(ctx context.Context, customer *Customer) ([]*CompanySummary, error) {
|
||||||
if len(customer.CompanyIDs) == 0 {
|
if len(customer.Companies) == 0 {
|
||||||
return []*CompanySummary{}, nil
|
return []*CompanySummary{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load companies in batch using the new GetCompaniesByIDs method
|
// Load companies in batch using the new GetCompaniesByIDs method
|
||||||
companies, err := s.companyService.GetByIDs(ctx, customer.CompanyIDs)
|
companies, err := s.companyService.GetByIDs(ctx, customer.Companies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to load companies for customer", map[string]interface{}{
|
s.logger.Error("Failed to load companies for customer", map[string]interface{}{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
"customer_id": customer.ID,
|
"customer_id": customer.ID,
|
||||||
"company_ids": customer.CompanyIDs,
|
"company_ids": customer.Companies,
|
||||||
})
|
})
|
||||||
return []*CompanySummary{}, err
|
return []*CompanySummary{}, err
|
||||||
}
|
}
|
||||||
@@ -1064,7 +1064,7 @@ func (s *customerService) loadCompaniesForCustomer(ctx context.Context, customer
|
|||||||
|
|
||||||
s.logger.Info("Companies loaded for customer", map[string]interface{}{
|
s.logger.Info("Companies loaded for customer", map[string]interface{}{
|
||||||
"customer_id": customer.ID,
|
"customer_id": customer.ID,
|
||||||
"requested_count": len(customer.CompanyIDs),
|
"requested_count": len(customer.Companies),
|
||||||
"loaded_count": len(companySummaries),
|
"loaded_count": len(companySummaries),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user