@backstage-community/plugin-copilot-backend 0.5.0 → 0.7.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.
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"metricHelpers.cjs.js","sources":["../../src/utils/metricHelpers.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 { DateTime } from 'luxon';\nimport { MetricDbRow } from '../db/DatabaseHandler';\nimport {\n Metric,\n MetricsType,\n} from '@backstage-community/plugin-copilot-common';\n\nexport function filterNewMetrics(\n metrics: Metric[],\n lastDay?: string,\n): Metric[] {\n return metrics\n .sort(\n (a, b) =>\n DateTime.fromISO(a.day).toMillis() - DateTime.fromISO(b.day).toMillis(),\n )\n .filter(metric => {\n const metricDate = DateTime.fromISO(metric.day);\n\n const lastDayDate = lastDay\n ? DateTime.fromJSDate(new Date(lastDay))\n : null;\n\n return !lastDay || (lastDayDate?.isValid && metricDate > lastDayDate);\n });\n}\n\nexport function prepareMetricsForInsert(\n metrics: Metric[],\n type: MetricsType,\n team_name?: string,\n): MetricDbRow[] {\n return metrics.map(({ breakdown, ...rest }) => ({\n ...rest,\n type,\n team_name,\n breakdown: JSON.stringify(breakdown),\n })) as MetricDbRow[];\n}\n"],"names":["DateTime"],"mappings":";;;;AAsBgB,SAAA,gBAAA,CACd,SACA,OACU,EAAA;AACV,EAAA,OAAO,OACJ,CAAA,IAAA;AAAA,IACC,CAAC,CAAA,EAAG,CACF,KAAAA,cAAA,CAAS,QAAQ,CAAE,CAAA,GAAG,CAAE,CAAA,QAAA,KAAaA,cAAS,CAAA,OAAA,CAAQ,CAAE,CAAA,GAAG,EAAE,QAAS;AAAA,GAC1E,CACC,OAAO,CAAU,MAAA,KAAA;AAChB,IAAA,MAAM,UAAa,GAAAA,cAAA,CAAS,OAAQ,CAAA,MAAA,CAAO,GAAG,CAAA;AAE9C,IAAM,MAAA,WAAA,GAAc,UAChBA,cAAS,CAAA,UAAA,CAAW,IAAI,IAAK,CAAA,OAAO,CAAC,CACrC,GAAA,IAAA;AAEJ,IAAA,OAAO,CAAC,OAAA,IAAY,WAAa,EAAA,OAAA,IAAW,UAAa,GAAA,WAAA;AAAA,GAC1D,CAAA;AACL;AAEgB,SAAA,uBAAA,CACd,OACA,EAAA,IAAA,EACA,SACe,EAAA;AACf,EAAA,OAAO,QAAQ,GAAI,CAAA,CAAC,EAAE,SAAW,EAAA,GAAG,MAAY,MAAA;AAAA,IAC9C,GAAG,IAAA;AAAA,IACH,IAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA,EAAW,IAAK,CAAA,SAAA,CAAU,SAAS;AAAA,GACnC,CAAA,CAAA;AACJ;;;;;"}
1
+ {"version":3,"file":"metricHelpers.cjs.js","sources":["../../src/utils/metricHelpers.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 { DateTime } from 'luxon';\nimport {\n CopilotIdeChatsDb,\n CopilotIdeChatsEditorModelDb,\n CopilotIdeChatsEditorsDb,\n CopilotIdeCodeCompletionsDb,\n CopilotIdeCodeCompletionsEditorModelLanguagesDb,\n CopilotIdeCodeCompletionsEditorModelsDb,\n CopilotIdeCodeCompletionsEditorsDb,\n CopilotIdeCodeCompletionsLanguageDb,\n CopilotMetricsDb,\n MetricDbRow,\n} from '../db/DatabaseHandler';\nimport {\n Metric,\n MetricsType,\n CopilotMetrics,\n} from '@backstage-community/plugin-copilot-common';\n\nexport function filterNewMetricsV2(\n metrics: CopilotMetrics[],\n lastDay?: string,\n): CopilotMetrics[] {\n return metrics\n .sort(\n (a, b) =>\n DateTime.fromISO(a.date).toMillis() -\n DateTime.fromISO(b.date).toMillis(),\n )\n .filter(metric => {\n const metricDate = DateTime.fromISO(metric.date);\n\n const lastDayDate = lastDay\n ? DateTime.fromJSDate(new Date(lastDay))\n : null;\n\n return !lastDay || (lastDayDate?.isValid && metricDate > lastDayDate);\n });\n}\n\nexport function filterBaseMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotMetricsDb[] {\n return metrics\n .map(metric => ({\n day: metric.date,\n type: type,\n team_name: team,\n total_engaged_users: metric.total_engaged_users,\n total_active_users: metric.total_active_users,\n }))\n .filter(metric => metric.total_engaged_users > 0);\n}\n\nexport function filterIdeCompletionMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotIdeCodeCompletionsDb[] {\n return metrics\n .map(metric => ({\n day: metric.date,\n type: type,\n team_name: team,\n total_engaged_users:\n metric.copilot_ide_code_completions.total_engaged_users,\n }))\n .filter(completion => completion.total_engaged_users > 0);\n}\n\nexport function filterIdeCompletionLanguageMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotIdeCodeCompletionsLanguageDb[] {\n return metrics\n .flatMap((metric: CopilotMetrics) =>\n metric.copilot_ide_code_completions.languages.map(language => ({\n day: metric.date,\n type: type,\n team_name: team,\n language: language.name,\n total_engaged_users: language.total_engaged_users,\n })),\n )\n .filter(language => language.total_engaged_users > 0);\n}\nexport function filterIdeCompletionEditorMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotIdeCodeCompletionsEditorsDb[] {\n return metrics\n .flatMap((metric: CopilotMetrics) =>\n metric.copilot_ide_code_completions.editors.map(editor => ({\n day: metric.date,\n type: type,\n team_name: team,\n editor: editor.name,\n total_engaged_users: editor.total_engaged_users,\n })),\n )\n .filter(editor => editor.total_engaged_users > 0);\n}\n\nexport function filterIdeCompletionEditorModelMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotIdeCodeCompletionsEditorModelsDb[] {\n return metrics\n .flatMap((metric: CopilotMetrics) =>\n metric.copilot_ide_code_completions.editors.flatMap(editor =>\n editor.models.map(model => ({\n day: metric.date,\n type: type,\n team_name: team,\n editor: editor.name,\n model: model.name,\n total_engaged_users: model.total_engaged_users,\n })),\n ),\n )\n .filter(model => model.total_engaged_users > 0);\n}\nexport function filterIdeCompletionEditorModelLanguageMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotIdeCodeCompletionsEditorModelLanguagesDb[] {\n return metrics\n .flatMap((metric: CopilotMetrics) =>\n metric.copilot_ide_code_completions.editors.flatMap(editor =>\n editor.models.flatMap(model =>\n model.languages.map(language => ({\n day: metric.date,\n type: type,\n team_name: team,\n editor: editor.name,\n model: model.name,\n language: language.name,\n total_engaged_users: language.total_engaged_users,\n total_code_acceptances: language.total_code_acceptances,\n total_code_suggestions: language.total_code_suggestions,\n total_code_lines_accepted: language.total_code_lines_accepted,\n total_code_lines_suggested: language.total_code_lines_suggested,\n })),\n ),\n ),\n )\n .filter(language => language.total_engaged_users > 0);\n}\n\nexport function filterIdeChatMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotIdeChatsDb[] {\n return metrics\n .map((metric: CopilotMetrics) => ({\n day: metric.date,\n type: type,\n team_name: team,\n total_engaged_users: metric.copilot_ide_chat.total_engaged_users,\n }))\n .filter(chat => chat.total_engaged_users > 0);\n}\n\nexport function filterIdeEditorMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotIdeChatsEditorsDb[] {\n return metrics\n .flatMap((metric: CopilotMetrics) =>\n metric.copilot_ide_chat.editors.map(editor => ({\n day: metric.date,\n type: type,\n team_name: team,\n editor: editor.name,\n total_engaged_users: editor.total_engaged_users,\n })),\n )\n .filter(editor => editor.total_engaged_users > 0);\n}\n\nexport function filterIdeChatEditorModelMetrics(\n metrics: CopilotMetrics[],\n type: MetricsType,\n team?: string,\n): CopilotIdeChatsEditorModelDb[] {\n return metrics\n .flatMap((metric: CopilotMetrics) =>\n metric.copilot_ide_chat.editors.flatMap(editor =>\n editor.models.map(model => ({\n day: metric.date,\n type: type,\n team_name: team,\n editor: editor.name,\n model: model.name,\n total_engaged_users: model.total_engaged_users,\n total_chat_copy_events: model.total_chat_copy_events,\n total_chats: model.total_chats,\n total_chat_insertion_events: model.total_chat_insertion_events,\n })),\n ),\n )\n .filter(model => model.total_engaged_users > 0);\n}\n\nexport function prepareMetricsForInsert(\n metrics: Metric[],\n type: MetricsType,\n team_name?: string,\n): MetricDbRow[] {\n return metrics.map(({ breakdown, ...rest }) => ({\n ...rest,\n type,\n team_name,\n breakdown: JSON.stringify(breakdown),\n })) as MetricDbRow[];\n}\n"],"names":["DateTime"],"mappings":"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"}
@@ -0,0 +1,394 @@
1
+ /*
2
+ * Copyright 2024 The Backstage Authors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * @param {import('knex').Knex} knex
18
+ */
19
+ exports.up = async function up(knex) {
20
+ await knex.schema.createTable('copilot_metrics', table => {
21
+ table.comment('Table for storing metrics for CoPilot in general');
22
+ table.date('day').notNullable().comment('Date of the metrics data');
23
+ table
24
+ .string('type')
25
+ .notNullable()
26
+ .defaultTo('organization')
27
+ .comment('The type of metric');
28
+ table.string('team_name', 255).nullable().comment('Name of the team');
29
+ table
30
+ .integer('total_engaged_users')
31
+ .notNullable()
32
+ .comment('Total engaged users for the day');
33
+ table
34
+ .integer('total_active_users')
35
+ .notNullable()
36
+ .comment('Total active users for the day');
37
+ table.unique(['day', 'type', 'team_name'], { indexName: 'uk_day' });
38
+ });
39
+
40
+ await knex.schema.createTable('ide_completions', table => {
41
+ table.comment('Table for storing metrics for IDE completions');
42
+ table.date('day').notNullable().comment('Date of the metrics data');
43
+ table
44
+ .string('type')
45
+ .notNullable()
46
+ .defaultTo('organization')
47
+ .comment('The type of metric');
48
+ table.string('team_name', 255).nullable().comment('Name of the team');
49
+ table
50
+ .integer('total_engaged_users')
51
+ .notNullable()
52
+ .comment('Total engaged users for the day');
53
+ table.unique(['day', 'type', 'team_name'], {
54
+ indexName: 'uk_ide_comp_day_type_team',
55
+ });
56
+ });
57
+
58
+ await knex.schema.createTable('ide_completions_language_users', table => {
59
+ table.comment('Table for storing metrics for IDE completions per language');
60
+ table.date('day').notNullable().comment('Date of the metrics data');
61
+ table
62
+ .string('language')
63
+ .notNullable()
64
+ .comment('The language of the IDE completion');
65
+ table
66
+ .string('type')
67
+ .notNullable()
68
+ .defaultTo('organization')
69
+ .comment('The type of metric');
70
+ table.string('team_name', 255).nullable().comment('Name of the team');
71
+ table
72
+ .integer('total_engaged_users')
73
+ .notNullable()
74
+ .comment('Total engaged users for the day');
75
+ table.unique(['day', 'language', 'type', 'team_name'], {
76
+ indexName: 'uk_ide_comp_day_lang_type_team',
77
+ });
78
+ });
79
+
80
+ await knex.schema.createTable('ide_completions_language_editors', table => {
81
+ table.comment('Table for storing metrics for IDE completions per editor');
82
+ table.date('day').notNullable().comment('Date of the metrics data');
83
+ table
84
+ .string('editor')
85
+ .notNullable()
86
+ .comment('The editor of the IDE completion');
87
+ table
88
+ .string('type')
89
+ .notNullable()
90
+ .defaultTo('organization')
91
+ .comment('The type of metric');
92
+ table.string('team_name', 255).nullable().comment('Name of the team');
93
+ table
94
+ .integer('total_engaged_users')
95
+ .notNullable()
96
+ .comment('Total engaged users for the day');
97
+ table.unique(['day', 'editor', 'type', 'team_name'], {
98
+ indexName: 'uk_ide_comp_day_editor_type_team',
99
+ });
100
+ });
101
+
102
+ await knex.schema.createTable(
103
+ 'ide_completions_language_editors_model',
104
+ table => {
105
+ table.comment(
106
+ 'Table for storing metrics for IDE completions per editor per model',
107
+ );
108
+ table.date('day').notNullable().comment('Date of the metrics data');
109
+ table
110
+ .string('type')
111
+ .notNullable()
112
+ .defaultTo('organization')
113
+ .comment('The type of metric');
114
+ table.string('team_name', 255).nullable().comment('Name of the team');
115
+ table
116
+ .string('editor')
117
+ .notNullable()
118
+ .comment('The editor of the IDE completion');
119
+ table
120
+ .string('model')
121
+ .notNullable()
122
+ .comment('The model of the editor of the IDE completion');
123
+ table
124
+ .integer('total_engaged_users')
125
+ .notNullable()
126
+ .comment('Total engaged users for the day');
127
+ table.unique(['day', 'editor', 'model', 'type', 'team_name'], {
128
+ indexName: 'uk_ide_comp_day_editor_model_type_team',
129
+ });
130
+ },
131
+ );
132
+
133
+ await knex.schema.createTable(
134
+ 'ide_completions_language_editors_model_language',
135
+ table => {
136
+ table.comment(
137
+ 'Table for storing metrics for IDE completions per editor per model per language',
138
+ );
139
+ table.date('day').notNullable().comment('Date of the metrics data');
140
+ table
141
+ .string('type')
142
+ .notNullable()
143
+ .defaultTo('organization')
144
+ .comment('The type of metric');
145
+ table.string('team_name', 255).nullable().comment('Name of the team');
146
+ table
147
+ .string('editor')
148
+ .notNullable()
149
+ .comment('The editor of the IDE completion');
150
+ table
151
+ .string('model')
152
+ .notNullable()
153
+ .comment('The model of the editor of the IDE completion');
154
+ table
155
+ .string('language')
156
+ .notNullable()
157
+ .comment('The model of the editor of the IDE completion');
158
+ table
159
+ .integer('total_engaged_users')
160
+ .notNullable()
161
+ .comment('Total engaged users for the day');
162
+ table
163
+ .integer('total_code_acceptances')
164
+ .notNullable()
165
+ .comment('Total acceptances for the day');
166
+ table
167
+ .integer('total_code_suggestions')
168
+ .notNullable()
169
+ .comment('Total code suggestions for the day');
170
+ table
171
+ .integer('total_code_lines_accepted')
172
+ .notNullable()
173
+ .comment('Total code lines accepted for the day');
174
+ table
175
+ .integer('total_code_lines_suggested')
176
+ .notNullable()
177
+ .comment('The total code lines suggested for the day');
178
+ table.unique(
179
+ ['day', 'editor', 'model', 'language', 'type', 'team_name'],
180
+ {
181
+ indexName: 'uk_ide_comp_day_editor_model_language_type_team',
182
+ },
183
+ );
184
+ },
185
+ );
186
+
187
+ // IDE chats
188
+ await knex.schema.createTable('ide_chats', table => {
189
+ table.comment('Table for storing metrics for IDE completions');
190
+ table.date('day').notNullable().comment('Date of the metrics data');
191
+ table
192
+ .string('type')
193
+ .notNullable()
194
+ .defaultTo('organization')
195
+ .comment('The type of metric');
196
+ table.string('team_name', 255).nullable().comment('Name of the team');
197
+ table
198
+ .integer('total_engaged_users')
199
+ .notNullable()
200
+ .comment('Total engaged users for the day');
201
+ table.unique(['day', 'type', 'team_name'], {
202
+ indexName: 'uk_ide_chats_day_type_team',
203
+ });
204
+ });
205
+
206
+ await knex.schema.createTable('ide_chat_editors', table => {
207
+ table.comment('Table for storing metrics for IDE chats per editor');
208
+ table.date('day').notNullable().comment('Date of the metrics data');
209
+ table
210
+ .string('type')
211
+ .notNullable()
212
+ .defaultTo('organization')
213
+ .comment('The type of metric');
214
+ table.string('team_name', 255).nullable().comment('Name of the team');
215
+ table.string('editor').notNullable().comment('The editor of the IDE chat');
216
+ table
217
+ .integer('total_engaged_users')
218
+ .notNullable()
219
+ .comment('Total engaged users for the day');
220
+ table.unique(['day', 'editor', 'type', 'team_name'], {
221
+ indexName: 'uk_ide_chat_day_editor_type_team',
222
+ });
223
+ });
224
+
225
+ await knex.schema.createTable('ide_chat_editors_model', table => {
226
+ table.comment(
227
+ 'Table for storing metrics for IDE chats per editor per model',
228
+ );
229
+ table.date('day').notNullable().comment('Date of the metrics data');
230
+ table
231
+ .string('type')
232
+ .notNullable()
233
+ .defaultTo('organization')
234
+ .comment('The type of metric');
235
+ table.string('team_name', 255).nullable().comment('Name of the team');
236
+ table.string('editor').notNullable().comment('The editor of the IDE chat');
237
+ table.string('model').notNullable().comment('The model of the IDE chat');
238
+ table
239
+ .integer('total_engaged_users')
240
+ .notNullable()
241
+ .comment('Total engaged users for the day');
242
+ table
243
+ .integer('total_chat_copy_events')
244
+ .notNullable()
245
+ .comment('Total copy events for the day');
246
+ table
247
+ .integer('total_chat_insertion_events')
248
+ .notNullable()
249
+ .comment('Total insertions for the day');
250
+ table
251
+ .integer('total_chats')
252
+ .notNullable()
253
+ .comment('Total chats for the day');
254
+ table.unique(['day', 'editor', 'model', 'type', 'team_name'], {
255
+ indexName: 'uk_ide_chat_day_editor_model_type_team',
256
+ });
257
+ });
258
+
259
+ // github.com chats
260
+ // chats
261
+ await knex.schema.createTable('dotcom_chats', table => {
262
+ table.comment('Table for storing metrics for IDE completions');
263
+ table.date('day').notNullable().comment('Date of the metrics data');
264
+ table
265
+ .string('type')
266
+ .notNullable()
267
+ .defaultTo('organization')
268
+ .comment('The type of metric');
269
+ table.string('team_name', 255).nullable().comment('Name of the team');
270
+ table
271
+ .integer('total_engaged_users')
272
+ .notNullable()
273
+ .comment('Total engaged users for the day');
274
+ table.unique(['day', 'type', 'team_name'], {
275
+ indexName: 'uk_day_type_team',
276
+ });
277
+ });
278
+
279
+ await knex.schema.createTable('dotcom_chat_models', table => {
280
+ table.comment('Table for storing metrics for IDE chats per editor');
281
+ table.date('day').notNullable().comment('Date of the metrics data');
282
+ table.string('model').notNullable().comment('The model of chat');
283
+ table
284
+ .string('type')
285
+ .notNullable()
286
+ .defaultTo('organization')
287
+ .comment('The type of metric');
288
+ table.string('team_name', 255).nullable().comment('Name of the team');
289
+ table
290
+ .integer('total_engaged_users')
291
+ .notNullable()
292
+ .comment('Total engaged users for the day');
293
+ table
294
+ .integer('total_chats')
295
+ .notNullable()
296
+ .comment('Total chats for the day');
297
+ table.unique(['day', 'model', 'type', 'team_name'], {
298
+ indexName: 'uk_day_model_type_team',
299
+ });
300
+ });
301
+
302
+ // dotcom pull requests
303
+ await knex.schema.createTable('dotcom_prs', table => {
304
+ table.comment('Table for storing metrics for IDE completions');
305
+ table.date('day').notNullable().comment('Date of the metrics data');
306
+ table
307
+ .string('type')
308
+ .notNullable()
309
+ .defaultTo('organization')
310
+ .comment('The type of metric');
311
+ table.string('team_name', 255).nullable().comment('Name of the team');
312
+ table
313
+ .integer('total_engaged_users')
314
+ .notNullable()
315
+ .comment('Total engaged users for the day');
316
+ table.unique(['day', 'type', 'team_name'], {
317
+ indexName: 'uk_pr_day_type_team',
318
+ });
319
+ });
320
+
321
+ await knex.schema.createTable('dotcom_pr_repositories', table => {
322
+ table.comment('Table for storing metrics for IDE completions');
323
+ table.date('day').notNullable().comment('Date of the metrics data');
324
+ table
325
+ .string('type')
326
+ .notNullable()
327
+ .defaultTo('organization')
328
+ .comment('The type of metric');
329
+ table.string('team_name', 255).nullable().comment('Name of the team');
330
+ table
331
+ .string('repository')
332
+ .notNullable()
333
+ .comment('The repository of the pull request');
334
+ table
335
+ .integer('total_engaged_users')
336
+ .notNullable()
337
+ .comment('Total engaged users for the day');
338
+ table.unique(['day', 'type', 'team_name', 'repository'], {
339
+ indexName: 'uk_day_type_team_repo',
340
+ });
341
+ });
342
+
343
+ await knex.schema.createTable('dotcom_pr_repositories_models', table => {
344
+ table.comment('Table for storing metrics for IDE completions');
345
+ table.date('day').notNullable().comment('Date of the metrics data');
346
+ table
347
+ .string('type')
348
+ .notNullable()
349
+ .defaultTo('organization')
350
+ .comment('The type of metric');
351
+ table.string('team_name', 255).nullable().comment('Name of the team');
352
+ table
353
+ .string('repository')
354
+ .notNullable()
355
+ .comment('The repository of the pull request');
356
+ table
357
+ .string('model')
358
+ .notNullable()
359
+ .comment('The model of the pull request');
360
+ table
361
+ .integer('total_engaged_users')
362
+ .notNullable()
363
+ .comment('Total engaged users for the day');
364
+ table
365
+ .integer('total_pr_summaries')
366
+ .notNullable()
367
+ .comment('Total pull request summaries for the day');
368
+ table.unique(['day', 'type', 'team_name', 'repository', 'model'], {
369
+ indexName: 'uk_day_type_team_repo_model',
370
+ });
371
+ });
372
+ };
373
+
374
+ /**
375
+ * @param {import('knex').Knex} knex
376
+ */
377
+ exports.down = async function down(knex) {
378
+ await knex.schema.dropTable('dotcom_pr_repositories_models');
379
+ await knex.schema.dropTable('dotcom_pr_repositories');
380
+ await knex.schema.dropTable('dotcom_prs');
381
+ await knex.schema.dropTable('dotcom_chat_models');
382
+ await knex.schema.dropTable('dotcom_chats');
383
+ await knex.schema.dropTable('ide_chat_editors_model');
384
+ await knex.schema.dropTable('ide_chat_editors');
385
+ await knex.schema.dropTable('ide_chats');
386
+ await knex.schema.dropTable(
387
+ 'ide_completions_language_editors_model_language',
388
+ );
389
+ await knex.schema.dropTable('ide_completions_language_editors_model');
390
+ await knex.schema.dropTable('ide_completions_language_editors');
391
+ await knex.schema.dropTable('ide_completions_language_users');
392
+ await knex.schema.dropTable('ide_completions');
393
+ await knex.schema.dropTable('copilot_metrics');
394
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage-community/plugin-copilot-backend",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "homepage": "https://backstage.io",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.cjs.js",
@@ -17,7 +17,10 @@
17
17
  "@backstage-community/plugin-copilot",
18
18
  "@backstage-community/plugin-copilot-backend",
19
19
  "@backstage-community/plugin-copilot-common"
20
- ]
20
+ ],
21
+ "features": {
22
+ ".": "@backstage/BackendFeature"
23
+ }
21
24
  },
22
25
  "publishConfig": {
23
26
  "access": "public",
@@ -39,10 +42,10 @@
39
42
  "postpack": "backstage-cli package postpack"
40
43
  },
41
44
  "dependencies": {
42
- "@backstage-community/plugin-copilot-common": "^0.5.0",
43
- "@backstage/backend-app-api": "^1.1.1",
44
- "@backstage/backend-defaults": "^0.7.0",
45
- "@backstage/backend-plugin-api": "^1.1.1",
45
+ "@backstage-community/plugin-copilot-common": "^0.7.0",
46
+ "@backstage/backend-app-api": "^1.2.0",
47
+ "@backstage/backend-defaults": "^0.8.1",
48
+ "@backstage/backend-plugin-api": "^1.2.0",
46
49
  "@backstage/config": "^1.3.2",
47
50
  "@backstage/errors": "^1.2.7",
48
51
  "@backstage/integration": "^1.16.1",
@@ -57,11 +60,11 @@
57
60
  "zod": "^3.23.8"
58
61
  },
59
62
  "devDependencies": {
60
- "@backstage/backend-test-utils": "^1.2.1",
61
- "@backstage/cli": "^0.29.6",
62
- "@backstage/plugin-auth-backend": "^0.24.2",
63
- "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.4",
64
- "@backstage/test-utils": "^1.7.4",
63
+ "@backstage/backend-test-utils": "^1.3.0",
64
+ "@backstage/cli": "^0.30.0",
65
+ "@backstage/plugin-auth-backend": "^0.24.3",
66
+ "@backstage/plugin-auth-backend-module-guest-provider": "^0.2.5",
67
+ "@backstage/test-utils": "^1.7.5",
65
68
  "@types/node-fetch": "^2.6.11",
66
69
  "@types/supertest": "^2.0.8",
67
70
  "msw": "^1.0.0",