125 lines
3.0 KiB
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
|
|
}
|