labels

package
v0.19.927 Latest Latest
Warning

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

Go to latest
Published: May 12, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithLabels

func WithLabels(column string, lbls Labels) func(*gorm.DB) *gorm.DB

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

type Labels map[string]string

Labels defines a custom type for map[string]string that works with JSONB in GORM.

func ParseLabelsQuery

func ParseLabelsQuery(raw string) Labels

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

func (l Labels) GormDataType() string

GormDataType returns the GORM data type for this field.

func (Labels) HasLabel

func (l Labels) HasLabel(key, value string) bool

HasLabel returns true if the label with the given key and value exists.

func (*Labels) Merge

func (l *Labels) Merge(other Labels)

Merge adds all key-value pairs from other into the receiver, overwriting existing keys.

func (*Labels) RemoveKeys

func (l *Labels) RemoveKeys(keys []string)

RemoveKeys removes the specified keys from the labels.

func (*Labels) Scan

func (l *Labels) Scan(value interface{}) error

Scan implements the sql.Scanner interface for database deserialization.

func (Labels) Value

func (l Labels) Value() (driver.Value, error)

Value implements the driver.Valuer interface for database serialization.

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

func (s *Selector) Canonical() string

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

func (s *Selector) Matches(set Labels) bool

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

func (s *Selector) Validate() error

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.

Jump to

Keyboard shortcuts

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