Refactor customer domain by removing obsolete files and updating main application structure

- Deleted customer domain files including entities, services, handlers, and forms to streamline the codebase.
- Removed customer-related routes and service initializations from the main application.
- Updated Swagger documentation to reflect the removal of customer endpoints and definitions.
- Cleaned up the project structure to enhance maintainability and focus on user management functionality.
This commit is contained in:
n.nakhostin
2025-08-10 19:05:46 +03:30
parent c89041812a
commit dbcc2d1d4a
13 changed files with 60 additions and 5283 deletions
-571
View File
@@ -1,571 +0,0 @@
package customer
import (
"net/http"
"tm/pkg/response"
"github.com/asaskevich/govalidator"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
)
// Handler handles HTTP requests for customer operations
type Handler struct {
service Service
}
// NewHandler creates a new customer handler
func NewHandler(service Service) *Handler {
return &Handler{
service: service,
}
}
// RegisterRoutes registers all customer routes
func (h *Handler) RegisterRoutes(e *echo.Echo) {
v1 := e.Group("/api/v1")
v1.POST("/customers/register", h.RegisterCustomer)
// Public routes (no authentication required)
v1.POST("/customers/login", h.Login)
v1.POST("/customers/refresh-token", h.RefreshToken)
// Protected routes (authentication required)
customers := v1.Group("/customers")
customers.Use(h.authMiddleware) // TODO: Implement auth middleware
customers.GET("/profile", h.GetProfile)
customers.PUT("/profile", h.UpdateProfile)
customers.PUT("/change-password", h.ChangePassword)
customers.POST("/device-token", h.AddDeviceToken)
customers.DELETE("/device-token", h.RemoveDeviceToken)
customers.POST("/logout", h.Logout)
// Admin routes (admin authentication required)
admin := v1.Group("/admin/customers")
admin.Use(h.adminAuthMiddleware) // TODO: Implement admin auth middleware
admin.POST("/register", h.RegisterCustomer)
admin.GET("", h.ListCustomers)
admin.GET("/:id", h.GetCustomerByID)
admin.PUT("/:id/status", h.UpdateCustomerStatus)
admin.GET("/device-tokens", h.GetAllDeviceTokens)
}
// RegisterCustomer handles customer registration
// @Summary Register a new customer
// @Description Register a new customer with the provided information
// @Tags customers
// @Accept json
// @Produce json
// @Param customer body RegisterCustomerForm true "Customer registration information"
// @Success 201 {object} response.APIResponse{data=customer.CustomerResponse} "Customer registered successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 409 {object} response.APIResponse "Customer already exists"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /admin/customers/register [post]
func (h *Handler) RegisterCustomer(c echo.Context) error {
var form RegisterCustomerForm
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Register customer
customer, err := h.service.RegisterCustomer(c.Request().Context(), &form)
if err != nil {
return response.Conflict(c, err.Error())
}
return response.Created(c, customer.ToResponse(), "Customer registered successfully")
}
// Login handles customer authentication
// @Summary Customer login
// @Description Authenticate customer with email and password
// @Tags customers
// @Accept json
// @Produce json
// @Param credentials body LoginForm true "Login credentials"
// @Success 200 {object} response.APIResponse{data=customer.AuthResponse} "Login successful"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Invalid credentials"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /customers/login [post]
func (h *Handler) Login(c echo.Context) error {
var form LoginForm
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Authenticate customer
authResponse, err := h.service.Login(c.Request().Context(), &form)
if err != nil {
return response.Unauthorized(c, err.Error())
}
return response.Success(c, authResponse, "Login successful")
}
// RefreshToken handles token refresh
// @Summary Refresh access token
// @Description Refresh the access token using a refresh token
// @Tags customers
// @Accept json
// @Produce json
// @Param token body RefreshTokenForm true "Refresh token information"
// @Success 200 {object} response.APIResponse{data=customer.AuthResponse} "Token refreshed successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Invalid refresh token"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /customers/refresh-token [post]
func (h *Handler) RefreshToken(c echo.Context) error {
var form RefreshTokenForm
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Refresh token
authResponse, err := h.service.RefreshToken(c.Request().Context(), form.RefreshToken)
if err != nil {
return response.Unauthorized(c, err.Error())
}
return response.Success(c, authResponse, "Token refreshed successfully")
}
// GetProfile retrieves customer profile
// @Summary Get customer profile
// @Description Retrieve the authenticated customer's profile information
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} response.APIResponse{data=customer.CustomerResponse} "Profile retrieved successfully"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 404 {object} response.APIResponse "Customer not found"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /customers/profile [get]
func (h *Handler) GetProfile(c echo.Context) error {
// Get customer ID from context (set by auth middleware)
customerID, err := h.getCustomerIDFromContext(c)
if err != nil {
return response.Unauthorized(c, "Invalid authentication")
}
// Get customer
customer, err := h.service.GetCustomerByID(c.Request().Context(), customerID)
if err != nil {
return response.NotFound(c, "Customer not found")
}
return response.Success(c, customer.ToResponse(), "Profile retrieved successfully")
}
// UpdateProfile updates customer profile
// @Summary Update customer profile
// @Description Update the authenticated customer's profile information
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param profile body UpdateCustomerForm true "Profile update information"
// @Success 200 {object} response.APIResponse{data=customer.CustomerResponse} "Profile updated successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /customers/profile [put]
func (h *Handler) UpdateProfile(c echo.Context) error {
// Get customer ID from context
customerID, err := h.getCustomerIDFromContext(c)
if err != nil {
return response.Unauthorized(c, "Invalid authentication")
}
var form UpdateCustomerForm
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Update customer
customer, err := h.service.UpdateCustomer(c.Request().Context(), customerID, &form)
if err != nil {
return response.BadRequest(c, err.Error(), "")
}
return response.Success(c, customer.ToResponse(), "Profile updated successfully")
}
// ChangePassword changes customer password
// @Summary Change customer password
// @Description Change the authenticated customer's password
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param password body ChangePasswordForm true "Password change information"
// @Success 200 {object} response.APIResponse "Password changed successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /customers/change-password [put]
func (h *Handler) ChangePassword(c echo.Context) error {
// Get customer ID from context
customerID, err := h.getCustomerIDFromContext(c)
if err != nil {
return response.Unauthorized(c, "Invalid authentication")
}
var form ChangePasswordForm
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Change password
err = h.service.ChangePassword(c.Request().Context(), customerID, &form)
if err != nil {
return response.BadRequest(c, err.Error(), "")
}
return response.Success(c, nil, "Password changed successfully")
}
// AddDeviceToken adds a device token for push notifications
// @Summary Add device token
// @Description Add a device token for push notifications
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param device_token body AddDeviceTokenForm true "Device token information"
// @Success 200 {object} response.APIResponse "Device token added successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /customers/device-token [post]
func (h *Handler) AddDeviceToken(c echo.Context) error {
// Get customer ID from context
customerID, err := h.getCustomerIDFromContext(c)
if err != nil {
return response.Unauthorized(c, "Invalid authentication")
}
var form AddDeviceTokenForm
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Add device token
err = h.service.AddDeviceToken(c.Request().Context(), customerID, &form)
if err != nil {
return response.BadRequest(c, err.Error(), "")
}
return response.Success(c, nil, "Device token added successfully")
}
// RemoveDeviceToken removes a device token
// @Summary Remove device token
// @Description Remove a device token for push notifications
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param device_token body RemoveDeviceTokenForm true "Device token information"
// @Success 200 {object} response.APIResponse "Device token removed successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /customers/device-token [delete]
func (h *Handler) RemoveDeviceToken(c echo.Context) error {
// Get customer ID from context
customerID, err := h.getCustomerIDFromContext(c)
if err != nil {
return response.Unauthorized(c, "Invalid authentication")
}
var form RemoveDeviceTokenForm
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Remove device token
err = h.service.RemoveDeviceToken(c.Request().Context(), customerID, &form)
if err != nil {
return response.BadRequest(c, err.Error(), "")
}
return response.Success(c, nil, "Device token removed successfully")
}
// Logout handles customer logout
// @Summary Customer logout
// @Description Logout customer and invalidate device token
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param logout body object true "Logout request with device token"
// @Success 200 {object} response.APIResponse "Logged out successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /customers/logout [post]
func (h *Handler) Logout(c echo.Context) error {
// Get customer ID from context
customerID, err := h.getCustomerIDFromContext(c)
if err != nil {
return response.Unauthorized(c, "Invalid authentication")
}
// Get device token from request body
var req struct {
DeviceToken string `json:"device_token" valid:"required"`
}
if err := c.Bind(&req); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate request
if _, err := govalidator.ValidateStruct(req); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Logout
err = h.service.Logout(c.Request().Context(), customerID, req.DeviceToken)
if err != nil {
return response.BadRequest(c, err.Error(), "")
}
return response.Success(c, nil, "Logged out successfully")
}
// ListCustomers lists customers (admin only)
// @Summary List customers
// @Description Retrieve a paginated list of customers (admin only)
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param page query int false "Page number" default(1)
// @Param limit query int false "Number of items per page" default(20)
// @Param search query string false "Search term"
// @Success 200 {object} response.APIResponse{data=[]customer.CustomerResponse} "Customers retrieved successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /admin/customers [get]
func (h *Handler) ListCustomers(c echo.Context) error {
var form ListCustomersForm
// Bind query parameters
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid query parameters", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// List customers
customers, total, err := h.service.ListCustomers(c.Request().Context(), &form)
if err != nil {
return response.InternalServerError(c, err.Error())
}
// Convert to responses
var responses []*CustomerResponse
for _, customer := range customers {
responses = append(responses, customer.ToResponse())
}
// Create metadata
meta := &response.Meta{
Total: total,
Limit: 20, // Default limit
Offset: 0, // Default offset
}
if form.Limit != nil {
meta.Limit = *form.Limit
}
if form.Offset != nil {
meta.Offset = *form.Offset
}
return response.SuccessWithMeta(c, responses, meta, "Customers retrieved successfully")
}
// GetCustomerByID retrieves a customer by ID (admin only)
// @Summary Get customer by ID
// @Description Retrieve customer information by ID (admin only)
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "Customer ID"
// @Success 200 {object} response.APIResponse{data=customer.CustomerResponse} "Customer retrieved successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 404 {object} response.APIResponse "Customer not found"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /admin/customers/{id} [get]
func (h *Handler) GetCustomerByID(c echo.Context) error {
// Parse customer ID
customerIDStr := c.Param("id")
customerID, err := uuid.Parse(customerIDStr)
if err != nil {
return response.BadRequest(c, "Invalid customer ID", err.Error())
}
// Get customer
customer, err := h.service.GetCustomerByID(c.Request().Context(), customerID)
if err != nil {
return response.NotFound(c, "Customer not found")
}
return response.Success(c, customer.ToResponse(), "Customer retrieved successfully")
}
// UpdateCustomerStatus updates customer status (admin only)
// @Summary Update customer status
// @Description Update customer status (admin only)
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "Customer ID"
// @Param status body UpdateCustomerStatusForm true "Status update information"
// @Success 200 {object} response.APIResponse "Customer status updated successfully"
// @Failure 400 {object} response.APIResponse "Bad request"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 404 {object} response.APIResponse "Customer not found"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /admin/customers/{id}/status [put]
func (h *Handler) UpdateCustomerStatus(c echo.Context) error {
// Parse customer ID
customerIDStr := c.Param("id")
customerID, err := uuid.Parse(customerIDStr)
if err != nil {
return response.BadRequest(c, "Invalid customer ID", err.Error())
}
var form UpdateCustomerStatusForm
if err := c.Bind(&form); err != nil {
return response.BadRequest(c, "Invalid request body", err.Error())
}
// Validate form
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, "Validation failed", err.Error())
}
// Update status
err = h.service.UpdateCustomerStatus(c.Request().Context(), customerID, &form)
if err != nil {
return response.BadRequest(c, err.Error(), "")
}
return response.Success(c, nil, "Customer status updated successfully")
}
// GetAllDeviceTokens retrieves all device tokens (admin only)
// @Summary Get all device tokens
// @Description Retrieve all device tokens (admin only)
// @Tags customers
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} response.APIResponse{data=[]string} "Device tokens retrieved successfully"
// @Failure 401 {object} response.APIResponse "Unauthorized"
// @Failure 500 {object} response.APIResponse "Internal server error"
// @Router /admin/customers/device-tokens [get]
func (h *Handler) GetAllDeviceTokens(c echo.Context) error {
// Get all device tokens
tokens, err := h.service.GetAllDeviceTokens(c.Request().Context())
if err != nil {
return response.InternalServerError(c, err.Error())
}
return response.Success(c, tokens, "Device tokens retrieved successfully")
}
// Helper methods
// getCustomerIDFromContext extracts customer ID from context
func (h *Handler) getCustomerIDFromContext(c echo.Context) (uuid.UUID, error) {
// TODO: Implement proper JWT token validation and extraction
// For now, we'll use a header-based approach
customerIDStr := c.Request().Header.Get("X-Customer-ID")
if customerIDStr == "" {
return uuid.Nil, echo.NewHTTPError(http.StatusUnauthorized, "Missing customer ID")
}
customerID, err := uuid.Parse(customerIDStr)
if err != nil {
return uuid.Nil, echo.NewHTTPError(http.StatusUnauthorized, "Invalid customer ID")
}
return customerID, nil
}
// authMiddleware is a placeholder for authentication middleware
func (h *Handler) authMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// TODO: Implement proper JWT token validation
// For now, we'll just pass through
return next(c)
}
}
// adminAuthMiddleware is a placeholder for admin authentication middleware
func (h *Handler) adminAuthMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// TODO: Implement proper admin authentication
// For now, we'll just pass through
return next(c)
}
}