Documentation
¶
Overview ¶
Package eventlog is the one place a customer's Events enter and are summarized (ADR 0016, use-case modules). Ingest resolves each Event's identity to an existing Contact (ADR 0002) and publishes the batch in a single transaction; Actions is the workspace's distinct-action query. The /site and /api handlers are thin adapters over it and no longer duplicate either piece.
The persist subscriber writes the Event rows asynchronously from the outbox, so Ingest is accept-then-process.
Index ¶
- type Filter
- type Input
- type LivePolicy
- type Module
- func (m *Module) Actions(ctx context.Context, s *ent.Scoped) ([]string, error)
- func (m *Module) Ingest(ctx context.Context, s *ent.Scoped, inputs []Input) error
- func (m *Module) IngestEach(ctx context.Context, s *ent.Scoped, inputs []Input) []error
- func (m *Module) List(ctx context.Context, s *ent.Scoped, f Filter, p pagination.Params) (pagination.Page[*ent.Event], error)
- func (m *Module) ListActions(ctx context.Context, s *ent.Scoped, p pagination.Params) (pagination.Page[string], error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Filter ¶
type Filter struct {
Action string
// ContactID selects a Contact's activity by the stable identity link, which includes
// anonymous Events stitched onto the Contact at Identify (ADR 0002).
ContactID *int64
// Email matches case-insensitively: Contact emails are stored as entered, but collect
// ingestion lowercases Event emails, so an exact match would miss tracked Events.
Email string
// IncludeMachine lists the opens and clicks made by software too (ADR 0053); by default
// they stay in the log and out of the page.
IncludeMachine bool
}
Filter narrows the Events List returns; a zero field does not filter.
type Input ¶
type Input struct {
SubjectID string
Email *string
Phone *string
Action string
OccurredAt time.Time // zero => publish time
Properties map[string]any
// ClientEventID is the client's own id for the Event ("" = none). A repeat of an id in
// a Workspace is a no-op, so a client can resend a load it never saw answered.
ClientEventID string
// Backfill records the Event as history: no Automation enrolls on it and no webhook
// endpoint receives it.
Backfill bool
}
Input is one customer Event to ingest. Action and Properties are the customer's own and are stored as-is; the alias keys (SubjectID, Email, Phone) identify the Contact it belongs to, if one exists.
type LivePolicy ¶
LivePolicy says how old a live Event may be: an older one is history and arrives as a Backfill, never as a live Event that could enroll an Automation. Now is the clock the age is judged against.
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module is the Events ingest and read module.
func New ¶
func New(bus *events.Bus, live LivePolicy) *Module
New builds the module over the domain-event bus (transactional publish). Reads and identity resolution go through the Workspace-scoped client each call receives.
func (*Module) Ingest ¶
Ingest attaches each Event to an existing Contact by stable identity (an unknown identity stays anonymous; a Contact is never created) and publishes the whole batch atomically: either every Event is accepted or none is. An Event that fails validate refuses the whole batch with an *events.RejectionError.
func (*Module) IngestEach ¶
IngestEach ingests each Event in its own transaction, so an invalid or failing item does not affect the others (Ingest, by contrast, is all-or-nothing). The returned errors are parallel to inputs; nil means the Event was accepted.
func (*Module) List ¶
func (m *Module) List(ctx context.Context, s *ent.Scoped, f Filter, p pagination.Params) (pagination.Page[*ent.Event], error)
List returns one page of the workspace's Events matching f, newest first (id breaks ties).
func (*Module) ListActions ¶
func (m *Module) ListActions(ctx context.Context, s *ent.Scoped, p pagination.Params) (pagination.Page[string], error)
ListActions returns one page of the distinct Event actions, ascending.