diff --git a/database/category_model.go b/database/category_model.go index 474022c..fe20a57 100644 --- a/database/category_model.go +++ b/database/category_model.go @@ -11,4 +11,6 @@ type Category struct { CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"` UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"` DeletedAt time.Time `gorm:"default:null" json:"deleted_at"` + + News []News `gorm:"many2many:news_categories" json:"news"` } diff --git a/database/tag_module.go b/database/tag_model.go similarity index 88% rename from database/tag_module.go rename to database/tag_model.go index da6a06c..1f6ca6f 100644 --- a/database/tag_module.go +++ b/database/tag_model.go @@ -11,4 +11,6 @@ type Tag struct { CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"` UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"` DeletedAt time.Time `gorm:"default:null" json:"deleted_at"` + + News []News `gorm:"many2many:news_tags" json:"news"` } diff --git a/internal/accessor/category/create.go b/internal/accessor/category/create.go index 4460a09..3721014 100644 --- a/internal/accessor/category/create.go +++ b/internal/accessor/category/create.go @@ -14,7 +14,7 @@ func (a *accessor) CreateModel(spec categorydomain.CategoryReq) error { Code: spec.Code, } - if err := a.DB.Create(&data).Error; err != nil { + if err := a.db.Create(&data).Error; err != nil { return err } diff --git a/internal/accessor/category/delete.go b/internal/accessor/category/delete.go index 3427c77..8876530 100644 --- a/internal/accessor/category/delete.go +++ b/internal/accessor/category/delete.go @@ -2,11 +2,21 @@ package categoryrepository import ( "fmt" - categorydomain "legalgo-BE-go/internal/domain/category" + "legalgo-BE-go/database" ) func (a *accessor) Delete(id string) error { - if err := a.DB.Delete(&categorydomain.Category{}, "id = ?", id).Error; err != nil { + var category database.Category + + if err := a.db.First(&category, "id = ?", id).Error; err != nil { + return fmt.Errorf("failed to find category: %v", err) + } + + if err := a.db.Model(&category).Association("News").Clear(); err != nil { + return fmt.Errorf("failed to remove categories association: %v", err) + } + + if err := a.db.Delete(&category).Error; err != nil { return fmt.Errorf("failed to delete category %s : %v", id, err) } diff --git a/internal/accessor/category/get_all.go b/internal/accessor/category/get_all.go index 76e9e23..bd4412d 100644 --- a/internal/accessor/category/get_all.go +++ b/internal/accessor/category/get_all.go @@ -7,7 +7,7 @@ import ( func (a *accessor) GetAllModel() ([]categorydomain.Category, error) { var categories []categorydomain.Category - if err := a.DB.Find(&categories).Error; err != nil { + if err := a.db.Find(&categories).Error; err != nil { return nil, err } diff --git a/internal/accessor/category/get_by_ids.go b/internal/accessor/category/get_by_ids.go index 501ec95..0cf64a2 100644 --- a/internal/accessor/category/get_by_ids.go +++ b/internal/accessor/category/get_by_ids.go @@ -7,7 +7,7 @@ import ( func (a *accessor) GetByIDs(ids []string) ([]categorydomain.Category, error) { var categories []categorydomain.Category - if err := a.DB.Find(&categories, "id IN ?", ids).Error; err != nil { + if err := a.db.Find(&categories, "id IN ?", ids).Error; err != nil { return nil, err } diff --git a/internal/accessor/category/impl.go b/internal/accessor/category/impl.go index bbf0f2b..e654299 100644 --- a/internal/accessor/category/impl.go +++ b/internal/accessor/category/impl.go @@ -6,7 +6,7 @@ import ( ) type accessor struct { - DB *database.DB + db *database.DB } type Category interface { diff --git a/internal/accessor/category/update.go b/internal/accessor/category/update.go index bd07ce3..905de4f 100644 --- a/internal/accessor/category/update.go +++ b/internal/accessor/category/update.go @@ -8,7 +8,7 @@ import ( ) func (a *accessor) Update(spec categorydomain.Category) error { - if err := a.DB.Clauses(clause.OnConflict{ + if err := a.db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.AssignmentColumns([]string{"name", "code", "updated_at"}), }).Select("name", "code", "updated_at").Save(&spec).Error; err != nil { diff --git a/internal/accessor/news/delete.go b/internal/accessor/news/delete.go new file mode 100644 index 0000000..6f2decc --- /dev/null +++ b/internal/accessor/news/delete.go @@ -0,0 +1,28 @@ +package newsrepository + +import ( + "fmt" + newsdomain "legalgo-BE-go/internal/domain/news" +) + +func (a *accessor) Delete(id string) error { + var news newsdomain.News + + if err := a.db.Preload("Categories").Preload("Tags").First(&news, "id = ?", id).Error; err != nil { + return fmt.Errorf("failed to find news: %v", err) + } + + if err := a.db.Model(&news).Association("Categories").Clear(); err != nil { + return fmt.Errorf("failed to remove categories association: %v", err) + } + + if err := a.db.Model(&news).Association("Tags").Clear(); err != nil { + return fmt.Errorf("failed to remove tags association: %v", err) + } + + if err := a.db.Delete(&news, "id = ?", id).Error; err != nil { + return fmt.Errorf("failed to delete news %s : %v", id, err) + } + + return nil +} diff --git a/internal/accessor/news/impl.go b/internal/accessor/news/impl.go index 7dcacd7..d7b7fba 100644 --- a/internal/accessor/news/impl.go +++ b/internal/accessor/news/impl.go @@ -12,6 +12,7 @@ type accessor struct { type News interface { GetAll() ([]newsdomain.News, error) Create(newsdomain.News) error + Delete(string) error } func New(db *database.DB) News { diff --git a/internal/accessor/tag/create.go b/internal/accessor/tag/create.go index 6097ba6..1099d76 100644 --- a/internal/accessor/tag/create.go +++ b/internal/accessor/tag/create.go @@ -13,7 +13,7 @@ func (acc *accessor) Create(spec tagdomain.TagReq) error { Name: spec.Name, } - if err := acc.DB.Create(&data).Error; err != nil { + if err := acc.db.Create(&data).Error; err != nil { return err } diff --git a/internal/accessor/tag/delete.go b/internal/accessor/tag/delete.go index 38ed002..9b44f18 100644 --- a/internal/accessor/tag/delete.go +++ b/internal/accessor/tag/delete.go @@ -2,12 +2,22 @@ package tagrepository import ( "fmt" - tagdomain "legalgo-BE-go/internal/domain/tag" + "legalgo-BE-go/database" ) func (a *accessor) Delete(id string) error { - if err := a.DB.Delete(&tagdomain.Tag{}, "id = ?", id).Error; err != nil { - return fmt.Errorf("failed to delete category %s : %v", id, err) + var tag database.Tag + + if err := a.db.First(&tag, "id = ?", id).Error; err != nil { + return fmt.Errorf("failed to find tag: %v", err) + } + + if err := a.db.Model(&tag).Association("News").Clear(); err != nil { + return fmt.Errorf("failed to remove tag association: %v", err) + } + + if err := a.db.Delete(&tag).Error; err != nil { + return fmt.Errorf("failed to delete tag %s : %v", id, err) } return nil diff --git a/internal/accessor/tag/get_all.go b/internal/accessor/tag/get_all.go index 5306f79..8030b88 100644 --- a/internal/accessor/tag/get_all.go +++ b/internal/accessor/tag/get_all.go @@ -7,7 +7,7 @@ import ( func (acc *accessor) GetAll() ([]tagdomain.Tag, error) { var tags []tagdomain.Tag - if err := acc.DB.Find(&tags).Error; err != nil { + if err := acc.db.Find(&tags).Error; err != nil { return nil, err } diff --git a/internal/accessor/tag/get_by_ids.go b/internal/accessor/tag/get_by_ids.go index e2f483b..943bdef 100644 --- a/internal/accessor/tag/get_by_ids.go +++ b/internal/accessor/tag/get_by_ids.go @@ -5,7 +5,7 @@ import tagdomain "legalgo-BE-go/internal/domain/tag" func (a *accessor) GetByIDs(ids []string) ([]tagdomain.Tag, error) { var tags []tagdomain.Tag - if err := a.DB.Find(&tags, "id IN ?", ids).Error; err != nil { + if err := a.db.Find(&tags, "id IN ?", ids).Error; err != nil { return nil, err } diff --git a/internal/accessor/tag/impl.go b/internal/accessor/tag/impl.go index bdc5b4d..0e2b2e8 100644 --- a/internal/accessor/tag/impl.go +++ b/internal/accessor/tag/impl.go @@ -6,7 +6,7 @@ import ( ) type accessor struct { - DB *database.DB + db *database.DB } type TagAccessor interface { diff --git a/internal/accessor/tag/update.go b/internal/accessor/tag/update.go index 9200320..4ec7af3 100644 --- a/internal/accessor/tag/update.go +++ b/internal/accessor/tag/update.go @@ -8,7 +8,7 @@ import ( ) func (a *accessor) Update(spec tagdomain.Tag) error { - if err := a.DB.Clauses(clause.OnConflict{ + if err := a.db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.AssignmentColumns([]string{ "name", diff --git a/internal/api/http/news/delete.go b/internal/api/http/news/delete.go new file mode 100644 index 0000000..1bd9f8a --- /dev/null +++ b/internal/api/http/news/delete.go @@ -0,0 +1,53 @@ +package newshttp + +import ( + "fmt" + authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth" + newssvc "legalgo-BE-go/internal/services/news" + "legalgo-BE-go/internal/utilities/response" + "net/http" + + "github.com/go-chi/chi/v5" +) + +func Delete( + router chi.Router, + newsSvc newssvc.News, +) { + router. + With(authmiddleware.Authorize()). + Delete("/news/{news_id}/delete", func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + newsID := chi.URLParam(r, "news_id") + + if newsID == "" { + response.RespondJsonErrorWithCode( + ctx, + w, + fmt.Errorf("category id is not provided"), + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + "news id is not provided", + ) + return + } + + if err := newsSvc.Delete(newsID); err != nil { + response.RespondJsonErrorWithCode( + ctx, + w, + err, + response.ErrBadRequest.Code, + response.ErrBadRequest.HttpCode, + err.Error(), + ) + return + } + + response.RespondJsonSuccess(ctx, w, struct { + Message string + }{ + Message: "news has been deleted", + }) + }) +} diff --git a/internal/api/http/news/module.go b/internal/api/http/news/module.go index 22ea939..a239911 100644 --- a/internal/api/http/news/module.go +++ b/internal/api/http/news/module.go @@ -5,4 +5,5 @@ import "go.uber.org/fx" var Module = fx.Module("news", fx.Invoke( GetAll, Create, + Delete, )) diff --git a/internal/domain/category/spec.go b/internal/domain/category/spec.go index 4f4594c..ebaf438 100644 --- a/internal/domain/category/spec.go +++ b/internal/domain/category/spec.go @@ -1,6 +1,8 @@ package categorydomain -import "time" +import ( + "time" +) type Category struct { ID string `json:"id" gorm:"primaryKey"` diff --git a/internal/services/news/delete.go b/internal/services/news/delete.go new file mode 100644 index 0000000..c2aa3b9 --- /dev/null +++ b/internal/services/news/delete.go @@ -0,0 +1,5 @@ +package newssvc + +func (i *impl) Delete(id string) error { + return i.newsRepo.Delete(id) +} diff --git a/internal/services/news/impl.go b/internal/services/news/impl.go index 3bbd4e5..c82579c 100644 --- a/internal/services/news/impl.go +++ b/internal/services/news/impl.go @@ -16,6 +16,7 @@ type impl struct { type News interface { GetAll() ([]newsdomain.News, error) Create(newsdomain.NewsReq, string) error + Delete(string) error } func New(