@finos/legend-application-query 13.8.52 → 13.8.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/lib/__lib__/LegendQueryAgentChatTelemetryHelper.d.ts +23 -4
  2. package/lib/__lib__/LegendQueryAgentChatTelemetryHelper.d.ts.map +1 -1
  3. package/lib/__lib__/LegendQueryAgentChatTelemetryHelper.js +15 -10
  4. package/lib/__lib__/LegendQueryAgentChatTelemetryHelper.js.map +1 -1
  5. package/lib/__lib__/LegendQueryEvent.d.ts +19 -0
  6. package/lib/__lib__/LegendQueryEvent.d.ts.map +1 -1
  7. package/lib/__lib__/LegendQueryEvent.js +22 -0
  8. package/lib/__lib__/LegendQueryEvent.js.map +1 -1
  9. package/lib/__lib__/LegendQueryLifecycleTelemetry.d.ts +58 -0
  10. package/lib/__lib__/LegendQueryLifecycleTelemetry.d.ts.map +1 -0
  11. package/lib/__lib__/LegendQueryLifecycleTelemetry.js +90 -0
  12. package/lib/__lib__/LegendQueryLifecycleTelemetry.js.map +1 -0
  13. package/lib/__lib__/LegendQueryNavigation.d.ts +3 -3
  14. package/lib/__lib__/LegendQueryNavigation.d.ts.map +1 -1
  15. package/lib/__lib__/LegendQueryNavigation.js +13 -3
  16. package/lib/__lib__/LegendQueryNavigation.js.map +1 -1
  17. package/lib/__lib__/LegendQuerySourceInfo.d.ts +137 -0
  18. package/lib/__lib__/LegendQuerySourceInfo.d.ts.map +1 -0
  19. package/lib/__lib__/LegendQuerySourceInfo.js +33 -0
  20. package/lib/__lib__/LegendQuerySourceInfo.js.map +1 -0
  21. package/lib/__lib__/LegendQueryTelemetryHelper.d.ts +127 -1
  22. package/lib/__lib__/LegendQueryTelemetryHelper.d.ts.map +1 -1
  23. package/lib/__lib__/LegendQueryTelemetryHelper.js +63 -0
  24. package/lib/__lib__/LegendQueryTelemetryHelper.js.map +1 -1
  25. package/lib/application/LegendQueryApplicationConfig.d.ts +4 -4
  26. package/lib/application/LegendQueryApplicationConfig.d.ts.map +1 -1
  27. package/lib/application/LegendQueryApplicationConfig.js +4 -5
  28. package/lib/application/LegendQueryApplicationConfig.js.map +1 -1
  29. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -1
  30. package/lib/components/Core_LegendQueryApplicationPlugin.js +21 -3
  31. package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -1
  32. package/lib/components/QueryEditor.d.ts.map +1 -1
  33. package/lib/components/QueryEditor.js +21 -6
  34. package/lib/components/QueryEditor.js.map +1 -1
  35. package/lib/components/data-space/DataSpaceInfo.js +6 -6
  36. package/lib/components/data-space/DataSpaceInfo.js.map +1 -1
  37. package/lib/components/data-space/DataSpaceQuerySetup.d.ts.map +1 -1
  38. package/lib/components/data-space/DataSpaceQuerySetup.js +19 -0
  39. package/lib/components/data-space/DataSpaceQuerySetup.js.map +1 -1
  40. package/lib/components/data-space/LegendQueryDataSpaceQueryBuilder.d.ts.map +1 -1
  41. package/lib/components/data-space/LegendQueryDataSpaceQueryBuilder.js +19 -0
  42. package/lib/components/data-space/LegendQueryDataSpaceQueryBuilder.js.map +1 -1
  43. package/lib/index.css +1 -1
  44. package/lib/index.d.ts +2 -1
  45. package/lib/index.d.ts.map +1 -1
  46. package/lib/index.js +2 -1
  47. package/lib/index.js.map +1 -1
  48. package/lib/light-mode.css +1 -1
  49. package/lib/package.json +1 -1
  50. package/lib/stores/EditExistingQuerySetupStore.d.ts.map +1 -1
  51. package/lib/stores/EditExistingQuerySetupStore.js +4 -13
  52. package/lib/stores/EditExistingQuerySetupStore.js.map +1 -1
  53. package/lib/stores/LegendQueryApplicationPlugin.d.ts +2 -1
  54. package/lib/stores/LegendQueryApplicationPlugin.d.ts.map +1 -1
  55. package/lib/stores/LegendQueryApplicationPlugin.js +23 -0
  56. package/lib/stores/LegendQueryApplicationPlugin.js.map +1 -1
  57. package/lib/stores/QueryEditorStore.d.ts +50 -2
  58. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  59. package/lib/stores/QueryEditorStore.js +195 -82
  60. package/lib/stores/QueryEditorStore.js.map +1 -1
  61. package/lib/stores/QueryProductionizerSetupStore.d.ts.map +1 -1
  62. package/lib/stores/QueryProductionizerSetupStore.js +17 -13
  63. package/lib/stores/QueryProductionizerSetupStore.js.map +1 -1
  64. package/lib/stores/QuerySetupStore.d.ts.map +1 -1
  65. package/lib/stores/QuerySetupStore.js +2 -0
  66. package/lib/stores/QuerySetupStore.js.map +1 -1
  67. package/lib/stores/__test-utils__/LegendQueryApplicationTestUtils.d.ts.map +1 -1
  68. package/lib/stores/__test-utils__/LegendQueryApplicationTestUtils.js +0 -3
  69. package/lib/stores/__test-utils__/LegendQueryApplicationTestUtils.js.map +1 -1
  70. package/lib/stores/data-cube/ExistingQueryDataCubeViewer.d.ts.map +1 -1
  71. package/lib/stores/data-cube/ExistingQueryDataCubeViewer.js +1 -0
  72. package/lib/stores/data-cube/ExistingQueryDataCubeViewer.js.map +1 -1
  73. package/lib/stores/data-product/DataProductSampleQueryCreatorStore.d.ts +2 -0
  74. package/lib/stores/data-product/DataProductSampleQueryCreatorStore.d.ts.map +1 -1
  75. package/lib/stores/data-product/DataProductSampleQueryCreatorStore.js +12 -1
  76. package/lib/stores/data-product/DataProductSampleQueryCreatorStore.js.map +1 -1
  77. package/lib/stores/data-space/DataProductQueryCreatorStore.d.ts +10 -0
  78. package/lib/stores/data-space/DataProductQueryCreatorStore.d.ts.map +1 -1
  79. package/lib/stores/data-space/DataProductQueryCreatorStore.js +63 -19
  80. package/lib/stores/data-space/DataProductQueryCreatorStore.js.map +1 -1
  81. package/lib/stores/data-space/DataProductSelectorState.d.ts +4 -2
  82. package/lib/stores/data-space/DataProductSelectorState.d.ts.map +1 -1
  83. package/lib/stores/data-space/DataProductSelectorState.js +30 -9
  84. package/lib/stores/data-space/DataProductSelectorState.js.map +1 -1
  85. package/lib/stores/data-space/DataSpaceQueryBuilderHelper.d.ts.map +1 -1
  86. package/lib/stores/data-space/DataSpaceQueryBuilderHelper.js +5 -1
  87. package/lib/stores/data-space/DataSpaceQueryBuilderHelper.js.map +1 -1
  88. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts +2 -0
  89. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts.map +1 -1
  90. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js +13 -7
  91. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js.map +1 -1
  92. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.d.ts.map +1 -1
  93. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.js +1 -1
  94. package/lib/stores/data-space/LegendQueryBareQueryBuilderState.js.map +1 -1
  95. package/lib/stores/ingest/IngestQueryCreatorStore.d.ts +2 -0
  96. package/lib/stores/ingest/IngestQueryCreatorStore.d.ts.map +1 -1
  97. package/lib/stores/ingest/IngestQueryCreatorStore.js +10 -3
  98. package/lib/stores/ingest/IngestQueryCreatorStore.js.map +1 -1
  99. package/package.json +13 -13
  100. package/src/__lib__/LegendQueryAgentChatTelemetryHelper.ts +66 -10
  101. package/src/__lib__/LegendQueryEvent.ts +25 -0
  102. package/src/__lib__/LegendQueryLifecycleTelemetry.ts +132 -0
  103. package/src/__lib__/LegendQueryNavigation.ts +24 -5
  104. package/src/__lib__/LegendQuerySourceInfo.ts +162 -0
  105. package/src/__lib__/LegendQueryTelemetryHelper.ts +277 -1
  106. package/src/application/LegendQueryApplicationConfig.ts +12 -12
  107. package/src/components/Core_LegendQueryApplicationPlugin.tsx +47 -4
  108. package/src/components/QueryEditor.tsx +30 -2
  109. package/src/components/data-space/DataSpaceInfo.tsx +8 -8
  110. package/src/components/data-space/DataSpaceQuerySetup.tsx +25 -0
  111. package/src/components/data-space/LegendQueryDataSpaceQueryBuilder.tsx +25 -0
  112. package/src/index.ts +6 -1
  113. package/src/stores/EditExistingQuerySetupStore.ts +8 -20
  114. package/src/stores/LegendQueryApplicationPlugin.tsx +38 -0
  115. package/src/stores/QueryEditorStore.ts +269 -95
  116. package/src/stores/QueryProductionizerSetupStore.ts +24 -20
  117. package/src/stores/QuerySetupStore.ts +3 -0
  118. package/src/stores/__test-utils__/LegendQueryApplicationTestUtils.ts +0 -3
  119. package/src/stores/data-cube/ExistingQueryDataCubeViewer.ts +1 -0
  120. package/src/stores/data-product/DataProductSampleQueryCreatorStore.ts +17 -0
  121. package/src/stores/data-space/DataProductQueryCreatorStore.ts +99 -33
  122. package/src/stores/data-space/DataProductSelectorState.ts +58 -13
  123. package/src/stores/data-space/DataSpaceQueryBuilderHelper.ts +6 -1
  124. package/src/stores/data-space/DataSpaceTemplateQueryCreatorStore.ts +17 -6
  125. package/src/stores/data-space/LegendQueryBareQueryBuilderState.ts +5 -1
  126. package/src/stores/ingest/IngestQueryCreatorStore.ts +16 -5
  127. package/tsconfig.json +2 -0
@@ -39,6 +39,7 @@ import {
39
39
  returnUndefOnError,
40
40
  UnsupportedOperationError,
41
41
  filterByType,
42
+ buildTelemetryErrorFields,
42
43
  } from '@finos/legend-shared';
43
44
  import {
44
45
  type LightQuery,
@@ -138,9 +139,29 @@ import {
138
139
  ModelAccessPointDataProductExecutionState,
139
140
  LakehouseDataProductExecutionState,
140
141
  resolveDataProductAccessor,
142
+ QUERY_BUILDER_OPENED_FROM,
141
143
  } from '@finos/legend-query-builder';
142
144
  import { LegendQueryUserDataHelper } from '../__lib__/LegendQueryUserDataHelper.js';
143
- import { LegendQueryTelemetryHelper } from '../__lib__/LegendQueryTelemetryHelper.js';
145
+ import {
146
+ buildQueryCreateFailureData,
147
+ buildQueryIdentity,
148
+ buildQueryLifecycleFailureData,
149
+ buildQueryLoaderLifecycleTelemetryHandlers,
150
+ } from '../__lib__/LegendQueryLifecycleTelemetry.js';
151
+ import {
152
+ LegendQueryTelemetryHelper,
153
+ type InitializeTelemetrySource,
154
+ } from '../__lib__/LegendQueryTelemetryHelper.js';
155
+ import {
156
+ type LegendQueryDataProductSampleSourceInfo,
157
+ type LegendQueryDataProductSourceInfo,
158
+ type LegendQueryDataSpaceSourceInfo,
159
+ type LegendQueryIngestSourceInfo,
160
+ type LegendQueryMappingSourceInfo,
161
+ type LegendQueryServiceSourceInfo,
162
+ type LegendQuerySourceInfo,
163
+ LegendQuerySourceType,
164
+ } from '../__lib__/LegendQuerySourceInfo.js';
144
165
  import { type ResolvedDataSpaceEntityWithOrigin } from '@finos/legend-extension-dsl-data-space/application';
145
166
  import {
146
167
  type DataSpace,
@@ -276,13 +297,7 @@ export class QueryCreatorState {
276
297
  LegendQueryTelemetryHelper.logEvent_CreateQuerySucceeded(
277
298
  this.editorStore.applicationStore.telemetryService,
278
299
  {
279
- query: {
280
- id: query.id,
281
- name: query.name,
282
- groupId: query.groupId,
283
- artifactId: query.artifactId,
284
- versionId: query.versionId,
285
- },
300
+ ...buildQueryIdentity(query),
286
301
  ...queryBuilderState.getExtraTelemetryMetadata(),
287
302
  },
288
303
  );
@@ -300,6 +315,10 @@ export class QueryCreatorState {
300
315
  error,
301
316
  );
302
317
  this.editorStore.applicationStore.notificationService.notifyError(error);
318
+ LegendQueryTelemetryHelper.logEvent_CreateQueryFailed(
319
+ this.editorStore.applicationStore.telemetryService,
320
+ buildQueryCreateFailureData(this.queryName, error),
321
+ );
303
322
  } finally {
304
323
  this.createQueryState.reset();
305
324
  }
@@ -430,25 +449,13 @@ export abstract class QueryEditorStore {
430
449
  'recently viewed queries',
431
450
  )}`
432
451
  : `No recently viewed queries`,
433
- onQueryDeleted: (queryId): void =>
434
- LegendQueryUserDataHelper.removeRecentlyViewedQuery(
435
- this.applicationStore.userDataService,
436
- queryId,
437
- ),
438
- onQueryRenamed: (query): void => {
439
- LegendQueryTelemetryHelper.logEvent_RenameQuerySucceeded(
440
- applicationStore.telemetryService,
441
- {
442
- query: {
443
- id: query.id,
444
- name: query.name,
445
- groupId: query.groupId,
446
- artifactId: query.artifactId,
447
- versionId: query.versionId,
448
- },
449
- },
450
- );
451
- },
452
+ ...buildQueryLoaderLifecycleTelemetryHandlers(this.applicationStore, {
453
+ onQueryDeleted: (queryId): void =>
454
+ LegendQueryUserDataHelper.removeRecentlyViewedQuery(
455
+ this.applicationStore.userDataService,
456
+ queryId,
457
+ ),
458
+ }),
452
459
  handleFetchDefaultQueriesFailure: (): void =>
453
460
  LegendQueryUserDataHelper.removeRecentlyViewedQueries(
454
461
  this.applicationStore.userDataService,
@@ -608,9 +615,9 @@ export abstract class QueryEditorStore {
608
615
  return;
609
616
  }
610
617
 
618
+ const stopWatch = new StopWatch();
611
619
  try {
612
620
  this.initState.inProgress();
613
- const stopWatch = new StopWatch();
614
621
 
615
622
  // TODO: when we genericize the way to initialize an application page
616
623
  this.applicationStore.assistantService.setIsHidden(true);
@@ -623,7 +630,10 @@ export abstract class QueryEditorStore {
623
630
  clientConfig: {
624
631
  baseUrl: this.applicationStore.config.engineServerUrl,
625
632
  queryBaseUrl: this.applicationStore.config.engineQueryServerUrl,
633
+ queryClientName: this.applicationStore.config.engineQueryClientName,
626
634
  enableCompression: true,
635
+ useCookieAuthOnly:
636
+ this.applicationStore.config.engineUseCookieAuthOnly,
627
637
  },
628
638
  },
629
639
  {
@@ -632,12 +642,33 @@ export abstract class QueryEditorStore {
632
642
  );
633
643
 
634
644
  yield this.setUpEditorState();
635
- yield flowResult(this.buildGraph());
636
- this.queryBuilderState = (yield this.initializeQueryBuilderState(
637
- stopWatch,
638
- )) as QueryBuilderState;
645
+ try {
646
+ yield flowResult(this.buildGraph());
647
+ } catch (error) {
648
+ assertErrorThrown(error);
649
+ this.logBuildGraphFailure(error);
650
+ throw error;
651
+ }
652
+ try {
653
+ this.queryBuilderState = (yield this.initializeQueryBuilderState(
654
+ stopWatch,
655
+ )) as QueryBuilderState;
656
+ } catch (error) {
657
+ assertErrorThrown(error);
658
+ this.logInitializeQueryBuilderStateFailure(error);
659
+ throw error;
660
+ }
639
661
  this.queryLoaderState.initialize(this.queryBuilderState);
640
662
  this.initState.pass();
663
+ // the canonical "a query builder is loaded" signal, emitted for every
664
+ // route — creator and saved alike. Reported here rather than from each
665
+ // route's own load event so that counting opens does not require a union
666
+ // of differently shaped, half-covering events.
667
+ this.queryBuilderState.logOpened(this.getOpenedFrom(), {
668
+ ...this.getInitializeTelemetrySource(),
669
+ timings:
670
+ this.applicationStore.timeService.finalizeTimingsRecord(stopWatch),
671
+ });
641
672
  } catch (error) {
642
673
  assertErrorThrown(error);
643
674
  this.applicationStore.logService.error(
@@ -645,6 +676,9 @@ export abstract class QueryEditorStore {
645
676
  error,
646
677
  );
647
678
  this.applicationStore.notificationService.notifyError(error);
679
+ // NOTE: log before handling the failure, which may reset the editor
680
+ // state that the telemetry source is derived from
681
+ this.logInitializeFailureMetrics(stopWatch, error);
648
682
  this.onInitializeFailure();
649
683
  this.initState.fail();
650
684
  }
@@ -654,6 +688,53 @@ export abstract class QueryEditorStore {
654
688
  // Do Nothing
655
689
  }
656
690
 
691
+ /**
692
+ * Where the query was started from, used as the source info of the query
693
+ * builder state. Since this is derived from the editor state (e.g. the
694
+ * route) rather than the query builder state, it is also available when
695
+ * the editor fails to initialize.
696
+ */
697
+ getSourceInfo(): LegendQuerySourceInfo | undefined {
698
+ return undefined;
699
+ }
700
+
701
+ /**
702
+ * Which surface opened the query builder, reported as `openedFrom` on
703
+ * `query-builder.opened`. Creator routes inherit this; only
704
+ * `ExistingQueryEditorStore` overrides it.
705
+ *
706
+ * Note this names the surface only — what is being queried is already carried
707
+ * by `getSourceInfo()` on the same payload.
708
+ */
709
+ getOpenedFrom(): QUERY_BUILDER_OPENED_FROM {
710
+ return QUERY_BUILDER_OPENED_FROM.QUERY_CREATOR;
711
+ }
712
+
713
+ /**
714
+ * Where the query was started from, reported when the query creator is
715
+ * initialized
716
+ */
717
+ getInitializeTelemetrySource(): InitializeTelemetrySource {
718
+ return {
719
+ // spread flat, matching how `sourceInfo` is reported on every other query
720
+ // telemetry event — see `QueryBuilderTelemetryContext`
721
+ ...this.getSourceInfo(),
722
+ restoredFromRecent: false,
723
+ };
724
+ }
725
+
726
+ logInitializeFailureMetrics(stopWatch: StopWatch, error: Error): void {
727
+ LegendQueryTelemetryHelper.logEvent_InitializeQueryCreatorFailed(
728
+ this.applicationStore.telemetryService,
729
+ {
730
+ ...this.getInitializeTelemetrySource(),
731
+ ...buildTelemetryErrorFields(error),
732
+ timings:
733
+ this.applicationStore.timeService.finalizeTimingsRecord(stopWatch),
734
+ },
735
+ );
736
+ }
737
+
657
738
  *searchExistingQueryName(searchText: string): GeneratorFn<void> {
658
739
  const isValidSearchString =
659
740
  searchText.length >= DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH;
@@ -687,6 +768,33 @@ export abstract class QueryEditorStore {
687
768
  );
688
769
  }
689
770
 
771
+ /**
772
+ * Failure counterpart of {@link logBuildGraphMetrics}. Fires when the graph
773
+ * build stage of `initialize()` throws. Base emits with only the error
774
+ * dimensions — {@link ExistingQueryEditorStore} overrides to attach the
775
+ * loaded query's identity, mirroring how its success override attaches
776
+ * identity too.
777
+ */
778
+ logBuildGraphFailure(error: Error): void {
779
+ LegendQueryTelemetryHelper.logEvent_GraphInitializationFailed(
780
+ this.applicationStore.telemetryService,
781
+ buildTelemetryErrorFields(error),
782
+ );
783
+ }
784
+
785
+ /**
786
+ * Failure hook for the query builder state initialization stage of
787
+ * `initialize()`. Default is a no-op: creator routes already report a
788
+ * failure here through `INITIALIZE_QUERY_CREATOR__FAILURE`, so emitting a
789
+ * second event would double-count. {@link ExistingQueryEditorStore}
790
+ * overrides this to emit `VIEW_QUERY__FAILURE`, the counterpart of the
791
+ * `VIEW_QUERY__SUCCESS` its `initializeQueryBuilderState` fires on the
792
+ * happy path.
793
+ */
794
+ logInitializeQueryBuilderStateFailure(_error: Error): void {
795
+ // no-op by default; overrides on saved-query stores emit failure telemetry
796
+ }
797
+
690
798
  *buildFullGraph(): GeneratorFn<void> {
691
799
  const stopWatch = new StopWatch();
692
800
 
@@ -1282,6 +1390,10 @@ export abstract class QueryEditorStore {
1282
1390
  | ((val: ResolvedDataSpaceEntityWithOrigin) => void)
1283
1391
  | undefined,
1284
1392
  productSelectorState?: DataProductSelectorState | undefined,
1393
+ sourceInfo?:
1394
+ | LegendQueryDataProductSourceInfo
1395
+ | LegendQueryDataProductSampleSourceInfo
1396
+ | undefined,
1285
1397
  ): Promise<LegendQueryDataProductQueryBuilderState> {
1286
1398
  // 3. Build minimal graph and get analysis result
1287
1399
  const dataProductAnalysisResult =
@@ -1325,12 +1437,6 @@ export abstract class QueryEditorStore {
1325
1437
  }
1326
1438
  // 6. Create query builder state
1327
1439
  const projectInfo = { groupId, artifactId, versionId };
1328
- const sourceInfo = {
1329
- groupId,
1330
- artifactId,
1331
- versionId,
1332
- dataProduct: dataProductPath,
1333
- };
1334
1440
  const queryBuilderState = new LegendQueryDataProductQueryBuilderState(
1335
1441
  this.applicationStore,
1336
1442
  this.graphManagerState,
@@ -1348,11 +1454,20 @@ export abstract class QueryEditorStore {
1348
1454
  new DataProductSelectorState(
1349
1455
  this.depotServerClient,
1350
1456
  this.applicationStore,
1457
+ this.lakehouseState?.contractServerClient,
1351
1458
  ),
1352
1459
  onLegacyDataSpaceChange,
1353
1460
  undefined,
1354
1461
  this.applicationStore.config.options.queryBuilderConfig,
1355
- sourceInfo,
1462
+ sourceInfo ?? {
1463
+ sourceType: LegendQuerySourceType.DATA_PRODUCT,
1464
+ groupId,
1465
+ artifactId,
1466
+ versionId,
1467
+ dataProduct: dataProductPath,
1468
+ accessType: dataProductAccessType,
1469
+ accessId,
1470
+ },
1356
1471
  );
1357
1472
 
1358
1473
  if (
@@ -1449,13 +1564,19 @@ export class MappingQueryCreatorStore extends QueryEditorStore {
1449
1564
  };
1450
1565
  }
1451
1566
 
1452
- async initializeQueryBuilderState(): Promise<QueryBuilderState> {
1453
- const projectInfo = this.getProjectInfo();
1454
- const sourceInfo = {
1455
- groupId: projectInfo.groupId,
1456
- artifactId: projectInfo.artifactId,
1457
- versionId: projectInfo.versionId,
1567
+ override getSourceInfo(): LegendQueryMappingSourceInfo {
1568
+ return {
1569
+ sourceType: LegendQuerySourceType.MAPPING,
1570
+ groupId: this.groupId,
1571
+ artifactId: this.artifactId,
1572
+ versionId: this.versionId,
1573
+ mapping: this.mappingPath,
1574
+ runtime: this.runtimePath,
1458
1575
  };
1576
+ }
1577
+
1578
+ async initializeQueryBuilderState(): Promise<QueryBuilderState> {
1579
+ const sourceInfo = this.getSourceInfo();
1459
1580
  const queryBuilderState = new MappingQueryBuilderState(
1460
1581
  this.applicationStore,
1461
1582
  this.graphManagerState,
@@ -1574,6 +1695,16 @@ export class ServiceQueryCreatorStore extends QueryEditorStore {
1574
1695
  };
1575
1696
  }
1576
1697
 
1698
+ override getSourceInfo(): LegendQueryServiceSourceInfo {
1699
+ return {
1700
+ sourceType: LegendQuerySourceType.SERVICE,
1701
+ groupId: this.groupId,
1702
+ artifactId: this.artifactId,
1703
+ versionId: this.versionId,
1704
+ service: this.servicePath,
1705
+ };
1706
+ }
1707
+
1577
1708
  async initializeQueryBuilderState(): Promise<QueryBuilderState> {
1578
1709
  const service = this.graphManagerState.graph.getService(this.servicePath);
1579
1710
  assertType(
@@ -1582,13 +1713,7 @@ export class ServiceQueryCreatorStore extends QueryEditorStore {
1582
1713
  `Can't process service execution: only Pure execution is supported`,
1583
1714
  );
1584
1715
 
1585
- const projectInfo = this.getProjectInfo();
1586
- const sourceInfo = {
1587
- groupId: projectInfo.groupId,
1588
- artifactId: projectInfo.artifactId,
1589
- versionId: projectInfo.versionId,
1590
- service: service.path,
1591
- };
1716
+ const sourceInfo = this.getSourceInfo();
1592
1717
  const queryBuilderState = new ServiceQueryBuilderState(
1593
1718
  this.applicationStore,
1594
1719
  this.graphManagerState,
@@ -1799,13 +1924,7 @@ export class ExistingQueryUpdateState {
1799
1924
  LegendQueryTelemetryHelper.logEvent_UpdateQuerySucceeded(
1800
1925
  this.editorStore.applicationStore.telemetryService,
1801
1926
  {
1802
- query: {
1803
- id: query.id,
1804
- name: query.name,
1805
- groupId: query.groupId,
1806
- artifactId: query.artifactId,
1807
- versionId: query.versionId,
1808
- },
1927
+ ...buildQueryIdentity(query),
1809
1928
  ...queryBuilderState.getExtraTelemetryMetadata(),
1810
1929
  },
1811
1930
  );
@@ -1819,6 +1938,10 @@ export class ExistingQueryUpdateState {
1819
1938
  error,
1820
1939
  );
1821
1940
  this.editorStore.applicationStore.notificationService.notifyError(error);
1941
+ LegendQueryTelemetryHelper.logEvent_UpdateQueryFailed(
1942
+ this.editorStore.applicationStore.telemetryService,
1943
+ buildQueryLifecycleFailureData(this.editorStore.id, error),
1944
+ );
1822
1945
  } finally {
1823
1946
  this.updateQueryState.complete();
1824
1947
  }
@@ -1848,13 +1971,7 @@ export class ExistingQueryUpdateState {
1848
1971
  LegendQueryTelemetryHelper.logEvent_UpdateQuerySucceeded(
1849
1972
  this.editorStore.applicationStore.telemetryService,
1850
1973
  {
1851
- query: {
1852
- id: updatedQuery.id,
1853
- name: updatedQuery.name,
1854
- groupId: updatedQuery.groupId,
1855
- artifactId: updatedQuery.artifactId,
1856
- versionId: updatedQuery.versionId,
1857
- },
1974
+ ...buildQueryIdentity(updatedQuery),
1858
1975
  ...extraTelemetryMetadata,
1859
1976
  },
1860
1977
  );
@@ -1865,6 +1982,10 @@ export class ExistingQueryUpdateState {
1865
1982
  error,
1866
1983
  );
1867
1984
  this.editorStore.applicationStore.notificationService.notifyError(error);
1985
+ LegendQueryTelemetryHelper.logEvent_UpdateQueryFailed(
1986
+ this.editorStore.applicationStore.telemetryService,
1987
+ buildQueryLifecycleFailureData(queryId, error),
1988
+ );
1868
1989
  } finally {
1869
1990
  this.updateQueryState.complete();
1870
1991
  }
@@ -2002,17 +2123,45 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2002
2123
  this.applicationStore.telemetryService,
2003
2124
  {
2004
2125
  graph: graphBuilderReportData,
2005
- query: {
2006
- id: currentQuery.id,
2007
- name: currentQuery.name,
2008
- groupId: currentQuery.groupId,
2009
- artifactId: currentQuery.artifactId,
2010
- versionId: currentQuery.versionId,
2011
- },
2126
+ ...buildQueryIdentity(currentQuery),
2127
+ },
2128
+ );
2129
+ }
2130
+
2131
+ override logBuildGraphFailure(error: Error): void {
2132
+ // attach whatever identity is already known — `_lightQuery` is only
2133
+ // populated once the query resolves, which may not have happened yet, so
2134
+ // the route id is the only guaranteed field
2135
+ const currentQuery = this._lightQuery;
2136
+ LegendQueryTelemetryHelper.logEvent_GraphInitializationFailed(
2137
+ this.applicationStore.telemetryService,
2138
+ {
2139
+ ...buildTelemetryErrorFields(error),
2140
+ ...(currentQuery ? buildQueryIdentity(currentQuery) : {}),
2012
2141
  },
2013
2142
  );
2014
2143
  }
2015
2144
 
2145
+ override logInitializeQueryBuilderStateFailure(error: Error): void {
2146
+ const currentQuery = this._lightQuery;
2147
+ LegendQueryTelemetryHelper.logEvent_ViewQueryFailed(
2148
+ this.applicationStore.telemetryService,
2149
+ {
2150
+ queryId: this.queryId,
2151
+ ...(currentQuery ? buildQueryIdentity(currentQuery) : {}),
2152
+ ...buildTelemetryErrorFields(error),
2153
+ },
2154
+ );
2155
+ }
2156
+
2157
+ override getOpenedFrom(): QUERY_BUILDER_OPENED_FROM {
2158
+ return QUERY_BUILDER_OPENED_FROM.QUERY_SAVED;
2159
+ }
2160
+
2161
+ override logInitializeFailureMetrics(): void {
2162
+ // Do nothing: an existing query is not a query creator
2163
+ }
2164
+
2016
2165
  setLightQuery(val: LightQuery): void {
2017
2166
  this._lightQuery = val;
2018
2167
  }
@@ -2162,12 +2311,14 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2162
2311
  runtime,
2163
2312
  );
2164
2313
  if (matchingExecutionContext) {
2165
- const sourceInfo = {
2314
+ const sourceInfo: LegendQueryDataSpaceSourceInfo = {
2315
+ sourceType: LegendQuerySourceType.DATA_SPACE,
2166
2316
  groupId: queryInfo.groupId,
2167
2317
  artifactId: queryInfo.artifactId,
2168
2318
  versionId: queryInfo.versionId,
2169
2319
  queryId: queryInfo.id,
2170
2320
  dataSpace: dataSpace.path,
2321
+ executionContext: exec.executionKey,
2171
2322
  };
2172
2323
  const visitedDataSpaces =
2173
2324
  LegendQueryUserDataHelper.getRecentlyVisitedDataSpaces(
@@ -2264,6 +2415,7 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2264
2415
  new DataProductSelectorState(
2265
2416
  this.depotServerClient,
2266
2417
  this.applicationStore,
2418
+ this.lakehouseState?.contractServerClient,
2267
2419
  ),
2268
2420
  () => {
2269
2421
  this.applicationStore.notificationService.notifyWarning(
@@ -2318,11 +2470,14 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2318
2470
  }
2319
2471
  } else if (exec instanceof QueryExplicitExecutionContextInfo) {
2320
2472
  const projectInfo = this.getProjectInfo();
2321
- const sourceInfo = {
2473
+ const sourceInfo: LegendQueryMappingSourceInfo = {
2474
+ sourceType: LegendQuerySourceType.MAPPING,
2322
2475
  groupId: projectInfo.groupId,
2323
2476
  artifactId: projectInfo.artifactId,
2324
2477
  versionId: projectInfo.versionId,
2325
2478
  queryId: queryInfo.id,
2479
+ mapping: exec.mapping,
2480
+ runtime: exec.runtime,
2326
2481
  };
2327
2482
  const classQueryBuilderState = new ClassQueryBuilderState(
2328
2483
  this.applicationStore,
@@ -2387,6 +2542,18 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2387
2542
  'Switching data products is not supported from the existing query editor. Please open a new query instead.',
2388
2543
  );
2389
2544
  },
2545
+ undefined,
2546
+ undefined,
2547
+ {
2548
+ sourceType: LegendQuerySourceType.DATA_PRODUCT,
2549
+ groupId: queryInfo.groupId,
2550
+ artifactId: queryInfo.artifactId,
2551
+ versionId: queryInfo.versionId,
2552
+ queryId: queryInfo.id,
2553
+ dataProduct: exec.dataProductPath,
2554
+ accessType,
2555
+ accessId: executionContextId,
2556
+ },
2390
2557
  );
2391
2558
  return queryBuilderState;
2392
2559
  } else if (exec instanceof QueryIngestExecutionContextInfo) {
@@ -2445,11 +2612,14 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2445
2612
  projectInfo,
2446
2613
  this.applicationStore.config.options.queryBuilderConfig,
2447
2614
  {
2615
+ sourceType: LegendQuerySourceType.INGEST,
2448
2616
  groupId: projectInfo.groupId,
2449
2617
  artifactId: projectInfo.artifactId,
2450
2618
  versionId: projectInfo.versionId,
2451
2619
  queryId: queryInfo.id,
2452
- },
2620
+ ingestDefinitionPath: exec.ingestDefinitionPath,
2621
+ dataSet: exec.dataSet,
2622
+ } satisfies LegendQueryIngestSourceInfo,
2453
2623
  );
2454
2624
  await ingestQueryBuilderState.changeAccessorOwner(ingestDefinition);
2455
2625
  await ingestQueryBuilderState.changeAccessor({
@@ -2516,11 +2686,27 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2516
2686
  }
2517
2687
  }
2518
2688
 
2519
- queryBuilderState.initializeWithQuery(
2520
- existingQueryLambda,
2521
- defaultParameters,
2522
- query.gridConfig,
2523
- );
2689
+ try {
2690
+ queryBuilderState.initializeWithQuery(
2691
+ existingQueryLambda,
2692
+ defaultParameters,
2693
+ query.gridConfig,
2694
+ );
2695
+ } catch (error) {
2696
+ assertErrorThrown(error);
2697
+ // pair with `INITIALIZE_QUERY_STATE__SUCCESS` below — this is the tight
2698
+ // boundary that success wraps, so failure is reported here rather than
2699
+ // in the outer catch (which owns `VIEW_QUERY__FAILURE`)
2700
+ LegendQueryTelemetryHelper.logEvent_InitializeQueryStateFailed(
2701
+ this.applicationStore.telemetryService,
2702
+ {
2703
+ queryId: this.queryId,
2704
+ ...buildQueryIdentity(query),
2705
+ ...buildTelemetryErrorFields(error),
2706
+ },
2707
+ );
2708
+ throw error;
2709
+ }
2524
2710
  initailizeQueryStateReport.timings =
2525
2711
  this.applicationStore.timeService.finalizeTimingsRecord(
2526
2712
  initailizeQueryStateStopWatch,
@@ -2537,26 +2723,14 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2537
2723
  this.applicationStore.telemetryService,
2538
2724
  {
2539
2725
  ...initailizeQueryStateReport,
2540
- query: {
2541
- id: query.id,
2542
- name: query.name,
2543
- groupId: query.groupId,
2544
- artifactId: query.artifactId,
2545
- versionId: query.versionId,
2546
- },
2726
+ ...buildQueryIdentity(query),
2547
2727
  },
2548
2728
  );
2549
2729
  LegendQueryTelemetryHelper.logEvent_ViewQuerySucceeded(
2550
2730
  this.applicationStore.telemetryService,
2551
2731
  {
2552
2732
  ...report,
2553
- query: {
2554
- id: query.id,
2555
- name: query.name,
2556
- groupId: query.groupId,
2557
- artifactId: query.artifactId,
2558
- versionId: query.versionId,
2559
- },
2733
+ ...buildQueryIdentity(query),
2560
2734
  },
2561
2735
  );
2562
2736
  return queryBuilderState;
@@ -25,8 +25,9 @@ import type { LegendQueryApplicationStore } from './LegendQueryBaseStore.js';
25
25
  import { EXTERNAL_APPLICATION_NAVIGATION__generateStudioProductionizeQueryUrl } from '../__lib__/LegendQueryNavigation.js';
26
26
  import { BaseQuerySetupStore } from './QuerySetupStore.js';
27
27
  import { LegendQueryUserDataHelper } from '../__lib__/LegendQueryUserDataHelper.js';
28
- import { quantifyList } from '@finos/legend-shared';
28
+ import { buildQueryLoaderLifecycleTelemetryHandlers } from '../__lib__/LegendQueryLifecycleTelemetry.js';
29
29
  import { LegendQueryTelemetryHelper } from '../__lib__/LegendQueryTelemetryHelper.js';
30
+ import { quantifyList } from '@finos/legend-shared';
30
31
 
31
32
  export class QueryProductionizerSetupStore extends BaseQuerySetupStore {
32
33
  readonly queryLoaderState: QueryLoaderState;
@@ -61,25 +62,13 @@ export class QueryProductionizerSetupStore extends BaseQuerySetupStore {
61
62
  'recently viewed queries',
62
63
  )}`
63
64
  : `No recently viewed queries`,
64
- onQueryDeleted: (queryId): void =>
65
- LegendQueryUserDataHelper.removeRecentlyViewedQuery(
66
- this.applicationStore.userDataService,
67
- queryId,
68
- ),
69
- onQueryRenamed: (query): void => {
70
- LegendQueryTelemetryHelper.logEvent_RenameQuerySucceeded(
71
- applicationStore.telemetryService,
72
- {
73
- query: {
74
- id: query.id,
75
- name: query.name,
76
- groupId: query.groupId,
77
- artifactId: query.artifactId,
78
- versionId: query.versionId,
79
- },
80
- },
81
- );
82
- },
65
+ ...buildQueryLoaderLifecycleTelemetryHandlers(this.applicationStore, {
66
+ onQueryDeleted: (queryId): void =>
67
+ LegendQueryUserDataHelper.removeRecentlyViewedQuery(
68
+ this.applicationStore.userDataService,
69
+ queryId,
70
+ ),
71
+ }),
83
72
  handleFetchDefaultQueriesFailure: (): void =>
84
73
  LegendQueryUserDataHelper.removeRecentlyViewedQueries(
85
74
  this.applicationStore.userDataService,
@@ -108,6 +97,21 @@ export class QueryProductionizerSetupStore extends BaseQuerySetupStore {
108
97
  prompt: 'Please do not close the application',
109
98
  showLoading: true,
110
99
  });
100
+ // emitted at the actual handoff to studio — the setup landing action
101
+ // that lands us on this route is upstream and may be abandoned before
102
+ // the user picks a query, so emitting here counts real launches only
103
+ LegendQueryTelemetryHelper.logEvent_ProductionizeQueryLaunched(
104
+ this.applicationStore.telemetryService,
105
+ {
106
+ query: {
107
+ id: selectedQuery.id,
108
+ name: selectedQuery.name,
109
+ groupId: selectedQuery.groupId,
110
+ artifactId: selectedQuery.artifactId,
111
+ versionId: selectedQuery.versionId,
112
+ },
113
+ },
114
+ );
111
115
  this.applicationStore.navigationService.navigator.goToAddress(
112
116
  EXTERNAL_APPLICATION_NAVIGATION__generateStudioProductionizeQueryUrl(
113
117
  matchingSDLCEntry.url,
@@ -80,7 +80,10 @@ export abstract class BaseQuerySetupStore {
80
80
  clientConfig: {
81
81
  baseUrl: this.applicationStore.config.engineServerUrl,
82
82
  queryBaseUrl: this.applicationStore.config.engineQueryServerUrl,
83
+ queryClientName: this.applicationStore.config.engineQueryClientName,
83
84
  enableCompression: true,
85
+ useCookieAuthOnly:
86
+ this.applicationStore.config.engineUseCookieAuthOnly,
84
87
  },
85
88
  },
86
89
  {
@@ -30,9 +30,6 @@ const TEST_DATA__appConfig = {
30
30
  url: 'https://testStudioUrl',
31
31
  instances: [],
32
32
  },
33
- taxonomy: {
34
- url: 'https://testTaxonomyUrl',
35
- },
36
33
  };
37
34
 
38
35
  export const TEST__getTestLegendQueryApplicationConfig = (
@@ -71,6 +71,7 @@ export class ExistingQueryDataCubeEditorStore {
71
71
  clientConfig: {
72
72
  baseUrl: this.applicationStore.config.engineServerUrl,
73
73
  queryBaseUrl: this.applicationStore.config.engineQueryServerUrl,
74
+ queryClientName: this.applicationStore.config.engineQueryClientName,
74
75
  enableCompression: true,
75
76
  },
76
77
  },