Files
RenewCMS/internal/infrastructure/useCases/UpdateVariant.go
T
2026-10-08 02:33:32 +02:00

118 lines
3.5 KiB
Go

package useCases
import (
"RenewCMS/internal/domain/audit"
"RenewCMS/internal/domain/image"
"context"
"time"
)
type UpdateVariantCommand struct {
Name string
VariantDefinitionCommand
GenerateOnUpload *bool
Enabled *bool
}
type UpdateVariantResult struct {
VariantSummary
PurgedFiles int
}
type UpdateVariantUseCase struct {
variants image.VariantRepository
files image.VariantFileRepository
cache variantCache
renderer image.VariantRenderer
now func() time.Time
recorder audit.Recorder
}
func NewUpdateVariantUseCase(variants image.VariantRepository, files image.VariantFileRepository, storage image.Storage, renderer image.VariantRenderer, now func() time.Time, recorder audit.Recorder) *UpdateVariantUseCase {
return &UpdateVariantUseCase{variants, files, variantCache{files, storage}, renderer, now, recorder}
}
func (u *UpdateVariantUseCase) EncodableFormats() []image.VariantFormat {
return u.renderer.EncodableFormats()
}
func (u *UpdateVariantUseCase) Update(ctx context.Context, command UpdateVariantCommand) (UpdateVariantResult, error) {
current, err := u.variants.Get(command.Name)
if err != nil {
return UpdateVariantResult{}, err
}
settings, err := command.settings(u.renderer.EncodableFormats())
if err != nil {
return UpdateVariantResult{}, err
}
next := withSwitches(current.WithSettings(settings), command)
renderingChanged := !settings.IsSameAs(current.Settings())
if !renderingChanged && next.Enabled == current.Enabled && next.GenerateOnUpload == current.GenerateOnUpload {
return u.result(current, 0)
}
event := audit.NewEvent(audit.ActionVariantUpdate, audit.CategoryMedia)
event.Target = audit.VariantTarget(current.Name)
purged, err := u.purgeIfRendering(renderingChanged, current.Name)
if err != nil {
recordFailure(ctx, u.recorder, event, err)
return UpdateVariantResult{}, err
}
next.UpdatedAt = u.now()
updated, err := u.variants.Update(next)
if err != nil {
recordFailure(ctx, u.recorder, event, err)
return UpdateVariantResult{}, err
}
u.record(ctx, event, current, updated, renderingChanged, purged)
return u.result(updated, purged)
}
func withSwitches(variant image.Variant, command UpdateVariantCommand) image.Variant {
if command.GenerateOnUpload != nil {
variant.GenerateOnUpload = *command.GenerateOnUpload
}
if command.Enabled != nil {
variant.Enabled = *command.Enabled
}
return variant
}
func (u *UpdateVariantUseCase) purgeIfRendering(renderingChanged bool, name string) (int, error) {
if !renderingChanged {
return 0, nil
}
result, err := u.cache.purgeVariant(name)
return result.Files, err
}
func (u *UpdateVariantUseCase) record(ctx context.Context, event audit.Event, before image.Variant, after image.Variant, renderingChanged bool, purged int) {
if renderingChanged {
event.Changes = audit.VariantChanges(before.Settings(), after.Settings())
event.Params = map[string]any{audit.ParamPurgedFiles: purged}
u.recorder.Record(ctx, event)
}
if before.Enabled != after.Enabled {
u.recorder.Record(ctx, enabledEvent(after))
}
}
func (u *UpdateVariantUseCase) result(variant image.Variant, purged int) (UpdateVariantResult, error) {
summary, err := summaryOf(variant, u.files)
if err != nil {
return UpdateVariantResult{}, err
}
return UpdateVariantResult{summary, purged}, nil
}
func enabledEvent(variant image.Variant) audit.Event {
action := audit.ActionVariantDisable
if variant.Enabled {
action = audit.ActionVariantEnable
}
event := audit.NewEvent(action, audit.CategoryMedia)
event.Target = audit.VariantTarget(variant.Name)
return event
}