Update API documentation to reflect customer authorization changes
- Changed tags from "Customers-Mobile" to "Customers-Authorization" in Swagger documentation for customer logout and profile retrieval endpoints. - Updated the Company entity to replace CustomerID with OwnerCustomerID to better represent ownership. - Removed obsolete customer assignment methods and related forms from the company domain, streamlining the codebase. - Adjusted customer forms to include CompanyID instead of CompanyName for better consistency in customer management. - Enhanced Swagger documentation to accurately reflect the new structure and authorization details for customer-related endpoints.
This commit is contained in:
@@ -3914,7 +3914,7 @@ const docTemplate = `{
|
|||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Customers-Mobile"
|
"Customers-Authorization"
|
||||||
],
|
],
|
||||||
"summary": "Customer logout",
|
"summary": "Customer logout",
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -3954,7 +3954,7 @@ const docTemplate = `{
|
|||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Customers-Mobile"
|
"Customers-Authorization"
|
||||||
],
|
],
|
||||||
"summary": "Get customer profile",
|
"summary": "Get customer profile",
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|||||||
@@ -3907,7 +3907,7 @@
|
|||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Customers-Mobile"
|
"Customers-Authorization"
|
||||||
],
|
],
|
||||||
"summary": "Customer logout",
|
"summary": "Customer logout",
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -3947,7 +3947,7 @@
|
|||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"Customers-Mobile"
|
"Customers-Authorization"
|
||||||
],
|
],
|
||||||
"summary": "Get customer profile",
|
"summary": "Get customer profile",
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|||||||
@@ -3413,7 +3413,7 @@ paths:
|
|||||||
- BearerAuth: []
|
- BearerAuth: []
|
||||||
summary: Customer logout
|
summary: Customer logout
|
||||||
tags:
|
tags:
|
||||||
- Customers-Mobile
|
- Customers-Authorization
|
||||||
/api/v1/profile:
|
/api/v1/profile:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -3447,7 +3447,7 @@ paths:
|
|||||||
- BearerAuth: []
|
- BearerAuth: []
|
||||||
summary: Get customer profile
|
summary: Get customer profile
|
||||||
tags:
|
tags:
|
||||||
- Customers-Mobile
|
- Customers-Authorization
|
||||||
/api/v1/refresh-token:
|
/api/v1/refresh-token:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ type Company struct {
|
|||||||
Currency string `bson:"currency" json:"currency"` // Default: "USD"
|
Currency string `bson:"currency" json:"currency"` // Default: "USD"
|
||||||
Timezone string `bson:"timezone" json:"timezone"` // Default: "UTC"
|
Timezone string `bson:"timezone" json:"timezone"` // Default: "UTC"
|
||||||
|
|
||||||
// Customer assignment (for login credentials)
|
// Company ownership - which customer owns this company
|
||||||
CustomerID *string `bson:"customer_id,omitempty" json:"customer_id,omitempty"`
|
OwnerCustomerID *string `bson:"owner_customer_id,omitempty" json:"owner_customer_id,omitempty"`
|
||||||
|
|
||||||
// Audit fields
|
// Audit fields
|
||||||
CreatedBy *string `bson:"created_by,omitempty" json:"created_by,omitempty"`
|
CreatedBy *string `bson:"created_by,omitempty" json:"created_by,omitempty"`
|
||||||
@@ -165,7 +165,7 @@ type CompanyResponse struct {
|
|||||||
Language string `json:"language"`
|
Language string `json:"language"`
|
||||||
Currency string `json:"currency"`
|
Currency string `json:"currency"`
|
||||||
Timezone string `json:"timezone"`
|
Timezone string `json:"timezone"`
|
||||||
CustomerID *string `json:"customer_id,omitempty"`
|
OwnerCustomerID *string `json:"owner_customer_id,omitempty"`
|
||||||
CreatedAt int64 `json:"created_at"`
|
CreatedAt int64 `json:"created_at"`
|
||||||
UpdatedAt int64 `json:"updated_at"`
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
CreatedBy *string `json:"created_by,omitempty"`
|
CreatedBy *string `json:"created_by,omitempty"`
|
||||||
@@ -198,7 +198,7 @@ func (c *Company) ToResponse() *CompanyResponse {
|
|||||||
Language: c.Language,
|
Language: c.Language,
|
||||||
Currency: c.Currency,
|
Currency: c.Currency,
|
||||||
Timezone: c.Timezone,
|
Timezone: c.Timezone,
|
||||||
CustomerID: c.CustomerID,
|
OwnerCustomerID: c.OwnerCustomerID,
|
||||||
CreatedAt: c.CreatedAt,
|
CreatedAt: c.CreatedAt,
|
||||||
UpdatedAt: c.UpdatedAt,
|
UpdatedAt: c.UpdatedAt,
|
||||||
CreatedBy: c.CreatedBy,
|
CreatedBy: c.CreatedBy,
|
||||||
|
|||||||
@@ -61,9 +61,6 @@ type UpdateCompanyForm struct {
|
|||||||
// Tags for categorization and search
|
// Tags for categorization and search
|
||||||
Tags *CompanyTagsForm `json:"tags,omitempty"`
|
Tags *CompanyTagsForm `json:"tags,omitempty"`
|
||||||
|
|
||||||
// Customer assignment (for login credentials)
|
|
||||||
CustomerID *string `json:"customer_id,omitempty" valid:"optional,uuid"`
|
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
Language *string `json:"language,omitempty" valid:"optional,in(en|ar|fr|es|de|zh|ja|ko)"`
|
Language *string `json:"language,omitempty" valid:"optional,in(en|ar|fr|es|de|zh|ja|ko)"`
|
||||||
Currency *string `json:"currency,omitempty" valid:"optional,in(USD|EUR|GBP|JPY|CAD|AUD|CHF|CNY|INR|BRL)"`
|
Currency *string `json:"currency,omitempty" valid:"optional,in(USD|EUR|GBP|JPY|CAD|AUD|CHF|CNY|INR|BRL)"`
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ func (h *Handler) RegisterRoutes(e *echo.Echo) {
|
|||||||
adminV1.GET("/search", h.SearchCompanies)
|
adminV1.GET("/search", h.SearchCompanies)
|
||||||
adminV1.PATCH("/:id/status", h.UpdateCompanyStatus)
|
adminV1.PATCH("/:id/status", h.UpdateCompanyStatus)
|
||||||
adminV1.PATCH("/:id/verification", h.UpdateCompanyVerification)
|
adminV1.PATCH("/:id/verification", h.UpdateCompanyVerification)
|
||||||
adminV1.POST("/:id/assign-customer", h.AssignCustomer)
|
|
||||||
adminV1.POST("/:id/unassign-customer", h.UnassignCustomer)
|
|
||||||
adminV1.PUT("/:id/tags", h.UpdateCompanyTags)
|
adminV1.PUT("/:id/tags", h.UpdateCompanyTags)
|
||||||
adminV1.POST("/:id/tags/add", h.AddTags)
|
adminV1.POST("/:id/tags/add", h.AddTags)
|
||||||
adminV1.POST("/:id/tags/remove", h.RemoveTags)
|
adminV1.POST("/:id/tags/remove", h.RemoveTags)
|
||||||
@@ -370,86 +368,6 @@ func (h *Handler) UpdateCompanyVerification(c echo.Context) error {
|
|||||||
}, "Company verification updated successfully")
|
}, "Company verification updated successfully")
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssignCustomer assigns a customer to a company (Web Panel)
|
|
||||||
// @Summary Assign customer to company
|
|
||||||
// @Description Assign a customer to a company for login credentials
|
|
||||||
// @Tags Companies-Admin
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param id path string true "Company ID"
|
|
||||||
// @Param assignment body AssignCustomerForm true "Customer assignment information"
|
|
||||||
// @Success 200 {object} response.APIResponse "Customer assigned successfully"
|
|
||||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid input data"
|
|
||||||
// @Failure 404 {object} response.APIResponse "Not found - Company not found"
|
|
||||||
// @Failure 409 {object} response.APIResponse "Conflict - Customer already assigned"
|
|
||||||
// @Failure 422 {object} response.APIResponse "Validation error - Invalid request data"
|
|
||||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
|
||||||
// @Security BearerAuth
|
|
||||||
// @Router /admin/v1/companies/{id}/assign-customer [post]
|
|
||||||
func (h *Handler) AssignCustomer(c echo.Context) error {
|
|
||||||
id := c.Param("id")
|
|
||||||
form, err := response.Parse[AssignCustomerForm](c)
|
|
||||||
if err != nil {
|
|
||||||
return response.ValidationError(c, "Invalid request data", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get user ID from JWT token context
|
|
||||||
assignedBy, err := user.GetUserIDFromContext(c)
|
|
||||||
if err != nil {
|
|
||||||
return response.Unauthorized(c, "User not authenticated")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.service.AssignCustomer(c.Request().Context(), id, form, &assignedBy)
|
|
||||||
if err != nil {
|
|
||||||
if err.Error() == "company not found" {
|
|
||||||
return response.NotFound(c, "Company not found")
|
|
||||||
}
|
|
||||||
if err.Error() == "customer is already assigned to another company" {
|
|
||||||
return response.Conflict(c, err.Error())
|
|
||||||
}
|
|
||||||
return response.InternalServerError(c, "Failed to assign customer")
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.Success(c, map[string]interface{}{
|
|
||||||
"message": "Customer assigned successfully",
|
|
||||||
}, "Customer assigned successfully")
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnassignCustomer unassigns a customer from a company (Web Panel)
|
|
||||||
// @Summary Unassign customer from company
|
|
||||||
// @Description Remove customer assignment from a company
|
|
||||||
// @Tags Companies-Admin
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Param id path string true "Company ID"
|
|
||||||
// @Success 200 {object} response.APIResponse "Customer unassigned successfully"
|
|
||||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid company ID"
|
|
||||||
// @Failure 404 {object} response.APIResponse "Not found - Company not found"
|
|
||||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
|
||||||
// @Security BearerAuth
|
|
||||||
// @Router /admin/v1/companies/{id}/unassign-customer [post]
|
|
||||||
func (h *Handler) UnassignCustomer(c echo.Context) error {
|
|
||||||
id := c.Param("id")
|
|
||||||
|
|
||||||
// Get user ID from JWT token context
|
|
||||||
unassignedBy, err := user.GetUserIDFromContext(c)
|
|
||||||
if err != nil {
|
|
||||||
return response.Unauthorized(c, "User not authenticated")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.service.UnassignCustomer(c.Request().Context(), id, &unassignedBy)
|
|
||||||
if err != nil {
|
|
||||||
if err.Error() == "company not found" {
|
|
||||||
return response.NotFound(c, "Company not found")
|
|
||||||
}
|
|
||||||
return response.InternalServerError(c, "Failed to unassign customer")
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.Success(c, map[string]interface{}{
|
|
||||||
"message": "Customer unassigned successfully",
|
|
||||||
}, "Customer unassigned successfully")
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateCompanyTags updates company tags (Web Panel)
|
// UpdateCompanyTags updates company tags (Web Panel)
|
||||||
// @Summary Update company tags
|
// @Summary Update company tags
|
||||||
// @Description Update company tags (CPV, categories, keywords, specializations, certifications)
|
// @Description Update company tags (CPV, categories, keywords, specializations, certifications)
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ type Repository interface {
|
|||||||
CountWithCustomer(ctx context.Context) (int64, error)
|
CountWithCustomer(ctx context.Context) (int64, error)
|
||||||
UpdateStatus(ctx context.Context, id string, status CompanyStatus) error
|
UpdateStatus(ctx context.Context, id string, status CompanyStatus) error
|
||||||
UpdateVerification(ctx context.Context, id string, isVerified, isCompliant bool, complianceNotes *string) error
|
UpdateVerification(ctx context.Context, id string, isVerified, isCompliant bool, complianceNotes *string) error
|
||||||
AssignCustomer(ctx context.Context, id string, customerID string) error
|
|
||||||
UnassignCustomer(ctx context.Context, id string) error
|
|
||||||
UpdateTags(ctx context.Context, id string, tags *CompanyTags) error
|
UpdateTags(ctx context.Context, id string, tags *CompanyTags) error
|
||||||
AddTags(ctx context.Context, id string, cpvCodes []string, categories []string, keywords []string, specializations []string, certifications []string) error
|
AddTags(ctx context.Context, id string, cpvCodes []string, categories []string, keywords []string, specializations []string, certifications []string) error
|
||||||
RemoveTags(ctx context.Context, id string, cpvCodes []string, categories []string, keywords []string, specializations []string, certifications []string) error
|
RemoveTags(ctx context.Context, id string, cpvCodes []string, categories []string, keywords []string, specializations []string, certifications []string) error
|
||||||
@@ -591,66 +589,6 @@ func (r *companyRepository) UpdateVerification(ctx context.Context, id string, i
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssignCustomer assigns a customer to a company
|
|
||||||
func (r *companyRepository) AssignCustomer(ctx context.Context, id string, customerID string) error {
|
|
||||||
// Get company first
|
|
||||||
company, err := r.GetByID(ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign customer
|
|
||||||
company.CustomerID = &customerID
|
|
||||||
company.SetUpdatedAt(time.Now().Unix())
|
|
||||||
|
|
||||||
// Update in database
|
|
||||||
err = r.ormRepo.Update(ctx, company)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.Error("Failed to assign customer to company", map[string]interface{}{
|
|
||||||
"error": err.Error(),
|
|
||||||
"company_id": id,
|
|
||||||
"customer_id": customerID,
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
r.logger.Info("Customer assigned to company successfully", map[string]interface{}{
|
|
||||||
"company_id": id,
|
|
||||||
"customer_id": customerID,
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnassignCustomer unassigns a customer from a company
|
|
||||||
func (r *companyRepository) UnassignCustomer(ctx context.Context, id string) error {
|
|
||||||
// Get company first
|
|
||||||
company, err := r.GetByID(ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unassign customer
|
|
||||||
company.CustomerID = nil
|
|
||||||
company.SetUpdatedAt(time.Now().Unix())
|
|
||||||
|
|
||||||
// Update in database
|
|
||||||
err = r.ormRepo.Update(ctx, company)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.Error("Failed to unassign customer from company", map[string]interface{}{
|
|
||||||
"error": err.Error(),
|
|
||||||
"company_id": id,
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
r.logger.Info("Customer unassigned from company successfully", map[string]interface{}{
|
|
||||||
"company_id": id,
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateTags updates company tags
|
// UpdateTags updates company tags
|
||||||
func (r *companyRepository) UpdateTags(ctx context.Context, id string, tags *CompanyTags) error {
|
func (r *companyRepository) UpdateTags(ctx context.Context, id string, tags *CompanyTags) error {
|
||||||
// Get company first
|
// Get company first
|
||||||
|
|||||||
@@ -25,11 +25,6 @@ type Service interface {
|
|||||||
UpdateCompanyStatus(ctx context.Context, id string, form *UpdateCompanyStatusForm, updatedBy *string) error
|
UpdateCompanyStatus(ctx context.Context, id string, form *UpdateCompanyStatusForm, updatedBy *string) error
|
||||||
UpdateCompanyVerification(ctx context.Context, id string, form *UpdateCompanyVerificationForm, updatedBy *string) error
|
UpdateCompanyVerification(ctx context.Context, id string, form *UpdateCompanyVerificationForm, updatedBy *string) error
|
||||||
|
|
||||||
// Customer assignment
|
|
||||||
AssignCustomer(ctx context.Context, id string, form *AssignCustomerForm, assignedBy *string) error
|
|
||||||
UnassignCustomer(ctx context.Context, id string, unassignedBy *string) error
|
|
||||||
GetCompanyByCustomerID(ctx context.Context, customerID string) (*Company, error)
|
|
||||||
|
|
||||||
// Tag management
|
// Tag management
|
||||||
UpdateCompanyTags(ctx context.Context, id string, form *UpdateCompanyTagsForm, updatedBy *string) error
|
UpdateCompanyTags(ctx context.Context, id string, form *UpdateCompanyTagsForm, updatedBy *string) error
|
||||||
AddTags(ctx context.Context, id string, form *AddTagsForm, updatedBy *string) error
|
AddTags(ctx context.Context, id string, form *AddTagsForm, updatedBy *string) error
|
||||||
@@ -101,7 +96,6 @@ func (s *companyService) CreateCompany(ctx context.Context, form *CreateCompanyF
|
|||||||
Phone: form.Phone,
|
Phone: form.Phone,
|
||||||
Email: form.Email,
|
Email: form.Email,
|
||||||
Tags: s.convertCompanyTagsForm(form.Tags),
|
Tags: s.convertCompanyTagsForm(form.Tags),
|
||||||
CustomerID: form.CustomerID,
|
|
||||||
IsVerified: false,
|
IsVerified: false,
|
||||||
IsCompliant: false,
|
IsCompliant: false,
|
||||||
Language: s.getDefaultLanguage(form.Language),
|
Language: s.getDefaultLanguage(form.Language),
|
||||||
@@ -238,10 +232,6 @@ func (s *companyService) UpdateCompany(ctx context.Context, id string, form *Upd
|
|||||||
company.Tags = s.convertCompanyTagsForm(form.Tags)
|
company.Tags = s.convertCompanyTagsForm(form.Tags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if form.CustomerID != nil {
|
|
||||||
company.CustomerID = form.CustomerID
|
|
||||||
}
|
|
||||||
|
|
||||||
if form.Language != nil {
|
if form.Language != nil {
|
||||||
company.Language = *form.Language
|
company.Language = *form.Language
|
||||||
}
|
}
|
||||||
@@ -479,66 +469,6 @@ func (s *companyService) UpdateCompanyVerification(ctx context.Context, id strin
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssignCustomer assigns a customer to a company
|
|
||||||
func (s *companyService) AssignCustomer(ctx context.Context, id string, form *AssignCustomerForm, assignedBy *string) error {
|
|
||||||
// Get company to check if exists
|
|
||||||
_, err := s.repository.GetByID(ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("company not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if customer is already assigned to another company
|
|
||||||
existingCompany, _ := s.repository.GetByCustomerID(ctx, form.CustomerID)
|
|
||||||
if existingCompany != nil {
|
|
||||||
return errors.New("customer is already assigned to another company")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign customer
|
|
||||||
err = s.repository.AssignCustomer(ctx, id, form.CustomerID)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Error("Failed to assign customer to company", map[string]interface{}{
|
|
||||||
"error": err.Error(),
|
|
||||||
"company_id": id,
|
|
||||||
"customer_id": form.CustomerID,
|
|
||||||
})
|
|
||||||
return errors.New("failed to assign customer to company")
|
|
||||||
}
|
|
||||||
|
|
||||||
s.logger.Info("Customer assigned to company successfully", map[string]interface{}{
|
|
||||||
"company_id": id,
|
|
||||||
"customer_id": form.CustomerID,
|
|
||||||
"assigned_by": assignedBy,
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnassignCustomer unassigns a customer from a company
|
|
||||||
func (s *companyService) UnassignCustomer(ctx context.Context, id string, unassignedBy *string) error {
|
|
||||||
// Get company to check if exists
|
|
||||||
_, err := s.repository.GetByID(ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("company not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unassign customer
|
|
||||||
err = s.repository.UnassignCustomer(ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Error("Failed to unassign customer from company", map[string]interface{}{
|
|
||||||
"error": err.Error(),
|
|
||||||
"company_id": id,
|
|
||||||
})
|
|
||||||
return errors.New("failed to unassign customer from company")
|
|
||||||
}
|
|
||||||
|
|
||||||
s.logger.Info("Customer unassigned from company successfully", map[string]interface{}{
|
|
||||||
"company_id": id,
|
|
||||||
"unassigned_by": unassignedBy,
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCompanyByCustomerID retrieves a company by customer ID
|
// GetCompanyByCustomerID retrieves a company by customer ID
|
||||||
func (s *companyService) GetCompanyByCustomerID(ctx context.Context, customerID string) (*Company, error) {
|
func (s *companyService) GetCompanyByCustomerID(ctx context.Context, customerID string) (*Company, error) {
|
||||||
company, err := s.repository.GetByCustomerID(ctx, customerID)
|
company, err := s.repository.GetByCustomerID(ctx, customerID)
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Customer represents a customer in the tender management system
|
// Customer represents a customer in the tender management system
|
||||||
|
// A customer can have an associated company for login purposes
|
||||||
type Customer struct {
|
type Customer struct {
|
||||||
mongo.Model
|
mongo.Model
|
||||||
Type CustomerType `bson:"type" json:"type"`
|
Type CustomerType `bson:"type" json:"type"`
|
||||||
Status CustomerStatus `bson:"status" json:"status"`
|
Status CustomerStatus `bson:"status" json:"status"`
|
||||||
CompanyID *string `bson:"company_id,omitempty" json:"company_id,omitempty"`
|
|
||||||
|
|
||||||
// Individual customer fields
|
// Individual customer fields
|
||||||
FirstName *string `bson:"first_name,omitempty" json:"first_name,omitempty"`
|
FirstName *string `bson:"first_name,omitempty" json:"first_name,omitempty"`
|
||||||
@@ -40,8 +40,8 @@ type Customer struct {
|
|||||||
Phone *string `bson:"phone,omitempty" json:"phone,omitempty"`
|
Phone *string `bson:"phone,omitempty" json:"phone,omitempty"`
|
||||||
Mobile *string `bson:"mobile,omitempty" json:"mobile,omitempty"`
|
Mobile *string `bson:"mobile,omitempty" json:"mobile,omitempty"`
|
||||||
|
|
||||||
// Company customer fields
|
// Company customer fields (for when customer represents a company)
|
||||||
CompanyName *string `bson:"company_name,omitempty" json:"company_name,omitempty"`
|
CompanyID *string `bson:"company_id,omitempty" json:"company_id,omitempty"`
|
||||||
RegistrationNumber *string `bson:"registration_number,omitempty" json:"registration_number,omitempty"`
|
RegistrationNumber *string `bson:"registration_number,omitempty" json:"registration_number,omitempty"`
|
||||||
TaxID *string `bson:"tax_id,omitempty" json:"tax_id,omitempty"`
|
TaxID *string `bson:"tax_id,omitempty" json:"tax_id,omitempty"`
|
||||||
Industry *string `bson:"industry,omitempty" json:"industry,omitempty"`
|
Industry *string `bson:"industry,omitempty" json:"industry,omitempty"`
|
||||||
@@ -63,7 +63,7 @@ type Customer struct {
|
|||||||
IsCompliant bool `bson:"is_compliant" json:"is_compliant"`
|
IsCompliant bool `bson:"is_compliant" json:"is_compliant"`
|
||||||
ComplianceNotes *string `bson:"compliance_notes,omitempty" json:"compliance_notes,omitempty"`
|
ComplianceNotes *string `bson:"compliance_notes,omitempty" json:"compliance_notes,omitempty"`
|
||||||
|
|
||||||
// Preferences and settings
|
// Settings
|
||||||
Language string `bson:"language" json:"language"` // Default: "en"
|
Language string `bson:"language" json:"language"` // Default: "en"
|
||||||
Currency string `bson:"currency" json:"currency"` // Default: "USD"
|
Currency string `bson:"currency" json:"currency"` // Default: "USD"
|
||||||
Timezone string `bson:"timezone" json:"timezone"` // Default: "UTC"
|
Timezone string `bson:"timezone" json:"timezone"` // Default: "UTC"
|
||||||
@@ -131,14 +131,13 @@ type CustomerResponse struct {
|
|||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
CompanyID *string `json:"company_id,omitempty"`
|
|
||||||
FirstName *string `json:"first_name,omitempty"`
|
FirstName *string `json:"first_name,omitempty"`
|
||||||
LastName *string `json:"last_name,omitempty"`
|
LastName *string `json:"last_name,omitempty"`
|
||||||
FullName *string `json:"full_name,omitempty"`
|
FullName *string `json:"full_name,omitempty"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Phone *string `json:"phone,omitempty"`
|
Phone *string `json:"phone,omitempty"`
|
||||||
Mobile *string `json:"mobile,omitempty"`
|
Mobile *string `json:"mobile,omitempty"`
|
||||||
CompanyName *string `json:"company_name,omitempty"`
|
CompanyID *string `json:"company_id,omitempty"`
|
||||||
RegistrationNumber *string `json:"registration_number,omitempty"`
|
RegistrationNumber *string `json:"registration_number,omitempty"`
|
||||||
TaxID *string `json:"tax_id,omitempty"`
|
TaxID *string `json:"tax_id,omitempty"`
|
||||||
Industry *string `json:"industry,omitempty"`
|
Industry *string `json:"industry,omitempty"`
|
||||||
@@ -167,7 +166,6 @@ func (c *Customer) ToResponse() *CustomerResponse {
|
|||||||
ID: c.ID,
|
ID: c.ID,
|
||||||
Type: string(c.Type),
|
Type: string(c.Type),
|
||||||
Status: string(c.Status),
|
Status: string(c.Status),
|
||||||
CompanyID: c.CompanyID,
|
|
||||||
FirstName: c.FirstName,
|
FirstName: c.FirstName,
|
||||||
LastName: c.LastName,
|
LastName: c.LastName,
|
||||||
FullName: c.FullName,
|
FullName: c.FullName,
|
||||||
@@ -175,7 +173,7 @@ func (c *Customer) ToResponse() *CustomerResponse {
|
|||||||
Email: c.Email,
|
Email: c.Email,
|
||||||
Phone: c.Phone,
|
Phone: c.Phone,
|
||||||
Mobile: c.Mobile,
|
Mobile: c.Mobile,
|
||||||
CompanyName: c.CompanyName,
|
CompanyID: c.CompanyID,
|
||||||
RegistrationNumber: c.RegistrationNumber,
|
RegistrationNumber: c.RegistrationNumber,
|
||||||
TaxID: c.TaxID,
|
TaxID: c.TaxID,
|
||||||
Industry: c.Industry,
|
Industry: c.Industry,
|
||||||
|
|||||||
+18
-18
@@ -145,27 +145,27 @@ type CustomerListResponse struct {
|
|||||||
|
|
||||||
// Mobile-specific forms (simplified for mobile app)
|
// Mobile-specific forms (simplified for mobile app)
|
||||||
type CreateCustomerMobileForm struct {
|
type CreateCustomerMobileForm struct {
|
||||||
Type string `json:"type" valid:"required,in(individual|company)"`
|
Type string `json:"type" valid:"required,in(individual|company)"`
|
||||||
FirstName *string `json:"first_name,omitempty" valid:"optional,length(2|50)"`
|
FirstName *string `json:"first_name,omitempty" valid:"optional,length(2|50)"`
|
||||||
LastName *string `json:"last_name,omitempty" valid:"optional,length(2|50)"`
|
LastName *string `json:"last_name,omitempty" valid:"optional,length(2|50)"`
|
||||||
FullName *string `json:"full_name,omitempty" valid:"optional,length(2|100)"`
|
FullName *string `json:"full_name,omitempty" valid:"optional,length(2|100)"`
|
||||||
Username string `json:"username" valid:"required,alphanum,length(3|30)"`
|
Username string `json:"username" valid:"required,alphanum,length(3|30)"`
|
||||||
Email string `json:"email" valid:"required,email"`
|
Email string `json:"email" valid:"required,email"`
|
||||||
Password string `json:"password" valid:"required,length(8|128)"`
|
Password string `json:"password" valid:"required,length(8|128)"`
|
||||||
Phone *string `json:"phone,omitempty" valid:"optional,length(10|20)"`
|
Phone *string `json:"phone,omitempty" valid:"optional,length(10|20)"`
|
||||||
Mobile *string `json:"mobile,omitempty" valid:"optional,length(10|20)"`
|
Mobile *string `json:"mobile,omitempty" valid:"optional,length(10|20)"`
|
||||||
CompanyName *string `json:"company_name,omitempty" valid:"optional,length(2|200)"`
|
CompanyID *string `json:"company_id,omitempty" valid:"optional,uuid"`
|
||||||
Industry *string `json:"industry,omitempty" valid:"optional,length(2|100)"`
|
Industry *string `json:"industry,omitempty" valid:"optional,length(2|100)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateCustomerMobileForm struct {
|
type UpdateCustomerMobileForm struct {
|
||||||
FirstName *string `json:"first_name,omitempty" valid:"optional,length(2|50)"`
|
FirstName *string `json:"first_name,omitempty" valid:"optional,length(2|50)"`
|
||||||
LastName *string `json:"last_name,omitempty" valid:"optional,length(2|50)"`
|
LastName *string `json:"last_name,omitempty" valid:"optional,length(2|50)"`
|
||||||
FullName *string `json:"full_name,omitempty" valid:"optional,length(2|100)"`
|
FullName *string `json:"full_name,omitempty" valid:"optional,length(2|100)"`
|
||||||
Phone *string `json:"phone,omitempty" valid:"optional,length(10|20)"`
|
Phone *string `json:"phone,omitempty" valid:"optional,length(10|20)"`
|
||||||
Mobile *string `json:"mobile,omitempty" valid:"optional,length(10|20)"`
|
Mobile *string `json:"mobile,omitempty" valid:"optional,length(10|20)"`
|
||||||
CompanyName *string `json:"company_name,omitempty" valid:"optional,length(2|200)"`
|
CompanyID *string `json:"company_id,omitempty" valid:"optional,uuid"`
|
||||||
Industry *string `json:"industry,omitempty" valid:"optional,length(2|100)"`
|
Industry *string `json:"industry,omitempty" valid:"optional,length(2|100)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Customer Authentication DTOs
|
// Customer Authentication DTOs
|
||||||
|
|||||||
@@ -672,7 +672,7 @@ func (h *Handler) RefreshToken(c echo.Context) error {
|
|||||||
// GetProfile retrieves customer profile information (Mobile)
|
// GetProfile retrieves customer profile information (Mobile)
|
||||||
// @Summary Get customer profile
|
// @Summary Get customer profile
|
||||||
// @Description Retrieve current customer profile information
|
// @Description Retrieve current customer profile information
|
||||||
// @Tags Customers-Mobile
|
// @Tags Customers-Authorization
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Security BearerAuth
|
// @Security BearerAuth
|
||||||
@@ -702,7 +702,7 @@ func (h *Handler) GetProfile(c echo.Context) error {
|
|||||||
// Logout handles customer logout (Mobile)
|
// Logout handles customer logout (Mobile)
|
||||||
// @Summary Customer logout
|
// @Summary Customer logout
|
||||||
// @Description Logout customer and invalidate access token
|
// @Description Logout customer and invalidate access token
|
||||||
// @Tags Customers-Mobile
|
// @Tags Customers-Authorization
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Security BearerAuth
|
// @Security BearerAuth
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ func (s *customerService) CreateCustomer(ctx context.Context, form *CreateCustom
|
|||||||
Password: string(hashedPassword),
|
Password: string(hashedPassword),
|
||||||
Phone: form.Phone,
|
Phone: form.Phone,
|
||||||
Mobile: form.Mobile,
|
Mobile: form.Mobile,
|
||||||
CompanyName: form.CompanyName,
|
|
||||||
RegistrationNumber: form.RegistrationNumber,
|
RegistrationNumber: form.RegistrationNumber,
|
||||||
TaxID: form.TaxID,
|
TaxID: form.TaxID,
|
||||||
Industry: form.Industry,
|
Industry: form.Industry,
|
||||||
@@ -211,15 +210,6 @@ func (s *customerService) UpdateCustomer(ctx context.Context, id string, form *U
|
|||||||
customer.Username = *form.Username
|
customer.Username = *form.Username
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if company name already exists (if changing company name)
|
|
||||||
if form.CompanyName != nil && *form.CompanyName != *customer.CompanyName {
|
|
||||||
existingCustomer, _ := s.repository.GetByCompanyName(ctx, *form.CompanyName)
|
|
||||||
if existingCustomer != nil {
|
|
||||||
return nil, errors.New("company with this name already exists")
|
|
||||||
}
|
|
||||||
customer.CompanyName = form.CompanyName
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if registration number already exists (if changing)
|
// Check if registration number already exists (if changing)
|
||||||
if form.RegistrationNumber != nil && *form.RegistrationNumber != *customer.RegistrationNumber {
|
if form.RegistrationNumber != nil && *form.RegistrationNumber != *customer.RegistrationNumber {
|
||||||
existingCustomer, _ := s.repository.GetByRegistrationNumber(ctx, *form.RegistrationNumber)
|
existingCustomer, _ := s.repository.GetByRegistrationNumber(ctx, *form.RegistrationNumber)
|
||||||
@@ -576,7 +566,7 @@ func (s *customerService) CreateCustomerMobile(ctx context.Context, form *Create
|
|||||||
Password: "", // Will be set after hashing
|
Password: "", // Will be set after hashing
|
||||||
Phone: form.Phone,
|
Phone: form.Phone,
|
||||||
Mobile: form.Mobile,
|
Mobile: form.Mobile,
|
||||||
CompanyName: form.CompanyName,
|
CompanyID: form.CompanyID,
|
||||||
Industry: form.Industry,
|
Industry: form.Industry,
|
||||||
IsVerified: false,
|
IsVerified: false,
|
||||||
IsCompliant: false,
|
IsCompliant: false,
|
||||||
@@ -647,8 +637,8 @@ func (s *customerService) UpdateCustomerMobile(ctx context.Context, id string, f
|
|||||||
customer.Mobile = form.Mobile
|
customer.Mobile = form.Mobile
|
||||||
}
|
}
|
||||||
|
|
||||||
if form.CompanyName != nil {
|
if form.CompanyID != nil {
|
||||||
customer.CompanyName = form.CompanyName
|
customer.CompanyID = form.CompanyID
|
||||||
}
|
}
|
||||||
|
|
||||||
if form.Industry != nil {
|
if form.Industry != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user