diff --git a/frontend/src/component/application/ApplicationEdit/ApplicationEdit.tsx b/frontend/src/component/application/ApplicationEdit/ApplicationEdit.tsx index ead182bb86..56a675c5e7 100644 --- a/frontend/src/component/application/ApplicationEdit/ApplicationEdit.tsx +++ b/frontend/src/component/application/ApplicationEdit/ApplicationEdit.tsx @@ -14,7 +14,6 @@ import { import { Link as LinkIcon } from '@mui/icons-material'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { UPDATE_APPLICATION } from 'component/providers/AccessProvider/permissions'; -import { ApplicationOverview } from '../ApplicationOverview'; import { ApplicationUpdate } from '../ApplicationUpdate/ApplicationUpdate'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { PageContent } from 'component/common/PageContent/PageContent'; diff --git a/src/lib/openapi/index.ts b/src/lib/openapi/index.ts index fa12f347bc..753764e285 100644 --- a/src/lib/openapi/index.ts +++ b/src/lib/openapi/index.ts @@ -198,6 +198,8 @@ import { projectApplicationsSchema } from './spec/project-applications-schema'; import { projectApplicationSchema } from './spec/project-application-schema'; import { projectApplicationSdkSchema } from './spec/project-application-sdk-schema'; import { rolesSchema } from './spec/roles-schema'; +import { applicationOverviewSchema } from './spec/application-overview-schema'; +import { applicationOverviewEnvironmentSchema } from './spec/application-overview-environment-schema'; // Schemas must have an $id property on the form "#/components/schemas/mySchema". export type SchemaId = (typeof schemas)[keyof typeof schemas]['$id']; @@ -245,6 +247,8 @@ export const schemas: UnleashSchemas = { apiTokenSchema, apiTokensSchema, applicationSchema, + applicationOverviewSchema, + applicationOverviewEnvironmentSchema, applicationUsageSchema, applicationsSchema, batchFeaturesSchema, diff --git a/src/lib/openapi/spec/application-overview-environment-schema.ts b/src/lib/openapi/spec/application-overview-environment-schema.ts new file mode 100644 index 0000000000..037b01d364 --- /dev/null +++ b/src/lib/openapi/spec/application-overview-environment-schema.ts @@ -0,0 +1,41 @@ +import { FromSchema } from 'json-schema-to-ts'; + +export const applicationOverviewEnvironmentSchema = { + $id: '#/components/schemas/applicationOverviewEnvironmentSchema', + type: 'object', + description: 'Data about an application environment', + additionalProperties: false, + required: ['name', 'instanceCount', 'sdks', 'lastSeen'], + properties: { + name: { + description: 'Name of the application environment', + type: 'string', + example: 'production', + }, + instanceCount: { + description: + 'The number of instances of the application environment', + type: 'number', + example: 5, + }, + sdks: { + description: 'SDKs used in the application environment', + type: 'array', + items: { + type: 'string', + }, + example: ['unleash-client-node:5.4.0', 'unleash-client-node:5.3.0'], + }, + lastSeen: { + type: 'string', + format: 'date-time', + example: '2023-04-19T08:15:14.000Z', + description: 'The last time the application environment was seen', + }, + }, + components: {}, +} as const; + +export type ApplicationOverviewEnvironmentSchema = FromSchema< + typeof applicationOverviewEnvironmentSchema +>; diff --git a/src/lib/openapi/spec/application-overview-schema.test.ts b/src/lib/openapi/spec/application-overview-schema.test.ts new file mode 100644 index 0000000000..2255b64449 --- /dev/null +++ b/src/lib/openapi/spec/application-overview-schema.test.ts @@ -0,0 +1,26 @@ +import { validateSchema } from '../validate'; + +test('applicationOverviewSchema', () => { + const app = { + projects: ['default', 'dx'], + featureCount: 12, + environments: [ + { + name: 'production', + instanceCount: 34, + sdks: ['unleash-client-node:5.4.0'], + lastSeen: '2021-10-01T12:00:00Z', + }, + { + name: 'development', + instanceCount: 16, + sdks: ['unleash-client-java:5.4.0'], + lastSeen: '2021-10-01T12:00:00Z', + }, + ], + }; + + expect( + validateSchema('#/components/schemas/applicationOverviewSchema', app), + ).toBeUndefined(); +}); diff --git a/src/lib/openapi/spec/application-overview-schema.ts b/src/lib/openapi/spec/application-overview-schema.ts new file mode 100644 index 0000000000..e0c4310e36 --- /dev/null +++ b/src/lib/openapi/spec/application-overview-schema.ts @@ -0,0 +1,42 @@ +import { FromSchema } from 'json-schema-to-ts'; +import { applicationOverviewEnvironmentSchema } from './application-overview-environment-schema'; + +export const applicationOverviewSchema = { + $id: '#/components/schemas/applicationOverviewSchema', + type: 'object', + description: + "Data about an application that's connected to Unleash via an SDK.", + additionalProperties: false, + required: ['projects', 'featureCount', 'environments'], + properties: { + projects: { + description: 'The list of projects the application has been using.', + type: 'array', + items: { + type: 'string', + }, + example: ['default', 'payment'], + }, + featureCount: { + description: + 'The number of features the application has been using.', + type: 'number', + example: 5, + }, + environments: { + type: 'array', + description: + 'The list of environments the application has been using.', + items: { + $ref: '#/components/schemas/applicationOverviewEnvironmentSchema', + }, + }, + }, + components: { + applicationOverviewEnvironmentSchema, + }, +} as const; + +export type ApplicationOverviewSchema = FromSchema< + typeof applicationOverviewSchema +>; diff --git a/src/lib/routes/admin-api/metrics.ts b/src/lib/routes/admin-api/metrics.ts index 261df6bd5f..4abc8b8e8f 100644 --- a/src/lib/routes/admin-api/metrics.ts +++ b/src/lib/routes/admin-api/metrics.ts @@ -117,6 +117,25 @@ class MetricsController extends Controller { }), ], }); + this.route({ + method: 'get', + path: '/applications/:appName/overview', + handler: this.getApplicationOverview, + permission: NONE, + middleware: [ + openApiService.validPath({ + tags: ['Unstable'], + operationId: 'getApplicationOverview', + summary: 'Get application overview', + description: + 'Returns an overview of the specified application (`appName`).', + responses: { + 200: createResponseSchema('applicationOverviewSchema'), + ...getStandardResponses(404), + }, + }), + ], + }); } async deprecated(req: Request, res: Response): Promise { @@ -174,5 +193,11 @@ class MetricsController extends Controller { await this.clientInstanceService.getApplication(appName); res.json(appDetails); } + async getApplicationOverview( + req: Request, + res: Response, + ): Promise { + throw new Error('Not implemented'); + } } export default MetricsController;