Refactor Notification Management and Enhance Customer Features

- Updated the notification handling logic to utilize a new SDK for sending notifications, improving the flexibility and scalability of the notification system.
- Introduced new methods in the notification service for sending notifications to users and customers based on various target audience types, enhancing the notification delivery capabilities.
- Added a new endpoint to assign companies to a customer, improving customer management functionalities.
- Refactored the customer entity and forms to replace 'CompanyIDs' with 'Companies', ensuring consistency across the data model.
- Enhanced API documentation with Swagger comments for the new endpoint and updated notification structures, ensuring clarity for API consumers.
This commit is contained in:
n.nakhostin
2025-09-20 16:54:51 +03:30
parent d2f7c6a1e5
commit 9037cb5917
18 changed files with 607 additions and 1471 deletions
+1
View File
@@ -60,6 +60,7 @@ type CustomerResponse struct {
CreatedAt int64 `json:"created_at"`
LastLoginAt *int64 `json:"last_login_at"`
Companies []*CompanySummary `json:"companies"`
DeviceToken []string `json:"-"`
}
// ToResponse converts Customer to CustomerResponse
+45
View File
@@ -20,6 +20,9 @@ type Repository interface {
GetByID(ctx context.Context, id string) (*Customer, error)
GetByEmail(ctx context.Context, email string) (*Customer, error)
GetByUsername(ctx context.Context, username string) (*Customer, error)
GetByIDs(ctx context.Context, ids []string) ([]Customer, error)
GetByRole(ctx context.Context, role CustomerRole) ([]Customer, error)
GetByCompanies(ctx context.Context, companies []string) ([]Customer, error)
GetByCompanyID(ctx context.Context, companyID string, pagination *response.Pagination) ([]*Customer, int64, error)
Search(ctx context.Context, form *SearchCustomersForm, pagination *response.Pagination) ([]Customer, int64, error)
Delete(ctx context.Context, id string) error
@@ -168,6 +171,48 @@ func (r *customerRepository) GetByUsername(ctx context.Context, username string)
return customer, nil
}
// GetByIDs retrieves customers by IDs
func (r *customerRepository) GetByIDs(ctx context.Context, ids []string) ([]Customer, error) {
customers, err := r.ormRepo.FindAll(ctx, bson.M{"_id": bson.M{"$in": ids}}, orm.NewPaginationBuilder().Limit(len(ids)).Build())
if err != nil {
if errors.Is(err, orm.ErrDocumentNotFound) {
return nil, errors.New("customers not found")
}
r.logger.Error("Failed to get customers by IDs", map[string]interface{}{
"error": err.Error(),
"ids": ids,
})
return nil, err
}
return customers.Items, nil
}
// GetByRole retrieves customers by role
func (r *customerRepository) GetByRole(ctx context.Context, role CustomerRole) ([]Customer, error) {
customers, err := r.ormRepo.FindAll(ctx, bson.M{"role": role}, orm.NewPaginationBuilder().Build())
if err != nil {
if errors.Is(err, orm.ErrDocumentNotFound) {
return nil, errors.New("customers not found")
}
r.logger.Error("Failed to get customers by role", map[string]interface{}{
"error": err.Error(),
"role": role,
})
return nil, err
}
return customers.Items, nil
}
// GetByCompanies retrieves customers by companies
func (r *customerRepository) GetByCompanies(ctx context.Context, companies []string) ([]Customer, error) {
customers, err := r.ormRepo.FindAll(ctx, bson.M{"companies": bson.M{"$in": companies}}, orm.NewPaginationBuilder().Build())
if err != nil {
return nil, err
}
return customers.Items, nil
}
// GetByCompanyID retrieves customers by company ID with pagination
func (r *customerRepository) GetByCompanyID(ctx context.Context, companyID string, pagination *response.Pagination) ([]*Customer, int64, error) {
// Build pagination
+62
View File
@@ -29,6 +29,9 @@ type Service interface {
Register(ctx context.Context, form *CreateCustomerForm) (*CustomerResponse, error)
GetByID(ctx context.Context, id string) (*CustomerResponse, error)
Search(ctx context.Context, form *SearchCustomersForm, pagination *response.Pagination) (*CustomerListResponse, error)
GetCustomersByIDs(ctx context.Context, ids []string) (*CustomerListResponse, error)
GetCustomersByRole(ctx context.Context, role string) (*CustomerListResponse, error)
GetCustomersByCompanies(ctx context.Context, companies []string) (*CustomerListResponse, error)
Update(ctx context.Context, id string, form *UpdateCustomerForm) (*CustomerResponse, error)
Delete(ctx context.Context, id string) error
UpdateStatus(ctx context.Context, id string, form *UpdateStatusForm) error
@@ -206,6 +209,65 @@ func (s *customerService) Search(ctx context.Context, form *SearchCustomersForm,
}, nil
}
// GetCustomersByIDs retrieves customers by IDs
func (s *customerService) GetCustomersByIDs(ctx context.Context, ids []string) (*CustomerListResponse, error) {
customers, err := s.repository.GetByIDs(ctx, ids)
if err != nil {
return nil, err
}
var customerResponses []*CustomerResponse
for _, customer := range customers {
customerResponses = append(customerResponses, customer.ToResponse(nil))
}
return &CustomerListResponse{
Customers: customerResponses,
}, nil
}
// GetCustomersByRole retrieves customers by role
func (s *customerService) GetCustomersByRole(ctx context.Context, role string) (*CustomerListResponse, error) {
customers, err := s.repository.GetByRole(ctx, CustomerRole(role))
if err != nil {
s.logger.Error("Failed to get customers by role", map[string]interface{}{
"error": err.Error(),
"role": role,
})
return nil, err
}
var customerResponses []*CustomerResponse
for _, customer := range customers {
customerResponses = append(customerResponses, customer.ToResponse(nil))
}
return &CustomerListResponse{
Customers: customerResponses,
}, nil
}
// GetCustomersByCompanies retrieves customers by companies
func (s *customerService) GetCustomersByCompanies(ctx context.Context, companies []string) (*CustomerListResponse, error) {
customers, err := s.repository.GetByCompanies(ctx, companies)
if err != nil {
s.logger.Error("Failed to get customers by companies", map[string]interface{}{
"error": err.Error(),
"companies": companies,
})
return nil, err
}
var customerResponses []*CustomerResponse
for _, customer := range customers {
customerResponses = append(customerResponses, customer.ToResponse(nil))
}
return &CustomerListResponse{
Customers: customerResponses,
}, nil
}
// Update updates a customer
func (s *customerService) Update(ctx context.Context, id string, form *UpdateCustomerForm) (*CustomerResponse, error) {
// Get existing customer