feat: Authors feature backend (and upgraded deprecated mods)
This commit is contained in:
1 parent
a11338094e
commit
b34a173d83
103 files changed
+6454
-240
No files matched your search
@@ -3,9 +3,12 @@ package useCases
|
||||
import (
|
||||
"RenewCMS/internal/domain/article"
|
||||
"RenewCMS/internal/domain/audit"
|
||||
"RenewCMS/internal/domain/author"
|
||||
"RenewCMS/internal/domain/site"
|
||||
"context"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type UpdateArticleUseCase struct {
|
||||
@@ -13,16 +16,18 @@ type UpdateArticleUseCase struct {
|
||||
bodyRenderer article.BodyRenderer
|
||||
recorder audit.Recorder
|
||||
sites site.Repository
|
||||
authors author.Repository
|
||||
}
|
||||
|
||||
type UpdateArticleCommand struct {
|
||||
Body *string
|
||||
SiteID *uint32
|
||||
Format article.BodyFormat
|
||||
Body *string
|
||||
SiteID *uint32
|
||||
AuthorIDs *[]uint32
|
||||
Format article.BodyFormat
|
||||
}
|
||||
|
||||
func NewUpdateArticleUseCase(articleRepository article.Repository, bodyRenderer article.BodyRenderer, recorder audit.Recorder, sites site.Repository) *UpdateArticleUseCase {
|
||||
return &UpdateArticleUseCase{articleRepository: articleRepository, bodyRenderer: bodyRenderer, recorder: recorder, sites: sites}
|
||||
func NewUpdateArticleUseCase(articleRepository article.Repository, bodyRenderer article.BodyRenderer, recorder audit.Recorder, sites site.Repository, authors author.Repository) *UpdateArticleUseCase {
|
||||
return &UpdateArticleUseCase{articleRepository: articleRepository, bodyRenderer: bodyRenderer, recorder: recorder, sites: sites, authors: authors}
|
||||
}
|
||||
|
||||
func (g *UpdateArticleUseCase) UpdateBody(ctx context.Context, id uint32, body string, format article.BodyFormat) (article.Article, error) {
|
||||
@@ -38,7 +43,10 @@ func (g *UpdateArticleUseCase) Update(ctx context.Context, id uint32, command Up
|
||||
if err != nil {
|
||||
return article.Article{}, err
|
||||
}
|
||||
updated, err := g.articleRepository.Update(id, article.Update{Body: command.Body, SiteID: command.SiteID})
|
||||
if err := g.ensureAuthorsExist(command.AuthorIDs); err != nil {
|
||||
return article.Article{}, err
|
||||
}
|
||||
updated, err := g.articleRepository.Update(id, article.Update{Body: command.Body, SiteID: command.SiteID, AuthorIDs: command.AuthorIDs})
|
||||
if err != nil {
|
||||
g.recordFailure(ctx, audit.ActionArticleEdit, before, err)
|
||||
return article.Article{}, err
|
||||
@@ -58,11 +66,51 @@ func (g *UpdateArticleUseCase) destinationSite(command UpdateArticleCommand) (*s
|
||||
return &destination, nil
|
||||
}
|
||||
|
||||
func (g *UpdateArticleUseCase) ensureAuthorsExist(ids *[]uint32) error {
|
||||
if ids == nil {
|
||||
return nil
|
||||
}
|
||||
for _, id := range *ids {
|
||||
if _, err := g.authors.Get(id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func authorsChange(before article.Article, after article.Article) (audit.Change, bool) {
|
||||
beforeIDs := bylineIDs(before.Authors)
|
||||
afterIDs := bylineIDs(after.Authors)
|
||||
if slices.Equal(beforeIDs, afterIDs) {
|
||||
return audit.Change{}, false
|
||||
}
|
||||
return audit.TextChange(audit.FieldAuthors, bylineNames(before.Authors), bylineNames(after.Authors)), true
|
||||
}
|
||||
|
||||
func bylineIDs(bylines []author.Byline) []uint32 {
|
||||
ids := make([]uint32, 0, len(bylines))
|
||||
for _, byline := range bylines {
|
||||
ids = append(ids, byline.ID)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
func bylineNames(bylines []author.Byline) string {
|
||||
names := make([]string, 0, len(bylines))
|
||||
for _, byline := range bylines {
|
||||
names = append(names, byline.Name)
|
||||
}
|
||||
return strings.Join(names, authorChangeSeparator)
|
||||
}
|
||||
|
||||
func (g *UpdateArticleUseCase) recordEdit(ctx context.Context, before article.Article, after article.Article, destination *site.Site) {
|
||||
changes := audit.ArticleChanges(before, after)
|
||||
if destination != nil && before.SiteID != after.SiteID {
|
||||
changes = append(changes, audit.TextChange(audit.FieldSite, g.siteName(before.SiteID), destination.Name))
|
||||
}
|
||||
if change, changed := authorsChange(before, after); changed {
|
||||
changes = append(changes, change)
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user