Implement JWT session and token
This commit is contained in:
@@ -19,12 +19,14 @@ import (
|
||||
)
|
||||
|
||||
type SelfOrderHandler struct {
|
||||
orderService service.OrderService
|
||||
categoryService service.CategoryService
|
||||
productService service.ProductService
|
||||
tableRepo repository.TableRepositoryInterface
|
||||
outletRepo processor.OutletRepository
|
||||
userRepo processor.UserRepository
|
||||
orderService service.OrderService
|
||||
categoryService service.CategoryService
|
||||
productService service.ProductService
|
||||
tableRepo repository.TableRepositoryInterface
|
||||
outletRepo processor.OutletRepository
|
||||
userRepo processor.UserRepository
|
||||
selfOrderJWTSecret string
|
||||
selfOrderJWTTTL int
|
||||
}
|
||||
|
||||
func NewSelfOrderHandler(
|
||||
@@ -34,44 +36,120 @@ func NewSelfOrderHandler(
|
||||
tableRepo repository.TableRepositoryInterface,
|
||||
outletRepo processor.OutletRepository,
|
||||
userRepo processor.UserRepository,
|
||||
selfOrderJWTSecret string,
|
||||
selfOrderJWTTTL int,
|
||||
) *SelfOrderHandler {
|
||||
return &SelfOrderHandler{
|
||||
orderService: orderService,
|
||||
categoryService: categoryService,
|
||||
productService: productService,
|
||||
tableRepo: tableRepo,
|
||||
outletRepo: outletRepo,
|
||||
userRepo: userRepo,
|
||||
orderService: orderService,
|
||||
categoryService: categoryService,
|
||||
productService: productService,
|
||||
tableRepo: tableRepo,
|
||||
outletRepo: outletRepo,
|
||||
userRepo: userRepo,
|
||||
selfOrderJWTSecret: selfOrderJWTSecret,
|
||||
selfOrderJWTTTL: selfOrderJWTTTL,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SelfOrderHandler) GetMenu(c *gin.Context) {
|
||||
func (h *SelfOrderHandler) getSelfOrderContext(c *gin.Context) (uuid.UUID, string, string, error) {
|
||||
tableIDStr, _ := c.Get("self_order_table_id")
|
||||
customerName, _ := c.Get("self_order_customer_name")
|
||||
phoneStr, _ := c.Get("self_order_phone")
|
||||
|
||||
tableIDStrTyped, ok := tableIDStr.(string)
|
||||
if !ok || tableIDStrTyped == "" {
|
||||
return uuid.Nil, "", "", fmt.Errorf("table_id not found in context")
|
||||
}
|
||||
tableID, err := uuid.Parse(tableIDStrTyped)
|
||||
if err != nil {
|
||||
return uuid.Nil, "", "", fmt.Errorf("invalid table_id in token")
|
||||
}
|
||||
|
||||
nameTyped, ok := customerName.(string)
|
||||
if !ok || nameTyped == "" {
|
||||
return uuid.Nil, "", "", fmt.Errorf("customer_name not found in context")
|
||||
}
|
||||
|
||||
phone, _ := phoneStr.(string)
|
||||
|
||||
return tableID, nameTyped, phone, nil
|
||||
}
|
||||
|
||||
func (h *SelfOrderHandler) CreateSession(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
|
||||
var req contract.SelfOrderMenuRequest
|
||||
var req contract.SelfOrderSessionRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::GetMenu -> request binding failed")
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::CreateSession -> request binding failed")
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error()),
|
||||
}), "SelfOrderHandler::GetMenu")
|
||||
}), "SelfOrderHandler::CreateSession")
|
||||
return
|
||||
}
|
||||
|
||||
if req.TableID == uuid.Nil {
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, "table_id is required"),
|
||||
}), "SelfOrderHandler::GetMenu")
|
||||
}), "SelfOrderHandler::CreateSession")
|
||||
return
|
||||
}
|
||||
|
||||
if req.CustomerName == "" {
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, "customer_name is required"),
|
||||
}), "SelfOrderHandler::GetMenu")
|
||||
}), "SelfOrderHandler::CreateSession")
|
||||
return
|
||||
}
|
||||
|
||||
table, err := h.tableRepo.GetByID(ctx, req.TableID)
|
||||
if err != nil {
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::CreateSession -> table not found")
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.NotFoundErrorCode, constants.TableEntity, "table not found"),
|
||||
}), "SelfOrderHandler::CreateSession")
|
||||
return
|
||||
}
|
||||
|
||||
if !table.IsActive {
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.ValidationErrorCode, constants.TableEntity, "table is not active"),
|
||||
}), "SelfOrderHandler::CreateSession")
|
||||
return
|
||||
}
|
||||
|
||||
phone := ""
|
||||
if req.Phone != nil {
|
||||
phone = *req.Phone
|
||||
}
|
||||
|
||||
token, expiresAt, err := util.GenerateSelfOrderSessionToken(req.TableID, req.CustomerName, phone, h.selfOrderJWTSecret, h.selfOrderJWTTTL)
|
||||
if err != nil {
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::CreateSession -> failed to generate token")
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.InternalServerErrorCode, constants.OrderServiceEntity, "failed to create session"),
|
||||
}), "SelfOrderHandler::CreateSession")
|
||||
return
|
||||
}
|
||||
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(&contract.SelfOrderSessionResponse{
|
||||
Token: token,
|
||||
ExpiresAt: expiresAt,
|
||||
TableID: req.TableID,
|
||||
}), "SelfOrderHandler::CreateSession")
|
||||
}
|
||||
|
||||
func (h *SelfOrderHandler) GetMenu(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
|
||||
tableID, customerName, _, err := h.getSelfOrderContext(c)
|
||||
if err != nil {
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.ValidationErrorCode, constants.RequestEntity, err.Error()),
|
||||
}), "SelfOrderHandler::GetMenu")
|
||||
return
|
||||
}
|
||||
|
||||
table, err := h.tableRepo.GetByID(ctx, tableID)
|
||||
if err != nil {
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::GetMenu -> table not found")
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
@@ -96,6 +174,8 @@ func (h *SelfOrderHandler) GetMenu(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
_ = customerName
|
||||
|
||||
isActive := true
|
||||
catResp := h.categoryService.ListCategories(ctx, &contract.ListCategoriesRequest{
|
||||
OrganizationID: &table.OrganizationID,
|
||||
@@ -192,6 +272,14 @@ func (h *SelfOrderHandler) buildMenuResponse(
|
||||
func (h *SelfOrderHandler) CreateOrder(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
|
||||
tableID, customerName, phone, err := h.getSelfOrderContext(c)
|
||||
if err != nil {
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.ValidationErrorCode, constants.RequestEntity, err.Error()),
|
||||
}), "SelfOrderHandler::CreateOrder")
|
||||
return
|
||||
}
|
||||
|
||||
var req contract.SelfOrderCreateOrderRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::CreateOrder -> request binding failed")
|
||||
@@ -208,7 +296,7 @@ func (h *SelfOrderHandler) CreateOrder(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
table, err := h.tableRepo.GetByID(ctx, req.TableID)
|
||||
table, err := h.tableRepo.GetByID(ctx, tableID)
|
||||
if err != nil {
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::CreateOrder -> table not found")
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
@@ -243,22 +331,27 @@ func (h *SelfOrderHandler) CreateOrder(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
metadata := make(map[string]interface{})
|
||||
metadata["self_order"] = true
|
||||
metadata["customer_name"] = req.CustomerName
|
||||
customerPhone := phone
|
||||
if req.Phone != nil {
|
||||
metadata["customer_phone"] = *req.Phone
|
||||
customerPhone = *req.Phone
|
||||
}
|
||||
|
||||
tableID := req.TableID
|
||||
metadata := make(map[string]interface{})
|
||||
metadata["self_order"] = true
|
||||
metadata["customer_name"] = customerName
|
||||
if customerPhone != "" {
|
||||
metadata["customer_phone"] = customerPhone
|
||||
}
|
||||
|
||||
tableIDPtr := tableID
|
||||
modelReq := &models.CreateOrderRequest{
|
||||
OutletID: table.OutletID,
|
||||
UserID: userID,
|
||||
TableID: &tableID,
|
||||
TableID: &tableIDPtr,
|
||||
TableNumber: &table.TableName,
|
||||
OrderType: constants.OrderTypeDineIn,
|
||||
OrderItems: orderItems,
|
||||
CustomerName: &req.CustomerName,
|
||||
CustomerName: &customerName,
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
@@ -276,12 +369,6 @@ func (h *SelfOrderHandler) CreateOrder(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *SelfOrderHandler) validateCreateOrderRequest(req *contract.SelfOrderCreateOrderRequest) error {
|
||||
if req.TableID == uuid.Nil {
|
||||
return fmt.Errorf("table_id is required")
|
||||
}
|
||||
if req.CustomerName == "" {
|
||||
return fmt.Errorf("customer_name is required")
|
||||
}
|
||||
if len(req.OrderItems) == 0 {
|
||||
return fmt.Errorf("at least one order item is required")
|
||||
}
|
||||
@@ -299,23 +386,15 @@ func (h *SelfOrderHandler) validateCreateOrderRequest(req *contract.SelfOrderCre
|
||||
func (h *SelfOrderHandler) ListCategories(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
|
||||
var req contract.SelfOrderListCategoriesRequest
|
||||
if err := c.ShouldBindQuery(&req); err != nil {
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::ListCategories -> query binding failed")
|
||||
tableID, _, _, err := h.getSelfOrderContext(c)
|
||||
if err != nil {
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error()),
|
||||
contract.NewResponseError(constants.ValidationErrorCode, constants.RequestEntity, err.Error()),
|
||||
}), "SelfOrderHandler::ListCategories")
|
||||
return
|
||||
}
|
||||
|
||||
if req.TableID == uuid.Nil {
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, "table_id is required"),
|
||||
}), "SelfOrderHandler::ListCategories")
|
||||
return
|
||||
}
|
||||
|
||||
table, err := h.tableRepo.GetByID(ctx, req.TableID)
|
||||
table, err := h.tableRepo.GetByID(ctx, tableID)
|
||||
if err != nil {
|
||||
logger.FromContext(ctx).WithError(err).Error("SelfOrderHandler::ListCategories -> table not found")
|
||||
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{
|
||||
|
||||
Reference in New Issue
Block a user