@revturbine/sdk 0.10.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -40,6 +40,48 @@ also require a changelog entry.
40
40
 
41
41
  ---
42
42
 
43
+ ## 0.10.1
44
+
45
+ ### Treatment interactions carry the identified `account_id`
46
+
47
+ **What changed.** Every treatment interaction the SDK sends to
48
+ `/api/events/interactions` — the impression that writes a
49
+ `placement_presentations` row, plus dismiss / click / conversion — now carries
50
+ `account_id`, taken from the account the integration identified
51
+ (`identify(userId, { account_id })` / `setUserContext`). It was never sent at
52
+ all, so the ingest route's `account_id ?? user_id` fallback stamped a **user**
53
+ id into an **account** column. `placement_presentations.account_id` is a join
54
+ key, not a label: `monetization_funnel` matches it against account ids from
55
+ `events_clickstream` / `events_billing`, and every experiment summary pipe
56
+ reads it when `analysis_unit='account'`. Those joins therefore matched only
57
+ where a user id happened to equal an account id — and an account-grain
58
+ experiment readout returned the user-grain n while looking perfectly valid.
59
+
60
+ Two details make it a usable key. The value is PII-redacted **identically to
61
+ `/api/track`**, so an email-shaped account id becomes the same hash in
62
+ `placement_presentations` and in `events_clickstream` and the funnel actually
63
+ joins. And when no account was identified the field is **omitted**, never set
64
+ to the user id — the route keeps its own fallback for SDKs that have not
65
+ upgraded, but a wrong join key is worse than a missing one.
66
+
67
+ No public API change: nothing new is asked of the caller, and
68
+ `RevTurbineTreatmentInteractionInput` is unchanged. Integrations that already
69
+ pass `account_id` to `identify()` get correct account-grain analytics with no
70
+ code change; integrations that never identify an account are unaffected on the
71
+ wire and see the same route-side fallback as before.
72
+
73
+ **Landed in** `0.10.1`. **Fail-closed in** n/a — additive; nothing old is
74
+ rejected.
75
+
76
+ **Proving test:** `web-sdk/interaction-wire-contract.test.ts` — "the account
77
+ identity the analytics joins key on": the identified account reaches the wire
78
+ distinct from `user_id`, an unidentified one is omitted rather than copied from
79
+ `user_id`, an email-shaped account id matches the `/api/track` lane
80
+ byte-for-byte, and a re-queued batch keeps the account that was acting when
81
+ each interaction happened.
82
+
83
+ ---
84
+
43
85
  ## 0.10.0
44
86
 
45
87
  ### `publicKey` is the browser credential; `apiKey` is the server key
@@ -21597,6 +21597,24 @@ declare class RevTurbineCustomerSdk {
21597
21597
  * persistent failure is observable instead of merely quiet.
21598
21598
  */
21599
21599
  private failInteractionFlush;
21600
+ /**
21601
+ * The account identity to stamp on a treatment interaction, or `undefined`
21602
+ * when the integration has identified none.
21603
+ *
21604
+ * Two rules make this a usable join key rather than a label:
21605
+ *
21606
+ * 1. **Redacted identically to `/api/track`.** Both paths run the account id
21607
+ * through {@link redactIdentityField}, so an email-shaped account id
21608
+ * becomes the SAME hash in `placement_presentations` and in
21609
+ * `events_clickstream`. Hashing on one path only would produce a hash on
21610
+ * one side and a raw email on the other, and `monetization_funnel` would
21611
+ * join nothing (identity keys are hashed, not sentinelled — the contract
21612
+ * is byte-identical across repos).
21613
+ * 2. **Never falls back to the user id.** An absent account is absent. The
21614
+ * ingest route keeps its own `account_id ?? user_id` fallback for SDKs
21615
+ * that do not send the field yet; this SDK no longer feeds it.
21616
+ */
21617
+ private interactionAccountId;
21600
21618
  trackTreatmentInteraction(input: RevTurbineTreatmentInteractionInput): Promise<void>;
21601
21619
  getPlacementContent(placementId: string, request?: JsonObject): Promise<RevTurbinePlacementContent>;
21602
21620
  /**
@@ -21884,7 +21902,11 @@ declare class RevTurbineCustomerSdk {
21884
21902
  snooze(outputId: string, seconds?: number): Promise<void>;
21885
21903
  convert(outputId: string): Promise<void>;
21886
21904
  /**
21887
- * Emit a canonical trigger event recognised by the decision engine.
21905
+ * Emit a canonical trigger event. There is no in-SDK consumer that matches
21906
+ * on trigger names — the shipped behavior is ingest to `events_clickstream`
21907
+ * only (plan 250's wire/consumer matrix); a decision-engine placement
21908
+ * trigger matches `trigger.slot_id` against registered slots, not this
21909
+ * event's name.
21888
21910
  *
21889
21911
  * Convenience wrapper over {@link emitSemantic} that constrains the event
21890
21912
  * name to {@link RevTurbineTriggerEvent} and attaches standard context