Files
enkly-ai/pkg/eventbus/topology.go
enkly 79ce8dc4c0
Some checks failed
Go CI Pipeline / build_and_test (push) Failing after 22m0s
Init Project
2026-10-30 18:06:55 +01:00

64 lines
2.9 KiB
Go

// Package eventbus is enkly's thin wrapper around RabbitMQ (via
// github.com/rabbitmq/amqp091-go) for every *asynchronous*,
// fire-and-forget cross-context notification — the counterpart to the
// synchronous, request/response calls services make over gRPC (see
// api/proto). Per-service request/response traffic (e.g. the agent
// service asking billing "is this user over quota?") always uses gRPC;
// RabbitMQ is reserved for events a publisher doesn't need an answer to,
// mirroring the rule stated in the task: "gRPC for synchronous
// communication, RabbitMQ for asynchronous communication."
//
// Topology: one durable topic exchange, "enkly.events". Each event is
// published with a routing key of the form "<context>.<aggregate>.
// <event>" (e.g. "iam.user.registered"); a consumer binds a durable
// queue to the routing keys it cares about. Using a topic exchange
// rather than one queue per consumer lets a new consumer be added later
// (e.g. an analytics service) without touching the publisher.
package eventbus
// ExchangeName is the single durable topic exchange every service
// publishes domain events to.
const ExchangeName = "enkly.events"
// Routing keys. Each constant is "<owning context>.<aggregate>.<event,
// past tense>" — only the owning bounded context ever publishes to its
// own keys (see each service's internal/infrastructure/eventing
// package), but any service may subscribe.
const (
// Published by iam (services/iam) — see internal/handlers/auth.go's
// sendVerificationEmail/sendResetEmail, now decoupled from the
// synchronous request path.
RoutingKeyVerificationCodeIssued = "iam.user.verification_code_issued"
RoutingKeyPasswordResetRequested = "iam.user.password_reset_requested"
RoutingKeyUserRegistered = "iam.user.registered"
RoutingKeyUserEmailVerified = "iam.user.email_verified"
// Published by billing (services/billing).
RoutingKeySubscriptionChanged = "billing.subscription.changed"
// Published by conversation (services/conversation) — not consumed
// by anything in this port of the monolith, but kept so a future
// consumer (search indexing, analytics, audit) has something to
// bind to without a producer-side change.
RoutingKeyMessageCreated = "conversation.message.created"
)
// QueueBinding names the durable queue a consumer should declare and
// the routing key(s) it should bind, so every consumer's topology is
// declared in one place next to the keys it reads.
type QueueBinding struct {
Queue string
RoutingKeys []string
}
// NotificationQueueBindings is the notification service's subscription
// (services/notification/internal/infrastructure/eventing) — every
// event that results in an outbound email.
var NotificationQueueBindings = QueueBinding{
Queue: "enkly.notification.verification_and_reset",
RoutingKeys: []string{
RoutingKeyVerificationCodeIssued,
RoutingKeyPasswordResetRequested,
},
}