notification

package
v1.0.0-beta.232 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

README

Notifications

Notifications turn selected OpenMeter domain events into durable, customer-configured webhook deliveries.

A source event is not itself a notification event. The notification consumer matches it against active rules and creates notification events for the matching rule and trigger. A single balance snapshot can produce separate events for an active usage threshold and an active balance threshold. Each event contains a payload snapshot and one delivery status for every active channel assigned to that rule.

Domain model

  • A channel is a delivery destination. Webhooks are currently the only channel type; the channel owns its URL, headers, signing secret, and disabled state.
  • A rule selects one notification event type, its type-specific conditions, and one to five channels. Rule and channel types are immutable.
  • An event records that one rule matched one source fact. Its type, rule ID, payload, and creation time are immutable. The referenced rule remains mutable; its configuration and channel assignments are not copied into the event.
  • A delivery status is the mutable per-event, per-channel delivery record. It contains the state, next attempt, failure reason, and provider attempts.

Rules and channels are namespaced and soft-deleted. A channel cannot be deleted while a rule still references it. Events have no update or delete lifecycle; payload compatibility and retention therefore matter for historical data.

Ownership and runtime boundaries

  • Billing owns invoice lifecycle and invoice domain events. Entitlements own balance calculation, usage periods, and snapshot events. Notifications do not reconstruct either domain's current state.
  • The notification consumer owns rule matching, threshold evaluation, notification-event creation, and the mapping from source events to persisted notification payloads.
  • Event creation atomically persists the event and its initial PENDING delivery statuses. It does not synchronously send the webhook.
  • The notification worker consumes balance and invoice events and records notification events. A leader-elected reconciler in the API server delivers and reconciles them through Svix. See the runtime architecture.
  • Svix owns outbound webhook attempts. OpenMeter owns the rule and channel model, the durable notification event, and its mirrored per-channel delivery state.

Each OpenMeter webhook channel is mirrored by a Svix endpoint. Rule assignment is also reflected in Svix's endpoint filters. Channel and rule changes must keep PostgreSQL and provider state consistent; changing only one side breaks delivery or leaves delivery status unreconcilable.

Source events and matching

notification type source matching behavior
entitlements.balance.threshold entitlement snapshot update or reset optional feature scope; evaluates configured usage and balance thresholds
entitlements.reset entitlement reset snapshot optional feature scope
invoice.created billing standard-invoice created event every active rule of the type
invoice.updated billing standard-invoice updated event every active rule of the type

No active matching rule means no notification event is persisted. Invoice and balance-threshold rules are evaluated independently, so matching rules can produce separate events from the same source fact. Reset-event deduplication currently uses a broader usage-period lookup and does not provide that per-rule guarantee.

Balance-threshold notifications are evaluated only for active metered entitlements with a complete balance and usage snapshot. Within each threshold kind, the most advanced active threshold is selected. Deduplication is scoped to the rule, entitlement, feature, usage period, measurement start, and threshold kind. It suppresses repeated snapshots at the same active threshold, not events from another rule.

This deduplication belongs to the balance-threshold handler; CreateEvent has no generic source-event idempotency contract. Its hashes are persisted with the event and legacy hash forms remain part of lookup compatibility.

Invoice notifications ignore invoices still in gathering: that state is an incomplete billing aggregate, not a deliverable invoice snapshot.

Payloads are historical snapshots

The persisted payload is the source for both notification API responses and later webhook delivery. Delivery must not look up the current invoice, entitlement, customer, feature, or subject and silently change what the event means.

  • Entitlement payloads contain API-shaped entitlement, feature, customer, subject, and calculated value data from the consumed snapshot.
  • Invoice payloads are eagerly converted from the billing event to api.Invoice before persistence. The notification package does not persist the internal billing aggregate.
  • Current invoice payloads use persisted payload version 1. Invoice reads reject unsupported versions. Entitlement payloads remain unversioned, so payload-version changes must account for existing rows by event type.

Adding or changing an event type is therefore a persistence and external contract change, not only a new consumer branch. The domain type, rule and payload validation, source-event mapping, API payload, stored JSON handling, Svix event registration, and historical reads must agree.

Testing a rule is not a dry-run. It creates a normal persisted notification event, marked with the notification.rule.test annotation, and its delivery statuses enter the same reconciliation flow.

Delivery lifecycle

Delivery is tracked independently for each channel:

PENDING -> SENDING -> SUCCESS
                   -> FAILED
     \-> FAILED

SENDING -> PENDING (missing provider message recovery)

SENDING, SUCCESS, or FAILED -> RESENDING -> SENDING
  • PENDING means the event exists but the provider message is not yet known to be accepted. Repeated sends converge on the notification event ID at Svix.
  • SENDING mirrors provider-side retries and attempt details.
  • SUCCESS and FAILED are terminal until an explicit resend changes the selected statuses to RESENDING.
  • Reconciliation handles transient provider errors using next_attempt. Missing provider message state can eventually return SENDING to PENDING; missing endpoints, missing rule assignments, disabled provider endpoints, and invalid configuration are terminal for that delivery.
  • By default, a delivery that remains PENDING fails three hours after its delivery status was created, and one in SENDING fails 48 hours after creation. The current implementation does not restart that clock on resend, so an old delivery can reach the sending timeout immediately after a resend. These timeouts and the reconciliation interval are configurable.
  • A failed delivery does not disable its rule or channel. Future matching source events remain independent.

Resend reuses the persisted event payload. It may target selected channels, but only channels assigned to the event's rule and statuses already in SENDING, SUCCESS, or FAILED are eligible.

Documentation

Index

Constants

View Source
const (
	// AnnotationRuleTestEvent indicates that the event is generated as part of testing a notification rule
	AnnotationRuleTestEvent = "notification.rule.test"

	AnnotationEventFeatureKey = "event.feature.key"
	AnnotationEventFeatureID  = "event.feature.id"
	AnnotationEventSubjectKey = "event.subject.key"
	AnnotationEventSubjectID  = "event.subject.id"

	AnnotationEventCustomerID  = "event.customer.id"
	AnnotationEventCustomerKey = "event.customer.key"

	// TODO[later]: deprecate this annotation and use a generic one
	AnnotationBalanceEventDedupeHash = "event.balance.dedupe.hash"

	AnnotationEventInvoiceID     = "event.invoice.id"
	AnnotationEventInvoiceNumber = "event.invoice.number"

	AnnotationEventResendTimestamp = "event.resend.timestamp"
)
View Source
const (
	DefaultDisabled   = false
	DefaultPageNumber = 1
	DefaultPageSize   = 100
)
View Source
const (
	DefaultReconcileInterval           = 15 * time.Second
	DefaultDispatchTimeout             = 30 * time.Second
	DefaultDeliveryStatePendingTimeout = 3 * time.Hour
	DefaultDeliveryStateSendingTimeout = 48 * time.Hour
)
View Source
const (
	// EventPayloadVersionCurrent is the version written for all new events.
	EventPayloadVersionCurrent int = 1
)
View Source
const MaxChannelsPerRule = 5

Variables

View Source
var DefaultReconcilerWorkers = runtime.GOMAXPROCS(0)

Functions

func ChannelIDsByType

func ChannelIDsByType(channels []Channel, channelType ChannelType) []string

ChannelIDsByType returns a list of Channel identifiers from Channel slice with the provided ChannelType

func InterfaceMapToStringMap

func InterfaceMapToStringMap(m map[string]interface{}) map[string]string

func SortEventDeliveryAttemptsInDescOrder

func SortEventDeliveryAttemptsInDescOrder(attempts []EventDeliveryAttempt)

SortEventDeliveryAttemptsInDescOrder sorts the EventDeliveryAttempts in descending order by timestamp.

func StrictInterfaceMapToStringMap

func StrictInterfaceMapToStringMap(m map[string]interface{}) (map[string]string, error)

func ValidateRuleConfigWithFeatures

func ValidateRuleConfigWithFeatures(ctx context.Context, service FeatureService, namespace string) models.ValidatorFunc[RuleConfig]

Types

type BalanceThresholdPayload

type BalanceThresholdPayload struct {
	EntitlementValuePayloadBase

	Threshold api.NotificationRuleBalanceThresholdValue `json:"threshold"`
}

func (BalanceThresholdPayload) Validate

func (b BalanceThresholdPayload) Validate() error

Validate returns an error if the balance threshold payload is invalid.

func (BalanceThresholdPayload) ValidateWith

type BalanceThresholdRuleConfig

type BalanceThresholdRuleConfig struct {
	// Features store the list of features the rule is associated with.
	Features []string `json:"features"`
	// Thresholds store the list of thresholds used to trigger a new notification event if the balance exceeds one of the thresholds.
	Thresholds []BalanceThreshold `json:"thresholds"`
}

BalanceThresholdRuleConfig defines the configuration specific to rule.

func (BalanceThresholdRuleConfig) Validate

func (b BalanceThresholdRuleConfig) Validate() error

Validate returns an error if the balance threshold configuration is invalid.

func (BalanceThresholdRuleConfig) ValidateWith

type Channel

type Channel struct {
	models.NamespacedID
	models.ManagedModel
	models.Annotations
	models.Metadata

	// Type of the notification channel (e.g. webhook)
	Type ChannelType `json:"type"`
	// Name of is the user provided name of the Channel.
	Name string `json:"name"`
	// Disabled defines whether the Channel is disabled or not.
	Disabled bool `json:"disabled"`
	// Config stores the actual Channel configuration specific to the Type.
	Config ChannelConfig `json:"config"`
}

Channel represents a notification channel with specific type and configuration.

type ChannelConfig

type ChannelConfig struct {
	ChannelConfigMeta

	// WebHook
	WebHook WebHookChannelConfig `json:"webhook"`
}

ChannelConfig is a union type capturing configuration parameters for all type of channels.

func (ChannelConfig) Validate

func (c ChannelConfig) Validate() error

Validate invokes channel type specific validator and returns an error if channel configuration is invalid.

type ChannelConfigMeta

type ChannelConfigMeta struct {
	Type ChannelType `json:"type"`
}

func (ChannelConfigMeta) Validate

func (m ChannelConfigMeta) Validate() error

type ChannelIDsDifference

type ChannelIDsDifference struct {
	// contains filtered or unexported fields
}

func NewChannelIDsDifference

func NewChannelIDsDifference(new, old []string) *ChannelIDsDifference

func (ChannelIDsDifference) Additions

func (d ChannelIDsDifference) Additions() []string

func (ChannelIDsDifference) All

func (d ChannelIDsDifference) All() []string

func (ChannelIDsDifference) Has

func (d ChannelIDsDifference) Has(id string) bool

func (ChannelIDsDifference) HasChanged

func (d ChannelIDsDifference) HasChanged() bool

func (ChannelIDsDifference) InAdditions

func (d ChannelIDsDifference) InAdditions(id string) bool

func (ChannelIDsDifference) InRemovals

func (d ChannelIDsDifference) InRemovals(id string) bool

func (ChannelIDsDifference) Removals

func (d ChannelIDsDifference) Removals() []string

type ChannelRepository

type ChannelRepository interface {
	ListChannels(ctx context.Context, params ListChannelsInput) (pagination.Result[Channel], error)
	CreateChannel(ctx context.Context, params CreateChannelInput) (*Channel, error)
	DeleteChannel(ctx context.Context, params DeleteChannelInput) error
	GetChannel(ctx context.Context, params GetChannelInput) (*Channel, error)
	UpdateChannel(ctx context.Context, params UpdateChannelInput) (*Channel, error)
}

type ChannelService

type ChannelService interface {
	ListChannels(ctx context.Context, params ListChannelsInput) (ListChannelsResult, error)
	CreateChannel(ctx context.Context, params CreateChannelInput) (*Channel, error)
	DeleteChannel(ctx context.Context, params DeleteChannelInput) error
	GetChannel(ctx context.Context, params GetChannelInput) (*Channel, error)
	UpdateChannel(ctx context.Context, params UpdateChannelInput) (*Channel, error)
}

type ChannelType

type ChannelType string
const (
	ChannelTypeWebhook ChannelType = "WEBHOOK"
)

func ChannelTypes

func ChannelTypes(channels []Channel) []ChannelType

ChannelTypes returns a set of ChannelType from Channel slice

func (ChannelType) Validate

func (t ChannelType) Validate() error

func (ChannelType) Values

func (t ChannelType) Values() []string

type CreateChannelInput

type CreateChannelInput struct {
	models.NamespacedModel

	// Type defines the Channel type (e.g. webhook)
	Type ChannelType
	// Name stores the user defined name of the Channel.
	Name string
	// Disabled defines whether the Channel is disabled or not. Deleted Channels are always disabled.
	Disabled bool
	// Config stores the Channel Type specific configuration.
	Config ChannelConfig
	// Metadata
	Metadata models.Metadata
	// Annotations
	Annotations models.Annotations
}

func (CreateChannelInput) Validate

func (i CreateChannelInput) Validate() error

func (CreateChannelInput) ValidateWith

func (i CreateChannelInput) ValidateWith(validators ...models.ValidatorFunc[CreateChannelInput]) error

type CreateEventInput

type CreateEventInput struct {
	models.NamespacedModel
	Annotations models.Annotations `json:"annotations,omitempty"`

	// Type of the notification Event (e.g. entitlements.balance.threshold)
	Type EventType `json:"type"`
	// Payload is the actual payload sent to Channel as part of the notification Event.
	Payload EventPayload `json:"payload"`
	// RuleID defines the notification Rule that generated this Event.
	RuleID string `json:"ruleId"`
	// HandlerDeduplicationHash is a hash that the handler can use to deduplicate events if needed
	HandlerDeduplicationHash string `json:"handlerDeduplicationHash"`
}

func (CreateEventInput) Validate

func (i CreateEventInput) Validate() error

func (CreateEventInput) ValidateWith

func (i CreateEventInput) ValidateWith(validators ...models.ValidatorFunc[CreateEventInput]) error

type CreateRuleInput

type CreateRuleInput struct {
	models.NamespacedModel

	// Type defines the Rule type (e.g. entitlements.balance.threshold)
	Type EventType
	// Name stores the user defined name of the Rule.
	Name string
	// Disabled defines whether the Rule is disabled or not. Deleted Rules are always disabled.
	Disabled bool
	// Config stores the Rule Type specific configuration.
	Config RuleConfig
	// Channels defines the list of Channels the Rule needs to send Events.
	Channels []string
	// Metadata
	Metadata models.Metadata
	// Annotations
	Annotations models.Annotations
}

func (CreateRuleInput) Validate

func (i CreateRuleInput) Validate() error

func (CreateRuleInput) ValidateWith

func (i CreateRuleInput) ValidateWith(validators ...models.ValidatorFunc[CreateRuleInput]) error

type DeleteChannelInput

type DeleteChannelInput = GetChannelInput

type DeleteRuleInput

type DeleteRuleInput = GetRuleInput

type EntitlementResetPayload

type EntitlementResetPayload EntitlementValuePayloadBase

func (EntitlementResetPayload) Validate

func (e EntitlementResetPayload) Validate() error

func (EntitlementResetPayload) ValidateWith

type EntitlementResetRuleConfig

type EntitlementResetRuleConfig struct {
	Features []string `json:"features"`
}

func (EntitlementResetRuleConfig) Validate

func (e EntitlementResetRuleConfig) Validate() error

func (EntitlementResetRuleConfig) ValidateWith

type EntitlementValuePayloadBase

type EntitlementValuePayloadBase struct {
	Entitlement api.EntitlementMetered `json:"entitlement"`
	Feature     api.Feature            `json:"feature"`
	Subject     api.Subject            `json:"subject"`
	Value       api.EntitlementValue   `json:"value"`
	Customer    api.Customer           `json:"customer"`
}

func (EntitlementValuePayloadBase) Validate

func (e EntitlementValuePayloadBase) Validate() error

func (EntitlementValuePayloadBase) ValidateWith

type Event

type Event struct {
	models.NamespacedID
	models.Annotations

	// Type of the notification Event (e.g. entitlements.balance.threshold)
	Type EventType `json:"type"`
	// CreatedAt Timestamp when the notification event was created.
	CreatedAt time.Time `json:"createdAt"`
	// DeliveryStatus defines the delivery status of the notification Event per Channel.
	DeliveryStatus []EventDeliveryStatus `json:"deliveryStatus"`
	// Payload is the actual payload sent to Channel as part of the notification Event.
	Payload EventPayload `json:"payload"`
	// Rule defines the notification Rule that generated this Event.
	Rule Rule `json:"rule"`
	// DeduplicationHash is a hash that the handler can use to deduplicate events if needed
	HandlerDeduplicationHash string `json:"-"`
}

type EventDeliveryAttempt

type EventDeliveryAttempt struct {
	State     EventDeliveryStatusState     `json:"state"`
	Response  EventDeliveryAttemptResponse `json:"response"`
	Timestamp time.Time                    `json:"timestamp"`
}

type EventDeliveryAttemptResponse

type EventDeliveryAttemptResponse struct {
	StatusCode *int          `json:"status_code,omitempty,omitzero"`
	Body       string        `json:"body,omitzero"`
	Duration   time.Duration `json:"duration,omitempty,omitzero"`
	URL        *string       `json:"url,omitempty,omitzero"`
}

type EventDeliveryStatus

type EventDeliveryStatus struct {
	models.NamespacedID

	// EventID defines the Event identifier the EventDeliveryStatus belongs to.
	EventID string

	ChannelID string
	State     EventDeliveryStatusState
	Reason    string
	CreatedAt time.Time
	UpdatedAt time.Time

	Attempts    []EventDeliveryAttempt
	NextAttempt *time.Time

	Annotations models.Annotations
}

type EventDeliveryStatusState

type EventDeliveryStatusState string
const (
	EventDeliveryStatusStateSuccess   EventDeliveryStatusState = "SUCCESS"
	EventDeliveryStatusStateFailed    EventDeliveryStatusState = "FAILED"
	EventDeliveryStatusStateSending   EventDeliveryStatusState = "SENDING"
	EventDeliveryStatusStatePending   EventDeliveryStatusState = "PENDING"
	EventDeliveryStatusStateResending EventDeliveryStatusState = "RESENDING"
)

func DeliveryStatusStates

func DeliveryStatusStates(statuses []EventDeliveryStatus) []EventDeliveryStatusState

DeliveryStatusStates returns a list of EventDeliveryStatusState from EventDeliveryStatus slice

func (EventDeliveryStatusState) String

func (e EventDeliveryStatusState) String() string

func (EventDeliveryStatusState) Validate

func (e EventDeliveryStatusState) Validate() error

func (EventDeliveryStatusState) Values

func (e EventDeliveryStatusState) Values() []string

type EventDispatcher

type EventDispatcher interface {
	Dispatch(ctx context.Context, event *Event) error
}

type EventHandler

type EventHandler interface {
	EventDispatcher
	EventReconciler

	Start() error
	Close() error
}

type EventPayload

type EventPayload struct {
	EventPayloadMeta

	// Entitlements
	BalanceThreshold *BalanceThresholdPayload `json:"balanceThreshold,omitempty"`
	EntitlementReset *EntitlementResetPayload `json:"entitlementReset,omitempty"`

	// Invoice
	Invoice *InvoicePayload `json:"invoice,omitempty"`
}

EventPayload is a union type capturing payload for all EventType of Events.

func (EventPayload) Validate

func (p EventPayload) Validate() error

type EventPayloadMeta

type EventPayloadMeta struct {
	Type    EventType `json:"type"`
	Version int       `json:"version,omitempty"`
}

func (EventPayloadMeta) Validate

func (m EventPayloadMeta) Validate() error

type EventReconciler

type EventReconciler interface {
	Reconcile(ctx context.Context) error
}

type EventRepository

type EventRepository interface {
	ListEvents(ctx context.Context, params ListEventsInput) (pagination.Result[Event], error)
	GetEvent(ctx context.Context, params GetEventInput) (*Event, error)
	CreateEvent(ctx context.Context, params CreateEventInput) (*Event, error)
	ListEventsDeliveryStatus(ctx context.Context, params ListEventsDeliveryStatusInput) (pagination.Result[EventDeliveryStatus], error)
	GetEventDeliveryStatus(ctx context.Context, params GetEventDeliveryStatusInput) (*EventDeliveryStatus, error)
	UpdateEventDeliveryStatus(ctx context.Context, params UpdateEventDeliveryStatusInput) (*EventDeliveryStatus, error)
}

type EventService

type EventService interface {
	ListEvents(ctx context.Context, params ListEventsInput) (ListEventsResult, error)
	GetEvent(ctx context.Context, params GetEventInput) (*Event, error)
	CreateEvent(ctx context.Context, params CreateEventInput) (*Event, error)
	ResendEvent(ctx context.Context, params ResendEventInput) error
	ListEventsDeliveryStatus(ctx context.Context, params ListEventsDeliveryStatusInput) (ListEventsDeliveryStatusResult, error)
	GetEventDeliveryStatus(ctx context.Context, params GetEventDeliveryStatusInput) (*EventDeliveryStatus, error)
	UpdateEventDeliveryStatus(ctx context.Context, params UpdateEventDeliveryStatusInput) (*EventDeliveryStatus, error)
}

type EventType

type EventType string
const (
	EventTypeBalanceThreshold EventType = "entitlements.balance.threshold"
	EventTypeEntitlementReset EventType = "entitlements.reset"
)
const (
	EventTypeInvoiceCreated EventType = "invoice.created"
	EventTypeInvoiceUpdated EventType = "invoice.updated"
)

func EventTypes

func EventTypes() []EventType

func (EventType) String

func (t EventType) String() string

func (EventType) Validate

func (t EventType) Validate() error

func (EventType) Values

func (t EventType) Values() []string

type FeatureMeta

type FeatureMeta = api.FeatureMeta

type FeatureService

type FeatureService interface {
	ListFeature(ctx context.Context, namespace string, features ...string) ([]feature.Feature, error)
}

type GetChannelInput

type GetChannelInput models.NamespacedID

func (GetChannelInput) Validate

func (i GetChannelInput) Validate() error

func (GetChannelInput) ValidateWith

func (i GetChannelInput) ValidateWith(validators ...models.ValidatorFunc[GetChannelInput]) error

type GetEventDeliveryStatusInput

type GetEventDeliveryStatusInput struct {
	models.NamespacedID

	// EventID defines the Event identifier the EventDeliveryStatus belongs to. Must be provided if ID is empty.
	EventID string
	// ChannelID defines the Channel identifier the EventDeliveryStatus belongs to. Must be provided if ID is empty.
	ChannelID string
}

func (GetEventDeliveryStatusInput) Validate

func (i GetEventDeliveryStatusInput) Validate() error

func (GetEventDeliveryStatusInput) ValidateWith

type GetEventInput

type GetEventInput models.NamespacedID

func (GetEventInput) Validate

func (i GetEventInput) Validate() error

func (GetEventInput) ValidateWith

func (i GetEventInput) ValidateWith(validators ...models.ValidatorFunc[GetEventInput]) error

type GetRuleInput

type GetRuleInput models.NamespacedID

func (GetRuleInput) Validate

func (i GetRuleInput) Validate() error

func (GetRuleInput) ValidateWith

func (i GetRuleInput) ValidateWith(validators ...models.ValidatorFunc[GetRuleInput]) error

type InvoicePayload

type InvoicePayload struct {
	api.Invoice
}

func (InvoicePayload) Validate

func (ip InvoicePayload) Validate() error

func (InvoicePayload) ValidateWith

func (ip InvoicePayload) ValidateWith(validators ...models.ValidatorFunc[InvoicePayload]) error

type InvoiceRuleConfig

type InvoiceRuleConfig struct{}

func (InvoiceRuleConfig) Validate

func (c InvoiceRuleConfig) Validate() error

func (InvoiceRuleConfig) ValidateWith

func (c InvoiceRuleConfig) ValidateWith(validators ...models.ValidatorFunc[InvoiceRuleConfig]) error

type ListChannelsInput

type ListChannelsInput struct {
	pagination.Page

	Namespaces      []string
	Channels        []string
	IncludeDisabled bool

	OrderBy OrderBy
	Order   sortx.Order
}

func (ListChannelsInput) Validate

func (i ListChannelsInput) Validate() error

func (ListChannelsInput) ValidateWith

func (i ListChannelsInput) ValidateWith(validators ...models.ValidatorFunc[ListChannelsInput]) error

type ListChannelsResult

type ListChannelsResult = pagination.Result[Channel]

type ListEventsDeliveryStatusInput

type ListEventsDeliveryStatusInput struct {
	pagination.Page

	// Namespaces is a list of namespaces to be used to filter the list of EventDeliveryStatus to be returned.
	Namespaces []string

	// From limits the scope fo the request by defining the earliest date to be used for lookup.
	// This filter is applied to EventDeliveryStatus.UpdatedAt field.
	From time.Time
	// To limits the scope fo the request by defining the latest date to be used for lookup.
	// This filter is applied to EventDeliveryStatus.UpdatedAt field.
	To time.Time

	// Events is a list of Event identifiers used as filter.
	Events []string
	// Channels is a list of Channel identifiers used as filter.
	Channels []string
	// State is a list of Event State used as filter.
	States []EventDeliveryStatusState
}

func (ListEventsDeliveryStatusInput) Validate

func (i ListEventsDeliveryStatusInput) Validate() error

func (ListEventsDeliveryStatusInput) ValidateWith

type ListEventsDeliveryStatusResult

type ListEventsDeliveryStatusResult = pagination.Result[EventDeliveryStatus]

type ListEventsInput

type ListEventsInput struct {
	pagination.Page

	Namespaces []string `json:"namespaces,omitempty"`
	Events     []string `json:"events,omitempty"`

	From time.Time `json:"from,omitempty"`
	To   time.Time `json:"to,omitempty"`

	Subjects []string `json:"subjects,omitempty"`
	Features []string `json:"features,omitempty"`

	Rules    []string `json:"rules,omitempty"`
	Channels []string `json:"channels,omitempty"`

	DeduplicationHashes []string `json:"deduplicationHashes,omitempty"`

	DeliveryStatusStates []EventDeliveryStatusState `json:"deliveryStatusStates,omitempty"`

	NextAttemptBefore time.Time `json:"nextAttemptBefore,omitempty"`

	OrderBy OrderBy
	Order   sortx.Order
}

func (ListEventsInput) Validate

func (i ListEventsInput) Validate() error

func (ListEventsInput) ValidateWith

func (i ListEventsInput) ValidateWith(validators ...models.ValidatorFunc[ListEventsInput]) error

type ListEventsResult

type ListEventsResult = pagination.Result[Event]

type ListRulesInput

type ListRulesInput struct {
	pagination.Page

	Namespaces      []string
	Rules           []string
	IncludeDisabled bool
	Types           []EventType
	Channels        []string

	OrderBy OrderBy
	Order   sortx.Order
}

func (ListRulesInput) Validate

func (i ListRulesInput) Validate() error

func (ListRulesInput) ValidateWith

func (i ListRulesInput) ValidateWith(validators ...models.ValidatorFunc[ListRulesInput]) error

type ListRulesResult

type ListRulesResult = pagination.Result[Rule]

type NotFoundError

type NotFoundError struct {
	models.NamespacedID
}

func (NotFoundError) Error

func (e NotFoundError) Error() string

type OrderBy

type OrderBy string
const (
	OrderByID        OrderBy = "id"
	OrderByType      OrderBy = "type"
	OrderByCreatedAt OrderBy = "createdAt"
	OrderByUpdatedAt OrderBy = "updatedAt"
)

type RawPayload

type RawPayload map[string]any

func AsRawPayload

func AsRawPayload(t any) (RawPayload, error)

type ResendEventInput

type ResendEventInput struct {
	models.NamespacedID

	Channels []string `json:"channels,omitempty"`
}

func (ResendEventInput) Validate

func (i ResendEventInput) Validate() error

func (ResendEventInput) ValidateWith

func (i ResendEventInput) ValidateWith(validators ...models.ValidatorFunc[ResendEventInput]) error

type Rule

type Rule struct {
	models.NamespacedID
	models.ManagedModel
	models.Annotations
	models.Metadata

	// Type of the notification Rule (e.g. entitlements.balance.threshold)
	Type EventType `json:"type"`
	// Name of is the user provided name of the Rule.
	Name string `json:"name"`
	// Disabled defines whether the Rule is disabled or not.
	Disabled bool `json:"disabled"`
	// Config stores the actual Rule configuration specific to the Type.
	Config RuleConfig `json:"config"`
	// Channels stores the list of channels the Rule send notification Events to.
	Channels []Channel `json:"channels"`
}

func (Rule) Validate

func (r Rule) Validate() error

func (Rule) ValidateWith

func (r Rule) ValidateWith(validators ...models.ValidatorFunc[Rule]) error

type RuleConfig

type RuleConfig struct {
	RuleConfigMeta

	// Balance Threshold
	BalanceThreshold *BalanceThresholdRuleConfig `json:"balanceThreshold,omitempty"`
	EntitlementReset *EntitlementResetRuleConfig `json:"entitlementReset,omitempty"`

	// Invoice
	Invoice *InvoiceRuleConfig `json:"invoice,omitempty"`
}

RuleConfig is a union type capturing configuration parameters for all type of rules.

func (RuleConfig) Validate

func (c RuleConfig) Validate() error

Validate invokes channel type specific validator and returns an error if channel configuration is invalid.

func (RuleConfig) ValidateWith

func (c RuleConfig) ValidateWith(validators ...models.ValidatorFunc[RuleConfig]) error

type RuleConfigMeta

type RuleConfigMeta struct {
	Type EventType `json:"type"`
}

func (RuleConfigMeta) Validate

func (m RuleConfigMeta) Validate() error

func (RuleConfigMeta) ValidateWith

func (m RuleConfigMeta) ValidateWith(validators ...models.ValidatorFunc[RuleConfigMeta]) error

type RuleRepository

type RuleRepository interface {
	ListRules(ctx context.Context, params ListRulesInput) (pagination.Result[Rule], error)
	CreateRule(ctx context.Context, params CreateRuleInput) (*Rule, error)
	DeleteRule(ctx context.Context, params DeleteRuleInput) error
	GetRule(ctx context.Context, params GetRuleInput) (*Rule, error)
	UpdateRule(ctx context.Context, params UpdateRuleInput) (*Rule, error)
}

type RuleService

type RuleService interface {
	ListRules(ctx context.Context, params ListRulesInput) (ListRulesResult, error)
	CreateRule(ctx context.Context, params CreateRuleInput) (*Rule, error)
	DeleteRule(ctx context.Context, params DeleteRuleInput) error
	GetRule(ctx context.Context, params GetRuleInput) (*Rule, error)
	UpdateRule(ctx context.Context, params UpdateRuleInput) (*Rule, error)
}

type UpdateAfterDeleteError

type UpdateAfterDeleteError genericError

func (UpdateAfterDeleteError) Error

func (e UpdateAfterDeleteError) Error() string

func (UpdateAfterDeleteError) Unwrap

func (e UpdateAfterDeleteError) Unwrap() error

type UpdateChannelInput

type UpdateChannelInput struct {
	models.NamespacedID

	// Type defines the Channel type (e.g. webhook)
	Type ChannelType
	// Name stores the user-defined name of the Channel.
	Name string
	// Disabled defines whether the Channel is disabled or not. Deleted Channels are always disabled.
	Disabled bool
	// Config stores the Channel Type specific configuration.
	Config ChannelConfig
	// Metadata
	Metadata models.Metadata
	// Annotations
	Annotations models.Annotations
}

func (UpdateChannelInput) Validate

func (i UpdateChannelInput) Validate() error

func (UpdateChannelInput) ValidateWith

func (i UpdateChannelInput) ValidateWith(validators ...models.ValidatorFunc[UpdateChannelInput]) error

type UpdateEventDeliveryStatusInput

type UpdateEventDeliveryStatusInput struct {
	models.NamespacedID

	// State is the delivery state of the Event.
	State EventDeliveryStatusState
	// Reason describes the reason for the latest State transition.
	Reason string
	// Annotations
	Annotations models.Annotations
	// NextAttempt defines the next time the Event should be attempted to be delivered.
	NextAttempt *time.Time
	// Attempts is a list of delivery attempts for the Event.
	Attempts []EventDeliveryAttempt
}

func (UpdateEventDeliveryStatusInput) Validate

func (UpdateEventDeliveryStatusInput) ValidateWith

type UpdateRuleInput

type UpdateRuleInput struct {
	models.NamespacedID

	// Type defines the Rule type (e.g. entitlements.balance.threshold)
	Type EventType
	// Name stores the user defined name of the Rule.
	Name string
	// Disabled defines whether the Rule is disabled or not. Deleted Rules are always disabled.
	Disabled bool
	// Config stores the Rule Type specific configuration.
	Config RuleConfig
	// Channels defines the list of Channels the Rule needs to send Events.
	Channels []string
	// Metadata
	Metadata models.Metadata
	// Annotations
	Annotations models.Annotations
}

func (UpdateRuleInput) Validate

func (i UpdateRuleInput) Validate() error

func (UpdateRuleInput) ValidateWith

func (i UpdateRuleInput) ValidateWith(validators ...models.ValidatorFunc[UpdateRuleInput]) error

type WebHookChannelConfig

type WebHookChannelConfig struct {
	// CustomHeaders stores a set of HTTP headers which are applied to the outgoing webhook message.
	CustomHeaders map[string]string `json:"customHeaders,omitempty"`
	// URL is the webhook endpoint url where the messages are sent to.
	URL string `json:"url"`
	// SigningSecret defines the secret which can be used for validating the signature of the message sent
	// to the webhook endpoint.
	SigningSecret string `json:"signingSecret"`
}

WebHookChannelConfig defines the configuration specific to a channel with a webhook type.

func (WebHookChannelConfig) Validate

func (w WebHookChannelConfig) Validate() error

Validate returns an error if webhook channel configuration is invalid.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL