Fix PostHog alias parameter order to properly merge backend and frontend events

This commit is contained in:
amanape 2025-11-13 16:53:09 +04:00
parent b605c96796
commit c830616990
3 changed files with 21 additions and 17 deletions

View File

@ -118,7 +118,8 @@ async def get_user(
try:
user: User = await client.get_user()
# Alias git provider login with Keycloak user ID in PostHog (SaaS mode only)
# Alias Keycloak user ID with git provider login in PostHog (SaaS mode only)
# This merges backend events (keycloak_id) into frontend user profile (git_login)
if user_id and user.login and server_config.app_mode == AppMode.SAAS:
alias_user_identities(
keycloak_user_id=user_id,

View File

@ -224,24 +224,25 @@ def alias_user_identities(
) -> None:
"""Alias a user's Keycloak ID with their git provider login for unified tracking.
This allows PostHog to link events tracked from the frontend (using git provider login)
with events tracked from the backend (using Keycloak user ID).
This allows PostHog to link events tracked from the backend (using Keycloak user ID)
with events tracked from the frontend (using git provider login).
PostHog Python alias syntax: alias(previous_id, distinct_id)
- previous_id: The old/previous distinct ID that will be merged
- distinct_id: The new/canonical distinct ID to merge into
- previous_id: The ID to merge FROM (no restrictions, only used in capture())
- distinct_id: The ID to merge INTO (already identified, has merge restrictions)
For our use case:
- Git provider login is the previous_id (first used in frontend, before backend auth)
- Keycloak user ID is the distinct_id (canonical backend ID)
- Result: All events with git login will be merged into Keycloak user ID
- Keycloak user ID is the previous_id (backend, only used in capture(), no restrictions)
- Git provider login is the distinct_id (frontend, already identified, is canonical)
- Result: All backend events (keycloak_id) will be merged into frontend profile (git_login)
Args:
keycloak_user_id: The Keycloak user ID (canonical distinct_id)
git_login: The git provider username (GitHub/GitLab/Bitbucket) to merge
keycloak_user_id: The Keycloak user ID (previous_id to merge from)
git_login: The git provider username (distinct_id to merge into, GitHub/GitLab/Bitbucket)
Reference:
https://github.com/PostHog/posthog-python/blob/master/posthog/client.py
https://posthog.com/docs/product-analytics/identify#alias-assigning-multiple-distinct-ids-to-the-same-user
"""
_init_posthog()
@ -249,14 +250,15 @@ def alias_user_identities(
return
try:
# Merge git provider login into Keycloak user ID
# Merge Keycloak user ID into git provider login
# posthog.alias(previous_id, distinct_id) - official Python SDK signature
posthog.alias(git_login, keycloak_user_id)
# previous_id (keycloak) has NO restrictions, distinct_id (git_login) was identified
posthog.alias(keycloak_user_id, git_login)
logger.debug(
'posthog_alias',
extra={
'previous_id': git_login,
'distinct_id': keycloak_user_id,
'previous_id': keycloak_user_id,
'distinct_id': git_login,
},
)
except Exception as e:

View File

@ -312,7 +312,8 @@ def test_alias_user_identities(mock_posthog):
"""Test aliasing user identities.
Verifies that posthog.alias(previous_id, distinct_id) is called correctly
where git_login is the previous_id and keycloak_user_id is the distinct_id.
where keycloak_user_id is the previous_id (no restrictions) and
git_login is the distinct_id (already identified).
"""
import openhands.utils.posthog_tracker as tracker
@ -324,8 +325,8 @@ def test_alias_user_identities(mock_posthog):
git_login='git-user',
)
# Verify: posthog.alias(previous_id='git-user', distinct_id='keycloak-123')
mock_posthog.alias.assert_called_once_with('git-user', 'keycloak-123')
# Verify: posthog.alias(previous_id='keycloak-123', distinct_id='git-user')
mock_posthog.alias.assert_called_once_with('keycloak-123', 'git-user')
def test_alias_user_identities_handles_errors(mock_posthog):