feat: add telemetry for workflow save and default view (#9734)

Add two new telemetry events: `app:workflow_saved` (with `is_app` and
`is_new` metadata) and `app:default_view_set` for App Builder (with the
chosen view mode). Instrumented in workflowService and
useAppSetDefaultView.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9734-feat-add-telemetry-for-workflow-save-and-default-view-3206d73d3650814e8678f83c8419625f)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Robin Huang
2026-03-11 09:31:21 -07:00
committed by GitHub
parent 08a2f8ae15
commit fd7ce3a852
7 changed files with 56 additions and 3 deletions

View File

@@ -3,6 +3,7 @@ import type { AuditLog } from '@/services/customerEventsService'
import type {
AuthMetadata,
BeginCheckoutMetadata,
DefaultViewSetMetadata,
EnterLinearMetadata,
ShareFlowMetadata,
ExecutionErrorMetadata,
@@ -27,7 +28,8 @@ import type {
TemplateMetadata,
UiButtonClickMetadata,
WorkflowCreatedMetadata,
WorkflowImportMetadata
WorkflowImportMetadata,
WorkflowSavedMetadata
} from './types'
/**
@@ -157,6 +159,14 @@ export class TelemetryRegistry implements TelemetryDispatcher {
this.dispatch((provider) => provider.trackWorkflowOpened?.(metadata))
}
trackWorkflowSaved(metadata: WorkflowSavedMetadata): void {
this.dispatch((provider) => provider.trackWorkflowSaved?.(metadata))
}
trackDefaultViewSet(metadata: DefaultViewSetMetadata): void {
this.dispatch((provider) => provider.trackDefaultViewSet?.(metadata))
}
trackEnterLinear(metadata: EnterLinearMetadata): void {
this.dispatch((provider) => provider.trackEnterLinear?.(metadata))
}

View File

@@ -14,6 +14,7 @@ import { getExecutionContext } from '../../utils/getExecutionContext'
import type {
AuthMetadata,
CreditTopupMetadata,
DefaultViewSetMetadata,
EnterLinearMetadata,
ShareFlowMetadata,
ExecutionContext,
@@ -40,7 +41,8 @@ import type {
TemplateMetadata,
UiButtonClickMetadata,
WorkflowCreatedMetadata,
WorkflowImportMetadata
WorkflowImportMetadata,
WorkflowSavedMetadata
} from '../../types'
import { remoteConfig } from '@/platform/remoteConfig/remoteConfig'
import type { RemoteConfig } from '@/platform/remoteConfig/types'
@@ -359,6 +361,14 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
this.trackEvent(TelemetryEvents.WORKFLOW_OPENED, metadata)
}
trackWorkflowSaved(metadata: WorkflowSavedMetadata): void {
this.trackEvent(TelemetryEvents.WORKFLOW_SAVED, metadata)
}
trackDefaultViewSet(metadata: DefaultViewSetMetadata): void {
this.trackEvent(TelemetryEvents.DEFAULT_VIEW_SET, metadata)
}
trackEnterLinear(metadata: EnterLinearMetadata): void {
this.trackEvent(TelemetryEvents.ENTER_LINEAR_MODE, metadata)
}

View File

@@ -82,6 +82,7 @@ describe('PostHogTelemetryProvider', () => {
expect(hoisted.mockInit).toHaveBeenCalledWith('phc_test_token', {
api_host: 'https://t.comfy.org',
ui_host: 'https://us.posthog.com',
autocapture: false,
capture_pageview: false,
capture_pageleave: false,

View File

@@ -7,6 +7,7 @@ import type { RemoteConfig } from '@/platform/remoteConfig/types'
import type {
AuthMetadata,
DefaultViewSetMetadata,
EnterLinearMetadata,
ShareFlowMetadata,
ExecutionContext,
@@ -34,7 +35,8 @@ import type {
TemplateMetadata,
UiButtonClickMetadata,
WorkflowCreatedMetadata,
WorkflowImportMetadata
WorkflowImportMetadata,
WorkflowSavedMetadata
} from '../../types'
import { TelemetryEvents } from '../../types'
import { getExecutionContext } from '../../utils/getExecutionContext'
@@ -102,6 +104,7 @@ export class PostHogTelemetryProvider implements TelemetryProvider {
this.posthog!.init(apiKey, {
api_host:
window.__CONFIG__?.posthog_api_host || 'https://t.comfy.org',
ui_host: 'https://us.posthog.com',
autocapture: false,
capture_pageview: false,
capture_pageleave: false,
@@ -344,6 +347,14 @@ export class PostHogTelemetryProvider implements TelemetryProvider {
this.trackEvent(TelemetryEvents.WORKFLOW_OPENED, metadata)
}
trackWorkflowSaved(metadata: WorkflowSavedMetadata): void {
this.trackEvent(TelemetryEvents.WORKFLOW_SAVED, metadata)
}
trackDefaultViewSet(metadata: DefaultViewSetMetadata): void {
this.trackEvent(TelemetryEvents.DEFAULT_VIEW_SET, metadata)
}
trackEnterLinear(metadata: EnterLinearMetadata): void {
this.trackEvent(TelemetryEvents.ENTER_LINEAR_MODE, metadata)
}

View File

@@ -149,6 +149,15 @@ export interface EnterLinearMetadata {
source?: string
}
export interface WorkflowSavedMetadata {
is_app: boolean
is_new: boolean
}
export interface DefaultViewSetMetadata {
default_view: 'app' | 'graph'
}
type ShareFlowStep =
| 'dialog_opened'
| 'save_prompted'
@@ -377,6 +386,8 @@ export interface TelemetryProvider {
// Workflow management events
trackWorkflowImported?(metadata: WorkflowImportMetadata): void
trackWorkflowOpened?(metadata: WorkflowImportMetadata): void
trackWorkflowSaved?(metadata: WorkflowSavedMetadata): void
trackDefaultViewSet?(metadata: DefaultViewSetMetadata): void
trackEnterLinear?(metadata: EnterLinearMetadata): void
trackShareFlow?(metadata: ShareFlowMetadata): void
@@ -490,6 +501,8 @@ export const TelemetryEvents = {
// Workflow Creation
WORKFLOW_CREATED: 'app:workflow_created',
WORKFLOW_SAVED: 'app:workflow_saved',
DEFAULT_VIEW_SET: 'app:default_view_set',
// Execution Lifecycle
EXECUTION_START: 'execution_start',
@@ -540,4 +553,6 @@ export type TelemetryEventProperties =
| WorkflowCreatedMetadata
| EnterLinearMetadata
| ShareFlowMetadata
| WorkflowSavedMetadata
| DefaultViewSetMetadata
| SubscriptionMetadata

View File

@@ -149,6 +149,8 @@ export const useWorkflowService = () => {
await openWorkflow(tempWorkflow)
await workflowStore.saveWorkflow(tempWorkflow)
}
useTelemetry()?.trackWorkflowSaved({ is_app: isApp, is_new: true })
return true
}
@@ -189,6 +191,7 @@ export const useWorkflowService = () => {
}
await workflowStore.saveWorkflow(workflow)
useTelemetry()?.trackWorkflowSaved({ is_app: isApp, is_new: false })
}
}