Documentation
¶
Index ¶
- func BindPublicRequest(ctx context.Context, projectID, flowID, sessionID string)
- func Emit(ctx context.Context, stmts EventInserter, spec EmitSpec) error
- func FromContext(ctx context.Context, eventType domain.EventType, category domain.EventCategory) *domain.Event
- func Insert(ctx context.Context, stmts EventInserter, ev *domain.Event) error
- func UserAttributeAuditFields(user map[string]any, schemaJSON []byte) (keys []string, attributes map[string]any)
- func WithActorContext(ctx context.Context, ac ActorContext) context.Context
- func WithActorSlot(ctx context.Context) context.Context
- func WithEntity(ev *domain.Event, entityType, entityID string) *domain.Event
- func WithPayload(ev *domain.Event, payload any) (*domain.Event, error)
- func WithProjectID(ev *domain.Event, projectID string) *domain.Event
- func WithRequestEventMiddleware(buf *RequestBuffer, next http.Handler) http.Handler
- type ActorContext
- type BatchInserter
- type EmitSpec
- type EventBatchInserter
- type EventExportSource
- type EventInserter
- type EventPurger
- type ExportConfig
- type RequestBuffer
- type RequestBufferConfig
- type RetentionConfig
- type RetentionJob
- type SequentialBatchInserter
- type Shipper
- type SinkConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BindPublicRequest ¶
BindPublicRequest stamps project/flow/session onto the actor slot so Path A can emit request.api without a token (hosted login/flow). No-op when projectID is empty or there is no slot. Does not set Authenticated.
func Emit ¶
func Emit(ctx context.Context, stmts EventInserter, spec EmitSpec) error
Emit builds and inserts a Path B event. Empty ProjectID skips the insert (no actor/project scope yet).
func FromContext ¶
func FromContext(ctx context.Context, eventType domain.EventType, category domain.EventCategory) *domain.Event
FromContext builds a domain.Event skeleton from ActorContext when present.
func Insert ¶
Insert persists a Path B event via stmts.InsertEvent. When ProjectID is empty the insert is skipped (optional / no actor scope yet).
func UserAttributeAuditFields ¶
func UserAttributeAuditFields(user map[string]any, schemaJSON []byte) (keys []string, attributes map[string]any)
UserAttributeAuditFields builds attribute_keys and x-audit attribute values for user.created / user.updated payloads. Keys come from the written attributes. Values are included only when the matching top-level schema property has x-audit set (true or a non-empty string). When schemaJSON is empty or unparsable, keys are still returned and attributes is empty.
func WithActorContext ¶
func WithActorContext(ctx context.Context, ac ActorContext) context.Context
WithActorContext stores ActorContext on ctx and updates any actor slot.
func WithActorSlot ¶
WithActorSlot plants a mutable actor slot on ctx so net/http middleware can observe AuthGate enrichment that happens inside ogen on a child context.
func WithProjectID ¶
WithProjectID sets ProjectID when the actor context did not supply one.
func WithRequestEventMiddleware ¶
func WithRequestEventMiddleware(buf *RequestBuffer, next http.Handler) http.Handler
WithRequestEventMiddleware enqueues Path A request.api events after the handler when project_id is known (authenticated API, public login/flow, or POST /projects after the new id is stamped). Probes (healthz) leave project_id empty and are skipped.
Types ¶
type ActorContext ¶
type ActorContext struct {
ProjectID string
TeamID *string
ActorID *string
ActorType *domain.EventActorType
ClientID string
TokenID string
DelegationType string
DelegationID string
Grantor string
Fingerprint string
SessionID *string
FlowID *string
RequestID *string
Authenticated bool
}
ActorContext holds server-authoritative WHO/HOW dimensions for event emission (ADR 048 §5).
func ActorFromContext ¶
func ActorFromContext(ctx context.Context) (ActorContext, bool)
func ActorSlotFromContext ¶
func ActorSlotFromContext(ctx context.Context) (*ActorContext, bool)
type BatchInserter ¶
BatchInserter adapts a batch insert func to EventBatchInserter.
func (BatchInserter) InsertEvents ¶
type EmitSpec ¶
type EmitSpec struct {
Type domain.EventType
Category domain.EventCategory
ProjectID string
EntityType string
EntityID string
Payload any
SessionID *string
TokenID string
// Optional actor overrides when the request ActorContext is empty
// (anonymous session mint, token issue before AuthGate, etc.).
ActorID *string
ActorType *domain.EventActorType
}
EmitSpec is one Path B wide-event emission (ADR 048).
type EventBatchInserter ¶
type EventBatchInserter interface {
InsertEvents(ctx context.Context, events []*domain.Event) error
}
EventBatchInserter persists a Path A flush batch in one call (preferably one TX).
type EventExportSource ¶
type EventExportSource interface {
ListClaimedProjectIDs(ctx context.Context) ([]string, error)
EnsureSink(ctx context.Context, sink *domain.EventSink) error
GetEventSinkCursor(ctx context.Context, sinkID, projectID string) (*domain.EventSinkCursor, error)
UpsertEventSinkCursor(ctx context.Context, cursor *domain.EventSinkCursor) error
ListEventsAfterCursor(ctx context.Context, projectID string, afterCreatedAt time.Time, afterID string, limit int) ([]*domain.Event, error)
}
EventExportSource backs the shipper with claimed projects and sink cursors.
type EventInserter ¶
EventInserter persists a single event (Path B TX site or Path A batch item).
type EventPurger ¶
type EventPurger interface {
DeleteEventsOlderThan(ctx context.Context, createdBefore time.Time) (int64, error)
}
EventPurger deletes old events across all projects (including orphaned project_id values after hard-delete).
type ExportConfig ¶
type ExportConfig struct {
Enabled bool `mapstructure:"enabled"`
Interval time.Duration `mapstructure:"interval"`
Sinks []SinkConfig `mapstructure:"sinks"`
}
ExportConfig holds deployment-scoped sinks and shipper tuning.
func DefaultExportConfig ¶
func DefaultExportConfig() ExportConfig
type RequestBuffer ¶
type RequestBuffer struct {
// contains filtered or unexported fields
}
RequestBuffer is an in-process Path A queue. Flush when the buffer holds at least BatchSize events (a prefix of that many) or the oldest event exceeds MaxAge. A single background flusher owns all inserts.
func NewRequestBuffer ¶
func NewRequestBuffer(insert EventBatchInserter, cfg RequestBufferConfig) *RequestBuffer
NewRequestBuffer starts a background flusher. Call Close on shutdown.
func (*RequestBuffer) Close ¶
func (b *RequestBuffer) Close()
Close drains the buffer and stops the flusher.
func (*RequestBuffer) Dropped ¶
func (b *RequestBuffer) Dropped() uint64
func (*RequestBuffer) Enqueue ¶
func (b *RequestBuffer) Enqueue(ev *domain.Event)
Enqueue adds a request event. Drops when full (never blocks). occurred_at is enqueue time (tests / callers without a request start).
func (*RequestBuffer) EnqueueSince ¶
func (b *RequestBuffer) EnqueueSince(ev *domain.Event, startedAt time.Time)
EnqueueSince records a request event whose forensic occurred_at is startedAt (HTTP middleware entry), not enqueue/flush time.
func (*RequestBuffer) Flushed ¶
func (b *RequestBuffer) Flushed() uint64
func (*RequestBuffer) Len ¶
func (b *RequestBuffer) Len() int
type RequestBufferConfig ¶
type RequestBufferConfig struct {
BatchSize int
MaxAge time.Duration
Capacity int
ShutdownTimeout time.Duration
}
RequestBufferConfig tunes Path A batching (ADR 048).
func DefaultRequestBufferConfig ¶
func DefaultRequestBufferConfig() RequestBufferConfig
type RetentionConfig ¶
type RetentionConfig struct {
Retention time.Duration `mapstructure:"window"`
Interval time.Duration `mapstructure:"interval"`
Enabled bool `mapstructure:"enabled"`
}
RetentionConfig controls time-only event purge (ADR 049).
func DefaultRetentionConfig ¶
func DefaultRetentionConfig() RetentionConfig
type RetentionJob ¶
type RetentionJob struct {
// contains filtered or unexported fields
}
RetentionJob periodically deletes events older than the retention window.
func NewRetentionJob ¶
func NewRetentionJob(purge EventPurger, cfg RetentionConfig) *RetentionJob
func (*RetentionJob) Close ¶
func (j *RetentionJob) Close()
func (*RetentionJob) Start ¶
func (j *RetentionJob) Start()
type SequentialBatchInserter ¶
type SequentialBatchInserter struct {
Inner EventInserter
}
SequentialBatchInserter inserts each event via EventInserter (tests / fallback).
func (SequentialBatchInserter) InsertEvents ¶
type Shipper ¶
type Shipper struct {
// contains filtered or unexported fields
}
Shipper delivers events to deployment-configured sinks (ADR 049).
func NewShipper ¶
func NewShipper(src EventExportSource, cfg ExportConfig) *Shipper
type SinkConfig ¶
type SinkConfig struct {
Type domain.EventSinkType `mapstructure:"type"`
URL string `mapstructure:"url"`
// Enabled is opt-out: a configured sink (non-empty type) ships unless this
// is explicitly false.
Enabled *bool `mapstructure:"enabled"`
}
SinkConfig is a deployment-configured event sink (no project CRUD in v1).