Refactor customer domain to use string IDs and integrate MongoDB ORM
- Updated Customer entity to embed MongoDB model and replace uuid.UUID with string for ID fields. - Modified repository methods to accept string IDs instead of uuid.UUID, enhancing compatibility with MongoDB. - Refactored service and handler methods to align with the new ID type, ensuring consistent usage across customer management functionality. - Improved response handling in CustomerResponse to directly use string IDs. - Streamlined index creation in the customer repository using the MongoDB ORM for better maintainability. - Added new forms for customer suspension and updated validation rules. - Enhanced Swagger documentation for customer-related endpoints to reflect changes in ID handling and request structures.
This commit is contained in:
+155
-158
@@ -7,7 +7,6 @@ import (
|
||||
"tm/pkg/logger"
|
||||
"tm/pkg/response"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
@@ -81,8 +80,11 @@ func (h *Handler) CreateCustomer(c echo.Context) error {
|
||||
return response.ValidationError(c, "Invalid request data", err.Error())
|
||||
}
|
||||
|
||||
// TODO: Get user ID from JWT token
|
||||
createdBy := uuid.New() // This should come from JWT token
|
||||
// Get user ID from JWT token context
|
||||
createdBy, err := user.GetUserIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.Unauthorized(c, "User not authenticated")
|
||||
}
|
||||
|
||||
customer, err := h.service.CreateCustomer(c.Request().Context(), form, &createdBy)
|
||||
if err != nil {
|
||||
@@ -98,32 +100,28 @@ func (h *Handler) CreateCustomer(c echo.Context) error {
|
||||
return response.Created(c, customer.ToResponse(), "Customer created successfully")
|
||||
}
|
||||
|
||||
// GetCustomerByID retrieves a customer by ID
|
||||
// GetCustomerByID retrieves a customer by ID (Web Panel)
|
||||
// @Summary Get customer by ID
|
||||
// @Description Retrieve detailed customer information by unique customer ID. Returns comprehensive customer data including personal details, company information, address, verification status, and audit fields.
|
||||
// @Description Retrieve detailed customer information by customer ID
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer UUID" format(uuid)
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Success 200 {object} response.APIResponse{data=CustomerResponse} "Customer retrieved successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID format"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer does not exist"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/{id} [get]
|
||||
func (h *Handler) GetCustomerByID(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := uuid.Parse(idStr)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid customer ID", err.Error())
|
||||
}
|
||||
|
||||
customer, err := h.service.GetCustomerByID(c.Request().Context(), id)
|
||||
customer, err := h.service.GetCustomerByID(c.Request().Context(), idStr)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
}
|
||||
return response.InternalServerError(c, "Failed to retrieve customer")
|
||||
return response.InternalServerError(c, "Failed to get customer")
|
||||
}
|
||||
|
||||
return response.Success(c, customer.ToResponse(), "Customer retrieved successfully")
|
||||
@@ -131,15 +129,15 @@ func (h *Handler) GetCustomerByID(c echo.Context) error {
|
||||
|
||||
// UpdateCustomer updates a customer (Web Panel)
|
||||
// @Summary Update customer information
|
||||
// @Description Update existing customer information with comprehensive details. All fields are optional and only provided fields will be updated. This endpoint is used by the web panel for full customer management.
|
||||
// @Description Update customer information including personal details, company information, address, and business details
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer UUID" format(uuid)
|
||||
// @Param customer body UpdateCustomerForm true "Customer update information - all fields are optional"
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Param customer body UpdateCustomerForm true "Updated customer information"
|
||||
// @Success 200 {object} response.APIResponse{data=CustomerResponse} "Customer updated successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID or input data"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer does not exist"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid input data"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 409 {object} response.APIResponse "Conflict - Customer with this email/company already exists"
|
||||
// @Failure 422 {object} response.APIResponse "Validation error - Invalid request data"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
@@ -147,20 +145,18 @@ func (h *Handler) GetCustomerByID(c echo.Context) error {
|
||||
// @Router /admin/v1/customers/{id} [put]
|
||||
func (h *Handler) UpdateCustomer(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := uuid.Parse(idStr)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid customer ID", err.Error())
|
||||
}
|
||||
|
||||
form, err := response.Parse[UpdateCustomerForm](c)
|
||||
if err != nil {
|
||||
return response.ValidationError(c, "Invalid request data", err.Error())
|
||||
}
|
||||
|
||||
// TODO: Get user ID from JWT token
|
||||
updatedBy := uuid.New() // This should come from JWT token
|
||||
// Get user ID from JWT token context
|
||||
updatedBy, err := user.GetUserIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.Unauthorized(c, "User not authenticated")
|
||||
}
|
||||
|
||||
customer, err := h.service.UpdateCustomer(c.Request().Context(), id, form, &updatedBy)
|
||||
customer, err := h.service.UpdateCustomer(c.Request().Context(), idStr, form, &updatedBy)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
@@ -177,30 +173,29 @@ func (h *Handler) UpdateCustomer(c echo.Context) error {
|
||||
return response.Success(c, customer.ToResponse(), "Customer updated successfully")
|
||||
}
|
||||
|
||||
// DeleteCustomer deletes a customer (soft delete)
|
||||
// DeleteCustomer deletes a customer (Web Panel)
|
||||
// @Summary Delete customer
|
||||
// @Description Soft delete a customer by setting status to inactive. The customer record is preserved but marked as deleted. This is a reversible operation.
|
||||
// @Description Soft delete a customer by setting status to inactive
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer UUID" format(uuid)
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Success 200 {object} response.APIResponse "Customer deleted successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID format"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer does not exist"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/{id} [delete]
|
||||
func (h *Handler) DeleteCustomer(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := uuid.Parse(idStr)
|
||||
|
||||
// Get user ID from JWT token context
|
||||
deletedBy, err := user.GetUserIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid customer ID", err.Error())
|
||||
return response.Unauthorized(c, "User not authenticated")
|
||||
}
|
||||
|
||||
// TODO: Get user ID from JWT token
|
||||
deletedBy := uuid.New() // This should come from JWT token
|
||||
|
||||
err = h.service.DeleteCustomer(c.Request().Context(), id, &deletedBy)
|
||||
err = h.service.DeleteCustomer(c.Request().Context(), idStr, &deletedBy)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
@@ -208,7 +203,9 @@ func (h *Handler) DeleteCustomer(c echo.Context) error {
|
||||
return response.InternalServerError(c, "Failed to delete customer")
|
||||
}
|
||||
|
||||
return response.Success(c, nil, "Customer deleted successfully")
|
||||
return response.Success(c, map[string]interface{}{
|
||||
"message": "Customer deleted successfully",
|
||||
}, "Customer deleted successfully")
|
||||
}
|
||||
|
||||
// ListCustomers lists customers with filters and pagination
|
||||
@@ -250,37 +247,35 @@ func (h *Handler) ListCustomers(c echo.Context) error {
|
||||
return response.Success(c, result, "Customers retrieved successfully")
|
||||
}
|
||||
|
||||
// UpdateCustomerStatus updates customer status
|
||||
// UpdateCustomerStatus updates customer status (Web Panel)
|
||||
// @Summary Update customer status
|
||||
// @Description Update the status of a customer account. Valid statuses include active, inactive, suspended, and pending. This affects the customer's ability to access the system.
|
||||
// @Description Update customer account status (active, inactive, suspended, pending)
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer UUID" format(uuid)
|
||||
// @Param status body UpdateCustomerStatusForm true "Status update information"
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Param status body UpdateCustomerStatusForm true "New customer status"
|
||||
// @Success 200 {object} response.APIResponse "Customer status updated successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID or status"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer does not exist"
|
||||
// @Failure 422 {object} response.APIResponse "Validation error - Invalid status value"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid input data"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 422 {object} response.APIResponse "Validation error - Invalid request data"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/{id}/status [patch]
|
||||
func (h *Handler) UpdateCustomerStatus(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := uuid.Parse(idStr)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid customer ID", err.Error())
|
||||
}
|
||||
|
||||
form, err := response.Parse[UpdateCustomerStatusForm](c)
|
||||
if err != nil {
|
||||
return response.ValidationError(c, "Invalid request data", err.Error())
|
||||
}
|
||||
|
||||
// TODO: Get user ID from JWT token
|
||||
updatedBy := uuid.New() // This should come from JWT token
|
||||
// Get user ID from JWT token context
|
||||
updatedBy, err := user.GetUserIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.Unauthorized(c, "User not authenticated")
|
||||
}
|
||||
|
||||
err = h.service.UpdateCustomerStatus(c.Request().Context(), id, form, &updatedBy)
|
||||
err = h.service.UpdateCustomerStatus(c.Request().Context(), idStr, form, &updatedBy)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
@@ -288,40 +283,40 @@ func (h *Handler) UpdateCustomerStatus(c echo.Context) error {
|
||||
return response.InternalServerError(c, "Failed to update customer status")
|
||||
}
|
||||
|
||||
return response.Success(c, nil, "Customer status updated successfully")
|
||||
return response.Success(c, map[string]interface{}{
|
||||
"message": "Customer status updated successfully",
|
||||
}, "Customer status updated successfully")
|
||||
}
|
||||
|
||||
// UpdateCustomerVerification updates customer verification status
|
||||
// @Summary Update customer verification and compliance status
|
||||
// @Description Update the verification and compliance status of a customer. This includes marking customers as verified and compliant, with optional compliance notes for audit purposes.
|
||||
// UpdateCustomerVerification updates customer verification status (Web Panel)
|
||||
// @Summary Update customer verification status
|
||||
// @Description Update customer verification and compliance status
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer UUID" format(uuid)
|
||||
// @Param verification body UpdateCustomerVerificationForm true "Verification and compliance update information"
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Param verification body UpdateCustomerVerificationForm true "Verification status update"
|
||||
// @Success 200 {object} response.APIResponse "Customer verification updated successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer does not exist"
|
||||
// @Failure 422 {object} response.APIResponse "Validation error - Invalid verification data"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid input data"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 422 {object} response.APIResponse "Validation error - Invalid request data"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/{id}/verification [patch]
|
||||
func (h *Handler) UpdateCustomerVerification(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := uuid.Parse(idStr)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid customer ID", err.Error())
|
||||
}
|
||||
|
||||
form, err := response.Parse[UpdateCustomerVerificationForm](c)
|
||||
if err != nil {
|
||||
return response.ValidationError(c, "Invalid request data", err.Error())
|
||||
}
|
||||
|
||||
// TODO: Get user ID from JWT token
|
||||
updatedBy := uuid.New() // This should come from JWT token
|
||||
// Get user ID from JWT token context
|
||||
updatedBy, err := user.GetUserIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.Unauthorized(c, "User not authenticated")
|
||||
}
|
||||
|
||||
err = h.service.UpdateCustomerVerification(c.Request().Context(), id, form, &updatedBy)
|
||||
err = h.service.UpdateCustomerVerification(c.Request().Context(), idStr, form, &updatedBy)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
@@ -329,33 +324,34 @@ func (h *Handler) UpdateCustomerVerification(c echo.Context) error {
|
||||
return response.InternalServerError(c, "Failed to update customer verification")
|
||||
}
|
||||
|
||||
return response.Success(c, nil, "Customer verification updated successfully")
|
||||
return response.Success(c, map[string]interface{}{
|
||||
"message": "Customer verification updated successfully",
|
||||
}, "Customer verification updated successfully")
|
||||
}
|
||||
|
||||
// VerifyCustomer verifies a customer
|
||||
// VerifyCustomer verifies a customer (Web Panel)
|
||||
// @Summary Verify customer
|
||||
// @Description Mark a customer as verified. This is a simple verification action that sets the customer's verification status to true.
|
||||
// @Description Mark a customer as verified
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer UUID" format(uuid)
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Success 200 {object} response.APIResponse "Customer verified successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer does not exist"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/{id}/verify [post]
|
||||
func (h *Handler) VerifyCustomer(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := uuid.Parse(idStr)
|
||||
|
||||
// Get user ID from JWT token context
|
||||
verifiedBy, err := user.GetUserIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid customer ID", err.Error())
|
||||
return response.Unauthorized(c, "User not authenticated")
|
||||
}
|
||||
|
||||
// TODO: Get user ID from JWT token
|
||||
verifiedBy := uuid.New() // This should come from JWT token
|
||||
|
||||
err = h.service.VerifyCustomer(c.Request().Context(), id, &verifiedBy)
|
||||
err = h.service.VerifyCustomer(c.Request().Context(), idStr, &verifiedBy)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
@@ -363,44 +359,40 @@ func (h *Handler) VerifyCustomer(c echo.Context) error {
|
||||
return response.InternalServerError(c, "Failed to verify customer")
|
||||
}
|
||||
|
||||
return response.Success(c, nil, "Customer verified successfully")
|
||||
return response.Success(c, map[string]interface{}{
|
||||
"message": "Customer verified successfully",
|
||||
}, "Customer verified successfully")
|
||||
}
|
||||
|
||||
// SuspendCustomer suspends a customer
|
||||
// @Summary Suspend customer account
|
||||
// @Description Suspend a customer account by setting their status to suspended. Suspended customers cannot access the system. A reason for suspension must be provided.
|
||||
// SuspendCustomer suspends a customer (Web Panel)
|
||||
// @Summary Suspend customer
|
||||
// @Description Suspend a customer account with optional reason
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer UUID" format(uuid)
|
||||
// @Param reason body object true "Suspension reason" SchemaExample({"reason": "Violation of terms of service"})
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Param suspension body SuspendCustomerForm true "Suspension information"
|
||||
// @Success 200 {object} response.APIResponse "Customer suspended successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID or missing reason"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer does not exist"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid input data"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 422 {object} response.APIResponse "Validation error - Invalid request data"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/{id}/suspend [post]
|
||||
func (h *Handler) SuspendCustomer(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := uuid.Parse(idStr)
|
||||
form, err := response.Parse[SuspendCustomerForm](c)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid customer ID", err.Error())
|
||||
return response.ValidationError(c, "Invalid request data", err.Error())
|
||||
}
|
||||
|
||||
var requestBody map[string]string
|
||||
if err := c.Bind(&requestBody); err != nil {
|
||||
return response.BadRequest(c, "Invalid request body", err.Error())
|
||||
// Get user ID from JWT token context
|
||||
suspendedBy, err := user.GetUserIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.Unauthorized(c, "User not authenticated")
|
||||
}
|
||||
|
||||
reason := requestBody["reason"]
|
||||
if reason == "" {
|
||||
return response.BadRequest(c, "Suspension reason is required", "")
|
||||
}
|
||||
|
||||
// TODO: Get user ID from JWT token
|
||||
suspendedBy := uuid.New() // This should come from JWT token
|
||||
|
||||
err = h.service.SuspendCustomer(c.Request().Context(), id, reason, &suspendedBy)
|
||||
err = h.service.SuspendCustomer(c.Request().Context(), idStr, form.Reason, &suspendedBy)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
@@ -408,33 +400,34 @@ func (h *Handler) SuspendCustomer(c echo.Context) error {
|
||||
return response.InternalServerError(c, "Failed to suspend customer")
|
||||
}
|
||||
|
||||
return response.Success(c, nil, "Customer suspended successfully")
|
||||
return response.Success(c, map[string]interface{}{
|
||||
"message": "Customer suspended successfully",
|
||||
}, "Customer suspended successfully")
|
||||
}
|
||||
|
||||
// ActivateCustomer activates a customer
|
||||
// @Summary Activate suspended customer account
|
||||
// @Description Reactivate a suspended customer account by setting their status back to active. This reverses the suspension action.
|
||||
// ActivateCustomer activates a customer (Web Panel)
|
||||
// @Summary Activate customer
|
||||
// @Description Activate a suspended customer account
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Customer UUID" format(uuid)
|
||||
// @Param id path string true "Customer ID"
|
||||
// @Success 200 {object} response.APIResponse "Customer activated successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid customer ID"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer does not exist"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/{id}/activate [post]
|
||||
func (h *Handler) ActivateCustomer(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := uuid.Parse(idStr)
|
||||
|
||||
// Get user ID from JWT token context
|
||||
activatedBy, err := user.GetUserIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid customer ID", err.Error())
|
||||
return response.Unauthorized(c, "User not authenticated")
|
||||
}
|
||||
|
||||
// TODO: Get user ID from JWT token
|
||||
activatedBy := uuid.New() // This should come from JWT token
|
||||
|
||||
err = h.service.ActivateCustomer(c.Request().Context(), id, &activatedBy)
|
||||
err = h.service.ActivateCustomer(c.Request().Context(), idStr, &activatedBy)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
@@ -442,61 +435,61 @@ func (h *Handler) ActivateCustomer(c echo.Context) error {
|
||||
return response.InternalServerError(c, "Failed to activate customer")
|
||||
}
|
||||
|
||||
return response.Success(c, nil, "Customer activated successfully")
|
||||
return response.Success(c, map[string]interface{}{
|
||||
"message": "Customer activated successfully",
|
||||
}, "Customer activated successfully")
|
||||
}
|
||||
|
||||
// GetCustomersByCompanyID retrieves customers by company ID
|
||||
// GetCustomersByCompanyID retrieves customers by company ID (Web Panel)
|
||||
// @Summary Get customers by company ID
|
||||
// @Description Retrieve all customers associated with a specific company. This is useful for company administrators to see all users within their organization.
|
||||
// @Description Retrieve all customers associated with a specific company
|
||||
// @Tags Customers-Admin
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param companyId path string true "Company UUID" format(uuid)
|
||||
// @Param limit query integer false "Number of customers per page (1-100)" minimum(1) maximum(100) default(20)
|
||||
// @Param offset query integer false "Number of customers to skip for pagination" minimum(0) default(0)
|
||||
// @Success 200 {object} response.APIResponse{data=[]CustomerResponse,meta=response.Meta} "Customers retrieved successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid company ID format"
|
||||
// @Param companyId path string true "Company ID"
|
||||
// @Param limit query int false "Number of customers to return (default: 10, max: 100)"
|
||||
// @Param offset query int false "Number of customers to skip (default: 0)"
|
||||
// @Success 200 {object} response.APIResponse{data=[]CustomerResponse} "Customers retrieved successfully"
|
||||
// @Failure 400 {object} response.APIResponse "Bad request - Invalid company ID"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/v1/customers/company/{companyId} [get]
|
||||
func (h *Handler) GetCustomersByCompanyID(c echo.Context) error {
|
||||
companyIDStr := c.Param("companyId")
|
||||
companyID, err := uuid.Parse(companyIDStr)
|
||||
if err != nil {
|
||||
return response.BadRequest(c, "Invalid company ID", err.Error())
|
||||
}
|
||||
|
||||
limit := 20
|
||||
// Parse pagination parameters
|
||||
limit := 10 // Default limit
|
||||
offset := 0 // Default offset
|
||||
|
||||
if limitStr := c.QueryParam("limit"); limitStr != "" {
|
||||
if parsedLimit, err := strconv.Atoi(limitStr); err == nil && parsedLimit > 0 && parsedLimit <= 100 {
|
||||
limit = parsedLimit
|
||||
}
|
||||
}
|
||||
|
||||
offset := 0
|
||||
if offsetStr := c.QueryParam("offset"); offsetStr != "" {
|
||||
if parsedOffset, err := strconv.Atoi(offsetStr); err == nil && parsedOffset >= 0 {
|
||||
offset = parsedOffset
|
||||
}
|
||||
}
|
||||
|
||||
customers, total, err := h.service.GetCustomersByCompanyID(c.Request().Context(), companyID, limit, offset)
|
||||
customers, total, err := h.service.GetCustomersByCompanyID(c.Request().Context(), companyIDStr, limit, offset)
|
||||
if err != nil {
|
||||
return response.InternalServerError(c, "Failed to retrieve customers by company")
|
||||
return response.InternalServerError(c, "Failed to get customers by company")
|
||||
}
|
||||
|
||||
// Convert to responses
|
||||
var customerResponses []*CustomerResponse
|
||||
for _, customer := range customers {
|
||||
customerResponses = append(customerResponses, customer.ToResponse())
|
||||
}
|
||||
|
||||
meta := &response.Meta{
|
||||
Total: int(total),
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
}
|
||||
|
||||
return response.SuccessWithMeta(c, customerResponses, meta, "Customers retrieved successfully")
|
||||
return response.Success(c, map[string]interface{}{
|
||||
"customers": customerResponses,
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
}, "Customers retrieved successfully")
|
||||
}
|
||||
|
||||
// GetCustomersByType retrieves customers by type
|
||||
@@ -676,66 +669,70 @@ func (h *Handler) RefreshToken(c echo.Context) error {
|
||||
return response.Success(c, authResponse, "Token refreshed successfully")
|
||||
}
|
||||
|
||||
// GetProfile retrieves customer profile information
|
||||
// GetProfile retrieves customer profile information (Mobile)
|
||||
// @Summary Get customer profile
|
||||
// @Description Retrieve authenticated customer's profile information. This endpoint requires a valid access token and returns the customer's own profile data.
|
||||
// @Tags Customers-Authorization
|
||||
// @Description Retrieve current customer profile information
|
||||
// @Tags Customers-Mobile
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} response.APIResponse{data=CustomerResponse} "Profile retrieved successfully"
|
||||
// @Failure 401 {object} response.APIResponse "Unauthorized - Invalid or missing access token"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer profile not found"
|
||||
// @Failure 401 {object} response.APIResponse "Unauthorized - Invalid or missing token"
|
||||
// @Failure 404 {object} response.APIResponse "Not found - Customer not found"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Router /api/v1/profile [get]
|
||||
func (h *Handler) GetProfile(c echo.Context) error {
|
||||
// Get customer ID from context (set by AuthMiddleware)
|
||||
// Extract customer ID from JWT token context
|
||||
customerID, err := GetCustomerIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.Unauthorized(c, "Customer ID not found in context")
|
||||
return response.Unauthorized(c, "Customer not authenticated")
|
||||
}
|
||||
|
||||
// Call service
|
||||
customer, err := h.service.GetProfile(c.Request().Context(), customerID)
|
||||
if err != nil {
|
||||
if err.Error() == "customer not found" {
|
||||
return response.NotFound(c, "Customer not found")
|
||||
}
|
||||
return response.InternalServerError(c, "Failed to retrieve customer profile")
|
||||
return response.InternalServerError(c, "Failed to get customer profile")
|
||||
}
|
||||
|
||||
return response.Success(c, customer.ToResponse(), "Profile retrieved successfully")
|
||||
}
|
||||
|
||||
// Logout handles customer logout
|
||||
// Logout handles customer logout (Mobile)
|
||||
// @Summary Customer logout
|
||||
// @Description Logout customer and invalidate access token. This ensures the token cannot be used for future requests.
|
||||
// @Tags Customers-Authorization
|
||||
// @Description Logout customer and invalidate access token
|
||||
// @Tags Customers-Mobile
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} response.APIResponse "Logout successful"
|
||||
// @Failure 401 {object} response.APIResponse "Unauthorized - Invalid or missing access token"
|
||||
// @Failure 401 {object} response.APIResponse "Unauthorized - Invalid or missing token"
|
||||
// @Failure 500 {object} response.APIResponse "Internal server error"
|
||||
// @Router /api/v1/logout [delete]
|
||||
func (h *Handler) Logout(c echo.Context) error {
|
||||
// Get customer ID from context (set by AuthMiddleware)
|
||||
// Extract customer ID from JWT token context
|
||||
customerID, err := GetCustomerIDFromContext(c)
|
||||
if err != nil {
|
||||
return response.Unauthorized(c, "Customer ID not found in context")
|
||||
return response.Unauthorized(c, "Customer not authenticated")
|
||||
}
|
||||
|
||||
// Get access token from context
|
||||
accessToken, err := GetAccessTokenFromContext(c)
|
||||
if err != nil {
|
||||
return response.Unauthorized(c, "Access token not found in context")
|
||||
return response.Unauthorized(c, "Access token not found")
|
||||
}
|
||||
|
||||
// Call service
|
||||
err = h.service.Logout(c.Request().Context(), customerID, accessToken)
|
||||
if err != nil {
|
||||
return response.InternalServerError(c, "Failed to logout customer")
|
||||
// Don't return error here as the customer should still be logged out
|
||||
h.logger.Warn("Failed to invalidate access token during logout", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"customer_id": customerID,
|
||||
})
|
||||
}
|
||||
|
||||
return response.Success(c, nil, "Logout successful")
|
||||
return response.Success(c, map[string]interface{}{
|
||||
"message": "Logout successful",
|
||||
}, "Logout successful")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user