package outbox import ( "context" "time" ) type Status string const ( StatusPending Status = "pending" StatusProcessing Status = "processing" StatusCompleted Status = "completed" StatusFailed Status = "failed" ) type Event struct { Seq int64 EventType string PartitionKey string IdempotencyKey *string Payload []byte CreatedAt time.Time } type Task struct { Seq int64 Consumer string PartitionKey string Status Status ProcessAfter *time.Time LeaseUntil *time.Time CompletedAt *time.Time Attempts int } type EmitOptions struct { ProcessAfter *time.Time IdempotencyKey *string } // Emitter writes events to the outbox. Called within a business transaction. type Emitter interface { Emit(ctx context.Context, eventType, partitionKey string, payload []byte, opts *EmitOptions) error } // Claimed pairs an event with its task. type Claimed struct { Event Event Task Task } // Consumer claims and completes tasks. Used by the worker. type Consumer interface { Claim(ctx context.Context, consumer string, leaseDuration time.Duration, limit int) ([]Claimed, error) Complete(ctx context.Context, seq int64, consumer string) error // Nack requeues a task for retry. If retryAfter is non-nil, // the task won't be claimed again until after that time. Nack(ctx context.Context, seq int64, consumer string, retryAfter *time.Time) error // Fail permanently marks a task as failed, stopping all future attempts. Fail(ctx context.Context, seq int64, consumer string) error }