fix: fix validation input fields in point feature
This commit is contained in:
parent
b6f5984eba
commit
db99c1a441
177
dto/article.go
177
dto/article.go
|
@ -1,20 +1,99 @@
|
|||
// package dto
|
||||
|
||||
// import (
|
||||
// "fmt"
|
||||
// "time"
|
||||
|
||||
// "github.com/go-playground/validator/v10"
|
||||
// )
|
||||
|
||||
// type ArticleRequest struct {
|
||||
// Title string `json:"title" validate:"required"`
|
||||
// CoverImage string `json:"coverImage" validate:"required"`
|
||||
// Author string `json:"author" validate:"required"`
|
||||
// Heading string `json:"heading" validate:"required"`
|
||||
// Content string `json:"content" validate:"required"`
|
||||
// }
|
||||
|
||||
// type ArticleResponse struct {
|
||||
// ID string `json:"id"`
|
||||
// Title string `json:"title"`
|
||||
// CoverImage string `json:"coverImage"`
|
||||
// Author string `json:"author"`
|
||||
// Heading string `json:"heading"`
|
||||
// Content string `json:"content"`
|
||||
// PublishedAt time.Time `json:"publishedAt"`
|
||||
// UpdatedAt time.Time `json:"updatedAt"`
|
||||
// PublishedAtFormatted string `json:"publishedAtt"`
|
||||
// UpdatedAtFormatted string `json:"updatedAtt"`
|
||||
// }
|
||||
|
||||
// type FormattedResponse struct {
|
||||
// ID string `json:"id"`
|
||||
// Title string `json:"title"`
|
||||
// CoverImage string `json:"coverImage"`
|
||||
// Author string `json:"author"`
|
||||
// Heading string `json:"heading"`
|
||||
// Content string `json:"content"`
|
||||
// PublishedAtFormatted string `json:"publishedAt"`
|
||||
// UpdatedAtFormatted string `json:"updatedAt"`
|
||||
// }
|
||||
// type ArticleUpdateRequest struct {
|
||||
// Title string `json:"title" validate:"required"`
|
||||
// CoverImage string `json:"coverImage" validate:"required"`
|
||||
// Author string `json:"author" validate:"required"`
|
||||
// Heading string `json:"heading" validate:"required"`
|
||||
// Content string `json:"content" validate:"required"`
|
||||
// }
|
||||
|
||||
// func (c *ArticleRequest) ValidatePostArticle() error {
|
||||
// err := validate.Struct(c)
|
||||
// if err != nil {
|
||||
|
||||
// for _, e := range err.(validator.ValidationErrors) {
|
||||
|
||||
// switch e.Field() {
|
||||
// case "Title":
|
||||
// return fmt.Errorf("judul harus diisi")
|
||||
// case "CoverImage":
|
||||
// return fmt.Errorf("gambar cover harus diisi")
|
||||
// case "Author":
|
||||
// return fmt.Errorf("penulis harus diisi")
|
||||
// case "Heading":
|
||||
// return fmt.Errorf("heading harus diisi")
|
||||
// case "Content":
|
||||
// return fmt.Errorf("konten artikel harus diisi")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// func (c *ArticleUpdateRequest) ValidateUpdateArticle() error {
|
||||
// err := validate.Struct(c)
|
||||
// if err != nil {
|
||||
|
||||
// for _, e := range err.(validator.ValidationErrors) {
|
||||
|
||||
// switch e.Field() {
|
||||
// case "Title":
|
||||
// return fmt.Errorf("judul harus diisi")
|
||||
// case "CoverImage":
|
||||
// return fmt.Errorf("gambar cover harus diisi")
|
||||
// case "Author":
|
||||
// return fmt.Errorf("penulis harus diisi")
|
||||
// case "Heading":
|
||||
// return fmt.Errorf("heading harus diisi")
|
||||
// case "Content":
|
||||
// return fmt.Errorf("konten artikel harus diisi")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
package dto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
type ArticleRequest struct {
|
||||
Title string `json:"title" validate:"required"`
|
||||
CoverImage string `json:"coverImage" validate:"required"`
|
||||
Author string `json:"author" validate:"required"`
|
||||
Heading string `json:"heading" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
|
||||
type ArticleResponse struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
|
@ -22,23 +101,11 @@ type ArticleResponse struct {
|
|||
Author string `json:"author"`
|
||||
Heading string `json:"heading"`
|
||||
Content string `json:"content"`
|
||||
PublishedAt time.Time `json:"publishedAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
PublishedAtFormatted string `json:"publishedAtt"`
|
||||
UpdatedAtFormatted string `json:"updatedAtt"`
|
||||
PublishedAt string `json:"publishedAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type FormattedResponse struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
CoverImage string `json:"coverImage"`
|
||||
Author string `json:"author"`
|
||||
Heading string `json:"heading"`
|
||||
Content string `json:"content"`
|
||||
PublishedAtFormatted string `json:"publishedAt"`
|
||||
UpdatedAtFormatted string `json:"updatedAt"`
|
||||
}
|
||||
type ArticleUpdateRequest struct {
|
||||
type ArticleCreateRequest struct {
|
||||
Title string `json:"title" validate:"required"`
|
||||
CoverImage string `json:"coverImage" validate:"required"`
|
||||
Author string `json:"author" validate:"required"`
|
||||
|
@ -46,48 +113,10 @@ type ArticleUpdateRequest struct {
|
|||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
|
||||
func (c *ArticleRequest) ValidatePostArticle() error {
|
||||
err := validate.Struct(c)
|
||||
if err != nil {
|
||||
|
||||
for _, e := range err.(validator.ValidationErrors) {
|
||||
|
||||
switch e.Field() {
|
||||
case "Title":
|
||||
return fmt.Errorf("judul harus diisi")
|
||||
case "CoverImage":
|
||||
return fmt.Errorf("gambar cover harus diisi")
|
||||
case "Author":
|
||||
return fmt.Errorf("penulis harus diisi")
|
||||
case "Heading":
|
||||
return fmt.Errorf("heading harus diisi")
|
||||
case "Content":
|
||||
return fmt.Errorf("konten artikel harus diisi")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ArticleUpdateRequest) ValidateUpdateArticle() error {
|
||||
err := validate.Struct(c)
|
||||
if err != nil {
|
||||
|
||||
for _, e := range err.(validator.ValidationErrors) {
|
||||
|
||||
switch e.Field() {
|
||||
case "Title":
|
||||
return fmt.Errorf("judul harus diisi")
|
||||
case "CoverImage":
|
||||
return fmt.Errorf("gambar cover harus diisi")
|
||||
case "Author":
|
||||
return fmt.Errorf("penulis harus diisi")
|
||||
case "Heading":
|
||||
return fmt.Errorf("heading harus diisi")
|
||||
case "Content":
|
||||
return fmt.Errorf("konten artikel harus diisi")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
type ArticleUpdateRequest struct {
|
||||
Title *string `json:"title,omitempty" validate:"omitempty,min=1"`
|
||||
CoverImage *string `json:"coverImage,omitempty" validate:"omitempty,url"`
|
||||
Author *string `json:"author,omitempty" validate:"omitempty,min=1"`
|
||||
Heading *string `json:"heading,omitempty" validate:"omitempty,min=1"`
|
||||
Content *string `json:"content,omitempty" validate:"omitempty,min=1"`
|
||||
}
|
||||
|
|
|
@ -14,6 +14,6 @@ type BannerCreateRequest struct {
|
|||
}
|
||||
|
||||
type BannerUpdateRequest struct {
|
||||
BannerName string `json:"bannername,omitempty"`
|
||||
BannerImage string `json:"bannerimage,omitempty"`
|
||||
BannerName *string `json:"bannername,omitempty"`
|
||||
BannerImage *string `json:"bannerimage,omitempty"`
|
||||
}
|
||||
|
|
|
@ -14,6 +14,16 @@ type PointCreateRequest struct {
|
|||
}
|
||||
|
||||
type PointUpdateRequest struct {
|
||||
CoinName string `json:"coin_name,omitempty"`
|
||||
ValuePerUnit float64 `json:"value_perunit,omitempty"`
|
||||
CoinName string `json:"coin_name" validate:"required"`
|
||||
ValuePerUnit float64 `json:"value_perunit" validate:"required,gt=0"`
|
||||
}
|
||||
|
||||
func (p *PointCreateRequest) Validate() error {
|
||||
validate := GetValidator()
|
||||
return validate.Struct(p)
|
||||
}
|
||||
|
||||
func (p *PointUpdateRequest) Validate() error {
|
||||
validate := GetValidator()
|
||||
return validate.Struct(p)
|
||||
}
|
|
@ -19,6 +19,10 @@ func AppRouter(app *fiber.App) {
|
|||
bannerService := services.NewBannerService(bannerRepo)
|
||||
bannerController := controllers.NewBannerController(bannerService)
|
||||
|
||||
articleRepo := repositories.NewArticleRepository()
|
||||
articleService := services.NewArticleService(articleRepo)
|
||||
articleController := controllers.NewArticleController(articleService)
|
||||
|
||||
// # api group domain endpoint #
|
||||
api := app.Group("/apirijikid")
|
||||
|
||||
|
@ -81,11 +85,11 @@ func AppRouter(app *fiber.App) {
|
|||
api.Delete("/address/delete-address/:id", middleware.AuthMiddleware, controllers.DeleteAddress)
|
||||
|
||||
// # article #
|
||||
api.Get("/articles", controllers.GetArticles)
|
||||
api.Get("/article/:id", controllers.GetArticleByID)
|
||||
api.Post("/article/create-article", middleware.RoleRequired(utils.RoleAdministrator), controllers.CreateArticle)
|
||||
api.Put("/article/update-article/:id", middleware.RoleRequired(utils.RoleAdministrator), controllers.UpdateArticle)
|
||||
api.Delete("/article/delete-article/:id", middleware.RoleRequired(utils.RoleAdministrator), controllers.DeleteArticle)
|
||||
api.Get("/articles", articleController.GetAllArticles)
|
||||
api.Get("/article/:id", articleController.GetArticleByID)
|
||||
api.Post("/article/create-article", middleware.RoleRequired(utils.RoleAdministrator), articleController.CreateArticle)
|
||||
api.Put("/article/update-article/:id", middleware.RoleRequired(utils.RoleAdministrator), articleController.UpdateArticle)
|
||||
api.Delete("/article/delete-article/:id", middleware.RoleRequired(utils.RoleAdministrator), articleController.DeleteArticle)
|
||||
|
||||
// # trash type #
|
||||
api.Get("/trash-categorys", controllers.GetTrashCategories)
|
||||
|
|
|
@ -7,214 +7,122 @@ import (
|
|||
"github.com/pahmiudahgede/senggoldong/utils"
|
||||
)
|
||||
|
||||
func CreateArticle(c *fiber.Ctx) error {
|
||||
var articleRequest dto.ArticleRequest
|
||||
type ArticleController struct {
|
||||
service *services.ArticleService
|
||||
}
|
||||
|
||||
if err := c.BodyParser(&articleRequest); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||
fiber.StatusBadRequest,
|
||||
"Input tidak valid",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
func NewArticleController(service *services.ArticleService) *ArticleController {
|
||||
return &ArticleController{service: service}
|
||||
}
|
||||
|
||||
if err := articleRequest.ValidatePostArticle(); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||
fiber.StatusBadRequest,
|
||||
err.Error(),
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
articleResponse, err := services.CreateArticle(&articleRequest)
|
||||
func (ac *ArticleController) GetAllArticles(c *fiber.Ctx) error {
|
||||
articles, err := ac.service.GetAllArticles()
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.ErrorResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
"Gagal membuat artikel",
|
||||
nil,
|
||||
"Failed to fetch articles",
|
||||
))
|
||||
}
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Articles fetched successfully",
|
||||
articles,
|
||||
))
|
||||
}
|
||||
|
||||
func (ac *ArticleController) GetArticleByID(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
article, err := ac.service.GetArticleByID(id)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusNotFound).JSON(utils.ErrorResponse(
|
||||
fiber.StatusNotFound,
|
||||
"Article not found",
|
||||
))
|
||||
}
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Article fetched successfully",
|
||||
article,
|
||||
))
|
||||
}
|
||||
|
||||
func (ac *ArticleController) CreateArticle(c *fiber.Ctx) error {
|
||||
var request dto.ArticleCreateRequest
|
||||
|
||||
if err := c.BodyParser(&request); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.ErrorResponse(
|
||||
fiber.StatusBadRequest,
|
||||
"Invalid request body",
|
||||
))
|
||||
}
|
||||
|
||||
articleResponse.PublishedAtFormatted = utils.FormatDateToIndonesianFormat(articleResponse.PublishedAt)
|
||||
articleResponse.UpdatedAtFormatted = utils.FormatDateToIndonesianFormat(articleResponse.UpdatedAt)
|
||||
|
||||
response := dto.FormattedResponse{
|
||||
ID: articleResponse.ID,
|
||||
Title: articleResponse.Title,
|
||||
CoverImage: articleResponse.CoverImage,
|
||||
Author: articleResponse.Author,
|
||||
Heading: articleResponse.Heading,
|
||||
Content: articleResponse.Content,
|
||||
PublishedAtFormatted: articleResponse.PublishedAtFormatted,
|
||||
UpdatedAtFormatted: articleResponse.UpdatedAtFormatted,
|
||||
article, err := ac.service.CreateArticle(&request)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.ErrorResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
err.Error(),
|
||||
))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusCreated).JSON(utils.FormatResponse(
|
||||
fiber.StatusCreated,
|
||||
"Artikel berhasil dibuat",
|
||||
response,
|
||||
"Article created successfully",
|
||||
article,
|
||||
))
|
||||
}
|
||||
|
||||
func GetArticles(c *fiber.Ctx) error {
|
||||
|
||||
articles, err := services.GetArticles()
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
"Gagal mengambil artikel",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
if len(articles) == 0 {
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Artikel berhasil diambil tetapi data kosong",
|
||||
[]dto.FormattedResponse{},
|
||||
))
|
||||
}
|
||||
|
||||
var formattedArticles []dto.FormattedResponse
|
||||
for _, article := range articles {
|
||||
article.PublishedAtFormatted = utils.FormatDateToIndonesianFormat(article.PublishedAt)
|
||||
article.UpdatedAtFormatted = utils.FormatDateToIndonesianFormat(article.UpdatedAt)
|
||||
|
||||
formattedArticles = append(formattedArticles, dto.FormattedResponse{
|
||||
ID: article.ID,
|
||||
Title: article.Title,
|
||||
CoverImage: article.CoverImage,
|
||||
Author: article.Author,
|
||||
Heading: article.Heading,
|
||||
Content: article.Content,
|
||||
PublishedAtFormatted: article.PublishedAtFormatted,
|
||||
UpdatedAtFormatted: article.UpdatedAtFormatted,
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Artikel berhasil diambil",
|
||||
formattedArticles,
|
||||
))
|
||||
}
|
||||
|
||||
func GetArticleByID(c *fiber.Ctx) error {
|
||||
|
||||
func (ac *ArticleController) UpdateArticle(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
var request dto.ArticleUpdateRequest
|
||||
|
||||
article, err := services.GetArticleByID(id)
|
||||
if err := c.BodyParser(&request); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.ErrorResponse(
|
||||
fiber.StatusBadRequest,
|
||||
"Invalid request body",
|
||||
))
|
||||
}
|
||||
|
||||
article, err := ac.service.UpdateArticle(id, &request)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||
if err.Error() == "article not found" {
|
||||
return c.Status(fiber.StatusNotFound).JSON(utils.ErrorResponse(
|
||||
fiber.StatusNotFound,
|
||||
"Artikel tidak ditemukan",
|
||||
nil,
|
||||
"Article not found",
|
||||
))
|
||||
}
|
||||
|
||||
article.PublishedAtFormatted = utils.FormatDateToIndonesianFormat(article.PublishedAt)
|
||||
article.UpdatedAtFormatted = utils.FormatDateToIndonesianFormat(article.UpdatedAt)
|
||||
|
||||
response := dto.FormattedResponse{
|
||||
ID: article.ID,
|
||||
Title: article.Title,
|
||||
CoverImage: article.CoverImage,
|
||||
Author: article.Author,
|
||||
Heading: article.Heading,
|
||||
Content: article.Content,
|
||||
PublishedAtFormatted: article.PublishedAtFormatted,
|
||||
UpdatedAtFormatted: article.UpdatedAtFormatted,
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Artikel berhasil diambil",
|
||||
response,
|
||||
))
|
||||
}
|
||||
|
||||
func UpdateArticle(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
|
||||
var articleUpdateRequest dto.ArticleUpdateRequest
|
||||
|
||||
if err := c.BodyParser(&articleUpdateRequest); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||
fiber.StatusBadRequest,
|
||||
"Input tidak valid",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
if err := articleUpdateRequest.ValidateUpdateArticle(); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||
fiber.StatusBadRequest,
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.ErrorResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
err.Error(),
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
updatedArticle, err := services.UpdateArticle(id, &articleUpdateRequest)
|
||||
if err != nil {
|
||||
|
||||
if err.Error() == "record not found" {
|
||||
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||
fiber.StatusNotFound,
|
||||
"id article tidak diketahui",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
"Gagal memperbarui artikel",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
updatedArticle.PublishedAtFormatted = utils.FormatDateToIndonesianFormat(updatedArticle.PublishedAt)
|
||||
updatedArticle.UpdatedAtFormatted = utils.FormatDateToIndonesianFormat(updatedArticle.UpdatedAt)
|
||||
|
||||
response := dto.FormattedResponse{
|
||||
ID: updatedArticle.ID,
|
||||
Title: updatedArticle.Title,
|
||||
CoverImage: updatedArticle.CoverImage,
|
||||
Author: updatedArticle.Author,
|
||||
Heading: updatedArticle.Heading,
|
||||
Content: updatedArticle.Content,
|
||||
PublishedAtFormatted: updatedArticle.PublishedAtFormatted,
|
||||
UpdatedAtFormatted: updatedArticle.UpdatedAtFormatted,
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Artikel berhasil diperbarui",
|
||||
response,
|
||||
"Article updated successfully",
|
||||
article,
|
||||
))
|
||||
}
|
||||
|
||||
func DeleteArticle(c *fiber.Ctx) error {
|
||||
func (ac *ArticleController) DeleteArticle(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
|
||||
err := services.DeleteArticle(id)
|
||||
err := ac.service.DeleteArticle(id)
|
||||
if err != nil {
|
||||
|
||||
if err.Error() == "record not found" {
|
||||
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||
if err.Error() == "article not found" {
|
||||
return c.Status(fiber.StatusNotFound).JSON(utils.ErrorResponse(
|
||||
fiber.StatusNotFound,
|
||||
"id article tidak diketahui",
|
||||
nil,
|
||||
"Article not found",
|
||||
))
|
||||
}
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.ErrorResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
"Gagal menghapus artikel",
|
||||
nil,
|
||||
err.Error(),
|
||||
))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Artikel berhasil dihapus",
|
||||
"Article deleted successfully",
|
||||
nil,
|
||||
))
|
||||
}
|
|
@ -58,8 +58,9 @@ func (pc *PointController) CreatePoint(c *fiber.Ctx) error {
|
|||
|
||||
point, err := pc.service.CreatePoint(&request)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.ErrorResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.ErrorResponse(
|
||||
fiber.StatusBadRequest,
|
||||
err.Error(),
|
||||
))
|
||||
}
|
||||
|
@ -84,14 +85,8 @@ func (pc *PointController) UpdatePoint(c *fiber.Ctx) error {
|
|||
|
||||
point, err := pc.service.UpdatePoint(id, &request)
|
||||
if err != nil {
|
||||
if err.Error() == "point not found" {
|
||||
return c.Status(fiber.StatusNotFound).JSON(utils.ErrorResponse(
|
||||
fiber.StatusNotFound,
|
||||
"Point not found",
|
||||
))
|
||||
}
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.ErrorResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.ErrorResponse(
|
||||
fiber.StatusBadRequest,
|
||||
err.Error(),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -1,99 +1,44 @@
|
|||
package repositories
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
"errors"
|
||||
|
||||
"github.com/pahmiudahgede/senggoldong/config"
|
||||
"github.com/pahmiudahgede/senggoldong/domain"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var ctx = context.Background()
|
||||
type ArticleRepository struct{}
|
||||
|
||||
func CreateArticle(article *domain.Article) error {
|
||||
err := config.DB.Create(article).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config.RedisClient.Del(ctx, "articles")
|
||||
return nil
|
||||
func NewArticleRepository() *ArticleRepository {
|
||||
return &ArticleRepository{}
|
||||
}
|
||||
|
||||
func GetArticles() ([]domain.Article, error) {
|
||||
func (r *ArticleRepository) GetAll() ([]domain.Article, error) {
|
||||
var articles []domain.Article
|
||||
|
||||
cachedArticles, err := config.RedisClient.Get(ctx, "articles").Result()
|
||||
if err == nil {
|
||||
err := json.Unmarshal([]byte(cachedArticles), &articles)
|
||||
err := config.DB.Find(&articles).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.New("failed to fetch articles from database")
|
||||
}
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
err = config.DB.Find(&articles).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
articlesJSON, _ := json.Marshal(articles)
|
||||
config.RedisClient.Set(ctx, "articles", articlesJSON, 10*time.Minute)
|
||||
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
func GetArticleByID(id string) (domain.Article, error) {
|
||||
func (r *ArticleRepository) GetByID(id string) (*domain.Article, error) {
|
||||
var article domain.Article
|
||||
|
||||
cachedArticle, err := config.RedisClient.Get(ctx, "article:"+id).Result()
|
||||
if err == nil {
|
||||
err := json.Unmarshal([]byte(cachedArticle), &article)
|
||||
err := config.DB.First(&article, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return article, err
|
||||
return nil, errors.New("article not found")
|
||||
}
|
||||
return article, nil
|
||||
}
|
||||
|
||||
err = config.DB.Where("id = ?", id).First(&article).Error
|
||||
if err != nil {
|
||||
return article, err
|
||||
}
|
||||
|
||||
articleJSON, _ := json.Marshal(article)
|
||||
config.RedisClient.Set(ctx, "article:"+id, articleJSON, 10*time.Minute)
|
||||
|
||||
return article, nil
|
||||
return &article, nil
|
||||
}
|
||||
|
||||
func UpdateArticle(article *domain.Article) error {
|
||||
err := config.DB.Save(article).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config.RedisClient.Del(ctx, "article:"+article.ID)
|
||||
config.RedisClient.Del(ctx, "articles")
|
||||
|
||||
return nil
|
||||
func (r *ArticleRepository) Create(article *domain.Article) error {
|
||||
return config.DB.Create(article).Error
|
||||
}
|
||||
|
||||
func DeleteArticle(id string) error {
|
||||
var article domain.Article
|
||||
|
||||
err := config.DB.Where("id = ?", id).First(&article).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = config.DB.Delete(&article).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config.RedisClient.Del(ctx, "article:"+id)
|
||||
config.RedisClient.Del(ctx, "articles")
|
||||
|
||||
return nil
|
||||
func (r *ArticleRepository) Update(article *domain.Article) error {
|
||||
return config.DB.Save(article).Error
|
||||
}
|
||||
|
||||
func (r *ArticleRepository) Delete(article *domain.Article) error {
|
||||
return config.DB.Delete(article).Error
|
||||
}
|
|
@ -1,162 +1,199 @@
|
|||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/pahmiudahgede/senggoldong/config"
|
||||
"github.com/pahmiudahgede/senggoldong/domain"
|
||||
"github.com/pahmiudahgede/senggoldong/dto"
|
||||
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||
"github.com/pahmiudahgede/senggoldong/utils"
|
||||
)
|
||||
|
||||
var ctx = context.Background()
|
||||
|
||||
func CreateArticle(articleRequest *dto.ArticleRequest) (dto.ArticleResponse, error) {
|
||||
article := domain.Article{
|
||||
Title: articleRequest.Title,
|
||||
CoverImage: articleRequest.CoverImage,
|
||||
Author: articleRequest.Author,
|
||||
Heading: articleRequest.Heading,
|
||||
Content: articleRequest.Content,
|
||||
}
|
||||
|
||||
err := repositories.CreateArticle(&article)
|
||||
if err != nil {
|
||||
return dto.ArticleResponse{}, err
|
||||
}
|
||||
|
||||
config.RedisClient.Del(ctx, "articles")
|
||||
|
||||
articleResponse := dto.ArticleResponse{
|
||||
ID: article.ID,
|
||||
Title: article.Title,
|
||||
CoverImage: article.CoverImage,
|
||||
Author: article.Author,
|
||||
Heading: article.Heading,
|
||||
Content: article.Content,
|
||||
PublishedAt: article.PublishedAt,
|
||||
UpdatedAt: article.UpdatedAt,
|
||||
}
|
||||
|
||||
return articleResponse, nil
|
||||
type ArticleService struct {
|
||||
repo *repositories.ArticleRepository
|
||||
}
|
||||
|
||||
func GetArticles() ([]dto.ArticleResponse, error) {
|
||||
var response []dto.ArticleResponse
|
||||
func NewArticleService(repo *repositories.ArticleRepository) *ArticleService {
|
||||
return &ArticleService{repo: repo}
|
||||
}
|
||||
|
||||
cachedArticles, err := config.RedisClient.Get(ctx, "articles").Result()
|
||||
if err == nil {
|
||||
err := json.Unmarshal([]byte(cachedArticles), &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (s *ArticleService) GetAllArticles() ([]dto.ArticleResponse, error) {
|
||||
ctx := config.Context()
|
||||
cacheKey := "articles:all"
|
||||
|
||||
cachedData, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||
if err == nil && cachedData != "" {
|
||||
var cachedArticles []dto.ArticleResponse
|
||||
if err := json.Unmarshal([]byte(cachedData), &cachedArticles); err == nil {
|
||||
return cachedArticles, nil
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
articles, err := repositories.GetArticles()
|
||||
articles, err := s.repo.GetAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []dto.ArticleResponse
|
||||
for _, article := range articles {
|
||||
response = append(response, dto.ArticleResponse{
|
||||
result = append(result, dto.ArticleResponse{
|
||||
ID: article.ID,
|
||||
Title: article.Title,
|
||||
CoverImage: article.CoverImage,
|
||||
Author: article.Author,
|
||||
Heading: article.Heading,
|
||||
Content: article.Content,
|
||||
PublishedAt: article.PublishedAt,
|
||||
UpdatedAt: article.UpdatedAt,
|
||||
PublishedAt: utils.FormatDateToIndonesianFormat(article.PublishedAt),
|
||||
UpdatedAt: utils.FormatDateToIndonesianFormat(article.UpdatedAt),
|
||||
})
|
||||
}
|
||||
|
||||
articlesJSON, _ := json.Marshal(response)
|
||||
config.RedisClient.Set(ctx, "articles", articlesJSON, 10*time.Minute)
|
||||
cacheData, _ := json.Marshal(result)
|
||||
config.RedisClient.Set(ctx, cacheKey, cacheData, time.Minute*5)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *ArticleService) GetArticleByID(id string) (*dto.ArticleResponse, error) {
|
||||
ctx := config.Context()
|
||||
cacheKey := "articles:" + id
|
||||
|
||||
cachedData, err := config.RedisClient.Get(ctx, cacheKey).Result()
|
||||
if err == nil && cachedData != "" {
|
||||
var cachedArticle dto.ArticleResponse
|
||||
if err := json.Unmarshal([]byte(cachedData), &cachedArticle); err == nil {
|
||||
return &cachedArticle, nil
|
||||
}
|
||||
}
|
||||
|
||||
article, err := s.repo.GetByID(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &dto.ArticleResponse{
|
||||
ID: article.ID,
|
||||
Title: article.Title,
|
||||
CoverImage: article.CoverImage,
|
||||
Author: article.Author,
|
||||
Heading: article.Heading,
|
||||
Content: article.Content,
|
||||
PublishedAt: utils.FormatDateToIndonesianFormat(article.PublishedAt),
|
||||
UpdatedAt: utils.FormatDateToIndonesianFormat(article.UpdatedAt),
|
||||
}
|
||||
|
||||
cacheData, _ := json.Marshal(result)
|
||||
config.RedisClient.Set(ctx, cacheKey, cacheData, time.Minute*5)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *ArticleService) CreateArticle(request *dto.ArticleCreateRequest) (*dto.ArticleResponse, error) {
|
||||
|
||||
if request.Title == "" || request.CoverImage == "" || request.Author == "" ||
|
||||
request.Heading == "" || request.Content == "" {
|
||||
return nil, errors.New("invalid input data")
|
||||
}
|
||||
|
||||
newArticle := &domain.Article{
|
||||
Title: request.Title,
|
||||
CoverImage: request.CoverImage,
|
||||
Author: request.Author,
|
||||
Heading: request.Heading,
|
||||
Content: request.Content,
|
||||
}
|
||||
|
||||
err := s.repo.Create(newArticle)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to create article")
|
||||
}
|
||||
|
||||
ctx := config.Context()
|
||||
config.RedisClient.Del(ctx, "articles:all")
|
||||
|
||||
response := &dto.ArticleResponse{
|
||||
ID: newArticle.ID,
|
||||
Title: newArticle.Title,
|
||||
CoverImage: newArticle.CoverImage,
|
||||
Author: newArticle.Author,
|
||||
Heading: newArticle.Heading,
|
||||
Content: newArticle.Content,
|
||||
PublishedAt: utils.FormatDateToIndonesianFormat(newArticle.PublishedAt),
|
||||
UpdatedAt: utils.FormatDateToIndonesianFormat(newArticle.UpdatedAt),
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func GetArticleByID(id string) (dto.ArticleResponse, error) {
|
||||
cachedArticle, err := config.RedisClient.Get(ctx, "article:"+id).Result()
|
||||
if err == nil {
|
||||
var article dto.ArticleResponse
|
||||
err := json.Unmarshal([]byte(cachedArticle), &article)
|
||||
func (s *ArticleService) UpdateArticle(id string, request *dto.ArticleUpdateRequest) (*dto.ArticleResponse, error) {
|
||||
|
||||
if err := dto.GetValidator().Struct(request); err != nil {
|
||||
return nil, errors.New("invalid input data")
|
||||
}
|
||||
|
||||
article, err := s.repo.GetByID(id)
|
||||
if err != nil {
|
||||
return article, err
|
||||
}
|
||||
return article, nil
|
||||
return nil, errors.New("article not found")
|
||||
}
|
||||
|
||||
article, err := repositories.GetArticleByID(id)
|
||||
if err != nil {
|
||||
return dto.ArticleResponse{}, err
|
||||
if request.Title != nil {
|
||||
article.Title = *request.Title
|
||||
}
|
||||
|
||||
articleResponse := dto.ArticleResponse{
|
||||
ID: article.ID,
|
||||
Title: article.Title,
|
||||
CoverImage: article.CoverImage,
|
||||
Author: article.Author,
|
||||
Heading: article.Heading,
|
||||
Content: article.Content,
|
||||
PublishedAt: article.PublishedAt,
|
||||
UpdatedAt: article.UpdatedAt,
|
||||
if request.CoverImage != nil {
|
||||
article.CoverImage = *request.CoverImage
|
||||
}
|
||||
|
||||
articleJSON, _ := json.Marshal(articleResponse)
|
||||
config.RedisClient.Set(ctx, "article:"+id, articleJSON, 10*time.Minute)
|
||||
|
||||
return articleResponse, nil
|
||||
}
|
||||
|
||||
func UpdateArticle(id string, articleUpdateRequest *dto.ArticleUpdateRequest) (*dto.ArticleResponse, error) {
|
||||
|
||||
article, err := repositories.GetArticleByID(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if request.Author != nil {
|
||||
article.Author = *request.Author
|
||||
}
|
||||
if request.Heading != nil {
|
||||
article.Heading = *request.Heading
|
||||
}
|
||||
if request.Content != nil {
|
||||
article.Content = *request.Content
|
||||
}
|
||||
|
||||
article.Title = articleUpdateRequest.Title
|
||||
article.CoverImage = articleUpdateRequest.CoverImage
|
||||
article.Author = articleUpdateRequest.Author
|
||||
article.Heading = articleUpdateRequest.Heading
|
||||
article.Content = articleUpdateRequest.Content
|
||||
article.UpdatedAt = time.Now()
|
||||
|
||||
err = repositories.UpdateArticle(&article)
|
||||
err = s.repo.Update(article)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.New("failed to update article")
|
||||
}
|
||||
|
||||
config.RedisClient.Del(ctx, "article:"+id)
|
||||
config.RedisClient.Del(ctx, "articles")
|
||||
ctx := config.Context()
|
||||
config.RedisClient.Del(ctx, "articles:all")
|
||||
config.RedisClient.Del(ctx, "articles:"+id)
|
||||
|
||||
updatedArticleResponse := dto.ArticleResponse{
|
||||
response := &dto.ArticleResponse{
|
||||
ID: article.ID,
|
||||
Title: article.Title,
|
||||
CoverImage: article.CoverImage,
|
||||
Author: article.Author,
|
||||
Heading: article.Heading,
|
||||
Content: article.Content,
|
||||
PublishedAt: article.PublishedAt,
|
||||
UpdatedAt: article.UpdatedAt,
|
||||
PublishedAt: utils.FormatDateToIndonesianFormat(article.PublishedAt),
|
||||
UpdatedAt: utils.FormatDateToIndonesianFormat(article.UpdatedAt),
|
||||
}
|
||||
|
||||
return &updatedArticleResponse, nil
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func DeleteArticle(id string) error {
|
||||
func (s *ArticleService) DeleteArticle(id string) error {
|
||||
|
||||
err := repositories.DeleteArticle(id)
|
||||
article, err := s.repo.GetByID(id)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.New("article not found")
|
||||
}
|
||||
|
||||
config.RedisClient.Del(ctx, "article:"+id)
|
||||
config.RedisClient.Del(ctx, "articles")
|
||||
err = s.repo.Delete(article)
|
||||
if err != nil {
|
||||
return errors.New("failed to delete article")
|
||||
}
|
||||
|
||||
ctx := config.Context()
|
||||
config.RedisClient.Del(ctx, "articles:all")
|
||||
config.RedisClient.Del(ctx, "articles:"+id)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -122,11 +122,11 @@ func (s *BannerService) UpdateBanner(id string, request *dto.BannerUpdateRequest
|
|||
return nil, errors.New("banner not found")
|
||||
}
|
||||
|
||||
if request.BannerName != "" {
|
||||
banner.BannerName = request.BannerName
|
||||
if request.BannerName != nil && *request.BannerName != "" {
|
||||
banner.BannerName = *request.BannerName
|
||||
}
|
||||
if request.BannerImage != "" {
|
||||
banner.BannerImage = request.BannerImage
|
||||
if request.BannerImage != nil && *request.BannerImage != "" {
|
||||
banner.BannerImage = *request.BannerImage
|
||||
}
|
||||
banner.UpdatedAt = time.Now()
|
||||
|
||||
|
|
|
@ -87,8 +87,8 @@ func (s *PointService) GetPointByID(id string) (*dto.PointResponse, error) {
|
|||
|
||||
func (s *PointService) CreatePoint(request *dto.PointCreateRequest) (*dto.PointResponse, error) {
|
||||
|
||||
if request.CoinName == "" || request.ValuePerUnit <= 0 {
|
||||
return nil, errors.New("invalid input data")
|
||||
if err := request.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newPoint := &domain.Point{
|
||||
|
@ -117,17 +117,17 @@ func (s *PointService) CreatePoint(request *dto.PointCreateRequest) (*dto.PointR
|
|||
|
||||
func (s *PointService) UpdatePoint(id string, request *dto.PointUpdateRequest) (*dto.PointResponse, error) {
|
||||
|
||||
if err := request.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
point, err := s.repo.GetByID(id)
|
||||
if err != nil {
|
||||
return nil, errors.New("point not found")
|
||||
}
|
||||
|
||||
if request.CoinName != "" {
|
||||
point.CoinName = request.CoinName
|
||||
}
|
||||
if request.ValuePerUnit > 0 {
|
||||
point.ValuePerUnit = request.ValuePerUnit
|
||||
}
|
||||
point.UpdatedAt = time.Now()
|
||||
|
||||
err = s.repo.Update(point)
|
||||
|
|
Loading…
Reference in New Issue