Compare commits

...

2 Commits

Author SHA1 Message Date
Robin Huang
8a9d8d134c feat: allow server-side PostHog init config overrides
Replace individual posthog_api_host/posthog_debug fields with a generic
posthog_config object in RemoteConfig that gets spread into the PostHog
init call, allowing any PostHog init parameter to be overridden from
the /api/features endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:25:13 -07:00
Robin Huang
7bcdd8fcea feat: add remote config support for PostHog debug mode
Allow PostHog debug mode to be controlled via the /api/features
endpoint (posthog_debug), with VITE_POSTHOG_DEBUG env var as fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:27:48 -07:00
4 changed files with 37 additions and 22 deletions

2
global.d.ts vendored
View File

@@ -34,7 +34,7 @@ interface Window {
ga_measurement_id?: string
mixpanel_token?: string
posthog_project_token?: string
posthog_api_host?: string
posthog_config?: Record<string, unknown>
require_whitelist?: boolean
subscription_required?: boolean
max_upload_size?: number

View File

@@ -1,3 +1,5 @@
import type { PostHogConfig } from 'posthog-js'
import type { TelemetryEventName } from '@/platform/telemetry/types'
/**
@@ -30,7 +32,7 @@ export type RemoteConfig = {
ga_measurement_id?: string
mixpanel_token?: string
posthog_project_token?: string
posthog_api_host?: string
posthog_config?: Partial<PostHogConfig>
subscription_required?: boolean
server_health_alert?: ServerHealthAlert
max_upload_size?: number

View File

@@ -40,8 +40,12 @@ vi.mock('@/composables/auth/useCurrentUser', () => ({
})
}))
const mockRemoteConfig = vi.hoisted(
() => ({ value: null }) as { value: Record<string, unknown> | null }
)
vi.mock('@/platform/remoteConfig/remoteConfig', () => ({
remoteConfig: { value: null }
remoteConfig: mockRemoteConfig
}))
vi.mock('posthog-js', () => hoisted.mockPosthog)
@@ -61,6 +65,7 @@ function createProvider(
describe('PostHogTelemetryProvider', () => {
beforeEach(() => {
vi.clearAllMocks()
mockRemoteConfig.value = null
window.__CONFIG__ = {
posthog_project_token: 'phc_test_token'
} as typeof window.__CONFIG__
@@ -80,28 +85,35 @@ describe('PostHogTelemetryProvider', () => {
createProvider()
await vi.dynamicImportSettled()
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,
persistence: 'localStorage+cookie',
debug: false
})
expect(hoisted.mockInit).toHaveBeenCalledWith(
'phc_test_token',
expect.objectContaining({
api_host: 'https://t.comfy.org',
ui_host: 'https://us.posthog.com',
autocapture: false,
capture_pageview: false,
capture_pageleave: false,
persistence: 'localStorage+cookie'
})
)
})
it('uses custom api_host from config when provided', async () => {
window.__CONFIG__ = {
posthog_project_token: 'phc_test_token',
posthog_api_host: 'https://custom.host.com'
} as typeof window.__CONFIG__
new PostHogTelemetryProvider()
it('applies posthog_config overrides from remote config', async () => {
mockRemoteConfig.value = {
posthog_config: {
debug: true,
api_host: 'https://custom.host.com'
}
}
createProvider()
await vi.dynamicImportSettled()
expect(hoisted.mockInit).toHaveBeenCalledWith(
'phc_test_token',
expect.objectContaining({ api_host: 'https://custom.host.com' })
expect.objectContaining({
debug: true,
api_host: 'https://custom.host.com'
})
)
})

View File

@@ -101,15 +101,16 @@ export class PostHogTelemetryProvider implements TelemetryProvider {
void import('posthog-js')
.then((posthogModule) => {
this.posthog = posthogModule.default
const serverConfig = remoteConfig.value?.posthog_config ?? {}
this.posthog!.init(apiKey, {
api_host:
window.__CONFIG__?.posthog_api_host || 'https://t.comfy.org',
api_host: 'https://t.comfy.org',
ui_host: 'https://us.posthog.com',
autocapture: false,
capture_pageview: false,
capture_pageleave: false,
persistence: 'localStorage+cookie',
debug: import.meta.env.VITE_POSTHOG_DEBUG === 'true'
debug: import.meta.env.VITE_POSTHOG_DEBUG === 'true',
...serverConfig
})
this.isInitialized = true
this.flushEventQueue()