Compare commits

..

1 Commits

Author SHA1 Message Date
Comfy Org PR Bot
9035f66df3 [backport cloud/1.44] Pr/12481 - fixed error (#12603)
Backport of #12574 to `cloud/1.44`

Automatically created by backport workflow.

Co-authored-by: Steven Tran <94876858+stevenltran@users.noreply.github.com>
Co-authored-by: Nav Singh <nav@comfy.org>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Steven Tran <steventran@Stevens-MacBook-Air.local>
Co-authored-by: Benjamin Lu <benjaminlu1107@gmail.com>
2026-06-02 11:01:36 -07:00
2 changed files with 116 additions and 1 deletions

View File

@@ -136,7 +136,7 @@ describe('PostHogTelemetryProvider', () => {
expect(hoisted.mockOnUserResolved).toHaveBeenCalledOnce()
})
it('identifies user when onUserResolved fires', async () => {
it('identifies user without setting first_auth_at when onUserResolved fires', async () => {
createProvider()
await vi.dynamicImportSettled()
@@ -172,6 +172,88 @@ describe('PostHogTelemetryProvider', () => {
)
})
it('sets first_auth_at on new-user auth', async () => {
const provider = createProvider()
await vi.dynamicImportSettled()
provider.trackAuth({
method: 'google',
is_new_user: true,
user_id: 'user-123'
})
expect(hoisted.mockIdentify).toHaveBeenCalledWith(
'user-123',
undefined,
expect.objectContaining({
first_auth_at: expect.any(String)
})
)
expect(hoisted.mockCapture).toHaveBeenCalledWith(
TelemetryEvents.USER_AUTH_COMPLETED,
{
method: 'google',
is_new_user: true,
user_id: 'user-123'
}
)
})
it('does not set first_auth_at on returning-user auth', async () => {
const provider = createProvider()
await vi.dynamicImportSettled()
provider.trackAuth({
method: 'google',
is_new_user: false,
user_id: 'user-123'
})
expect(hoisted.mockIdentify).not.toHaveBeenCalled()
expect(hoisted.mockCapture).toHaveBeenCalledWith(
TelemetryEvents.USER_AUTH_COMPLETED,
{
method: 'google',
is_new_user: false,
user_id: 'user-123'
}
)
})
it('flushes queued first_auth_at before queued auth event', async () => {
const provider = createProvider()
provider.trackAuth({
method: 'google',
is_new_user: true,
user_id: 'user-123'
})
expect(hoisted.mockIdentify).not.toHaveBeenCalled()
expect(hoisted.mockCapture).not.toHaveBeenCalled()
await vi.dynamicImportSettled()
expect(hoisted.mockIdentify).toHaveBeenCalledWith(
'user-123',
undefined,
expect.objectContaining({
first_auth_at: expect.any(String)
})
)
expect(hoisted.mockCapture).toHaveBeenCalledWith(
TelemetryEvents.USER_AUTH_COMPLETED,
{
method: 'google',
is_new_user: true,
user_id: 'user-123'
}
)
expect(hoisted.mockIdentify.mock.invocationCallOrder[0]).toBeLessThan(
hoisted.mockCapture.mock.invocationCallOrder[0]
)
})
it('queues events before initialization and flushes after', async () => {
const provider = createProvider()

View File

@@ -84,6 +84,7 @@ export class PostHogTelemetryProvider implements TelemetryProvider {
private isEnabled = true
private posthog: PostHog | null = null
private eventQueue: QueuedEvent[] = []
private pendingFirstAuthAt = new Map<string, string>()
private isInitialized = false
private lastTriggerSource: ExecutionTriggerSource | undefined
private disabledEvents = new Set<TelemetryEventName>(DEFAULT_DISABLED_EVENTS)
@@ -164,6 +165,8 @@ export class PostHogTelemetryProvider implements TelemetryProvider {
private flushEventQueue(): void {
if (!this.isInitialized || !this.posthog) return
this.flushPendingFirstAuthAt()
while (this.eventQueue.length > 0) {
const event = this.eventQueue.shift()!
try {
@@ -174,6 +177,33 @@ export class PostHogTelemetryProvider implements TelemetryProvider {
}
}
private flushPendingFirstAuthAt(): void {
for (const [userId, firstAuthAt] of this.pendingFirstAuthAt) {
this.setFirstAuthAt(userId, firstAuthAt)
}
this.pendingFirstAuthAt.clear()
}
private setFirstAuthAt(
userId: string,
firstAuthAt = new Date().toISOString()
): void {
if (!this.isEnabled) return
if (this.isInitialized && this.posthog) {
try {
this.posthog.identify(userId, undefined, { first_auth_at: firstAuthAt })
} catch (error) {
console.error('Failed to set PostHog first auth timestamp:', error)
}
return
}
if (!this.pendingFirstAuthAt.has(userId)) {
this.pendingFirstAuthAt.set(userId, firstAuthAt)
}
}
private trackEvent(
eventName: TelemetryEventName,
properties?: TelemetryEventProperties
@@ -254,6 +284,9 @@ export class PostHogTelemetryProvider implements TelemetryProvider {
}
trackAuth(metadata: AuthMetadata): void {
if (metadata.is_new_user && metadata.user_id) {
this.setFirstAuthAt(metadata.user_id)
}
this.trackEvent(TelemetryEvents.USER_AUTH_COMPLETED, metadata)
}