package command import ( "context" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/quota" "github.com/zitadel/zitadel/internal/telemetry/tracing" ) // ReportQuotaUsage writes a slice of *quota.NotificationDueEvent directly to the eventstore func (c *Commands) ReportQuotaUsage(ctx context.Context, dueNotifications []*quota.NotificationDueEvent) (err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() cmds := make([]eventstore.Command, 0, len(dueNotifications)) for _, notification := range dueNotifications { ctxFilter, spanFilter := tracing.NewNamedSpan(ctx, "filterNotificationDueEvents") events, errFilter := c.eventstore.Filter( ctxFilter, eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). InstanceID(notification.Aggregate().InstanceID). AddQuery(). AggregateTypes(quota.AggregateType). AggregateIDs(notification.Aggregate().ID). EventTypes(quota.NotificationDueEventType). EventData(map[string]interface{}{ "id": notification.ID, "periodStart": notification.PeriodStart, "threshold": notification.Threshold, }).Builder(), ) spanFilter.EndWithError(errFilter) if errFilter != nil { return errFilter } if len(events) > 0 { continue } cmds = append(cmds, notification) } if len(cmds) == 0 { return nil } ctxPush, spanPush := tracing.NewNamedSpan(ctx, "pushNotificationDueEvents") _, errPush := c.eventstore.Push(ctxPush, cmds...) spanPush.EndWithError(errPush) return errPush } func (c *Commands) UsageNotificationSent(ctx context.Context, dueEvent *quota.NotificationDueEvent) error { id, err := c.idGenerator.Next() if err != nil { return err } _, err = c.eventstore.Push( ctx, quota.NewNotifiedEvent(ctx, id, dueEvent), ) return err }