Help us shape the future of Go! Take the 2026 Go Developer Survey

segments

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package segments compiles a Segment's rule query (the typed tree of the API contract, ADR 0029) into a Contact predicate: a group {kind: "group", combinator: and|or, not, rules[]} whose entries are nested groups or leaves {kind: "rule", field, operator, value}, told apart by `kind`.

A leaf is built from ent's generated predicates wherever one exists: the core attributes (contact.EmailEQ …), Tags (contact.HasTagsWith) and Events (contact.HasEventsWith). The one dynamic piece is a Custom field's key inside the custom_fields JSON column, which no generated predicate covers; it is addressed with ent's JSON predicates (sqljson) after the key is checked. A leaf may only name a core attribute, a Tag, an Event action, or a Custom field of the Workspace's catalogue (ADR 0006).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidDefinition: the rule definition does not parse or does not fit the
	// Contact schema. The wrapped message is safe to show to the author.
	ErrInvalidDefinition = errors.New("segments: invalid definition")
	// ErrNotFound: no such Segment in this Workspace.
	ErrNotFound = errors.New("segments: segment not found")
)

Domain errors returned by Module. Callers match with errors.Is.

Functions

func Compile

func Compile(ctx context.Context, s *ent.Scoped, g Group) (predicate.Contact, error)

Compile turns a definition group into a Contact predicate. An empty rule set matches everyone (an empty negated group matches no one) — deliberate, so an empty rule is never a silent "nobody".

func ContactPredicate

func ContactPredicate(ctx context.Context, s *ent.Scoped, def string) (predicate.Contact, error)

ContactPredicate parses a stored definition and compiles it for the Workspace of s.

func Decode

func Decode(def string, into json.Unmarshaler) error

Decode loads a stored definition into an API DTO.

func Encode

func Encode(group json.Marshaler) (string, error)

Encode stores a rule group given as an API DTO. The API's typed tree is the stored shape: a definition is saved as its JSON, and ContactPredicate reads it back.

func UsingTag

func UsingTag(ctx context.Context, s *ent.Scoped, name string) ([]*ent.Segment, error)

UsingTag returns the Workspace's Segments whose rule names the Tag by its name, in id order. Archived ones count: restoring one must not leave it naming a missing Tag. A Segment rule keeps the name, not an id, so deleting the Tag would leave it matching nothing.

Types

type CreateInput

type CreateInput struct {
	Name       string
	Definition *string
}

CreateInput is a new Segment. A nil or empty Definition means "no rules yet".

type Group

type Group struct {
	Kind       string            `json:"kind"`
	Combinator string            `json:"combinator"`
	Not        bool              `json:"not,omitempty"`
	Rules      []json.RawMessage `json:"rules"`
}

Group is a group of the rule tree. Each rules[] entry is decoded lazily because it is either a nested Group or a leaf Rule, as its `kind` says.

func Parse

func Parse(def string) (Group, error)

Parse decodes a definition string into a Group. A blank definition is a valid "match everyone" group.

type Module

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

Module is the one place a Segment is written, validated, previewed and counted (ADR 0016). Create and update share one validation rule set; handlers stay thin adapters (scope check, call, map). Membership is the rule alone — Send-eligibility is subtracted only at send, never folded into a count (ADR 0001).

func New

func New(bus *events.Bus) *Module

New builds the Segments module. It holds no client: every call takes the Workspace's scoped client (ADR 0017); the bus runs the archive in one transaction.

func (*Module) Archive

func (s *Module) Archive(ctx context.Context, ws *ent.Scoped, id int64) error

Archive discards a Segment (ADR 0049), unless a draft or scheduled Broadcast uses it: then it returns an *inuse.Error naming those Broadcasts. A sent or failed Broadcast keeps its stored reference as history and does not block. A missing Segment is ErrNotFound; archiving an archived one changes nothing.

func (*Module) Contacts

func (s *Module) Contacts(ctx context.Context, ws *ent.Scoped, id int64, p pagination.Params) (pagination.Page[*ent.Contact], error)

Contacts returns one page of the Contacts a stored Segment matches, evaluated live, ascending by id.

func (*Module) Count

func (s *Module) Count(ctx context.Context, ws *ent.Scoped, id int64) (int, error)

Count counts the Contacts matching a stored Segment, evaluated live.

func (*Module) Create

func (s *Module) Create(ctx context.Context, ws *ent.Scoped, in CreateInput) (*ent.Segment, error)

Create validates the definition and stores the Segment.

func (*Module) List

func (s *Module) List(ctx context.Context, ws *ent.Scoped, p pagination.Params, archived bool) (pagination.Page[*ent.Segment], error)

List returns one page of the Workspace's Segments, ascending by id: the kept ones, or with archived the archived ones.

func (*Module) Preview

func (s *Module) Preview(ctx context.Context, ws *ent.Scoped, def string) (int, error)

Preview counts the Contacts in the Workspace that match an unsaved definition.

func (*Module) Unarchive

func (s *Module) Unarchive(ctx context.Context, ws *ent.Scoped, id int64) error

Unarchive brings an archived Segment back to the lists. Restoring one that is not archived changes nothing; a missing Segment is ErrNotFound.

func (*Module) Update

func (s *Module) Update(ctx context.Context, ws *ent.Scoped, id int64, in UpdateInput) (*ent.Segment, error)

Update validates a changed definition exactly as Create does, then applies the change.

func (*Module) Validate

func (s *Module) Validate(ctx context.Context, ws *ent.Scoped, def string) error

Validate checks a definition against the Contact attributes and the Workspace's Custom field catalogue. An empty definition is valid. This is the single rule set behind Create, Update, Preview and Count.

type Rule

type Rule struct {
	Kind     string `json:"kind"`
	Field    string `json:"field"`
	Operator string `json:"operator"`
	Value    string `json:"value"`
}

Rule is a leaf rule of the tree.

type UpdateInput

type UpdateInput struct {
	Name       *string
	Definition *string
}

UpdateInput changes a Segment; nil fields are left as they are.

Jump to

Keyboard shortcuts

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