This commit is contained in:
aditya.siregar
2025-04-26 12:23:12 +07:00
parent 09c9a4d59d
commit 06d7b4764f
32 changed files with 581 additions and 208 deletions
+7 -142
View File
@@ -2,8 +2,8 @@ package customerauth
import (
auth2 "enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/services/v2/auth"
"enaklo-pos-be/internal/services/v2/customer"
"fmt"
"net/http"
"strings"
@@ -15,7 +15,7 @@ import (
)
type AuthHandler struct {
service services.Auth
service auth.Service
userService services.User
customerSvc customer.Service
}
@@ -23,49 +23,29 @@ type AuthHandler struct {
func (a *AuthHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
authRoute := group.Group("/auth")
authRoute.POST("/login", a.AuthLogin)
authRoute.POST("/forgot-password", a.ForgotPassword)
authRoute.POST("/reset-password", jwt, a.ResetPassword)
authRoute.POST("/register", a.Register)
authRoute.POST("/verify", a.VerifyRegistration)
}
func NewAuthHandler(service services.Auth, userService services.User, customerSvc customer.Service) *AuthHandler {
func NewAuthHandler(service auth.Service) *AuthHandler {
return &AuthHandler{
service: service,
userService: userService,
customerSvc: customerSvc,
service: service,
}
}
// AuthLogin handles the authentication process for user login.
// @Summary User login
// @Description Authenticates a user based on the provided credentials and returns a JWT token.
// @Accept json
// @Produce json
// @Param bodyParam body auth2.LoginRequest true "User login credentials"
// @Success 200 {object} response.BaseResponse{data=response.LoginResponse} "Login successful"
// @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request"
// @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized"
// @Router /api/v1/auth/login [post]
// @Tags Auth Login API's
func (h *AuthHandler) AuthLogin(c *gin.Context) {
ctx := auth2.GetMyContext(c)
var bodyParam auth2.LoginRequest
if err := c.ShouldBindJSON(&bodyParam); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
email := strings.ToLower(bodyParam.Email)
authUser, err := h.service.AuthenticateUser(c, email, bodyParam.Password)
authUser, err := h.service.AuthCustomer(ctx, email, bodyParam.Password)
if err != nil {
response.ErrorWrapper(c, err)
return
}
if authUser.UserType != "CUSTOMER" {
response.ErrorWrapper(c, errors.ErrorUserIsNotFound)
return
}
resp := response.LoginResponseCustoemr{
ID: authUser.ID,
Token: authUser.Token,
@@ -80,118 +60,3 @@ func (h *AuthHandler) AuthLogin(c *gin.Context) {
Data: resp,
})
}
// ForgotPassword handles the request for password reset.
// @Summary Request password reset
// @Description Sends a password reset link to the user's email.
// @Accept json
// @Produce json
// @Param bodyParam body auth2.ForgotPasswordRequest true "User email"
// @Success 200 {object} response.BaseResponse "Password reset link sent"
// @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request"
// @Router /api/v1/auth/forgot-password [post]
// @Tags Auth Password API's
func (h *AuthHandler) ForgotPassword(c *gin.Context) {
var bodyParam auth2.ResetPasswordRequest
if err := c.ShouldBindJSON(&bodyParam); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
err := h.service.SendPasswordResetLink(c, bodyParam.Email)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Message: "Password reset link sent",
})
}
// ResetPassword handles the password reset process.
// @Summary Reset user password
// @Description Resets the user's password using the provided token.
// @Accept json
// @Produce json
// @Param bodyParam body auth2.ResetPasswordRequest true "Reset password details"
// @Success 200 {object} response.BaseResponse "Password reset successful"
// @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request"
// @Router /api/v1/auth/reset-password [post]
// @Tags Auth Password API's
func (h *AuthHandler) ResetPassword(c *gin.Context) {
ctx := auth2.GetMyContext(c)
var req auth2.ResetPasswordChangeRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if err := req.Validate(); err != nil {
response.ErrorWrapper(c, errors.NewError(
errors.ErrorBadRequest.ErrorType(),
fmt.Sprintf("invalid request %v", err.Error())))
return
}
err := h.service.ResetPassword(ctx, req.OldPassword, req.NewPassword)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Message: "Password reset successful",
})
}
func (h *AuthHandler) Register(c *gin.Context) {
var req auth2.CustomerRegister
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := auth2.GetMyContext(c)
customer, err := h.customerSvc.RegistrationMember(ctx, req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.CustomerRegistrationResp{
EmailVerificationRequired: true,
PhoneVerificationRequired: false,
VerificationID: customer.VerificationID,
},
})
}
func (h *AuthHandler) VerifyRegistration(c *gin.Context) {
var req auth2.VerifyEmailRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := auth2.GetMyContext(c)
err := h.customerSvc.VerifyOTP(ctx, req.VerificationID, req.OTPCode)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Message: "Email verification successful",
})
}
+213
View File
@@ -0,0 +1,213 @@
package http
import (
"enaklo-pos-be/internal/common/errors"
"enaklo-pos-be/internal/entity"
"enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/handlers/response"
"enaklo-pos-be/internal/services/v2/inprogress_order"
"enaklo-pos-be/internal/services/v2/product"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"net/http"
"strconv"
)
type MenuHandler struct {
service product.Service
orderService inprogress_order.InProgressOrderService
}
func NewMenuHandler(service product.Service, orderService inprogress_order.InProgressOrderService,
) *MenuHandler {
return &MenuHandler{
service: service,
orderService: orderService,
}
}
func (h *MenuHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/menu")
route.GET("/:partner_id", h.GetProducts)
route.POST("/order/create", h.OrderCreate)
route.POST("/order/member/create", jwt, h.OrderMemberCreate)
route.GET("/order", h.GetOrderID)
}
func (h *MenuHandler) GetProducts(c *gin.Context) {
ctx := request.GetMyContext(c)
partnerIDParam := c.Param("partner_id")
partnerID, err := strconv.ParseInt(partnerIDParam, 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if partnerID <= 0 {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
var req request.ProductParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
searchParam := req.ToEntity()
searchParam.PartnerID = partnerID
products, total, err := h.service.GetProductsByPartnerID(ctx, searchParam)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toProductResponseList(products, int64(total), req),
})
}
func (h *MenuHandler) toProductResponseList(resp []*entity.Product, total int64, req request.ProductParam) response.ProductList {
var products []response.Product
for _, b := range resp {
products = append(products, h.toProductResponse(b))
}
return response.ProductList{
Products: products,
Total: total,
Limit: req.Limit,
Offset: req.Offset,
}
}
func (h *MenuHandler) toProductResponse(resp *entity.Product) response.Product {
return response.Product{
ID: resp.ID,
Name: resp.Name,
Type: resp.Type,
Price: resp.Price,
Status: resp.Status,
Description: resp.Description,
Image: resp.Image,
}
}
func (h *MenuHandler) OrderCreate(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.OrderCustomer
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
validate := validator.New()
if err := validate.Struct(req); err != nil {
response.ErrorWrapper(c, err)
return
}
if req.PartnerID == 0 {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
orderRequest := req.ToEntity(req.PartnerID, 0)
order, err := h.orderService.Save(ctx, orderRequest)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapToOrderCreateResponse(order),
})
}
func (h *MenuHandler) OrderMemberCreate(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.OrderCustomer
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
validate := validator.New()
if err := validate.Struct(req); err != nil {
response.ErrorWrapper(c, err)
return
}
if req.PartnerID == 0 {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
userID := ctx.RequestedBy()
orderRequest := req.ToEntity(req.PartnerID, userID)
orderRequest.CustomerID = &userID
order, err := h.orderService.Save(ctx, orderRequest)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapToOrderCreateResponse(order),
})
}
type GetOrderParam struct {
PartnerID int64 `form:"partner_id" json:"partner_id"`
OrderID int64 `form:"order_id" json:"order_id"`
}
func (h *MenuHandler) GetOrderID(c *gin.Context) {
ctx := request.GetMyContext(c)
var req GetOrderParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
order, err := h.orderService.GetOrderByOrderAndPartnerID(ctx, req.PartnerID, req.OrderID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapToOrderCreateResponse(order),
})
}
func MapToOrderCreateResponse(result *entity.Order) response.OrderResponse {
resp := response.OrderResponse{
ID: result.ID,
Status: result.Status,
Amount: result.Amount,
Tax: result.Tax,
Total: result.Total,
PaymentType: result.PaymentType,
CreatedAt: result.CreatedAt,
Items: response.MapToOrderItemResponses(result.OrderItems),
}
return resp
}
+1 -1
View File
@@ -22,7 +22,7 @@ type OssHandler struct {
func (h *OssHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/file")
route.POST("/upload", h.UploadFile)
route.POST("/upload", jwt, h.UploadFile)
}
func NewOssHandler(ossService services.OSSService) *OssHandler {
+2 -7
View File
@@ -6,12 +6,10 @@ import (
"enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/handlers/response"
"enaklo-pos-be/internal/services"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"net/http"
"strconv"
)
type Handler struct {
@@ -275,9 +273,6 @@ func (h *Handler) toProductResponse(resp *entity.Product) response.Product {
Price: resp.Price,
Status: resp.Status,
Description: resp.Description,
CreatedAt: resp.CreatedAt.Format(time.RFC3339),
UpdatedAt: resp.CreatedAt.Format(time.RFC3339),
PartnerID: resp.PartnerID,
Image: resp.Image,
}
}
-3
View File
@@ -313,14 +313,11 @@ func (h *Handler) toProductResponseList(products []entity.Product) []response.Pr
for _, product := range products {
res = append(res, response.Product{
ID: product.ID,
PartnerID: product.PartnerID,
Name: product.Name,
Type: product.Type,
Price: product.Price,
Status: product.Status,
Description: product.Description,
CreatedAt: product.CreatedAt.Format(time.RFC3339),
UpdatedAt: product.UpdatedAt.Format(time.RFC3339),
})
}
return res