feat: add feature article
This commit is contained in:
parent
c326fcc6fc
commit
a05edce16a
|
@ -57,6 +57,7 @@ func InitDatabase() {
|
|||
&domain.MenuAccess{},
|
||||
&domain.PlatformHandle{},
|
||||
&domain.Address{},
|
||||
&domain.Article{},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal("Error: Failed to auto migrate domain:", err)
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package domain
|
||||
|
||||
import "time"
|
||||
|
||||
type Article struct {
|
||||
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
|
||||
Title string `gorm:"not null" json:"title"`
|
||||
CoverImage string `gorm:"not null" json:"coverImage"`
|
||||
Author string `gorm:"not null" json:"author"`
|
||||
Heading string `gorm:"not null" json:"heading"`
|
||||
Content string `gorm:"not null" json:"content"`
|
||||
PublishedAt time.Time `gorm:"not null" json:"publishedAt"`
|
||||
UpdatedAt time.Time `gorm:"not null" json:"updatedAt"`
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
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"`
|
||||
PublishedAt time.Time `json:"publishedAt" 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"`
|
||||
}
|
||||
|
||||
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 (ar *ArticleRequest) Validate() error {
|
||||
return validate.Struct(ar)
|
||||
}
|
|
@ -31,4 +31,11 @@ func AppRouter(app *fiber.App) {
|
|||
app.Post("/create-address", middleware.AuthMiddleware, controllers.CreateAddress)
|
||||
app.Put("/address/:id", middleware.AuthMiddleware, controllers.UpdateAddress)
|
||||
app.Delete("/address/:id", middleware.AuthMiddleware, controllers.DeleteAddress)
|
||||
|
||||
// # article
|
||||
app.Post("/articles", middleware.AuthMiddleware, controllers.CreateArticle)
|
||||
app.Get("/articles", middleware.AuthMiddleware, controllers.GetArticles)
|
||||
app.Get("/articles/:id", middleware.AuthMiddleware, controllers.GetArticleByID)
|
||||
app.Put("/articles/:id", middleware.AuthMiddleware, controllers.UpdateArticle)
|
||||
app.Delete("/articles/:id", middleware.AuthMiddleware, controllers.DeleteArticle)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/pahmiudahgede/senggoldong/dto"
|
||||
"github.com/pahmiudahgede/senggoldong/internal/services"
|
||||
"github.com/pahmiudahgede/senggoldong/utils"
|
||||
)
|
||||
|
||||
func CreateArticle(c *fiber.Ctx) error {
|
||||
var articleRequest dto.ArticleRequest
|
||||
if err := c.BodyParser(&articleRequest); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||
fiber.StatusBadRequest,
|
||||
"Invalid input",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
validate := validator.New()
|
||||
err := validate.Struct(articleRequest)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||
fiber.StatusBadRequest,
|
||||
"Validation error",
|
||||
err.Error(),
|
||||
))
|
||||
}
|
||||
|
||||
createdArticle, err := services.CreateArticle(&articleRequest)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
"Failed to create article",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusCreated).JSON(utils.FormatResponse(
|
||||
fiber.StatusCreated,
|
||||
"Article created successfully",
|
||||
createdArticle,
|
||||
))
|
||||
}
|
||||
|
||||
func GetArticles(c *fiber.Ctx) error {
|
||||
articles, err := services.GetArticles()
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
"Failed to fetch articles",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Articles fetched successfully",
|
||||
articles,
|
||||
))
|
||||
}
|
||||
|
||||
func GetArticleByID(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
|
||||
article, err := services.GetArticleByID(id)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
|
||||
fiber.StatusNotFound,
|
||||
"Article not found",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Article fetched successfully",
|
||||
article,
|
||||
))
|
||||
}
|
||||
|
||||
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,
|
||||
"Invalid input",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
validate := validator.New()
|
||||
err := validate.Struct(articleUpdateRequest)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
|
||||
fiber.StatusBadRequest,
|
||||
"Validation error",
|
||||
err.Error(),
|
||||
))
|
||||
}
|
||||
|
||||
updatedArticle, err := services.UpdateArticle(id, &articleUpdateRequest)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
"Failed to update article",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Article updated successfully",
|
||||
updatedArticle,
|
||||
))
|
||||
}
|
||||
|
||||
func DeleteArticle(c *fiber.Ctx) error {
|
||||
id := c.Params("id")
|
||||
|
||||
err := services.DeleteArticle(id)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
|
||||
fiber.StatusInternalServerError,
|
||||
"Failed to delete article",
|
||||
nil,
|
||||
))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
|
||||
fiber.StatusOK,
|
||||
"Article deleted successfully",
|
||||
nil,
|
||||
))
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package repositories
|
||||
|
||||
import (
|
||||
"github.com/pahmiudahgede/senggoldong/config"
|
||||
"github.com/pahmiudahgede/senggoldong/domain"
|
||||
)
|
||||
|
||||
func CreateArticle(article *domain.Article) error {
|
||||
err := config.DB.Create(article).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetArticles() ([]domain.Article, error) {
|
||||
var articles []domain.Article
|
||||
err := config.DB.Find(&articles).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
func GetArticleByID(id string) (domain.Article, error) {
|
||||
var article domain.Article
|
||||
err := config.DB.Where("id = ?", id).First(&article).Error
|
||||
if err != nil {
|
||||
return article, err
|
||||
}
|
||||
return article, nil
|
||||
}
|
||||
|
||||
func UpdateArticle(article *domain.Article) error {
|
||||
|
||||
err := config.DB.Save(article).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -11,7 +11,7 @@ func GetUserRoleByID(id string) (domain.UserRole, error) {
|
|||
var role domain.UserRole
|
||||
err := config.DB.Where("id = ?", id).First(&role).Error
|
||||
if err != nil {
|
||||
return role, errors.New("UserRole tidak ditemukan")
|
||||
return role, errors.New("userRole tidak ditemukan")
|
||||
}
|
||||
return role, nil
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ func GetAllUserRoles() ([]domain.UserRole, error) {
|
|||
var roles []domain.UserRole
|
||||
err := config.DB.Find(&roles).Error
|
||||
if err != nil {
|
||||
return nil, errors.New("Gagal mengambil data UserRole")
|
||||
return nil, errors.New("gagal mengambil data UserRole")
|
||||
}
|
||||
return roles, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
package services
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/pahmiudahgede/senggoldong/domain"
|
||||
"github.com/pahmiudahgede/senggoldong/dto"
|
||||
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||
)
|
||||
|
||||
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,
|
||||
PublishedAt: articleRequest.PublishedAt,
|
||||
UpdatedAt: articleRequest.PublishedAt,
|
||||
}
|
||||
|
||||
err := repositories.CreateArticle(&article)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &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,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetArticles() ([]dto.ArticleResponse, error) {
|
||||
articles, err := repositories.GetArticles()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []dto.ArticleResponse
|
||||
for _, article := range articles {
|
||||
response = append(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,
|
||||
})
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func GetArticleByID(id string) (dto.ArticleResponse, error) {
|
||||
article, err := repositories.GetArticleByID(id)
|
||||
if err != nil {
|
||||
return dto.ArticleResponse{}, err
|
||||
}
|
||||
return 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,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func UpdateArticle(id string, articleUpdateRequest *dto.ArticleUpdateRequest) (*dto.ArticleResponse, error) {
|
||||
|
||||
article, err := repositories.GetArticleByID(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &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,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func DeleteArticle(id string) error {
|
||||
|
||||
err := repositories.DeleteArticle(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue