package api import ( "database/sql" "net/http" db "git.nochill.in/nochill/naice_pos/db/sqlc" "git.nochill.in/nochill/naice_pos/util" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/lib/pq" ) type createUserMerchantRequest struct { Email string `json:"email" binding:"required,email"` Fullname string `json:"fullname" binding:"required,alphanum"` Password string `json:"password" binding:"required"` OutletName string `json:"outlet_name" binding:"required,alphanum"` } type userMerchantResponse struct { ID uuid.UUID `json:"id"` IndexID int64 `json:"index_id"` Email string `json:"email"` Fullname string `json:"fullname"` CreatedAt sql.NullTime `json:"created_at"` UpdatedAt sql.NullTime `json:"updated_at"` Outlet db.Merchant `json:"outlet"` } func newUserMerchantResponse(user db.User, merchant db.Merchant) userMerchantResponse { return userMerchantResponse{ ID: user.ID, IndexID: user.IndexID, Email: user.Email, Fullname: user.Fullname, CreatedAt: sql.NullTime{Valid: true, Time: user.CreatedAt.Time}, UpdatedAt: sql.NullTime{Valid: true, Time: user.UpdatedAt.Time}, Outlet: merchant, } } func (server *Server) createUserMerchant(ctx *gin.Context) { var req createUserMerchantRequest if err := ctx.ShouldBindJSON(&req); err != nil { ctx.JSON(http.StatusBadRequest, errorResponse(err)) return } hashedPassword, err := util.HashPassword(req.Password) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return } arg := db.UserMerchantTxParams{ Email: req.Email, Fullname: req.Fullname, Password: hashedPassword, OutletName: req.OutletName, } user, err := server.store.CreateUserMerchantTx(ctx, arg) if err != nil { if pqErr, ok := err.(*pq.Error); ok { switch pqErr.Code.Name() { case "foreign_key_violation", "unique_violation": ctx.JSON(http.StatusConflict, errorResponse(err)) return } } ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return } res := userMerchantResponse{ ID: user.OwnerProfile.ID, IndexID: user.OwnerProfile.IndexID, Email: user.OwnerProfile.Email, Fullname: user.OwnerProfile.Fullname, CreatedAt: sql.NullTime{Valid: true, Time: user.OwnerProfile.CreatedAt.Time}, UpdatedAt: sql.NullTime{Valid: true, Time: user.OwnerProfile.UpdatedAt.Time}, Outlet: user.OutletProfile, } ctx.JSON(http.StatusOK, res) } type userLoginRequest struct { Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required"` } type userLoginResponse struct { AccesToken string `json:"access_token"` UserMerchantResponse userMerchantResponse } func (server *Server) loginUser(ctx *gin.Context) { var req userLoginRequest if err := ctx.ShouldBindJSON(&req); err != nil { ctx.JSON(http.StatusBadRequest, errorResponse(err)) return } user, err := server.store.GetUserByEmail(ctx, req.Email) if err != nil { if err == sql.ErrNoRows { ctx.JSON(http.StatusNotFound, errorResponse(err)) return } ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return } outlet, err := server.store.GetMerchantByUserId(ctx, user.ID) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return } err = util.CheckPassword(req.Password, user.Password) if err != nil { ctx.JSON(http.StatusUnauthorized, errorResponse(err)) return } accessToken, err := server.tokenMaker.CreateToken( user.Email, outlet.ID.String(), server.config.TokenDuration, ) if err != nil { ctx.JSON(http.StatusInternalServerError, errorResponse(err)) return } userMerchant := newUserMerchantResponse(user, outlet) res := userLoginResponse{ AccesToken: accessToken, UserMerchantResponse: userMerchant, } ctx.JSON(http.StatusOK, res) }