newsletter: dev/deploy env wiring (PROFILE_URL, log sender), CampaignEvent.URL, plan + status docs

This commit is contained in:
mats committed 2026-08-05 15:07:39 +02:00
1 parent 0db9705063
commit 4aa9c91bc7
1 file changed
+33 -5
+33 -5
View File
@@ -76,12 +76,23 @@ const (
TrackPageEngaged Type = "track.page_engaged" TrackPageEngaged Type = "track.page_engaged"
TrackPageAction Type = "track.page_action" TrackPageAction Type = "track.page_action"
TrackExperiment Type = "track.experiment" TrackExperiment Type = "track.experiment"
// TrackPurchase — cut 23. Post-checkout funnel closure; emitted by // TrackPurchase — cut 23. Post-checkout funnel closure; emitted by
// event_handlers.go::TrackPurchase on a purchase request. Replaces // event_handlers.go::TrackPurchase on a purchase request. Replaces
// 5 hand-written `pevent.Type("track.purchase")` literals with this // 5 hand-written `pevent.Type("track.purchase")` literals with this
// typed constant. // typed constant.
TrackPurchase Type = "track.purchase" TrackPurchase Type = "track.purchase"
// Newsletter campaign attribution (review 3.8). Producer: the order
// service's MailerSend webhook receiver (cmd/order/newsletter-webhook.go)
// when MailerSend reports an open / click for a newsletter send. Consumer:
// slask-tracking (pkg/events/rabbit-tracking.go) — feeds per-send
// open/click rates for the backoffice delivery log. Payload is an
// event.CampaignEvent. Wire routing keys `track.campaign_open` /
// `track.campaign_click` ride the existing `track.*` pattern on the
// catalog exchange.
TrackCampaignOpen Type = "track.campaign_open"
TrackCampaignClick Type = "track.campaign_click"
// Wishlist attribution (W6d of docs/plan-wishlist-favorites.md). // Wishlist attribution (W6d of docs/plan-wishlist-favorites.md).
// Producers: profile service (share-page read) and cart service // Producers: profile service (share-page read) and cart service
// (list→cart conversion). Consumer: slask-tracking // (list→cart conversion). Consumer: slask-tracking
@@ -112,6 +123,24 @@ const (
CartToWishlist Type = "cart.to_wishlist" // cart → list conversion (cart service) CartToWishlist Type = "cart.to_wishlist" // cart → list conversion (cart service)
) )
// CampaignEvent is the payload for the newsletter campaign attribution
// events (TrackCampaignOpen / TrackCampaignClick). Deliberately pseudonymous
// (C5): it carries the send id (the `newsletter:{sendID}` MailerSend tag
// parsed from the webhook) and a sha256 hex hash of the recipient email,
// never the address itself. At is unix seconds (MailerSend's created_at;
// falls back to arrival time when absent).
//
// URL is the link that was clicked (TrackCampaignClick only): the webhook
// receiver stamps the MailerSend click URL so slask-tracking can aggregate
// top-clicked links per send. Empty for opens and for clicks whose payload
// carried no URL.
type CampaignEvent struct {
SendID string `json:"sendId"`
EmailHash string `json:"emailHash"`
At int64 `json:"at,omitempty"`
URL string `json:"url,omitempty"`
}
// WishlistEvent is the payload for the wishlist attribution events // WishlistEvent is the payload for the wishlist attribution events
// (WishlistViewed / WishlistToCart). Deliberately lean: list id + catalog // (WishlistViewed / WishlistToCart). Deliberately lean: list id + catalog
// item ids only — no owner id, no list name, no share token, so the // item ids only — no owner id, no list name, no share token, so the
@@ -184,7 +213,6 @@ func IsKnownType(s string) bool {
return false return false
} }
// Event is the one envelope. Payload is per-Type, agreed between producer and // Event is the one envelope. Payload is per-Type, agreed between producer and
// consumer (json.RawMessage, not a god-struct). A nil Payload means "the subject // consumer (json.RawMessage, not a god-struct). A nil Payload means "the subject
// changed; fetch the latest state." // changed; fetch the latest state."