Documentation
¶
Overview ¶
Package labels' match.go defines the SubscriptionMatch shape persisted as a nullable JSONB column on slack_channel_subscriptions. A nil column value (and equivalently a nil receiver here) means "every event in the org" — this collapses the legacy scope=org|install + InstallID *string design into a single column.
SubscriptionMatch composes per-resource TargetMatch slots; TargetMatch composes a list of IDs with an optional Selector. Composition rules:
- SubscriptionMatch.Matches: OR across non-nil kinds.
- TargetMatch.matches: OR within (id ∈ IDs OR Selector hit).
- Selector.Matches: AND across MatchLabels.
TargetKind is intentionally NOT shared with interests.ResourceKind: pkg/labels lives below internal/ in the import graph and the resource taxonomy is a property of the dispatch layer, not of label matching.
Index ¶
- func WithLabels(column string, lbls Labels) func(*gorm.DB) *gorm.DB
- type EventTargets
- type Labeled
- type Labels
- type Selector
- type SubscriptionMatch
- func (m *SubscriptionMatch) Canonical() string
- func (SubscriptionMatch) GormDataType() string
- func (m *SubscriptionMatch) Matches(t EventTargets) bool
- func (m *SubscriptionMatch) Scan(v interface{}) error
- func (m *SubscriptionMatch) Validate() error
- func (m SubscriptionMatch) Value() (driver.Value, error)
- type TargetKind
- type TargetMatch
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WithLabels ¶
WithLabels returns a GORM scope that filters rows where the JSONB column contains all the specified key-value pairs (PostgreSQL @> containment). A value of "*" is treated as a wildcard — it matches any value for that key (uses jsonb_exists() to check key existence). Returns a no-op scope if lbls is nil or empty.
Types ¶
type EventTargets ¶ added in v0.19.927
type EventTargets struct {
InstallID string
ComponentID string
ActionID string
InstallLabels Labels
ComponentLabels Labels
ActionLabels Labels
}
EventTargets is the projection of a dispatched event the matcher needs: the resolved entity IDs and their label sets at the time of dispatch. Any field may be empty — an absent ID short-circuits TargetMatch.matches so a component-only event never falsely satisfies an installs filter.
type Labeled ¶
type Labeled struct {
Labels Labels `json:"labels,omitzero" gorm:"default null" temporaljson:"labels,omitzero,omitempty"`
}
Labeled is an embeddable struct for any GORM model that supports labels. Embed it to get a consistent JSONB labels column with standard tags.
type Labels ¶
Labels defines a custom type for map[string]string that works with JSONB in GORM.
func ParseLabelsQuery ¶
ParseLabelsQuery parses a comma-separated "key:value" string into Labels. Returns nil for empty input. Entries without a separator are treated as wildcard key-only filters (value set to "*"). Supports both ":" and "=" as key-value separators. Splits on the first separator only, so values may contain colons or equals. A value of "*" means "match any value for this key" (wildcard).
func (Labels) GormDataType ¶
GormDataType returns the GORM data type for this field.
func (*Labels) Merge ¶
Merge adds all key-value pairs from other into the receiver, overwriting existing keys.
func (*Labels) RemoveKeys ¶
RemoveKeys removes the specified keys from the labels.
type Selector ¶ added in v0.19.927
type Selector struct {
MatchLabels Labels `json:"match_labels"`
}
Selector matches a label set with AND across keys. A value of "*" means "key must exist" (mirrors the wildcard semantics of WithLabels' jsonb_exists branch in scopes.go); any other value requires exact equality (mirrors @>).
Callers represent "match everything" as a *nil* Selector, never as Selector{MatchLabels: nil} — see Validate.
func (*Selector) Canonical ¶ added in v0.19.927
Canonical returns a deterministic JSON encoding (keys sorted) so the value can participate in the SlackChannelSubscription unique index without being at the mercy of Go map iteration order.
func (*Selector) Matches ¶ added in v0.19.927
Matches returns true iff every entry in MatchLabels is satisfied by set. Empty MatchLabels matches everything; callers should not construct such a Selector (Validate rejects it) but the matcher is permissive so dispatch never silently drops events on stale data.
func (*Selector) Validate ¶ added in v0.19.927
Validate enforces the invariant that a *non-nil* Selector carries at least one constraint. The "match everything" case is expressed by a nil pointer at the call site (TargetMatch.Selector == nil), not by an empty MatchLabels map — this keeps the dispatch / preview / canonical-key code paths from having to special-case an ambiguous shape.
type SubscriptionMatch ¶ added in v0.19.927
type SubscriptionMatch struct {
Installs *TargetMatch `json:"installs,omitempty"`
Components *TargetMatch `json:"components,omitempty"`
Actions *TargetMatch `json:"actions,omitempty"`
}
SubscriptionMatch is the per-subscription routing filter persisted as JSONB on slack_channel_subscriptions.match. Schema supports populating multiple kinds in one row (CLI uses this); the v1 modal will only ever write one kind at a time.
func (*SubscriptionMatch) Canonical ¶ added in v0.19.927
func (m *SubscriptionMatch) Canonical() string
Canonical returns a deterministic JSON encoding suitable for use in the slack_channel_subscriptions unique index column. Sorting nested slices / selector keys here means two semantically-equal matches produce identical bytes regardless of construction order or map iteration. "" for the match-all (nil / zero) case so it round-trips with the SQL NULL.
func (SubscriptionMatch) GormDataType ¶ added in v0.19.927
func (SubscriptionMatch) GormDataType() string
GormDataType marks the column as JSONB.
func (*SubscriptionMatch) Matches ¶ added in v0.19.927
func (m *SubscriptionMatch) Matches(t EventTargets) bool
Matches returns true if any non-nil kind matches its corresponding event target. A nil receiver is the org-wide subscription — match everything.
func (*SubscriptionMatch) Scan ¶ added in v0.19.927
func (m *SubscriptionMatch) Scan(v interface{}) error
Scan implements sql.Scanner for the JSONB match column. Mirrors the pattern used by interests.Interests so a NULL or empty column round-trips to a zero-valued struct (which Value() then turns back into NULL).
func (*SubscriptionMatch) Validate ¶ added in v0.19.927
func (m *SubscriptionMatch) Validate() error
Validate requires at least one populated kind and recurses into each. A fully-empty SubscriptionMatch should be expressed as a nil column, not as a row carrying an unconstrained struct.
func (SubscriptionMatch) Value ¶ added in v0.19.927
func (m SubscriptionMatch) Value() (driver.Value, error)
Value implements driver.Valuer. The zero match persists as SQL NULL — see isZero — so the column's "nil = match everything" semantics survive callers that hand us &SubscriptionMatch{} instead of nil.
type TargetKind ¶ added in v0.19.927
type TargetKind string
TargetKind is the set of entity kinds a SubscriptionMatch can target. Kept deliberately narrow — only kinds that the picker UI exposes today.
const ( TargetKindInstalls TargetKind = "installs" TargetKindComponents TargetKind = "components" TargetKindActions TargetKind = "actions" )
type TargetMatch ¶ added in v0.19.927
type TargetMatch struct {
IDs []string `json:"ids,omitempty"`
Selector *Selector `json:"selector,omitempty"`
}
TargetMatch filters one entity kind. An empty TargetMatch{} (no IDs, no Selector) is intentionally valid and means "any entity of this kind" — the modal needs an explicit "Any installs" option distinct from "Specific installs" / "By labels" without forcing a sentinel value.
func (*TargetMatch) Validate ¶ added in v0.19.927
func (t *TargetMatch) Validate() error
Validate ensures the filter is well-formed. Empty TargetMatch{} is allowed (see type doc); a non-nil Selector must itself be non-empty.