// Package events holds the JSON payload shape for every event listed in // pkg/eventbus's routing-key constants. Each type is versioned // implicitly by its routing key (a breaking change gets a new key, e.g. // "iam.user.registered.v2") rather than by a field in the struct, to // keep consumers' decoding code simple. package events import "time" // VerificationCodeIssued is published by iam whenever a 6-digit email // verification code is minted — at signup (Handlers.Signup) and on // resend (Handlers.ResendVerification). The notification service is its // only consumer today (pkg/eventbus.RoutingKeyVerificationCodeIssued). // // Carrying the raw code on the bus (rather than just a code ID) is a // deliberate, documented trade-off: it lets the email's content stay // exactly what the monolith sent without notification needing its own // read access to iam's verification_codes table (which would violate // "each service owns its own tables"). This is safe only because // RabbitMQ sits on the private service network, never reachable from // outside the cluster — see ARCHITECTURE.md's "Trust boundary of the // event bus" note. type VerificationCodeIssued struct { UserID int64 `json:"user_id"` Email string `json:"email"` Code string `json:"code"` ExpiresAt time.Time `json:"expires_at"` } // PasswordResetRequested is published by iam from Handlers.ForgotPassword. type PasswordResetRequested struct { UserID int64 `json:"user_id"` Email string `json:"email"` ResetLink string `json:"reset_link"` // already absolute (BaseURL + path + token), matching h.absURL ExpiresAt time.Time `json:"expires_at"` } // UserRegistered is published once a new account row is committed // (before email verification). Reserved for consumers that care about // the account existing at all rather than about delivering mail — e.g. // an analytics or growth service added later. type UserRegistered struct { UserID int64 `json:"user_id"` Email string `json:"email"` CreatedAt time.Time `json:"created_at"` } // UserEmailVerified is published when VerifyEmailCode succeeds. type UserEmailVerified struct { UserID int64 `json:"user_id"` Email string `json:"email"` }