abandoned-cart visibility: capture-mode campaigns + admin view
Bumps go-cart-actor (profile-link recovery-contact backfill, capture email sender, /carts/abandoned read API) and backoffice (Abandoned carts panel, storefront recovery-contact wiring). Compose shares CAMPAIGN_DIR between cart service and backoffice and sets CART_EMAIL_SENDER=capture for dev. Plan doc: docs/plan-abandoned-carts-visibility.md.
This commit is contained in:
1 parent
93cc736ea9
commit
be9ecd538b
1 file changed
+40
@@ -108,6 +108,20 @@ const (
|
||||
// 5 hand-written `pevent.Type("track.purchase")` literals with this
|
||||
// typed constant.
|
||||
TrackPurchase Type = "track.purchase"
|
||||
// ServerPurchase — the server-side confirmed-order fallback for
|
||||
// track.purchase (wishlist dual-channel style, W6d pattern). Emitted by
|
||||
// the order service's durable outbox when an order reaches StatusCaptured
|
||||
// (the same atomic emitOnApply that publishes order.created), so a
|
||||
// purchase is recorded even when the browser beacon was blocked (no JS /
|
||||
// no consent). Deliberately session-less: it carries catalog item ids
|
||||
// only — no session id, no customer identity (C5) — and feeds the
|
||||
// session-less co-occurrence AlsoBought intra-pair on the tracking side.
|
||||
// It must NOT ride the browser `track.purchase` type: the consumer
|
||||
// routes that through the session-keyed HandlePurchaseEvent (funnel +
|
||||
// converted label), which a session-less event would corrupt. Wire
|
||||
// routing key `track.purchase_server` rides the existing `track.*`
|
||||
// binding on the catalog exchange. Payload is an event.ServerPurchaseEvent.
|
||||
ServerPurchase Type = "track.purchase_server"
|
||||
// TrackPromotionView / TrackPromotionClick — storefront promotion
|
||||
// attribution. Producer: the storefront promotion-badge islands, PLP
|
||||
// promo badges, bundle picker and cart bundle upsell (lib/track.ts
|
||||
@@ -215,6 +229,32 @@ type WishlistMutationEvent struct {
|
||||
ItemId uint32 `json:"itemId,omitempty"`
|
||||
}
|
||||
|
||||
// PurchaseItem is one line of a confirmed order in a ServerPurchaseEvent.
|
||||
// ItemId is the numeric catalog (finder) item id the tracking pipeline keys
|
||||
// on; lines without one (added without catalog facts) are skipped by the
|
||||
// producer. Quantity mirrors the order line quantity.
|
||||
type PurchaseItem struct {
|
||||
Sku string `json:"sku,omitempty"`
|
||||
ItemId uint32 `json:"itemId"`
|
||||
Quantity uint `json:"quantity,omitempty"`
|
||||
}
|
||||
|
||||
// ServerPurchaseEvent is the payload for track.purchase_server (the order
|
||||
// service's confirmed-order fallback). Deliberately pseudonymous (C5): order
|
||||
// id + catalog item ids + optional session id only — never the customer
|
||||
// email/name/profile id, so the tracking pipeline can pair "these items were
|
||||
// bought together" without being able to attribute the purchase to a person.
|
||||
// SessionId is the tracking session (sid) captured at checkout start and
|
||||
// threaded through the checkout→order handoff; when > 0 the tracking
|
||||
// consumer routes the purchase through the session-keyed path (funnel +
|
||||
// converted label), when 0 it stays session-less (no consent / server-side
|
||||
// checkout).
|
||||
type ServerPurchaseEvent struct {
|
||||
OrderID string `json:"orderId"`
|
||||
SessionId int64 `json:"session_id,omitempty"`
|
||||
Items []PurchaseItem `json:"items"`
|
||||
}
|
||||
|
||||
// CartToWishlistEvent is the payload for cart.to_wishlist (cart service).
|
||||
// Carries the pseudonymised owner profile id (the cart's UserId — a
|
||||
// customer-scoped opaque uint64 id, never an email/name) plus the list the
|
||||
|
||||
Reference in new issue
Block a user