Skip to content

Commit

Permalink
fix: split features schema into archived and project features (#7973)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwasniew authored Aug 23, 2024
1 parent 4693f7c commit 1f3cc39
Show file tree
Hide file tree
Showing 10 changed files with 354 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ import {
import { DELETE_FEATURE, NONE, UPDATE_FEATURE } from '../../types/permissions';
import type FeatureToggleService from './feature-toggle-service';
import type { IAuthRequest } from '../../routes/unleash-types';
import {
featuresSchema,
type FeaturesSchema,
} from '../../openapi/spec/features-schema';
import { serializeDates } from '../../types/serialize-dates';
import type { OpenApiService } from '../../services/openapi-service';
import { createResponseSchema } from '../../openapi/util/create-response-schema';
Expand All @@ -24,6 +20,10 @@ import type {
TransactionCreator,
UnleashTransaction,
} from '../../db/transaction';
import {
archivedFeaturesSchema,
type ArchivedFeaturesSchema,
} from '../../openapi';

export default class ArchiveController extends Controller {
private featureService: FeatureToggleService;
Expand Down Expand Up @@ -67,7 +67,7 @@ export default class ArchiveController extends Controller {
'Retrieve a list of all [archived feature flags](https://docs.getunleash.io/reference/archived-toggles).',
operationId: 'getArchivedFeatures',
responses: {
200: createResponseSchema('featuresSchema'),
200: createResponseSchema('archivedFeaturesSchema'),
...getStandardResponses(401, 403),
},

Expand All @@ -89,7 +89,7 @@ export default class ArchiveController extends Controller {
description:
'Retrieves a list of archived features that belong to the provided project.',
responses: {
200: createResponseSchema('featuresSchema'),
200: createResponseSchema('archivedFeaturesSchema'),
...getStandardResponses(401, 403),
},

Expand Down Expand Up @@ -143,7 +143,7 @@ export default class ArchiveController extends Controller {

async getArchivedFeatures(
req: IAuthRequest,
res: Response<FeaturesSchema>,
res: Response<ArchivedFeaturesSchema>,
): Promise<void> {
const { user } = req;
const features = await this.featureService.getAllArchivedFeatures(
Expand All @@ -153,14 +153,14 @@ export default class ArchiveController extends Controller {
this.openApiService.respondWithValidation(
200,
res,
featuresSchema.$id,
archivedFeaturesSchema.$id,
{ version: 2, features: serializeDates(features) },
);
}

async getArchivedFeaturesByProjectId(
req: Request<{ projectId: string }, any, any, any>,
res: Response<FeaturesSchema>,
res: Response<ArchivedFeaturesSchema>,
): Promise<void> {
const { projectId } = req.params;
const features =
Expand All @@ -171,7 +171,7 @@ export default class ArchiveController extends Controller {
this.openApiService.respondWithValidation(
200,
res,
featuresSchema.$id,
archivedFeaturesSchema.$id,
{ version: 2, features: serializeDates(features) },
);
}
Expand Down
21 changes: 5 additions & 16 deletions src/lib/features/feature-toggle/feature-toggle-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ import {
type FeatureEnvironmentSchema,
featureSchema,
type FeatureSchema,
featuresSchema,
type FeaturesSchema,
featureStrategySchema,
type FeatureStrategySchema,
getStandardResponses,
type ParametersSchema,
projectFeaturesSchema,
type ProjectFeaturesSchema,
type SetStrategySortOrderSchema,
type TagsBulkAddSchema,
type TagSchema,
Expand Down Expand Up @@ -421,7 +420,7 @@ export default class ProjectFeaturesController extends Controller {
tags: ['Features'],
operationId: 'getFeatures',
responses: {
200: createResponseSchema('featuresSchema'),
200: createResponseSchema('projectFeaturesSchema'),
...getStandardResponses(400, 401, 403),
},
}),
Expand Down Expand Up @@ -606,7 +605,7 @@ export default class ProjectFeaturesController extends Controller {

async getFeatures(
req: IAuthRequest<ProjectParam, any, any, AdminFeaturesQuerySchema>,
res: Response<FeaturesSchema>,
res: Response<ProjectFeaturesSchema>,
): Promise<void> {
const { projectId } = req.params;
const query = await this.prepQuery(req.query, projectId);
Expand All @@ -617,7 +616,7 @@ export default class ProjectFeaturesController extends Controller {
this.openApiService.respondWithValidation(
200,
res,
featuresSchema.$id,
projectFeaturesSchema.$id,
{ version: 2, features: serializeDates(features) },
);
}
Expand Down Expand Up @@ -1155,14 +1154,4 @@ export default class ProjectFeaturesController extends Controller {
);
res.status(200).end();
}

async getStrategyParameters(
req: Request<StrategyIdParams, any, any, any>,
res: Response<ParametersSchema>,
): Promise<void> {
this.logger.info('Getting strategy parameters');
const { strategyId } = req.params;
const strategy = await this.featureService.getStrategy(strategyId);
res.status(200).json(strategy.parameters);
}
}
102 changes: 102 additions & 0 deletions src/lib/openapi/spec/archived-feature-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import type { FromSchema } from 'json-schema-to-ts';

export const archivedFeatureSchema = {
$id: '#/components/schemas/archivedFeatureSchema',
type: 'object',
additionalProperties: false,
required: ['name', 'project'],
description: 'An archived project feature flag definition',
properties: {
name: {
type: 'string',
example: 'disable-comments',
description: 'Unique feature name',
},
type: {
type: 'string',
example: 'kill-switch',
description:
'Type of the flag e.g. experiment, kill-switch, release, operational, permission',
},
description: {
type: 'string',
nullable: true,
example:
'Controls disabling of the comments section in case of an incident',
description: 'Detailed description of the feature',
},
project: {
type: 'string',
example: 'dx-squad',
description: 'Name of the project the feature belongs to',
},
stale: {
type: 'boolean',
example: false,
description:
'`true` if the feature is stale based on the age and feature type, otherwise `false`.',
},
impressionData: {
type: 'boolean',
example: false,
description:
'`true` if the impression data collection is enabled for the feature, otherwise `false`.',
},
createdAt: {
type: 'string',
format: 'date-time',
example: '2023-01-28T15:21:39.975Z',
description: 'The date the feature was created',
},
archivedAt: {
type: 'string',
format: 'date-time',
example: '2023-01-29T15:21:39.975Z',
description: 'The date the feature was archived',
},
lastSeenAt: {
type: 'string',
format: 'date-time',
nullable: true,
deprecated: true,
example: '2023-01-28T16:21:39.975Z',
description:
'The date when metrics where last collected for the feature. This field was deprecated in v5, use the one in featureEnvironmentSchema',
},
environments: {
type: 'array',
deprecated: true,
description:
'The list of environments where the feature can be used',
items: {
type: 'object',
properties: {
name: {
type: 'string',
example: 'my-dev-env',
description: 'The name of the environment',
},
lastSeenAt: {
type: 'string',
format: 'date-time',
nullable: true,
example: '2023-01-28T16:21:39.975Z',
description:
'The date when metrics where last collected for the feature environment',
},
enabled: {
type: 'boolean',
example: true,
description:
'`true` if the feature is enabled for the environment, otherwise `false`.',
},
},
},
},
},
components: {
schemas: {},
},
} as const;

export type ArchivedFeatureSchema = FromSchema<typeof archivedFeatureSchema>;
31 changes: 31 additions & 0 deletions src/lib/openapi/spec/archived-features-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { FromSchema } from 'json-schema-to-ts';
import { archivedFeatureSchema } from './archived-feature-schema';

export const archivedFeaturesSchema = {
$id: '#/components/schemas/archivedFeaturesSchema',
type: 'object',
additionalProperties: false,
required: ['version', 'features'],
description: 'A list of archived features',
deprecated: true,
properties: {
version: {
type: 'integer',
description: "The version of the feature's schema",
},
features: {
type: 'array',
items: {
$ref: '#/components/schemas/archivedFeatureSchema',
},
description: 'A list of features',
},
},
components: {
schemas: {
archivedFeatureSchema,
},
},
} as const;

export type ArchivedFeaturesSchema = FromSchema<typeof archivedFeaturesSchema>;
13 changes: 0 additions & 13 deletions src/lib/openapi/spec/features-schema.test.ts

This file was deleted.

49 changes: 0 additions & 49 deletions src/lib/openapi/spec/features-schema.ts

This file was deleted.

6 changes: 5 additions & 1 deletion src/lib/openapi/spec/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export * from './application-overview-schema';
export * from './application-schema';
export * from './application-usage-schema';
export * from './applications-schema';
export * from './archived-feature-schema';
export * from './archived-features-schema';
export * from './batch-features-schema';
export * from './batch-stale-schema';
export * from './bulk-metrics-schema';
Expand Down Expand Up @@ -93,7 +95,6 @@ export * from './feature-type-schema';
export * from './feature-types-schema';
export * from './feature-usage-schema';
export * from './feature-variants-schema';
export * from './features-schema';
export * from './feedback-create-schema';
export * from './feedback-response-schema';
export * from './feedback-update-schema';
Expand Down Expand Up @@ -144,6 +145,9 @@ export * from './project-application-sdk-schema';
export * from './project-applications-schema';
export * from './project-dora-metrics-schema';
export * from './project-environment-schema';
export * from './project-feature-environment-schema';
export * from './project-feature-schema';
export * from './project-features-schema';
export * from './project-flag-creators-schema';
export * from './project-insights-schema';
export * from './project-overview-schema';
Expand Down
Loading

0 comments on commit 1f3cc39

Please sign in to comment.