openmeter / subscription /patch /removeitem.go
Leon4gr45's picture
Upload folder using huggingface_hub (part 7)
16cdcb7 verified
Raw
History Blame Contribute Delete
2.89 kB
package patch
import (
"fmt"
"github.com/openmeterio/openmeter/openmeter/subscription"
"github.com/openmeterio/openmeter/pkg/datetime"
)
type PatchRemoveItem struct {
PhaseKey string
ItemKey string
}
func (r PatchRemoveItem) Op() subscription.PatchOperation {
return subscription.PatchOperationRemove
}
func (r PatchRemoveItem) Path() subscription.SpecPath {
return subscription.NewItemPath(r.PhaseKey, r.ItemKey)
}
func (r PatchRemoveItem) Validate() error {
if err := r.Path().Validate(); err != nil {
return err
}
if err := r.Op().Validate(); err != nil {
return err
}
return nil
}
var _ subscription.Patch = PatchRemoveItem{}
// RemoveItem removes the last version for the provided key
func (r PatchRemoveItem) ApplyTo(spec *subscription.SubscriptionSpec, actx subscription.ApplyContext) error {
phase, ok := spec.Phases[r.PhaseKey]
if !ok {
return &subscription.PatchValidationError{Msg: fmt.Sprintf("phase %s not found", r.PhaseKey)}
}
phaseStartTime, _ := phase.StartAfter.AddTo(spec.ActiveFrom)
if items, exists := phase.ItemsByKey[r.ItemKey]; !exists || len(items) == 0 {
return &subscription.PatchValidationError{Msg: fmt.Sprintf("items for key %s doesn't exists in phase %s", r.ItemKey, r.PhaseKey)}
}
// Checks we need:
// 1. You cannot remove items from previous phases
currentPhase, exists := spec.GetCurrentPhaseAt(actx.CurrentTime)
if !exists {
// either all phases are in the past or in the future
// if all phases are in the past then no removal is possible
//
// If all phases are in the past then the selected one is also in the past
if st, _ := phase.StartAfter.AddTo(spec.ActiveFrom); st.Before(actx.CurrentTime) {
return &subscription.PatchForbiddenError{Msg: fmt.Sprintf("cannot remove item from phase %s which starts before current phase", r.PhaseKey)}
}
} else {
currentPhaseStartTime, _ := currentPhase.StartAfter.AddTo(spec.ActiveFrom)
if phaseStartTime.Before(currentPhaseStartTime) {
return &subscription.PatchForbiddenError{Msg: fmt.Sprintf("cannot remove item from phase %s which starts before current phase", r.PhaseKey)}
}
}
// Finally, lets try to remove the item
if exists && currentPhase.PhaseKey == r.PhaseKey {
// If it's removed from the current phase, we should set its end time to the current time, instead of deleting it (as we cannot falsify history)
diff := datetime.ISODurationBetween(phaseStartTime, actx.CurrentTime)
phase.ItemsByKey[r.ItemKey][len(phase.ItemsByKey[r.ItemKey])-1].ActiveToOverrideRelativeToPhaseStart = &diff
} else {
// Otherwise (if its a future phase), we can just remove it
phase.ItemsByKey[r.ItemKey] = phase.ItemsByKey[r.ItemKey][:len(phase.ItemsByKey[r.ItemKey])-1]
// And let's clean up the items array if it's empty
if len(phase.ItemsByKey[r.ItemKey]) == 0 {
delete(phase.ItemsByKey, r.ItemKey)
}
}
return nil
}