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