Skip to content

Commit

Permalink
Merge pull request #12 from khanzadimahdi/8-users-should-be-able-to-w…
Browse files Browse the repository at this point in the history
…rite-comments-on-articles

introduce comments
  • Loading branch information
khanzadimahdi authored Jul 22, 2024
2 parents 8141898 + 1acf7c2 commit 008bbdb
Show file tree
Hide file tree
Showing 36 changed files with 1,282 additions and 0 deletions.
31 changes: 31 additions & 0 deletions backend/application/comment/createComment/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package createComment

import "github.com/khanzadimahdi/testproject/domain/comment"

type validationErrors map[string]string

type Request struct {
Body string `json:"body"`
AuthorUUID string `json:"-"`
ParentUUID string `json:"parent_uuid"`
ObjectUUID string `json:"object_uuid"`
ObjectType string `json:"object_type"`
}

func (r *Request) Validate() (bool, validationErrors) {
errors := make(validationErrors)

if len(r.Body) == 0 {
errors["body"] = "body is required"
}

if r.ObjectType != comment.ObjectTypeArticle {
errors["object_type"] = "object type is not supported"
}

if len(r.ObjectUUID) == 0 {
errors["object_uuid"] = "object_uuid is required"
}

return len(errors) == 0, errors
}
5 changes: 5 additions & 0 deletions backend/application/comment/createComment/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package createComment

type Response struct {
ValidationErrors validationErrors `json:"errors,omitempty"`
}
41 changes: 41 additions & 0 deletions backend/application/comment/createComment/usecase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package createComment

import (
"github.com/khanzadimahdi/testproject/domain/author"
"github.com/khanzadimahdi/testproject/domain/comment"
)

type UseCase struct {
commentRepository comment.Repository
}

func NewUseCase(commentRepository comment.Repository) *UseCase {
return &UseCase{
commentRepository: commentRepository,
}
}

func (uc *UseCase) CreateComment(request Request) (*Response, error) {
if ok, validation := request.Validate(); !ok {
return &Response{
ValidationErrors: validation,
}, nil
}

c := comment.Comment{
Body: request.Body,
Author: author.Author{
UUID: request.AuthorUUID,
},
ParentUUID: request.ParentUUID,
ObjectUUID: request.ObjectUUID,
ObjectType: request.ObjectType,
}

_, err := uc.commentRepository.Save(&c)
if err != nil {
return nil, err
}

return &Response{}, err
}
7 changes: 7 additions & 0 deletions backend/application/comment/getComments/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package getComments

type Request struct {
Page uint
ObjectUUID string
ObjectType string
}
55 changes: 55 additions & 0 deletions backend/application/comment/getComments/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package getComments

import (
"github.com/khanzadimahdi/testproject/domain/comment"
"time"
)

type commentResponse struct {
UUID string `json:"uuid"`
Body string `json:"body"`
Author authorResponse `json:"author"`
ParentUUID string `json:"parent_uuid,omitempty"`
CreatedAt time.Time `json:"created_at"`
}

type authorResponse struct {
UUID string `json:"uuid"`
Name string `json:"name"`
Avatar string `json:"avatar"`
}

type Response struct {
Items []commentResponse `json:"items"`
Pagination pagination `json:"pagination"`
}

type pagination struct {
TotalPages uint `json:"total_pages"`
CurrentPage uint `json:"current_page"`
}

func NewResponse(c []comment.Comment, totalPages, currentPage uint) *Response {
items := make([]commentResponse, len(c))

for i := range c {
items[i].UUID = c[i].UUID
items[i].Body = c[i].Body
items[i].ParentUUID = c[i].ParentUUID
items[i].CreatedAt = c[i].CreatedAt

items[i].Author = authorResponse{
UUID: c[i].Author.UUID,
Name: c[i].Author.Name,
Avatar: c[i].Author.Avatar,
}
}

return &Response{
Items: items,
Pagination: pagination{
TotalPages: totalPages,
CurrentPage: currentPage,
},
}
}
47 changes: 47 additions & 0 deletions backend/application/comment/getComments/usecase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package getComments

import (
"github.com/khanzadimahdi/testproject/domain/comment"
)

const limit = 10

type UseCase struct {
commentRepository comment.Repository
}

func NewUseCase(commentRepository comment.Repository) *UseCase {
return &UseCase{
commentRepository: commentRepository,
}
}

func (uc *UseCase) GetComments(request *Request) (*Response, error) {
totalComments, err := uc.commentRepository.CountApprovedByObjectUUID(request.ObjectType, request.ObjectUUID)
if err != nil {
return nil, err
}

currentPage := request.Page
var offset uint = 0
if currentPage > 0 {
offset = (currentPage - 1) * limit
}

totalPages := totalComments / limit

if (totalPages * limit) != totalComments {
totalPages++
}

c, err := uc.commentRepository.GetApprovedByObjectUUID(
request.ObjectType,
request.ObjectUUID,
offset, limit,
)
if err != nil {
return nil, err
}

return NewResponse(c, totalPages, currentPage), nil
}
35 changes: 35 additions & 0 deletions backend/application/dashboard/comment/createComment/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package createComment

import (
"github.com/khanzadimahdi/testproject/domain/comment"
"time"
)

type validationErrors map[string]string

type Request struct {
Body string `json:"body"`
AuthorUUID string `json:"author_uuid"`
ParentUUID string `json:"parent_uuid"`
ObjectUUID string `json:"object_uuid"`
ObjectType string `json:"object_type"`
ApprovedAt time.Time `json:"approved_at"`
}

func (r *Request) Validate() (bool, validationErrors) {
errors := make(validationErrors)

if len(r.Body) == 0 {
errors["body"] = "body is required"
}

if r.ObjectType != comment.ObjectTypeArticle {
errors["object_type"] = "object type is not supported"
}

if len(r.ObjectUUID) == 0 {
errors["object_uuid"] = "object_uuid is required"
}

return len(errors) == 0, errors
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package createComment

type Response struct {
ValidationErrors validationErrors `json:"errors,omitempty"`
}
42 changes: 42 additions & 0 deletions backend/application/dashboard/comment/createComment/usecase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package createComment

import (
"github.com/khanzadimahdi/testproject/domain/author"
"github.com/khanzadimahdi/testproject/domain/comment"
)

type UseCase struct {
commentRepository comment.Repository
}

func NewUseCase(commentRepository comment.Repository) *UseCase {
return &UseCase{
commentRepository: commentRepository,
}
}

func (uc *UseCase) CreateComment(request Request) (*Response, error) {
if ok, validation := request.Validate(); !ok {
return &Response{
ValidationErrors: validation,
}, nil
}

c := comment.Comment{
Body: request.Body,
Author: author.Author{
UUID: request.AuthorUUID,
},
ParentUUID: request.ParentUUID,
ObjectUUID: request.ObjectUUID,
ObjectType: request.ObjectType,
ApprovedAt: request.ApprovedAt,
}

_, err := uc.commentRepository.Save(&c)
if err != nil {
return nil, err
}

return &Response{}, err
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package createComment
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package deleteComment

type Request struct {
CommentUUID string `json:"uuid"`
}
19 changes: 19 additions & 0 deletions backend/application/dashboard/comment/deleteComment/usecase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package deleteComment

import (
"github.com/khanzadimahdi/testproject/domain/comment"
)

type UseCase struct {
commentRepository comment.Repository
}

func NewUseCase(commentRepository comment.Repository) *UseCase {
return &UseCase{
commentRepository: commentRepository,
}
}

func (uc *UseCase) DeleteComment(request Request) error {
return uc.commentRepository.Delete(request.CommentUUID)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package deleteComment
37 changes: 37 additions & 0 deletions backend/application/dashboard/comment/getComment/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package getComment

import (
"time"

"github.com/khanzadimahdi/testproject/domain/comment"
)

type Response struct {
UUID string `json:"uuid"`
Body string `json:"body"`
Author author `json:"author"`
ParentUUID string `json:"parent_uuid,omitempty"`
CreatedAt time.Time `json:"created_at"`
ApprovedAt time.Time `json:"approved_at"`
}

type author struct {
UUID string `json:"uuid"`
Name string `json:"name"`
Avatar string `json:"avatar"`
}

func NewResponse(c comment.Comment) *Response {
return &Response{
UUID: c.UUID,
Body: c.Body,
Author: author{
UUID: c.Author.UUID,
Name: c.Author.Name,
Avatar: c.Author.Avatar,
},
ParentUUID: c.ParentUUID,
CreatedAt: c.CreatedAt,
ApprovedAt: c.ApprovedAt,
}
}
24 changes: 24 additions & 0 deletions backend/application/dashboard/comment/getComment/useCase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package getComment

import (
"github.com/khanzadimahdi/testproject/domain/comment"
)

type UseCase struct {
commentRepository comment.Repository
}

func NewUseCase(commentRepository comment.Repository) *UseCase {
return &UseCase{
commentRepository: commentRepository,
}
}

func (uc *UseCase) GetArticle(UUID string) (*Response, error) {
c, err := uc.commentRepository.GetOne(UUID)
if err != nil {
return nil, err
}

return NewResponse(c), nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package getComment
7 changes: 7 additions & 0 deletions backend/application/dashboard/comment/getComments/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package getComments

type Request struct {
Page uint
ObjectUUID string
ObjectType string
}
Loading

0 comments on commit 008bbdb

Please sign in to comment.