profile keyword manual update and recommended tenders
This commit is contained in:
@@ -41,6 +41,7 @@ type Service interface {
|
||||
Login(ctx context.Context, form *LoginForm) (*AuthResponse, error)
|
||||
RefreshToken(ctx context.Context, refreshToken string) (*AuthResponse, error)
|
||||
GetProfileWithCompanies(ctx context.Context, id string) (*CustomerResponse, error)
|
||||
UpdateProfileKeywords(ctx context.Context, customerID string, keywords []string) (*CustomerResponse, error)
|
||||
Logout(ctx context.Context, id string, accessToken string) error
|
||||
|
||||
// Forgot password operations
|
||||
@@ -96,6 +97,9 @@ func (s *customerService) Register(ctx context.Context, form *CreateCustomerForm
|
||||
var Companies []string
|
||||
if len(form.Companies) > 0 {
|
||||
for _, companyID := range form.Companies {
|
||||
if _, err := bson.ObjectIDFromHex(companyID); err != nil {
|
||||
return nil, errors.New("invalid company ID format: " + companyID)
|
||||
}
|
||||
_, err := s.companyService.GetByID(ctx, companyID)
|
||||
if err != nil {
|
||||
s.logger.Error("Invalid company ID provided", map[string]interface{}{
|
||||
@@ -405,62 +409,7 @@ func (s *customerService) Update(ctx context.Context, id string, form *UpdateCus
|
||||
customer.KeywordsStatus = KeywordsStatusInProgress
|
||||
|
||||
// Save customer with in_progress status first, then process asynchronously
|
||||
customerID := customer.ID.Hex()
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
// Get fresh customer data for processing
|
||||
cust, err := s.repository.GetByID(ctx, customerID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get customer for keyword processing", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// If GLM SDK is not available, keep manual keywords and set status to ready
|
||||
if s.glmSDK == nil {
|
||||
s.logger.Info("GLM SDK not available, keeping manual keywords", map[string]interface{}{
|
||||
"customer_id": customerID,
|
||||
})
|
||||
cust.KeywordsStatus = KeywordsStatusReady
|
||||
} else {
|
||||
// Regenerate keywords based on updated customer info
|
||||
keywords, err := s.generateKeywords(ctx, cust)
|
||||
if err != nil {
|
||||
s.logger.Warn("Failed to process keywords after manual update", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
// Keep manual keywords but set status to failed
|
||||
cust.KeywordsStatus = KeywordsStatusFailed
|
||||
} else if len(keywords) > 0 {
|
||||
// Update with AI-generated keywords
|
||||
cust.Keywords = keywords
|
||||
cust.KeywordsStatus = KeywordsStatusReady
|
||||
} else {
|
||||
// Empty keywords from GLM, keep manual keywords and set status to ready
|
||||
s.logger.Warn("GLM returned empty keywords, keeping manual keywords", map[string]interface{}{
|
||||
"customer_id": customerID,
|
||||
})
|
||||
cust.KeywordsStatus = KeywordsStatusReady
|
||||
}
|
||||
}
|
||||
|
||||
// Update customer with new status
|
||||
err = s.repository.Update(ctx, cust)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to update customer keywords status", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
} else {
|
||||
s.logger.Info("Keywords processed successfully", map[string]interface{}{
|
||||
"customer_id": customerID,
|
||||
"status": cust.KeywordsStatus,
|
||||
})
|
||||
}
|
||||
}()
|
||||
s.processKeywordsAsync(customer.ID.Hex())
|
||||
} else if infoChanged || companiesChanged {
|
||||
// Customer info changed, regenerate keywords
|
||||
customer.KeywordsStatus = KeywordsStatusInProgress
|
||||
@@ -907,6 +856,42 @@ func (s *customerService) GetProfileWithCompanies(ctx context.Context, customerI
|
||||
return customerResponse, nil
|
||||
}
|
||||
|
||||
// UpdateProfileKeywords updates customer profile keywords and triggers AI enhancement asynchronously.
|
||||
func (s *customerService) UpdateProfileKeywords(ctx context.Context, customerID string, keywords []string) (*CustomerResponse, error) {
|
||||
customer, err := s.repository.GetByID(ctx, customerID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get customer for profile keyword update", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
return nil, errors.New("customer not found")
|
||||
}
|
||||
|
||||
customer.Keywords = keywords
|
||||
customer.KeywordsStatus = KeywordsStatusInProgress
|
||||
|
||||
if err := s.repository.Update(ctx, customer); err != nil {
|
||||
s.logger.Error("Failed to save profile keywords", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
return nil, errors.New("failed to update profile keywords")
|
||||
}
|
||||
|
||||
s.processKeywordsAsync(customerID)
|
||||
|
||||
companies, err := s.loadCompaniesForCustomer(ctx, customer)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to load companies after profile keyword update", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
companies = []*CompanySummary{}
|
||||
}
|
||||
|
||||
return customer.ToResponse(companies), nil
|
||||
}
|
||||
|
||||
// Logout handles customer logout
|
||||
func (s *customerService) Logout(ctx context.Context, customerID string, accessToken string) error {
|
||||
s.logger.Info("Customer logout", map[string]interface{}{
|
||||
@@ -1398,6 +1383,12 @@ func (s *customerService) generateKeywords(ctx context.Context, customer *Custom
|
||||
if comp.Industry != "" {
|
||||
customerInfo.WriteString(fmt.Sprintf(" (Industry: %s)", comp.Industry))
|
||||
}
|
||||
if comp.Address != nil && comp.Address.Country != "" {
|
||||
customerInfo.WriteString(fmt.Sprintf(" (Country: %s)", comp.Address.Country))
|
||||
}
|
||||
if comp.Tags != nil && len(comp.Tags.Keywords) > 0 {
|
||||
customerInfo.WriteString(fmt.Sprintf(" (Company Keywords: %s)", strings.Join(comp.Tags.Keywords, ", ")))
|
||||
}
|
||||
}
|
||||
}
|
||||
customerInfo.WriteString("\n")
|
||||
@@ -1452,3 +1443,54 @@ Return ONLY a comma-separated list of keywords, no explanations or additional te
|
||||
|
||||
return keywords, nil
|
||||
}
|
||||
|
||||
func (s *customerService) processKeywordsAsync(customerID string) {
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
cust, err := s.repository.GetByID(ctx, customerID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get customer for keyword processing", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if s.glmSDK == nil {
|
||||
s.logger.Info("GLM SDK not available, keeping manual keywords", map[string]interface{}{
|
||||
"customer_id": customerID,
|
||||
})
|
||||
cust.KeywordsStatus = KeywordsStatusReady
|
||||
} else {
|
||||
keywords, err := s.generateKeywords(ctx, cust)
|
||||
if err != nil {
|
||||
s.logger.Warn("Failed to process keywords after manual update", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
cust.KeywordsStatus = KeywordsStatusFailed
|
||||
} else if len(keywords) > 0 {
|
||||
cust.Keywords = keywords
|
||||
cust.KeywordsStatus = KeywordsStatusReady
|
||||
} else {
|
||||
s.logger.Warn("GLM returned empty keywords, keeping manual keywords", map[string]interface{}{
|
||||
"customer_id": customerID,
|
||||
})
|
||||
cust.KeywordsStatus = KeywordsStatusReady
|
||||
}
|
||||
}
|
||||
|
||||
err = s.repository.Update(ctx, cust)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to update customer keywords status", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
} else {
|
||||
s.logger.Info("Keywords processed successfully", map[string]interface{}{
|
||||
"customer_id": customerID,
|
||||
"status": cust.KeywordsStatus,
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user