diff --git a/docs/tracking-plan.md b/docs/tracking-plan.md index 4c6dfc8b349..cf7193d5806 100644 --- a/docs/tracking-plan.md +++ b/docs/tracking-plan.md @@ -162,6 +162,7 @@ Generated on Mon, Mar 10, 2025 - [Schema Validation Added](#event--SchemaValidationAddedEvent) - [Schema Validation Edited](#event--SchemaValidationEditedEvent) - [Schema Validation Updated](#event--SchemaValidationUpdatedEvent) +- [Schema Validation Generated](#event--SchemaValidationGeneratedEvent) ### Settings - [Theme Changed](#event--ThemeChangedEvent) @@ -1981,6 +1982,22 @@ This event is fired when user edits validation rules (without saving them). +### Schema Validation Generated + +This event is fired when user generates validation rules. + +**Properties**: + +- **is_compass_web** (optional): `true | undefined` +- **connection_id** (optional): `string | undefined` + - The id of the connection associated to this event. +- **variable_type_count** (required): `number` + - The count of fields with multiple types in the generated schema (not counting undefined). +This is only calculated for the top level fields, not nested fields and arrays. +- **optional_field_count** (required): `number` + - The count of fields that don't appear on all documents. This is only calculated for the top level fields, not nested fields and arrays. + + ### Schema Validation Updated This event is fired when user saves validation rules. diff --git a/packages/compass-schema-validation/src/modules/rules-generation.ts b/packages/compass-schema-validation/src/modules/rules-generation.ts index 352a611febd..99e73b58249 100644 --- a/packages/compass-schema-validation/src/modules/rules-generation.ts +++ b/packages/compass-schema-validation/src/modules/rules-generation.ts @@ -4,6 +4,12 @@ import { enableEditRules } from './edit-mode'; import type { MongoError } from 'mongodb'; import type { Action, AnyAction, Reducer } from 'redux'; import { validationLevelChanged, validatorChanged } from './validation'; +import { + type analyzeSchema as analyzeSchemaType, + calculateSchemaMetadata, +} from '@mongodb-js/compass-schema'; +import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import type { ConnectionInfoRef } from '@mongodb-js/compass-connections/provider'; export function isAction( action: AnyAction, @@ -150,6 +156,29 @@ export const stopRulesGeneration = (): SchemaValidationThunkAction => { }; }; +const _trackRulesGenerated = async ({ + schemaAccessor, + track, + connectionInfoRef, +}: { + schemaAccessor: Awaited>; + track: TrackFunction; + connectionInfoRef: ConnectionInfoRef; +}) => { + const internalSchema = await schemaAccessor?.getInternalSchema(); + if (!internalSchema) return; + const { variable_type_count, optional_field_count } = + await calculateSchemaMetadata(internalSchema); + track( + 'Schema Validation Generated', + { + variable_type_count, + optional_field_count, + }, + connectionInfoRef.current + ); +}; + /** * Get $jsonSchema from schema analysis * @returns @@ -166,6 +195,8 @@ export const generateValidationRules = (): SchemaValidationThunkAction< preferences, rulesGenerationAbortControllerRef, analyzeSchema, + track, + connectionInfoRef, } ) => { dispatch({ type: RulesGenerationActions.generationStarted }); @@ -214,6 +245,12 @@ export const generateValidationRules = (): SchemaValidationThunkAction< dispatch(enableEditRules()); dispatch({ type: RulesGenerationActions.generationFinished }); dispatch(zeroStateChanged(false)); + + void _trackRulesGenerated({ + schemaAccessor, + connectionInfoRef, + track, + }); } catch (error) { if (abortSignal.aborted) { dispatch({ type: RulesGenerationActions.generationFinished }); diff --git a/packages/compass-schema-validation/src/stores/store.spec.ts b/packages/compass-schema-validation/src/stores/store.spec.ts index 07b25d15a20..87090f6346c 100644 --- a/packages/compass-schema-validation/src/stores/store.spec.ts +++ b/packages/compass-schema-validation/src/stores/store.spec.ts @@ -82,6 +82,11 @@ const schemaAccessor = { setTimeout(() => resolve({ required: ['prop1'] }), 100); // waiting to give abort a chance }); }, + getInternalSchema: () => { + return new Promise((resolve) => { + setTimeout(() => resolve({ required: ['prop1'] }), 100); // waiting to give abort a chance + }); + }, }; describe('Schema Validation Store', function () { diff --git a/packages/compass-telemetry/src/telemetry-events.ts b/packages/compass-telemetry/src/telemetry-events.ts index 4211474c9ce..0086a8681a4 100644 --- a/packages/compass-telemetry/src/telemetry-events.ts +++ b/packages/compass-telemetry/src/telemetry-events.ts @@ -1906,6 +1906,27 @@ type SchemaValidationUpdatedEvent = ConnectionScopedEvent<{ }; }>; +/** + * This event is fired when user generates validation rules. + * + * @category Schema Validation + */ +type SchemaValidationGeneratedEvent = ConnectionScopedEvent<{ + name: 'Schema Validation Generated'; + payload: { + /* The count of fields with multiple types in a given schema (not counting undefined). + * This is only calculated for the top level fields, not nested fields and arrays. + */ + variable_type_count: number; + + /** + * The count of fields that don't appear on all documents. + * This is only calculated for the top level fields, not nested fields and arrays. + */ + optional_field_count: number; + }; +}>; + /** * This event is fired when user adds validation rules. * @@ -2754,6 +2775,7 @@ export type TelemetryEvent = | SchemaValidationAddedEvent | SchemaValidationEditedEvent | SchemaValidationUpdatedEvent + | SchemaValidationGeneratedEvent | ScreenEvent | ShellEvent | SignalActionButtonClickedEvent