package command import ( "context" "time" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/action" ) type ActionWriteModel struct { eventstore.WriteModel Name string Script string Timeout time.Duration AllowedToFail bool State domain.ActionState } func NewActionWriteModel(actionID string, resourceOwner string) *ActionWriteModel { return &ActionWriteModel{ WriteModel: eventstore.WriteModel{ AggregateID: actionID, ResourceOwner: resourceOwner, }, } } func (wm *ActionWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { case *action.AddedEvent: wm.Name = e.Name wm.Script = e.Script wm.Timeout = e.Timeout wm.AllowedToFail = e.AllowedToFail wm.State = domain.ActionStateActive case *action.ChangedEvent: if e.Name != nil { wm.Name = *e.Name } if e.Script != nil { wm.Script = *e.Script } if e.Timeout != nil { wm.Timeout = *e.Timeout } if e.AllowedToFail != nil { wm.AllowedToFail = *e.AllowedToFail } case *action.DeactivatedEvent: wm.State = domain.ActionStateInactive case *action.ReactivatedEvent: wm.State = domain.ActionStateActive case *action.RemovedEvent: wm.State = domain.ActionStateRemoved } } return wm.WriteModel.Reduce() } func (wm *ActionWriteModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). ResourceOwner(wm.ResourceOwner). AddQuery(). AggregateTypes(action.AggregateType). AggregateIDs(wm.AggregateID). EventTypes(action.AddedEventType, action.ChangedEventType, action.DeactivatedEventType, action.ReactivatedEventType, action.RemovedEventType). Builder() } func (wm *ActionWriteModel) NewChangedEvent( ctx context.Context, agg *eventstore.Aggregate, name string, script string, timeout time.Duration, allowedToFail bool, ) (*action.ChangedEvent, error) { changes := make([]action.ActionChanges, 0) if wm.Name != name { changes = append(changes, action.ChangeName(name, wm.Name)) } if wm.Script != script { changes = append(changes, action.ChangeScript(script)) } if wm.Timeout != timeout { changes = append(changes, action.ChangeTimeout(timeout)) } if wm.AllowedToFail != allowedToFail { changes = append(changes, action.ChangeAllowedToFail(allowedToFail)) } return action.NewChangedEvent(ctx, agg, changes) } func ActionAggregateFromWriteModel(wm *eventstore.WriteModel) *eventstore.Aggregate { return eventstore.AggregateFromWriteModel(wm, action.AggregateType, action.AggregateVersion) } func NewActionAggregate(id, resourceOwner string) *eventstore.Aggregate { return ActionAggregateFromWriteModel(&eventstore.WriteModel{ AggregateID: id, ResourceOwner: resourceOwner, }) } type ActionExistsModel struct { eventstore.WriteModel actionIDs []string checkedIDs []string } func NewActionsExistModel(actionIDs []string, resourceOwner string) *ActionExistsModel { return &ActionExistsModel{ WriteModel: eventstore.WriteModel{ ResourceOwner: resourceOwner, }, actionIDs: actionIDs, } } func (wm *ActionExistsModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { case *action.AddedEvent: wm.checkedIDs = append(wm.checkedIDs, e.Aggregate().ID) case *action.RemovedEvent: for i := len(wm.checkedIDs) - 1; i >= 0; i-- { if wm.checkedIDs[i] == e.Aggregate().ID { wm.checkedIDs[i] = wm.checkedIDs[len(wm.checkedIDs)-1] wm.checkedIDs[len(wm.checkedIDs)-1] = "" wm.checkedIDs = wm.checkedIDs[:len(wm.checkedIDs)-1] break } } } } return wm.WriteModel.Reduce() } func (wm *ActionExistsModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). ResourceOwner(wm.ResourceOwner). AddQuery(). AggregateTypes(action.AggregateType). AggregateIDs(wm.actionIDs...). EventTypes(action.AddedEventType, action.RemovedEventType). Builder() } type ActionsListByOrgModel struct { eventstore.WriteModel Actions map[string]*ActionWriteModel } func NewActionsListByOrgModel(resourceOwner string) *ActionsListByOrgModel { return &ActionsListByOrgModel{ WriteModel: eventstore.WriteModel{ ResourceOwner: resourceOwner, }, Actions: make(map[string]*ActionWriteModel), } } func (wm *ActionsListByOrgModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { case *action.AddedEvent: wm.Actions[e.Aggregate().ID] = &ActionWriteModel{ WriteModel: eventstore.WriteModel{ AggregateID: e.Aggregate().ID, ChangeDate: e.CreationDate(), }, Name: e.Name, State: domain.ActionStateActive, } case *action.DeactivatedEvent: wm.Actions[e.Aggregate().ID].State = domain.ActionStateInactive case *action.ReactivatedEvent: wm.Actions[e.Aggregate().ID].State = domain.ActionStateActive case *action.RemovedEvent: delete(wm.Actions, e.Aggregate().ID) } } return wm.WriteModel.Reduce() } func (wm *ActionsListByOrgModel) Query() *eventstore.SearchQueryBuilder { return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). ResourceOwner(wm.ResourceOwner). AddQuery(). AggregateTypes(action.AggregateType). EventTypes(action.AddedEventType, action.DeactivatedEventType, action.ReactivatedEventType, action.RemovedEventType). Builder() }