Files
comicverse/service/publication.go

125 lines
3.0 KiB
Go

package service
import (
"fmt"
"log/slog"
"time"
"code.capytal.cc/capytal/comicverse/model"
"code.capytal.cc/capytal/comicverse/repository"
"code.capytal.cc/loreddev/x/tinyssert"
"github.com/google/uuid"
)
type Publication struct {
publicationRepo *repository.Publication
permissionRepo *repository.Permissions
log *slog.Logger
assert tinyssert.Assertions
}
func NewPublication(
publication *repository.Publication,
permissions *repository.Permissions,
logger *slog.Logger,
assertions tinyssert.Assertions,
) *Publication {
return &Publication{
publicationRepo: publication,
permissionRepo: permissions,
log: logger,
assert: assertions,
}
}
func (svc Publication) Get(publicationID uuid.UUID) (model.Publication, error) {
p, err := svc.publicationRepo.GetByID(publicationID)
if err != nil {
return model.Publication{}, fmt.Errorf("service: failed to get publication: %w", err)
}
return p, nil
}
func (svc Publication) Create(title string, ownerUserID ...uuid.UUID) (model.Publication, error) {
log := svc.log.With(slog.String("title", title))
log.Info("Creating publication")
defer log.Info("Finished creating publication")
id, err := uuid.NewV7()
if err != nil {
return model.Publication{}, fmt.Errorf("service: failed to generate id: %w", err)
}
now := time.Now()
p := model.Publication{
ID: id,
Title: title,
DateCreated: now,
DateUpdated: now,
}
err = svc.publicationRepo.Create(p)
if err != nil {
return model.Publication{}, fmt.Errorf("service: failed to create publication: %w", err)
}
if len(ownerUserID) > 0 {
err := svc.SetAuthor(p.ID, ownerUserID[0])
if err != nil {
return model.Publication{}, err
}
}
return p, nil
}
func (svc Publication) SetAuthor(publicationID uuid.UUID, userID uuid.UUID) error {
log := svc.log.With(slog.String("publication", publicationID.String()), slog.String("user", userID.String()))
log.Info("Setting publication owner")
defer log.Info("Finished setting publication owner")
if _, err := svc.permissionRepo.GetByID(publicationID, userID); err == nil {
err := svc.permissionRepo.Update(publicationID, userID, model.PermissionAuthor)
if err != nil {
return fmt.Errorf("service: failed to update publication author: %w", err)
}
}
p := model.PermissionAuthor
err := svc.permissionRepo.Create(publicationID, userID, p)
if err != nil {
return fmt.Errorf("service: failed to set publication owner: %w", err)
}
return nil
}
func (svc Publication) ListOwnedBy(userID uuid.UUID) ([]model.Publication, error) {
perms, err := svc.permissionRepo.GetByUserID(userID)
if err != nil {
return nil, fmt.Errorf("service: failed to get user permissions: %w", err)
}
ids := []uuid.UUID{}
for publication, permissions := range perms {
if permissions.Has(model.PermissionRead) {
ids = append(ids, publication)
}
}
if len(ids) == 0 {
return []model.Publication{}, nil
}
publications, err := svc.publicationRepo.GetByIDs(ids)
if err != nil {
return nil, fmt.Errorf("service: failed to get publications: %w", err)
}
return publications, nil
}