Repository navigation
feat(analytics): hierarchical groups support - #476
tylerjroach wants to merge 16 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g requests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l groups projects Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
[Medium impact] The changes affect identity, event, and profile flows only for apps that enable hierarchical groups. The PR still needs the earlier fix that prevents caller-supplied Findings
Reviews (12) · Last reviewed commit: "refactor: leave deviceId off the Mixpane..." · Reviewed by Greptile |
… user delete on opt out On hierarchical groups projects in JavaScript mode, a /groups write keyed by $company_id now uses its own group id as $company_id instead of the currently identified company, so a saved getCompany() handle keeps writing to its company after identify or reset. Opting out now clears pending /groups updates before queuing the user delete, so only the delete is flushed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hierarchical groups opt-out clears the /groups queue before queuing the user delete. A batch already sending then removed the first records from the new queue when it finished, which could drop the delete unsent. The queue now counts clears, and a batch sent before a clear leaves the queue alone. Only the hierarchical groups opt-out clears a queue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A batch rejected with a 400 removed the first queued record even after a clear, which could drop the hierarchical groups opt-out delete. It now leaves the queue alone when a clear happened while it was sending, as a sent batch already does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
identify with an identity object called the bridge in a later Promise callback, so a track() made right after it reached the native SDK first and was recorded under the previous identity. Call it in the executor, as the string overload does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…elete optOutTracking set the opt-out flag only after clearing the /groups queue and sending the $user_id profile delete, so calls made meanwhile were still tracked and a profile update could be sent alongside the delete. The flag is now set first, and the delete is queued and sent through a core path that skips the opt-out checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Original ID Merge projects, and projects with ID Merge off, still identify users by distinct id, so the getter stays supported. Its docs now say not to use it on hierarchical groups projects and to prefer the identity getter where possible. Deprecation suppressions added for it are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eholder Demo and example apps must not ship a real project token. Set YOUR_HG_PROJECT_TOKEN to a project with hierarchical groups enabled to run the page, as the other demo pages do with their own placeholder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…vents On a hierarchical groups project the user is identified by $user_id and $company_id, which the request already carries, so the first-time event body no longer sends a distinct_id. Other projects send it as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a hierarchical groups project an identified user is $user_id and $company_id, so events leave out distinct_id rather than send the bare user id. Anonymous events still send the $device: distinct id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| ...(userId && companyIdentityProps.$company_id | ||
| ? {} | ||
| : { distinct_id: this.mixpanelPersistent.getDistinctId(token) }), |
There was a problem hiding this comment.
Caller identity still survives
In JavaScript mode, an identified hierarchical-groups user can still send distinct_id through event properties or saved super properties. Leaving it out of identityProps does not remove the earlier value when the objects are merged. Previously, the SDK overwrote that value. These events now carry conflicting identity fields instead of only $user_id and $company_id.
Remove distinct_id from the merged properties before freezing the event, and test both property sources.
Knowledge Base Used: Analytics events and identity
Ingestion rejects $identify without a distinct_id, and a hierarchical groups project ties the device to the user from the $device_id, $user_id and $company_id every later event carries. So identify (and optInTrackingWithIdentity) track no $identify there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SDK owns the device id, so the identity apps pass to identify() has only userId and companyId. getIdentity() returns a ReportedMixpanelIdentity that adds deviceId. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds hierarchical groups (HG) support: a
MixpanelIdentitycarrying user and company ids, HG-aware profile updates, and company-bound group writes. HG behavior is gated on the SDK's hierarchical groups init flag; projects without it behave as before.Draft, opened for an early automated review. Not ready to merge.
Commits
🤖 Generated with Claude Code