// Package auditrelay delivers Sense-owned audit facts to Bell without sharing databases. package auditrelay import ( "context" "encoding/json" "errors" "time" ) const ( MaxBatchSize = 100 MaxBodyBytes = 1 << 20 LeaseDuration = 30 * time.Second ) type Actor struct { Type string `json:"type"` ID string `json:"id"` } type ProjectionVersions struct { QuotaSourceVersion *int64 `json:"quota_source_version"` AreaPolicySourceVersion *int64 `json:"area_policy_source_version"` } type Event struct { EventID string `json:"event_id"` EventType string `json:"event_type"` TenantID string `json:"tenant_id"` SiteID string `json:"site_id"` DeviceID string `json:"device_id"` Actor Actor `json:"actor"` Reason *string `json:"reason"` TraceID *string `json:"trace_id"` AggregateGeneration int64 `json:"aggregate_generation"` ProjectionVersions ProjectionVersions `json:"projection_versions"` Data json.RawMessage `json:"data"` OccurredAt time.Time `json:"occurred_at"` } type Envelope struct { SchemaVersion int `json:"schema_version"` Event Event `json:"event"` } type BatchRequest struct { Events []Envelope `json:"events"` } type Result struct { EventID string `json:"event_id"` Status string `json:"status"` ErrorCode *string `json:"error_code,omitempty"` } type BatchResponse struct { Results []Result `json:"results"` } type QueuedEvent struct { Envelope LeaseToken int64 AttemptCount int } type Disposition string const ( Delivered Disposition = "delivered" DeadLetter Disposition = "dead_letter" Retry Disposition = "retry" ) type Completion struct { EventID string LeaseToken int64 Disposition Disposition ErrorCode string RetryAfter time.Duration } var ErrLeaseLost = errors.New("audit relay lease lost") type Repository interface { AuditRelayReady(context.Context) error ClaimAuditRelayBatch(context.Context, string, int, time.Duration) ([]QueuedEvent, error) CompleteAuditRelayBatch(context.Context, string, []Completion) error }