platform
This commit is contained in:
1 parent
e706f7d907
commit
21bcb63440
42 files changed
+5903
No files matched your search
@@ -0,0 +1,95 @@
|
||||
// Package event is the platform's shared event vocabulary: one envelope shape
|
||||
// (Event) and a small set of Type constants for the event meanings that
|
||||
// genuinely cross module boundaries. It imports only the stdlib — never an app
|
||||
// module, never a transport library — so every module can depend on it.
|
||||
//
|
||||
// Discipline: a Type constant earns its place only when a real producer emits it
|
||||
// AND it is meaningful to another module. We do not pre-declare aspirational
|
||||
// types. See docs/platform-event-messaging-sketch.md.
|
||||
package event
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Type is the semantic event kind — the cross-module contract. A module may use
|
||||
// its own private kinds internally; only meanings that cross a boundary belong
|
||||
// here.
|
||||
type Type string
|
||||
|
||||
const (
|
||||
// Editorial (graph-cms). Emitted by the CMS outbound bridge on content-graph
|
||||
// mutations. In-repo consumers are TBD (external generators today); this is
|
||||
// the first envelope producer, so the constants exist where they are emitted.
|
||||
ContentCreated Type = "content.created"
|
||||
ContentUpdated Type = "content.updated"
|
||||
ContentDeleted Type = "content.deleted"
|
||||
|
||||
// Catalog (finder). These meanings already cross modules today — finder
|
||||
// writer → reader and → backoffice (MountFinderListener) — but still travel
|
||||
// as finder's legacy ChangeTopic strings on the wire. The constants document
|
||||
// the shared vocabulary; the wire migration onto the envelope is a later step.
|
||||
CatalogItemChanged Type = "catalog.item_changed" // legacy: finder "item_added"
|
||||
CatalogSnapshotReady Type = "catalog.snapshot_ready" // legacy: finder "snapshot_ready"
|
||||
CatalogSettingsChanged Type = "catalog.settings_changed" // legacy: finder "settings_change"
|
||||
CatalogFacetChanged Type = "catalog.facet_changed" // legacy: finder "facet_change"
|
||||
CatalogAccessoryChanged Type = "catalog.accessory_changed" // legacy: finder "accessory_change"
|
||||
// CatalogProjectionPublished carries the commerce-facing catalog Projection
|
||||
// (platform/catalog) — producer maps raw items → Projection once, consumers
|
||||
// (cart / checkout / order / UCP) read the typed shape. Distinct from
|
||||
// CatalogItemChanged (raw bodies, consumed by inventory/backoffice): a
|
||||
// product index emits BOTH; a non-product index emits neither projection.
|
||||
// Payload is a []catalog.ProjectionUpdate batch (upserts + deletes per SKU).
|
||||
CatalogProjectionPublished Type = "catalog.projection_published"
|
||||
CatalogSortOverride Type = "catalog.sort_override" // finder-internal: per-session/group/popularity overrides
|
||||
CatalogFieldSortOverride Type = "catalog.field_sort_override" // finder-internal: live field ordering overrides
|
||||
|
||||
// Inventory (go-redis-inventory core, emitted by the cart-inventory service).
|
||||
// A coarse stock-level crossing (none/low/high) for one SKU+location —
|
||||
// never a quantity. Exact stock is a synchronous query against the inventory
|
||||
// service; only level crossings cross a module boundary. Payload is an
|
||||
// inventory.LevelChanged (platform/inventory). First consumer: finder stock
|
||||
// overlay (display hints). See docs/inventory-shape.md.
|
||||
InventoryLevelChanged Type = "inventory.level_changed"
|
||||
|
||||
// Commerce (order). Emitted by the order service saga after an order is
|
||||
// placed-and-paid (a durable outbox event). The authoritative "a sale
|
||||
// happened" fact — multiple modules react independently (inventory commits
|
||||
// stock, fulfillment allocates) without checkout coupling to any of them.
|
||||
// Payload is an order.Created (platform/order). See docs/inventory-shape.md
|
||||
// and docs/fulfillment-stance.md.
|
||||
OrderCreated Type = "order.created"
|
||||
|
||||
// Analytics (tracking). Replaces the integer enum 0–6 that finder and
|
||||
// slask-tracking use on the `tracking` topic today. Producer: slask-finder
|
||||
// (pkg/tracking/rabbit-tracking.go). Consumer: slask-tracking
|
||||
// (pkg/events/rabbit-tracking.go).
|
||||
TrackSession Type = "track.session" // 0 — session start
|
||||
TrackSearch Type = "track.search" // 1 — search query
|
||||
TrackClick Type = "track.click" // 2 — item click / product view
|
||||
TrackCart Type = "track.cart" // 3,4 — add to / remove from cart
|
||||
TrackImpression Type = "track.impression" // 5 — impression
|
||||
TrackAction Type = "track.action" // 6 — custom action (wishlist, etc.)
|
||||
TrackPageView Type = "track.page_view"
|
||||
TrackPageEngaged Type = "track.page_engaged"
|
||||
TrackPageAction Type = "track.page_action"
|
||||
)
|
||||
|
||||
// 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
|
||||
// changed; fetch the latest state."
|
||||
type Event struct {
|
||||
ID string `json:"id"` // unique; enables idempotent/at-least-once dedupe
|
||||
Type Type `json:"type"` // the vocabulary
|
||||
Source string `json:"source"` // module identifier ("graph-cms", "finder", ...)
|
||||
Subject string `json:"subject"` // the resource that changed (node id, sku, ...)
|
||||
Payload json.RawMessage `json:"payload,omitempty"` // per-Type body, or nil
|
||||
Time time.Time `json:"time"`
|
||||
Meta map[string]string `json:"meta,omitempty"` // trace id, causation, country, dataType, ...
|
||||
}
|
||||
|
||||
// Handler consumes an event. Returning an error means "not handled" — durable
|
||||
// transports may redeliver; fire-and-forget transports just log.
|
||||
type Handler func(ctx context.Context, e Event) error
|
||||
Reference in new issue
Block a user