@backstage-community/plugin-copilot-backend 0.5.0 → 0.6.0

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.
@@ -26,32 +26,95 @@ async function discoverEnterpriseTeamMetrics({
26
26
  logger.info(
27
27
  `[discoverEnterpriseTeamMetrics] Fetching metrics for team: ${team.slug}`
28
28
  );
29
- const metrics = await api.fetchEnterpriseTeamCopilotUsage(team.slug);
30
- logger.info(
31
- `[discoverEnterpriseTeamMetrics] Fetched ${metrics.length} metrics for team: ${team.slug}`
29
+ const copilotMetrics = await api.fetchEnterpriseTeamCopilotMetrics(
30
+ team.slug
32
31
  );
33
- const lastDay = await db.getMostRecentDayFromMetrics(type, team.slug);
32
+ const lastDay = await db.getMostRecentDayFromMetricsV2(type, team.slug);
34
33
  logger.info(
35
- `[discoverEnterpriseTeamMetrics] Found last processed day for team ${team.slug}: ${lastDay}`
34
+ `[discoverEnterpriseTeamMetrics] Found last day: ${lastDay}`
35
+ );
36
+ const newMetrics = metricHelpers.filterNewMetricsV2(
37
+ copilotMetrics,
38
+ lastDay
36
39
  );
37
- const newMetrics = metricHelpers.filterNewMetrics(metrics, lastDay);
38
40
  logger.info(
39
- `[discoverEnterpriseTeamMetrics] Found ${newMetrics.length} new metrics for team ${team.slug} to insert`
41
+ `[discoverEnterpriseTeamMetrics] Found ${newMetrics.length} new metrics to insert for team: ${team.slug}`
40
42
  );
41
43
  if (newMetrics.length > 0) {
44
+ const coPilotMetrics = metricHelpers.filterBaseMetrics(newMetrics, type, team.slug);
45
+ const ideCompletionsToInsert = metricHelpers.filterIdeCompletionMetrics(
46
+ newMetrics,
47
+ type,
48
+ team.slug
49
+ );
50
+ const ideCompletionsLanguagesToInsert = metricHelpers.filterIdeCompletionLanguageMetrics(newMetrics, type, team.slug);
51
+ const ideCompletionsEditorsToInsert = metricHelpers.filterIdeCompletionEditorMetrics(newMetrics, type, team.slug);
52
+ const ideCompletionsEditorModelsToInsert = metricHelpers.filterIdeCompletionEditorModelMetrics(newMetrics, type, team.slug);
53
+ const ideCompletionsEditorModelLanguagesToInsert = metricHelpers.filterIdeCompletionEditorModelLanguageMetrics(
54
+ newMetrics,
55
+ type,
56
+ team.slug
57
+ );
58
+ const ideChats = metricHelpers.filterIdeChatMetrics(newMetrics, type, team.slug);
59
+ const ideChatEditors = metricHelpers.filterIdeEditorMetrics(
60
+ newMetrics,
61
+ type,
62
+ team.slug
63
+ );
64
+ const ideChatEditorModels = metricHelpers.filterIdeChatEditorModelMetrics(
65
+ newMetrics,
66
+ type,
67
+ team.slug
68
+ );
69
+ await batchInsert.batchInsertInChunks(coPilotMetrics, 30, async (chunk) => {
70
+ await db.batchInsertMetrics(chunk);
71
+ });
72
+ await batchInsert.batchInsertInChunks(ideCompletionsToInsert, 30, async (chunk) => {
73
+ await db.batchInsertIdeCompletions(chunk);
74
+ });
75
+ await batchInsert.batchInsertInChunks(
76
+ ideCompletionsLanguagesToInsert,
77
+ 30,
78
+ async (chunk) => {
79
+ await db.batchInsertIdeCompletionsLanguages(chunk);
80
+ }
81
+ );
82
+ await batchInsert.batchInsertInChunks(
83
+ ideCompletionsEditorsToInsert,
84
+ 30,
85
+ async (chunk) => {
86
+ await db.batchInsertIdeCompletionsEditors(chunk);
87
+ }
88
+ );
89
+ await batchInsert.batchInsertInChunks(
90
+ ideCompletionsEditorModelsToInsert,
91
+ 30,
92
+ async (chunk) => {
93
+ await db.batchInsertIdeCompletionsEditorModels(chunk);
94
+ }
95
+ );
42
96
  await batchInsert.batchInsertInChunks(
43
- metricHelpers.prepareMetricsForInsert(newMetrics, type, team.slug),
97
+ ideCompletionsEditorModelLanguagesToInsert,
44
98
  30,
45
99
  async (chunk) => {
46
- await db.batchInsert(chunk);
100
+ await db.batchInsertIdeCompletionsEditorModelLanguages(chunk);
47
101
  }
48
102
  );
103
+ await batchInsert.batchInsertInChunks(ideChats, 30, async (chunk) => {
104
+ await db.batchInsertIdeChats(chunk);
105
+ });
106
+ await batchInsert.batchInsertInChunks(ideChatEditors, 30, async (chunk) => {
107
+ await db.batchInsertIdeChatEditors(chunk);
108
+ });
109
+ await batchInsert.batchInsertInChunks(ideChatEditorModels, 30, async (chunk) => {
110
+ await db.batchInsertIdeChatEditorModels(chunk);
111
+ });
49
112
  logger.info(
50
- `[discoverEnterpriseTeamMetrics] Successfully inserted new metrics for team ${team.slug} into the database`
113
+ `[discoverEnterpriseTeamMetrics] Inserted new metrics into the database for team: ${team.slug}`
51
114
  );
52
115
  } else {
53
116
  logger.info(
54
- `[discoverEnterpriseTeamMetrics] No new metrics found for team ${team.slug} to insert`
117
+ `[discoverEnterpriseTeamMetrics] No new metrics found to insert for team: ${team.slug}`
55
118
  );
56
119
  }
57
120
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"EnterpriseTeamTask.cjs.js","sources":["../../src/task/EnterpriseTeamTask.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverEnterpriseTeamMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.enterprise')) {\n logger.info(\n '[discoverEnterpriseTeamMetrics] Skipping: Enterprise configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'enterprise';\n\n try {\n const teams = await api.fetchEnterpriseTeams();\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetched ${teams.length} teams`,\n );\n\n for (const team of teams) {\n try {\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetching metrics for team: ${team.slug}`,\n );\n\n const metrics = await api.fetchEnterpriseTeamCopilotUsage(team.slug);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetched ${metrics.length} metrics for team: ${team.slug}`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type, team.slug);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Found last processed day for team ${team.slug}: ${lastDay}`,\n );\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Found ${newMetrics.length} new metrics for team ${team.slug} to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type, team.slug),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n `[discoverEnterpriseTeamMetrics] Successfully inserted new metrics for team ${team.slug} into the database`,\n );\n } else {\n logger.info(\n `[discoverEnterpriseTeamMetrics] No new metrics found for team ${team.slug} to insert`,\n );\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseTeamMetrics] Error processing metrics for team ${team.slug}: ${error}`,\n );\n }\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseTeamMetrics] Error fetching teams: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAwBA,eAAsB,6BAA8B,CAAA;AAAA,EAClD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,oBAAoB,CAAG,EAAA;AACnD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL;AAAA,KACF;AACA,IAAA;AAAA;AAGF,EAAA,MAAM,IAAoB,GAAA,YAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,KAAA,GAAQ,MAAM,GAAA,CAAI,oBAAqB,EAAA;AAC7C,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,wCAAA,EAA2C,MAAM,MAAM,CAAA,MAAA;AAAA,KACzD;AAEA,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,MAAI,IAAA;AACF,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAA,2DAAA,EAA8D,KAAK,IAAI,CAAA;AAAA,SACzE;AAEA,QAAA,MAAM,OAAU,GAAA,MAAM,GAAI,CAAA,+BAAA,CAAgC,KAAK,IAAI,CAAA;AACnE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA2C,wCAAA,EAAA,OAAA,CAAQ,MAAM,CAAA,mBAAA,EAAsB,KAAK,IAAI,CAAA;AAAA,SAC1F;AAEA,QAAA,MAAM,UAAU,MAAM,EAAA,CAAG,2BAA4B,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA;AACpE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAqE,kEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,OAAO,CAAA;AAAA,SAC5F;AAEA,QAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA;AACpD,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAyC,sCAAA,EAAA,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,KAAK,IAAI,CAAA,UAAA;AAAA,SAC9F;AAEA,QAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,UAAM,MAAAC,+BAAA;AAAA,YACJC,qCAAwB,CAAA,UAAA,EAAY,IAAM,EAAA,IAAA,CAAK,IAAI,CAAA;AAAA,YACnD,EAAA;AAAA,YACA,OAAO,KAAyB,KAAA;AAC9B,cAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA;AAAA;AAC5B,WACF;AACA,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,2EAAA,EAA8E,KAAK,IAAI,CAAA,kBAAA;AAAA,WACzF;AAAA,SACK,MAAA;AACL,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,8DAAA,EAAiE,KAAK,IAAI,CAAA,UAAA;AAAA,WAC5E;AAAA;AACF,eACO,KAAO,EAAA;AACd,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,CAAqE,kEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,SAC1F;AAAA;AACF;AACF,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,yDAAyD,KAAK,CAAA;AAAA,KAChE;AACA,IAAM,MAAA,KAAA;AAAA;AAEV;;;;"}
1
+ {"version":3,"file":"EnterpriseTeamTask.cjs.js","sources":["../../src/task/EnterpriseTeamTask.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n CopilotMetrics,\n MetricsType,\n} from '@backstage-community/plugin-copilot-common';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterBaseMetrics,\n filterIdeChatEditorModelMetrics,\n filterIdeChatMetrics,\n filterIdeCompletionEditorMetrics,\n filterIdeCompletionEditorModelLanguageMetrics,\n filterIdeCompletionEditorModelMetrics,\n filterIdeCompletionLanguageMetrics,\n filterIdeCompletionMetrics,\n filterIdeEditorMetrics,\n filterNewMetricsV2,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverEnterpriseTeamMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.enterprise')) {\n logger.info(\n '[discoverEnterpriseTeamMetrics] Skipping: Enterprise configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'enterprise';\n\n try {\n const teams = await api.fetchEnterpriseTeams();\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetched ${teams.length} teams`,\n );\n\n for (const team of teams) {\n try {\n logger.info(\n `[discoverEnterpriseTeamMetrics] Fetching metrics for team: ${team.slug}`,\n );\n\n const copilotMetrics = await api.fetchEnterpriseTeamCopilotMetrics(\n team.slug,\n );\n\n const lastDay = await db.getMostRecentDayFromMetricsV2(type, team.slug);\n logger.info(\n `[discoverEnterpriseTeamMetrics] Found last day: ${lastDay}`,\n );\n\n const newMetrics: CopilotMetrics[] = filterNewMetricsV2(\n copilotMetrics,\n lastDay,\n );\n logger.info(\n `[discoverEnterpriseTeamMetrics] Found ${newMetrics.length} new metrics to insert for team: ${team.slug}`,\n );\n\n if (newMetrics.length > 0) {\n const coPilotMetrics = filterBaseMetrics(newMetrics, type, team.slug);\n const ideCompletionsToInsert = filterIdeCompletionMetrics(\n newMetrics,\n type,\n team.slug,\n );\n const ideCompletionsLanguagesToInsert =\n filterIdeCompletionLanguageMetrics(newMetrics, type, team.slug);\n const ideCompletionsEditorsToInsert =\n filterIdeCompletionEditorMetrics(newMetrics, type, team.slug);\n const ideCompletionsEditorModelsToInsert =\n filterIdeCompletionEditorModelMetrics(newMetrics, type, team.slug);\n const ideCompletionsEditorModelLanguagesToInsert =\n filterIdeCompletionEditorModelLanguageMetrics(\n newMetrics,\n type,\n team.slug,\n );\n const ideChats = filterIdeChatMetrics(newMetrics, type, team.slug);\n const ideChatEditors = filterIdeEditorMetrics(\n newMetrics,\n type,\n team.slug,\n );\n const ideChatEditorModels = filterIdeChatEditorModelMetrics(\n newMetrics,\n type,\n team.slug,\n );\n\n await batchInsertInChunks(coPilotMetrics, 30, async chunk => {\n await db.batchInsertMetrics(chunk);\n });\n\n await batchInsertInChunks(ideCompletionsToInsert, 30, async chunk => {\n await db.batchInsertIdeCompletions(chunk);\n });\n\n await batchInsertInChunks(\n ideCompletionsLanguagesToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsLanguages(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorsToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditors(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorModelsToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditorModels(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorModelLanguagesToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditorModelLanguages(chunk);\n },\n );\n\n await batchInsertInChunks(ideChats, 30, async chunk => {\n await db.batchInsertIdeChats(chunk);\n });\n\n await batchInsertInChunks(ideChatEditors, 30, async chunk => {\n await db.batchInsertIdeChatEditors(chunk);\n });\n\n await batchInsertInChunks(ideChatEditorModels, 30, async chunk => {\n await db.batchInsertIdeChatEditorModels(chunk);\n });\n\n logger.info(\n `[discoverEnterpriseTeamMetrics] Inserted new metrics into the database for team: ${team.slug}`,\n );\n } else {\n logger.info(\n `[discoverEnterpriseTeamMetrics] No new metrics found to insert for team: ${team.slug}`,\n );\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseTeamMetrics] Error processing metrics for team ${team.slug}: ${error}`,\n );\n }\n }\n } catch (error) {\n logger.error(\n `[discoverEnterpriseTeamMetrics] Error fetching teams: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetricsV2","filterBaseMetrics","filterIdeCompletionMetrics","filterIdeCompletionLanguageMetrics","filterIdeCompletionEditorMetrics","filterIdeCompletionEditorModelMetrics","filterIdeCompletionEditorModelLanguageMetrics","filterIdeChatMetrics","filterIdeEditorMetrics","filterIdeChatEditorModelMetrics","batchInsertInChunks"],"mappings":"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"}
@@ -17,24 +17,81 @@ async function discoverOrganizationMetrics({
17
17
  }
18
18
  const type = "organization";
19
19
  try {
20
- const metrics = await api.fetchOrganizationCopilotUsage();
20
+ const copilotMetrics = await api.fetchOrganizationCopilotMetrics();
21
21
  logger.info(
22
- `[discoverOrganizationMetrics] Fetched ${metrics.length} metrics`
22
+ `[discoverOrganizationMetrics] Fetched ${copilotMetrics.length} metrics`
23
23
  );
24
- const lastDay = await db.getMostRecentDayFromMetrics(type);
24
+ const lastDay = await db.getMostRecentDayFromMetricsV2(type);
25
25
  logger.info(`[discoverOrganizationMetrics] Found last day: ${lastDay}`);
26
- const newMetrics = metricHelpers.filterNewMetrics(metrics, lastDay);
26
+ const newMetrics = metricHelpers.filterNewMetricsV2(
27
+ copilotMetrics,
28
+ lastDay
29
+ );
27
30
  logger.info(
28
31
  `[discoverOrganizationMetrics] Found ${newMetrics.length} new metrics to insert`
29
32
  );
30
33
  if (newMetrics.length > 0) {
34
+ const coPilotMetrics = metricHelpers.filterBaseMetrics(newMetrics, type);
35
+ const ideCompletionsToInsert = metricHelpers.filterIdeCompletionMetrics(
36
+ newMetrics,
37
+ type
38
+ );
39
+ const ideCompletionsLanguagesToInsert = metricHelpers.filterIdeCompletionLanguageMetrics(newMetrics, type);
40
+ const ideCompletionsEditorsToInsert = metricHelpers.filterIdeCompletionEditorMetrics(
41
+ newMetrics,
42
+ type
43
+ );
44
+ const ideCompletionsEditorModelsToInsert = metricHelpers.filterIdeCompletionEditorModelMetrics(newMetrics, type);
45
+ const ideCompletionsEditorModelLanguagesToInsert = metricHelpers.filterIdeCompletionEditorModelLanguageMetrics(newMetrics, type);
46
+ const ideChats = metricHelpers.filterIdeChatMetrics(newMetrics, type);
47
+ const ideChatEditors = metricHelpers.filterIdeEditorMetrics(newMetrics, type);
48
+ const ideChatEditorModels = metricHelpers.filterIdeChatEditorModelMetrics(
49
+ newMetrics,
50
+ type
51
+ );
52
+ await batchInsert.batchInsertInChunks(coPilotMetrics, 30, async (chunk) => {
53
+ await db.batchInsertMetrics(chunk);
54
+ });
55
+ await batchInsert.batchInsertInChunks(ideCompletionsToInsert, 30, async (chunk) => {
56
+ await db.batchInsertIdeCompletions(chunk);
57
+ });
58
+ await batchInsert.batchInsertInChunks(
59
+ ideCompletionsLanguagesToInsert,
60
+ 30,
61
+ async (chunk) => {
62
+ await db.batchInsertIdeCompletionsLanguages(chunk);
63
+ }
64
+ );
65
+ await batchInsert.batchInsertInChunks(
66
+ ideCompletionsEditorsToInsert,
67
+ 30,
68
+ async (chunk) => {
69
+ await db.batchInsertIdeCompletionsEditors(chunk);
70
+ }
71
+ );
72
+ await batchInsert.batchInsertInChunks(
73
+ ideCompletionsEditorModelsToInsert,
74
+ 30,
75
+ async (chunk) => {
76
+ await db.batchInsertIdeCompletionsEditorModels(chunk);
77
+ }
78
+ );
31
79
  await batchInsert.batchInsertInChunks(
32
- metricHelpers.prepareMetricsForInsert(newMetrics, type),
80
+ ideCompletionsEditorModelLanguagesToInsert,
33
81
  30,
34
82
  async (chunk) => {
35
- await db.batchInsert(chunk);
83
+ await db.batchInsertIdeCompletionsEditorModelLanguages(chunk);
36
84
  }
37
85
  );
86
+ await batchInsert.batchInsertInChunks(ideChats, 30, async (chunk) => {
87
+ await db.batchInsertIdeChats(chunk);
88
+ });
89
+ await batchInsert.batchInsertInChunks(ideChatEditors, 30, async (chunk) => {
90
+ await db.batchInsertIdeChatEditors(chunk);
91
+ });
92
+ await batchInsert.batchInsertInChunks(ideChatEditorModels, 30, async (chunk) => {
93
+ await db.batchInsertIdeChatEditorModels(chunk);
94
+ });
38
95
  logger.info(
39
96
  "[discoverOrganizationMetrics] Inserted new metrics into the database"
40
97
  );
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationTask.cjs.js","sources":["../../src/task/OrganizationTask.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverOrganizationMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.organization')) {\n logger.info(\n '[discoverOrganizationMetrics] Skipping: Organization configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'organization';\n\n try {\n const metrics = await api.fetchOrganizationCopilotUsage();\n logger.info(\n `[discoverOrganizationMetrics] Fetched ${metrics.length} metrics`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type);\n logger.info(`[discoverOrganizationMetrics] Found last day: ${lastDay}`);\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverOrganizationMetrics] Found ${newMetrics.length} new metrics to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n '[discoverOrganizationMetrics] Inserted new metrics into the database',\n );\n } else {\n logger.info(\n '[discoverOrganizationMetrics] No new metrics found to insert',\n );\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationMetrics] An error occurred while processing Github Copilot metrics: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAwBA,eAAsB,2BAA4B,CAAA;AAAA,EAChD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,sBAAsB,CAAG,EAAA;AACrD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL;AAAA,KACF;AACA,IAAA;AAAA;AAGF,EAAA,MAAM,IAAoB,GAAA,cAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,OAAA,GAAU,MAAM,GAAA,CAAI,6BAA8B,EAAA;AACxD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,sCAAA,EAAyC,QAAQ,MAAM,CAAA,QAAA;AAAA,KACzD;AAEA,IAAA,MAAM,OAAU,GAAA,MAAM,EAAG,CAAA,2BAAA,CAA4B,IAAI,CAAA;AACzD,IAAO,MAAA,CAAA,IAAA,CAAK,CAAiD,8CAAA,EAAA,OAAO,CAAE,CAAA,CAAA;AAEtE,IAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA;AACpD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,oCAAA,EAAuC,WAAW,MAAM,CAAA,sBAAA;AAAA,KAC1D;AAEA,IAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,MAAM,MAAAC,+BAAA;AAAA,QACJC,qCAAA,CAAwB,YAAY,IAAI,CAAA;AAAA,QACxC,EAAA;AAAA,QACA,OAAO,KAAyB,KAAA;AAC9B,UAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA;AAAA;AAC5B,OACF;AACA,MAAO,MAAA,CAAA,IAAA;AAAA,QACL;AAAA,OACF;AAAA,KACK,MAAA;AACL,MAAO,MAAA,CAAA,IAAA;AAAA,QACL;AAAA,OACF;AAAA;AACF,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,4FAA4F,KAAK,CAAA;AAAA,KACnG;AACA,IAAM,MAAA,KAAA;AAAA;AAEV;;;;"}
1
+ {"version":3,"file":"OrganizationTask.cjs.js","sources":["../../src/task/OrganizationTask.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n MetricsType,\n CopilotMetrics,\n} from '@backstage-community/plugin-copilot-common';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterBaseMetrics,\n filterNewMetricsV2,\n filterIdeCompletionMetrics,\n filterIdeCompletionLanguageMetrics,\n filterIdeCompletionEditorMetrics,\n filterIdeCompletionEditorModelMetrics,\n filterIdeCompletionEditorModelLanguageMetrics,\n filterIdeChatMetrics,\n filterIdeEditorMetrics,\n filterIdeChatEditorModelMetrics,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverOrganizationMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.organization')) {\n logger.info(\n '[discoverOrganizationMetrics] Skipping: Organization configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'organization';\n\n try {\n const copilotMetrics = await api.fetchOrganizationCopilotMetrics();\n logger.info(\n `[discoverOrganizationMetrics] Fetched ${copilotMetrics.length} metrics`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetricsV2(type);\n logger.info(`[discoverOrganizationMetrics] Found last day: ${lastDay}`);\n\n const newMetrics: CopilotMetrics[] = filterNewMetricsV2(\n copilotMetrics,\n lastDay,\n );\n logger.info(\n `[discoverOrganizationMetrics] Found ${newMetrics.length} new metrics to insert`,\n );\n\n if (newMetrics.length > 0) {\n const coPilotMetrics = filterBaseMetrics(newMetrics, type);\n const ideCompletionsToInsert = filterIdeCompletionMetrics(\n newMetrics,\n type,\n );\n const ideCompletionsLanguagesToInsert =\n filterIdeCompletionLanguageMetrics(newMetrics, type);\n const ideCompletionsEditorsToInsert = filterIdeCompletionEditorMetrics(\n newMetrics,\n type,\n );\n const ideCompletionsEditorModelsToInsert =\n filterIdeCompletionEditorModelMetrics(newMetrics, type);\n const ideCompletionsEditorModelLanguagesToInsert =\n filterIdeCompletionEditorModelLanguageMetrics(newMetrics, type);\n const ideChats = filterIdeChatMetrics(newMetrics, type);\n const ideChatEditors = filterIdeEditorMetrics(newMetrics, type);\n const ideChatEditorModels = filterIdeChatEditorModelMetrics(\n newMetrics,\n type,\n );\n\n await batchInsertInChunks(coPilotMetrics, 30, async chunk => {\n await db.batchInsertMetrics(chunk);\n });\n\n await batchInsertInChunks(ideCompletionsToInsert, 30, async chunk => {\n await db.batchInsertIdeCompletions(chunk);\n });\n\n await batchInsertInChunks(\n ideCompletionsLanguagesToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsLanguages(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorsToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditors(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorModelsToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditorModels(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorModelLanguagesToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditorModelLanguages(chunk);\n },\n );\n\n await batchInsertInChunks(ideChats, 30, async chunk => {\n await db.batchInsertIdeChats(chunk);\n });\n\n await batchInsertInChunks(ideChatEditors, 30, async chunk => {\n await db.batchInsertIdeChatEditors(chunk);\n });\n\n await batchInsertInChunks(ideChatEditorModels, 30, async chunk => {\n await db.batchInsertIdeChatEditorModels(chunk);\n });\n\n logger.info(\n '[discoverOrganizationMetrics] Inserted new metrics into the database',\n );\n } else {\n logger.info(\n '[discoverOrganizationMetrics] No new metrics found to insert',\n );\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationMetrics] An error occurred while processing Github Copilot metrics: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetricsV2","filterBaseMetrics","filterIdeCompletionMetrics","filterIdeCompletionLanguageMetrics","filterIdeCompletionEditorMetrics","filterIdeCompletionEditorModelMetrics","filterIdeCompletionEditorModelLanguageMetrics","filterIdeChatMetrics","filterIdeEditorMetrics","filterIdeChatEditorModelMetrics","batchInsertInChunks"],"mappings":"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"}
@@ -26,32 +26,95 @@ async function discoverOrganizationTeamMetrics({
26
26
  logger.info(
27
27
  `[discoverOrganizationTeamMetrics] Fetching metrics for team: ${team.slug}`
28
28
  );
29
- const metrics = await api.fetchOrganizationTeamCopilotUsage(team.slug);
30
- logger.info(
31
- `[discoverOrganizationTeamMetrics] Fetched ${metrics.length} metrics for team: ${team.slug}`
29
+ const copilotMetrics = await api.fetchOrganizationTeamCopilotMetrics(
30
+ team.slug
32
31
  );
33
- const lastDay = await db.getMostRecentDayFromMetrics(type, team.slug);
32
+ const lastDay = await db.getMostRecentDayFromMetricsV2(type, team.slug);
34
33
  logger.info(
35
- `[discoverOrganizationTeamMetrics] Found last processed day for team ${team.slug}: ${lastDay}`
34
+ `[discoverOrganizationTeamMetrics] Found last day: ${lastDay}`
35
+ );
36
+ const newMetrics = metricHelpers.filterNewMetricsV2(
37
+ copilotMetrics,
38
+ lastDay
36
39
  );
37
- const newMetrics = metricHelpers.filterNewMetrics(metrics, lastDay);
38
40
  logger.info(
39
- `[discoverOrganizationTeamMetrics] Found ${newMetrics.length} new metrics for team ${team.slug} to insert`
41
+ `[discoverOrganizationTeamMetrics] Found ${newMetrics.length} new metrics to insert for team: ${team.slug}`
40
42
  );
41
43
  if (newMetrics.length > 0) {
44
+ const coPilotMetrics = metricHelpers.filterBaseMetrics(newMetrics, type, team.slug);
45
+ const ideCompletionsToInsert = metricHelpers.filterIdeCompletionMetrics(
46
+ newMetrics,
47
+ type,
48
+ team.slug
49
+ );
50
+ const ideCompletionsLanguagesToInsert = metricHelpers.filterIdeCompletionLanguageMetrics(newMetrics, type, team.slug);
51
+ const ideCompletionsEditorsToInsert = metricHelpers.filterIdeCompletionEditorMetrics(newMetrics, type, team.slug);
52
+ const ideCompletionsEditorModelsToInsert = metricHelpers.filterIdeCompletionEditorModelMetrics(newMetrics, type, team.slug);
53
+ const ideCompletionsEditorModelLanguagesToInsert = metricHelpers.filterIdeCompletionEditorModelLanguageMetrics(
54
+ newMetrics,
55
+ type,
56
+ team.slug
57
+ );
58
+ const ideChats = metricHelpers.filterIdeChatMetrics(newMetrics, type, team.slug);
59
+ const ideChatEditors = metricHelpers.filterIdeEditorMetrics(
60
+ newMetrics,
61
+ type,
62
+ team.slug
63
+ );
64
+ const ideChatEditorModels = metricHelpers.filterIdeChatEditorModelMetrics(
65
+ newMetrics,
66
+ type,
67
+ team.slug
68
+ );
69
+ await batchInsert.batchInsertInChunks(coPilotMetrics, 30, async (chunk) => {
70
+ await db.batchInsertMetrics(chunk);
71
+ });
72
+ await batchInsert.batchInsertInChunks(ideCompletionsToInsert, 30, async (chunk) => {
73
+ await db.batchInsertIdeCompletions(chunk);
74
+ });
75
+ await batchInsert.batchInsertInChunks(
76
+ ideCompletionsLanguagesToInsert,
77
+ 30,
78
+ async (chunk) => {
79
+ await db.batchInsertIdeCompletionsLanguages(chunk);
80
+ }
81
+ );
82
+ await batchInsert.batchInsertInChunks(
83
+ ideCompletionsEditorsToInsert,
84
+ 30,
85
+ async (chunk) => {
86
+ await db.batchInsertIdeCompletionsEditors(chunk);
87
+ }
88
+ );
89
+ await batchInsert.batchInsertInChunks(
90
+ ideCompletionsEditorModelsToInsert,
91
+ 30,
92
+ async (chunk) => {
93
+ await db.batchInsertIdeCompletionsEditorModels(chunk);
94
+ }
95
+ );
42
96
  await batchInsert.batchInsertInChunks(
43
- metricHelpers.prepareMetricsForInsert(newMetrics, type, team.slug),
97
+ ideCompletionsEditorModelLanguagesToInsert,
44
98
  30,
45
99
  async (chunk) => {
46
- await db.batchInsert(chunk);
100
+ await db.batchInsertIdeCompletionsEditorModelLanguages(chunk);
47
101
  }
48
102
  );
103
+ await batchInsert.batchInsertInChunks(ideChats, 30, async (chunk) => {
104
+ await db.batchInsertIdeChats(chunk);
105
+ });
106
+ await batchInsert.batchInsertInChunks(ideChatEditors, 30, async (chunk) => {
107
+ await db.batchInsertIdeChatEditors(chunk);
108
+ });
109
+ await batchInsert.batchInsertInChunks(ideChatEditorModels, 30, async (chunk) => {
110
+ await db.batchInsertIdeChatEditorModels(chunk);
111
+ });
49
112
  logger.info(
50
- `[discoverOrganizationTeamMetrics] Successfully inserted new metrics for team ${team.slug} into the database`
113
+ `[discoverOrganizationTeamMetrics] Inserted new metrics into the database for team: ${team.slug}`
51
114
  );
52
115
  } else {
53
116
  logger.info(
54
- `[discoverOrganizationTeamMetrics] No new metrics found for team ${team.slug} to insert`
117
+ `[discoverOrganizationTeamMetrics] No new metrics found to insert for team: ${team.slug}`
55
118
  );
56
119
  }
57
120
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationTeamTask.cjs.js","sources":["../../src/task/OrganizationTeamTask.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MetricsType } from '@backstage-community/plugin-copilot-common';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterNewMetrics,\n prepareMetricsForInsert,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverOrganizationTeamMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.organization')) {\n logger.info(\n '[discoverOrganizationTeamMetrics] Skipping: Organization configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'organization';\n\n try {\n const teams = await api.fetchOrganizationTeams();\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetched ${teams.length} teams`,\n );\n\n for (const team of teams) {\n try {\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetching metrics for team: ${team.slug}`,\n );\n\n const metrics = await api.fetchOrganizationTeamCopilotUsage(team.slug);\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetched ${metrics.length} metrics for team: ${team.slug}`,\n );\n\n const lastDay = await db.getMostRecentDayFromMetrics(type, team.slug);\n logger.info(\n `[discoverOrganizationTeamMetrics] Found last processed day for team ${team.slug}: ${lastDay}`,\n );\n\n const newMetrics = filterNewMetrics(metrics, lastDay);\n logger.info(\n `[discoverOrganizationTeamMetrics] Found ${newMetrics.length} new metrics for team ${team.slug} to insert`,\n );\n\n if (newMetrics.length > 0) {\n await batchInsertInChunks<MetricDbRow>(\n prepareMetricsForInsert(newMetrics, type, team.slug),\n 30,\n async (chunk: MetricDbRow[]) => {\n await db.batchInsert(chunk);\n },\n );\n logger.info(\n `[discoverOrganizationTeamMetrics] Successfully inserted new metrics for team ${team.slug} into the database`,\n );\n } else {\n logger.info(\n `[discoverOrganizationTeamMetrics] No new metrics found for team ${team.slug} to insert`,\n );\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationTeamMetrics] Error processing metrics for team ${team.slug}: ${error}`,\n );\n }\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationTeamMetrics] Error fetching teams: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetrics","batchInsertInChunks","prepareMetricsForInsert"],"mappings":";;;;;AAyBA,eAAsB,+BAAgC,CAAA;AAAA,EACpD,GAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAA;AAAA,EACA;AACF,CAA+B,EAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,iBAAkB,CAAA,sBAAsB,CAAG,EAAA;AACrD,IAAO,MAAA,CAAA,IAAA;AAAA,MACL;AAAA,KACF;AACA,IAAA;AAAA;AAGF,EAAA,MAAM,IAAoB,GAAA,cAAA;AAE1B,EAAI,IAAA;AACF,IAAM,MAAA,KAAA,GAAQ,MAAM,GAAA,CAAI,sBAAuB,EAAA;AAC/C,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,0CAAA,EAA6C,MAAM,MAAM,CAAA,MAAA;AAAA,KAC3D;AAEA,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,MAAI,IAAA;AACF,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAA,6DAAA,EAAgE,KAAK,IAAI,CAAA;AAAA,SAC3E;AAEA,QAAA,MAAM,OAAU,GAAA,MAAM,GAAI,CAAA,iCAAA,CAAkC,KAAK,IAAI,CAAA;AACrE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA6C,0CAAA,EAAA,OAAA,CAAQ,MAAM,CAAA,mBAAA,EAAsB,KAAK,IAAI,CAAA;AAAA,SAC5F;AAEA,QAAA,MAAM,UAAU,MAAM,EAAA,CAAG,2BAA4B,CAAA,IAAA,EAAM,KAAK,IAAI,CAAA;AACpE,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAAuE,oEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,OAAO,CAAA;AAAA,SAC9F;AAEA,QAAM,MAAA,UAAA,GAAaA,8BAAiB,CAAA,OAAA,EAAS,OAAO,CAAA;AACpD,QAAO,MAAA,CAAA,IAAA;AAAA,UACL,CAA2C,wCAAA,EAAA,UAAA,CAAW,MAAM,CAAA,sBAAA,EAAyB,KAAK,IAAI,CAAA,UAAA;AAAA,SAChG;AAEA,QAAI,IAAA,UAAA,CAAW,SAAS,CAAG,EAAA;AACzB,UAAM,MAAAC,+BAAA;AAAA,YACJC,qCAAwB,CAAA,UAAA,EAAY,IAAM,EAAA,IAAA,CAAK,IAAI,CAAA;AAAA,YACnD,EAAA;AAAA,YACA,OAAO,KAAyB,KAAA;AAC9B,cAAM,MAAA,EAAA,CAAG,YAAY,KAAK,CAAA;AAAA;AAC5B,WACF;AACA,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,6EAAA,EAAgF,KAAK,IAAI,CAAA,kBAAA;AAAA,WAC3F;AAAA,SACK,MAAA;AACL,UAAO,MAAA,CAAA,IAAA;AAAA,YACL,CAAA,gEAAA,EAAmE,KAAK,IAAI,CAAA,UAAA;AAAA,WAC9E;AAAA;AACF,eACO,KAAO,EAAA;AACd,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,CAAuE,oEAAA,EAAA,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,SAC5F;AAAA;AACF;AACF,WACO,KAAO,EAAA;AACd,IAAO,MAAA,CAAA,KAAA;AAAA,MACL,2DAA2D,KAAK,CAAA;AAAA,KAClE;AACA,IAAM,MAAA,KAAA;AAAA;AAEV;;;;"}
1
+ {"version":3,"file":"OrganizationTeamTask.cjs.js","sources":["../../src/task/OrganizationTeamTask.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CopilotMetrics,\n MetricsType,\n} from '@backstage-community/plugin-copilot-common';\nimport { batchInsertInChunks } from '../utils/batchInsert';\nimport {\n filterBaseMetrics,\n filterIdeChatEditorModelMetrics,\n filterIdeChatMetrics,\n filterIdeCompletionEditorMetrics,\n filterIdeCompletionEditorModelLanguageMetrics,\n filterIdeCompletionEditorModelMetrics,\n filterIdeCompletionLanguageMetrics,\n filterIdeCompletionMetrics,\n filterIdeEditorMetrics,\n filterNewMetricsV2,\n} from '../utils/metricHelpers';\nimport { TaskOptions } from './TaskManagement';\n\nexport async function discoverOrganizationTeamMetrics({\n api,\n logger,\n db,\n config,\n}: TaskOptions): Promise<void> {\n if (!config.getOptionalString('copilot.organization')) {\n logger.info(\n '[discoverOrganizationTeamMetrics] Skipping: Organization configuration not found.',\n );\n return;\n }\n\n const type: MetricsType = 'organization';\n\n try {\n const teams = await api.fetchOrganizationTeams();\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetched ${teams.length} teams`,\n );\n\n for (const team of teams) {\n try {\n logger.info(\n `[discoverOrganizationTeamMetrics] Fetching metrics for team: ${team.slug}`,\n );\n\n const copilotMetrics = await api.fetchOrganizationTeamCopilotMetrics(\n team.slug,\n );\n\n const lastDay = await db.getMostRecentDayFromMetricsV2(type, team.slug);\n logger.info(\n `[discoverOrganizationTeamMetrics] Found last day: ${lastDay}`,\n );\n\n const newMetrics: CopilotMetrics[] = filterNewMetricsV2(\n copilotMetrics,\n lastDay,\n );\n logger.info(\n `[discoverOrganizationTeamMetrics] Found ${newMetrics.length} new metrics to insert for team: ${team.slug}`,\n );\n\n if (newMetrics.length > 0) {\n const coPilotMetrics = filterBaseMetrics(newMetrics, type, team.slug);\n const ideCompletionsToInsert = filterIdeCompletionMetrics(\n newMetrics,\n type,\n team.slug,\n );\n const ideCompletionsLanguagesToInsert =\n filterIdeCompletionLanguageMetrics(newMetrics, type, team.slug);\n const ideCompletionsEditorsToInsert =\n filterIdeCompletionEditorMetrics(newMetrics, type, team.slug);\n const ideCompletionsEditorModelsToInsert =\n filterIdeCompletionEditorModelMetrics(newMetrics, type, team.slug);\n const ideCompletionsEditorModelLanguagesToInsert =\n filterIdeCompletionEditorModelLanguageMetrics(\n newMetrics,\n type,\n team.slug,\n );\n const ideChats = filterIdeChatMetrics(newMetrics, type, team.slug);\n const ideChatEditors = filterIdeEditorMetrics(\n newMetrics,\n type,\n team.slug,\n );\n const ideChatEditorModels = filterIdeChatEditorModelMetrics(\n newMetrics,\n type,\n team.slug,\n );\n\n await batchInsertInChunks(coPilotMetrics, 30, async chunk => {\n await db.batchInsertMetrics(chunk);\n });\n\n await batchInsertInChunks(ideCompletionsToInsert, 30, async chunk => {\n await db.batchInsertIdeCompletions(chunk);\n });\n\n await batchInsertInChunks(\n ideCompletionsLanguagesToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsLanguages(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorsToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditors(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorModelsToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditorModels(chunk);\n },\n );\n\n await batchInsertInChunks(\n ideCompletionsEditorModelLanguagesToInsert,\n 30,\n async chunk => {\n await db.batchInsertIdeCompletionsEditorModelLanguages(chunk);\n },\n );\n\n await batchInsertInChunks(ideChats, 30, async chunk => {\n await db.batchInsertIdeChats(chunk);\n });\n\n await batchInsertInChunks(ideChatEditors, 30, async chunk => {\n await db.batchInsertIdeChatEditors(chunk);\n });\n\n await batchInsertInChunks(ideChatEditorModels, 30, async chunk => {\n await db.batchInsertIdeChatEditorModels(chunk);\n });\n\n logger.info(\n `[discoverOrganizationTeamMetrics] Inserted new metrics into the database for team: ${team.slug}`,\n );\n } else {\n logger.info(\n `[discoverOrganizationTeamMetrics] No new metrics found to insert for team: ${team.slug}`,\n );\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationTeamMetrics] Error processing metrics for team ${team.slug}: ${error}`,\n );\n }\n }\n } catch (error) {\n logger.error(\n `[discoverOrganizationTeamMetrics] Error fetching teams: ${error}`,\n );\n throw error;\n }\n}\n"],"names":["filterNewMetricsV2","filterBaseMetrics","filterIdeCompletionMetrics","filterIdeCompletionLanguageMetrics","filterIdeCompletionEditorMetrics","filterIdeCompletionEditorModelMetrics","filterIdeCompletionEditorModelLanguageMetrics","filterIdeChatMetrics","filterIdeEditorMetrics","filterIdeChatEditorModelMetrics","batchInsertInChunks"],"mappings":"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"}
@@ -29,9 +29,15 @@ class TaskManagement {
29
29
  try {
30
30
  await task();
31
31
  } catch (e) {
32
- this.options.logger.warn(
33
- `[TaskManagement] Failed to process task: ${e.message}`
34
- );
32
+ if (e instanceof Error) {
33
+ this.options.logger.error(
34
+ `[TaskManagement] Failed to process task: ${e.message}`
35
+ );
36
+ } else {
37
+ this.options.logger.error(
38
+ `[TaskManagement] Failed to process task: ${e}`
39
+ );
40
+ }
35
41
  }
36
42
  });
37
43
  await Promise.all(taskPromises);
@@ -1 +1 @@
1
- {"version":3,"file":"TaskManagement.cjs.js","sources":["../../src/task/TaskManagement.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Config } from '@backstage/config';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { GithubClient } from '../client/GithubClient';\nimport { DatabaseHandler } from '../db/DatabaseHandler';\nimport { discoverOrganizationMetrics } from './OrganizationTask';\nimport { discoverOrganizationTeamMetrics } from './OrganizationTeamTask';\nimport { discoverEnterpriseMetrics } from './EnterpriseTask';\nimport { discoverEnterpriseTeamMetrics } from './EnterpriseTeamTask';\n\nexport type TaskOptions = {\n api: GithubClient;\n config: Config;\n logger: LoggerService;\n db: DatabaseHandler;\n};\n\nexport default class TaskManagement {\n private readonly tasks: Array<() => Promise<void>>;\n\n constructor(private readonly options: TaskOptions) {\n this.tasks = [\n () => discoverOrganizationMetrics(this.options),\n () => discoverOrganizationTeamMetrics(this.options),\n () => discoverEnterpriseMetrics(this.options),\n () => discoverEnterpriseTeamMetrics(this.options),\n ];\n }\n\n static create(options: TaskOptions) {\n return new TaskManagement(options);\n }\n\n async runAsync() {\n this.options.logger.info(\n `[TaskManagement] Starting processing of ${this.tasks.length} tasks`,\n );\n\n const taskPromises = this.tasks.map(async task => {\n try {\n await task();\n } catch (e) {\n this.options.logger.warn(\n `[TaskManagement] Failed to process task: ${e.message}`,\n );\n }\n });\n\n await Promise.all(taskPromises);\n\n this.options.logger.info(\n `[TaskManagement] Completed processing of all tasks`,\n );\n }\n}\n"],"names":["discoverOrganizationMetrics","discoverOrganizationTeamMetrics","discoverEnterpriseMetrics","discoverEnterpriseTeamMetrics"],"mappings":";;;;;;;;;AA+BA,MAAqB,cAAe,CAAA;AAAA,EAGlC,YAA6B,OAAsB,EAAA;AAAtB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAC3B,IAAA,IAAA,CAAK,KAAQ,GAAA;AAAA,MACX,MAAMA,4CAA4B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAC9C,MAAMC,oDAAgC,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAClD,MAAMC,wCAA0B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAC5C,MAAMC,gDAA8B,CAAA,IAAA,CAAK,OAAO;AAAA,KAClD;AAAA;AACF,EATiB,KAAA;AAAA,EAWjB,OAAO,OAAO,OAAsB,EAAA;AAClC,IAAO,OAAA,IAAI,eAAe,OAAO,CAAA;AAAA;AACnC,EAEA,MAAM,QAAW,GAAA;AACf,IAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,MAClB,CAAA,wCAAA,EAA2C,IAAK,CAAA,KAAA,CAAM,MAAM,CAAA,MAAA;AAAA,KAC9D;AAEA,IAAA,MAAM,YAAe,GAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,OAAM,IAAQ,KAAA;AAChD,MAAI,IAAA;AACF,QAAA,MAAM,IAAK,EAAA;AAAA,eACJ,CAAG,EAAA;AACV,QAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,UAClB,CAAA,yCAAA,EAA4C,EAAE,OAAO,CAAA;AAAA,SACvD;AAAA;AACF,KACD,CAAA;AAED,IAAM,MAAA,OAAA,CAAQ,IAAI,YAAY,CAAA;AAE9B,IAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,MAClB,CAAA,kDAAA;AAAA,KACF;AAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"TaskManagement.cjs.js","sources":["../../src/task/TaskManagement.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Config } from '@backstage/config';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { GithubClient } from '../client/GithubClient';\nimport { DatabaseHandler } from '../db/DatabaseHandler';\nimport { discoverOrganizationMetrics } from './OrganizationTask';\nimport { discoverOrganizationTeamMetrics } from './OrganizationTeamTask';\nimport { discoverEnterpriseMetrics } from './EnterpriseTask';\nimport { discoverEnterpriseTeamMetrics } from './EnterpriseTeamTask';\n\nexport type TaskOptions = {\n api: GithubClient;\n config: Config;\n logger: LoggerService;\n db: DatabaseHandler;\n};\n\nexport default class TaskManagement {\n private readonly tasks: Array<() => Promise<void>>;\n\n constructor(private readonly options: TaskOptions) {\n this.tasks = [\n () => discoverOrganizationMetrics(this.options),\n () => discoverOrganizationTeamMetrics(this.options),\n () => discoverEnterpriseMetrics(this.options),\n () => discoverEnterpriseTeamMetrics(this.options),\n ];\n }\n\n static create(options: TaskOptions) {\n return new TaskManagement(options);\n }\n\n async runAsync() {\n this.options.logger.info(\n `[TaskManagement] Starting processing of ${this.tasks.length} tasks`,\n );\n\n const taskPromises = this.tasks.map(async task => {\n try {\n await task();\n } catch (e) {\n if (e instanceof Error) {\n this.options.logger.error(\n `[TaskManagement] Failed to process task: ${e.message}`,\n );\n } else {\n this.options.logger.error(\n `[TaskManagement] Failed to process task: ${e}`,\n );\n }\n }\n });\n\n await Promise.all(taskPromises);\n\n this.options.logger.info(\n `[TaskManagement] Completed processing of all tasks`,\n );\n }\n}\n"],"names":["discoverOrganizationMetrics","discoverOrganizationTeamMetrics","discoverEnterpriseMetrics","discoverEnterpriseTeamMetrics"],"mappings":";;;;;;;;;AA+BA,MAAqB,cAAe,CAAA;AAAA,EAGlC,YAA6B,OAAsB,EAAA;AAAtB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAC3B,IAAA,IAAA,CAAK,KAAQ,GAAA;AAAA,MACX,MAAMA,4CAA4B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAC9C,MAAMC,oDAAgC,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAClD,MAAMC,wCAA0B,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,MAC5C,MAAMC,gDAA8B,CAAA,IAAA,CAAK,OAAO;AAAA,KAClD;AAAA;AACF,EATiB,KAAA;AAAA,EAWjB,OAAO,OAAO,OAAsB,EAAA;AAClC,IAAO,OAAA,IAAI,eAAe,OAAO,CAAA;AAAA;AACnC,EAEA,MAAM,QAAW,GAAA;AACf,IAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,MAClB,CAAA,wCAAA,EAA2C,IAAK,CAAA,KAAA,CAAM,MAAM,CAAA,MAAA;AAAA,KAC9D;AAEA,IAAA,MAAM,YAAe,GAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,OAAM,IAAQ,KAAA;AAChD,MAAI,IAAA;AACF,QAAA,MAAM,IAAK,EAAA;AAAA,eACJ,CAAG,EAAA;AACV,QAAA,IAAI,aAAa,KAAO,EAAA;AACtB,UAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,KAAA;AAAA,YAClB,CAAA,yCAAA,EAA4C,EAAE,OAAO,CAAA;AAAA,WACvD;AAAA,SACK,MAAA;AACL,UAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,KAAA;AAAA,YAClB,4CAA4C,CAAC,CAAA;AAAA,WAC/C;AAAA;AACF;AACF,KACD,CAAA;AAED,IAAM,MAAA,OAAA,CAAQ,IAAI,YAAY,CAAA;AAE9B,IAAA,IAAA,CAAK,QAAQ,MAAO,CAAA,IAAA;AAAA,MAClB,CAAA,kDAAA;AAAA,KACF;AAAA;AAEJ;;;;"}
@@ -2,24 +2,134 @@
2
2
 
3
3
  var luxon = require('luxon');
4
4
 
5
- function filterNewMetrics(metrics, lastDay) {
5
+ function filterNewMetricsV2(metrics, lastDay) {
6
6
  return metrics.sort(
7
- (a, b) => luxon.DateTime.fromISO(a.day).toMillis() - luxon.DateTime.fromISO(b.day).toMillis()
7
+ (a, b) => luxon.DateTime.fromISO(a.date).toMillis() - luxon.DateTime.fromISO(b.date).toMillis()
8
8
  ).filter((metric) => {
9
- const metricDate = luxon.DateTime.fromISO(metric.day);
9
+ const metricDate = luxon.DateTime.fromISO(metric.date);
10
10
  const lastDayDate = lastDay ? luxon.DateTime.fromJSDate(new Date(lastDay)) : null;
11
11
  return !lastDay || lastDayDate?.isValid && metricDate > lastDayDate;
12
12
  });
13
13
  }
14
- function prepareMetricsForInsert(metrics, type, team_name) {
15
- return metrics.map(({ breakdown, ...rest }) => ({
16
- ...rest,
14
+ function filterBaseMetrics(metrics, type, team) {
15
+ return metrics.map((metric) => ({
16
+ day: metric.date,
17
17
  type,
18
- team_name,
19
- breakdown: JSON.stringify(breakdown)
20
- }));
18
+ team_name: team,
19
+ total_engaged_users: metric.total_engaged_users,
20
+ total_active_users: metric.total_active_users
21
+ })).filter((metric) => metric.total_engaged_users > 0);
22
+ }
23
+ function filterIdeCompletionMetrics(metrics, type, team) {
24
+ return metrics.map((metric) => ({
25
+ day: metric.date,
26
+ type,
27
+ team_name: team,
28
+ total_engaged_users: metric.copilot_ide_code_completions.total_engaged_users
29
+ })).filter((completion) => completion.total_engaged_users > 0);
30
+ }
31
+ function filterIdeCompletionLanguageMetrics(metrics, type, team) {
32
+ return metrics.flatMap(
33
+ (metric) => metric.copilot_ide_code_completions.languages.map((language) => ({
34
+ day: metric.date,
35
+ type,
36
+ team_name: team,
37
+ language: language.name,
38
+ total_engaged_users: language.total_engaged_users
39
+ }))
40
+ ).filter((language) => language.total_engaged_users > 0);
41
+ }
42
+ function filterIdeCompletionEditorMetrics(metrics, type, team) {
43
+ return metrics.flatMap(
44
+ (metric) => metric.copilot_ide_code_completions.editors.map((editor) => ({
45
+ day: metric.date,
46
+ type,
47
+ team_name: team,
48
+ editor: editor.name,
49
+ total_engaged_users: editor.total_engaged_users
50
+ }))
51
+ ).filter((editor) => editor.total_engaged_users > 0);
52
+ }
53
+ function filterIdeCompletionEditorModelMetrics(metrics, type, team) {
54
+ return metrics.flatMap(
55
+ (metric) => metric.copilot_ide_code_completions.editors.flatMap(
56
+ (editor) => editor.models.map((model) => ({
57
+ day: metric.date,
58
+ type,
59
+ team_name: team,
60
+ editor: editor.name,
61
+ model: model.name,
62
+ total_engaged_users: model.total_engaged_users
63
+ }))
64
+ )
65
+ ).filter((model) => model.total_engaged_users > 0);
66
+ }
67
+ function filterIdeCompletionEditorModelLanguageMetrics(metrics, type, team) {
68
+ return metrics.flatMap(
69
+ (metric) => metric.copilot_ide_code_completions.editors.flatMap(
70
+ (editor) => editor.models.flatMap(
71
+ (model) => model.languages.map((language) => ({
72
+ day: metric.date,
73
+ type,
74
+ team_name: team,
75
+ editor: editor.name,
76
+ model: model.name,
77
+ language: language.name,
78
+ total_engaged_users: language.total_engaged_users,
79
+ total_code_acceptances: language.total_code_acceptances,
80
+ total_code_suggestions: language.total_code_suggestions,
81
+ total_code_lines_accepted: language.total_code_lines_accepted,
82
+ total_code_lines_suggested: language.total_code_lines_suggested
83
+ }))
84
+ )
85
+ )
86
+ ).filter((language) => language.total_engaged_users > 0);
87
+ }
88
+ function filterIdeChatMetrics(metrics, type, team) {
89
+ return metrics.map((metric) => ({
90
+ day: metric.date,
91
+ type,
92
+ team_name: team,
93
+ total_engaged_users: metric.copilot_ide_chat.total_engaged_users
94
+ })).filter((chat) => chat.total_engaged_users > 0);
95
+ }
96
+ function filterIdeEditorMetrics(metrics, type, team) {
97
+ return metrics.flatMap(
98
+ (metric) => metric.copilot_ide_chat.editors.map((editor) => ({
99
+ day: metric.date,
100
+ type,
101
+ team_name: team,
102
+ editor: editor.name,
103
+ total_engaged_users: editor.total_engaged_users
104
+ }))
105
+ ).filter((editor) => editor.total_engaged_users > 0);
106
+ }
107
+ function filterIdeChatEditorModelMetrics(metrics, type, team) {
108
+ return metrics.flatMap(
109
+ (metric) => metric.copilot_ide_chat.editors.flatMap(
110
+ (editor) => editor.models.map((model) => ({
111
+ day: metric.date,
112
+ type,
113
+ team_name: team,
114
+ editor: editor.name,
115
+ model: model.name,
116
+ total_engaged_users: model.total_engaged_users,
117
+ total_chat_copy_events: model.total_chat_copy_events,
118
+ total_chats: model.total_chats,
119
+ total_chat_insertion_events: model.total_chat_insertion_events
120
+ }))
121
+ )
122
+ ).filter((model) => model.total_engaged_users > 0);
21
123
  }
22
124
 
23
- exports.filterNewMetrics = filterNewMetrics;
24
- exports.prepareMetricsForInsert = prepareMetricsForInsert;
125
+ exports.filterBaseMetrics = filterBaseMetrics;
126
+ exports.filterIdeChatEditorModelMetrics = filterIdeChatEditorModelMetrics;
127
+ exports.filterIdeChatMetrics = filterIdeChatMetrics;
128
+ exports.filterIdeCompletionEditorMetrics = filterIdeCompletionEditorMetrics;
129
+ exports.filterIdeCompletionEditorModelLanguageMetrics = filterIdeCompletionEditorModelLanguageMetrics;
130
+ exports.filterIdeCompletionEditorModelMetrics = filterIdeCompletionEditorModelMetrics;
131
+ exports.filterIdeCompletionLanguageMetrics = filterIdeCompletionLanguageMetrics;
132
+ exports.filterIdeCompletionMetrics = filterIdeCompletionMetrics;
133
+ exports.filterIdeEditorMetrics = filterIdeEditorMetrics;
134
+ exports.filterNewMetricsV2 = filterNewMetricsV2;
25
135
  //# sourceMappingURL=metricHelpers.cjs.js.map