Add cursor rules and initial configuration for Tender Management Go Backend
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
service "tm/internal/customer/service"
|
||||
"tm/pkg/logger"
|
||||
"tm/pkg/response"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// CustomerHandler handles authentication related HTTP requests for mobile customers
|
||||
type CustomerHandler struct {
|
||||
service service.CustomerService
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
// NewCustomerHandler creates a new customer authentication handler
|
||||
func NewHandler(
|
||||
customerAuthService service.CustomerService,
|
||||
logger logger.Logger,
|
||||
) *CustomerHandler {
|
||||
return &CustomerHandler{
|
||||
service: customerAuthService,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// Register handles customer registration
|
||||
// @Summary Register new customer
|
||||
// @Description Create a new customer account for mobile app
|
||||
// @Tags customer-auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body domain.CustomerRegisterRequest true "Customer registration request"
|
||||
// @Success 201 {object} response.APIResponse{data=domain.CustomerAuthResponse}
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 409 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /api/mobile/auth/register [post]
|
||||
func (h *CustomerHandler) Register(c echo.Context) error {
|
||||
var req service.RegisterForm
|
||||
|
||||
// Bind request body
|
||||
if err := c.Bind(&req); err != nil {
|
||||
return response.BadRequest(c, "Invalid request format", err.Error())
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if _, err := govalidator.ValidateStruct(&req); err != nil {
|
||||
return response.ValidationError(c, "Validation failed", err.Error())
|
||||
}
|
||||
|
||||
// Call service
|
||||
authResponse, err := h.service.Register(c.Request().Context(), req)
|
||||
if err != nil {
|
||||
return response.InternalServerError(c, "Registration failed")
|
||||
}
|
||||
|
||||
return response.Created(c, authResponse, "Customer registered successfully")
|
||||
}
|
||||
|
||||
// Login handles customer authentication
|
||||
// @Summary Customer login
|
||||
// @Description Authenticate customer and return tokens
|
||||
// @Tags customer-auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body domain.LoginRequest true "Login request"
|
||||
// @Success 200 {object} response.APIResponse{data=domain.CustomerAuthResponse}
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 401 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /api/mobile/auth/login [post]
|
||||
func (h *CustomerHandler) Login(c echo.Context) error {
|
||||
var req service.LoginForm
|
||||
|
||||
// Bind request body
|
||||
if err := c.Bind(&req); err != nil {
|
||||
return response.BadRequest(c, "Invalid request format", err.Error())
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if _, err := govalidator.ValidateStruct(&req); err != nil {
|
||||
return response.ValidationError(c, "Validation failed", err.Error())
|
||||
}
|
||||
|
||||
// Call service
|
||||
authResponse, err := h.service.Login(c.Request().Context(), req)
|
||||
if err != nil {
|
||||
return response.InternalServerError(c, "Login failed")
|
||||
}
|
||||
|
||||
return response.Success(c, authResponse, "Login successful")
|
||||
}
|
||||
|
||||
// RefreshToken handles token refresh for customers
|
||||
// @Summary Refresh customer access token
|
||||
// @Description Generate new access token using refresh token
|
||||
// @Tags customer-auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body RefreshTokenRequest true "Refresh token request"
|
||||
// @Success 200 {object} response.APIResponse{data=domain.CustomerAuthResponse}
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 401 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /api/mobile/auth/refresh [post]
|
||||
func (h *CustomerHandler) RefreshToken(c echo.Context) error {
|
||||
var req service.RefreshTokenForm
|
||||
|
||||
// Bind request body
|
||||
if err := c.Bind(&req); err != nil {
|
||||
return response.BadRequest(c, "Invalid request format", err.Error())
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if _, err := govalidator.ValidateStruct(&req); err != nil {
|
||||
return response.ValidationError(c, "Validation failed", err.Error())
|
||||
}
|
||||
|
||||
// Call service
|
||||
authResponse, err := h.service.RefreshToken(c.Request().Context(), req.RefreshToken)
|
||||
if err != nil {
|
||||
return response.InternalServerError(c, "Token refresh failed")
|
||||
}
|
||||
|
||||
return response.Success(c, authResponse, "Token refreshed successfully")
|
||||
}
|
||||
|
||||
// ChangePassword handles password change for customers
|
||||
// @Summary Change customer password
|
||||
// @Description Change authenticated customer's password
|
||||
// @Tags customer-auth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body ChangePasswordRequest true "Change password request"
|
||||
// @Success 200 {object} response.APIResponse
|
||||
// @Failure 400 {object} response.APIResponse
|
||||
// @Failure 401 {object} response.APIResponse
|
||||
// @Failure 500 {object} response.APIResponse
|
||||
// @Router /api/mobile/auth/change-password [post]
|
||||
func (h *CustomerHandler) ChangePassword(c echo.Context) error {
|
||||
var req service.ChangePasswordForm
|
||||
|
||||
// Bind request body
|
||||
if err := c.Bind(&req); err != nil {
|
||||
return response.BadRequest(c, "Invalid request format", err.Error())
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if _, err := govalidator.ValidateStruct(&req); err != nil {
|
||||
return response.ValidationError(c, "Validation failed", err.Error())
|
||||
}
|
||||
|
||||
// Get customer from context (set by auth middleware)
|
||||
// customer, ok := c.Get("customer").(*domain.Customer)
|
||||
// if !ok {
|
||||
// return response.Unauthorized(c, "Authentication required")
|
||||
// }
|
||||
|
||||
// Call service
|
||||
// err := h.customerAuthService.ChangePassword(c.Request().Context(), customer.ID, req.OldPassword, req.NewPassword)
|
||||
// if err != nil {
|
||||
// h.logger.Error("Customer password change failed", map[string]interface{}{
|
||||
// "error": err.Error(),
|
||||
// "customer_id": customer.ID.String(),
|
||||
// })
|
||||
|
||||
// if err.Error() == "invalid old password" {
|
||||
// return response.BadRequest(c, "Invalid old password", "")
|
||||
// }
|
||||
|
||||
// return response.InternalServerError(c, "Password change failed")
|
||||
// }
|
||||
|
||||
return response.Success(c, nil, "Password changed successfully")
|
||||
}
|
||||
|
||||
// GetProfile returns current customer profile
|
||||
// @Summary Get customer profile
|
||||
// @Description Get authenticated customer's profile information
|
||||
// @Tags customer-auth
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} response.APIResponse{data=domain.Customer}
|
||||
// @Failure 401 {object} response.APIResponse
|
||||
// @Router /api/mobile/auth/profile [get]
|
||||
func (h *CustomerHandler) GetProfile(c echo.Context) error {
|
||||
// Get customer from context (set by auth middleware)
|
||||
// customer, ok := c.Get("customer").(*domain.Customer)
|
||||
// if !ok {
|
||||
// return response.Unauthorized(c, "Authentication required")
|
||||
// }
|
||||
|
||||
return response.Success(c, nil, "Profile retrieved successfully")
|
||||
}
|
||||
|
||||
// Logout handles customer logout
|
||||
// @Summary Customer logout
|
||||
// @Description Logout customer (client should remove tokens)
|
||||
// @Tags customer-auth
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} response.APIResponse
|
||||
// @Router /api/mobile/auth/logout [post]
|
||||
func (h *CustomerHandler) Logout(c echo.Context) error {
|
||||
// In a stateless JWT implementation, logout is typically handled client-side
|
||||
// by removing the tokens from storage. However, you could implement token
|
||||
// blacklisting here if needed.
|
||||
|
||||
// customer, ok := c.Get("customer").(*domain.Customer)
|
||||
// if ok {
|
||||
// h.logger.Info("Customer logged out", map[string]interface{}{
|
||||
// "customer_id": customer.ID.String(),
|
||||
// "email": customer.Email,
|
||||
// })
|
||||
// }
|
||||
|
||||
return response.Success(c, nil, "Logged out successfully")
|
||||
}
|
||||
Reference in New Issue
Block a user