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 ¶
- Variables
- func Compile(ctx context.Context, s *ent.Scoped, g Group) (predicate.Contact, error)
- func ContactPredicate(ctx context.Context, s *ent.Scoped, def string) (predicate.Contact, error)
- func Decode(def string, into json.Unmarshaler) error
- func Encode(group json.Marshaler) (string, error)
- func UsingTag(ctx context.Context, s *ent.Scoped, name string) ([]*ent.Segment, error)
- type CreateInput
- type Group
- type Module
- func (s *Module) Archive(ctx context.Context, ws *ent.Scoped, id int64) error
- func (s *Module) Contacts(ctx context.Context, ws *ent.Scoped, id int64, p pagination.Params) (pagination.Page[*ent.Contact], error)
- func (s *Module) Count(ctx context.Context, ws *ent.Scoped, id int64) (int, error)
- func (s *Module) Create(ctx context.Context, ws *ent.Scoped, in CreateInput) (*ent.Segment, error)
- func (s *Module) List(ctx context.Context, ws *ent.Scoped, p pagination.Params, archived bool) (pagination.Page[*ent.Segment], error)
- func (s *Module) Preview(ctx context.Context, ws *ent.Scoped, def string) (int, error)
- func (s *Module) Unarchive(ctx context.Context, ws *ent.Scoped, id int64) error
- func (s *Module) Update(ctx context.Context, ws *ent.Scoped, id int64, in UpdateInput) (*ent.Segment, error)
- func (s *Module) Validate(ctx context.Context, ws *ent.Scoped, def string) error
- type Rule
- type UpdateInput
Constants ¶
This section is empty.
Variables ¶
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 ¶
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 ¶
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 ¶
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.
Types ¶
type CreateInput ¶
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.
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 ¶
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 ¶
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) 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 ¶
Preview counts the Contacts in the Workspace that match an unsaved definition.
func (*Module) Unarchive ¶
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.
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 ¶
UpdateInput changes a Segment; nil fields are left as they are.