mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-05 17:53:12 +02:00
feat: update backend to include technicalDebt
field (#10088)
Deprecate `health` for a more descriptive `technicalDebt` in project-related services and schemas.
This commit is contained in:
parent
c739ea71cf
commit
a5e5ea0436
@ -13,9 +13,13 @@ export type BasePersonalProject = {
|
|||||||
export type PersonalProject = BasePersonalProject & {
|
export type PersonalProject = BasePersonalProject & {
|
||||||
owners?: ProjectOwners;
|
owners?: ProjectOwners;
|
||||||
} & {
|
} & {
|
||||||
health: number;
|
technicalDebt: number;
|
||||||
memberCount: number;
|
memberCount: number;
|
||||||
featureCount: number;
|
featureCount: number;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
health: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IPersonalDashboardReadModel {
|
export interface IPersonalDashboardReadModel {
|
||||||
|
@ -96,6 +96,7 @@ export class PersonalDashboardService {
|
|||||||
id: project.id,
|
id: project.id,
|
||||||
name: project.name,
|
name: project.name,
|
||||||
health: project.health,
|
health: project.health,
|
||||||
|
technicalDebt: 100 - (project.health || 0),
|
||||||
memberCount: project.memberCount,
|
memberCount: project.memberCount,
|
||||||
featureCount: project.featureCount,
|
featureCount: project.featureCount,
|
||||||
}));
|
}));
|
||||||
@ -193,6 +194,7 @@ export class PersonalDashboardService {
|
|||||||
projectInsights?.potentiallyStaleFeatureCount || 0;
|
projectInsights?.potentiallyStaleFeatureCount || 0;
|
||||||
const staleFlags = projectInsights?.staleFeatureCount || 0;
|
const staleFlags = projectInsights?.staleFeatureCount || 0;
|
||||||
const currentHealth = projectInsights?.health || 0;
|
const currentHealth = projectInsights?.health || 0;
|
||||||
|
const technicalDebt = projectInsights?.technicalDebt || 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
latestEvents,
|
latestEvents,
|
||||||
@ -206,6 +208,10 @@ export class PersonalDashboardService {
|
|||||||
potentiallyStaleFlags,
|
potentiallyStaleFlags,
|
||||||
staleFlags,
|
staleFlags,
|
||||||
activeFlags: totalFlags - staleFlags - potentiallyStaleFlags,
|
activeFlags: totalFlags - staleFlags - potentiallyStaleFlags,
|
||||||
|
technicalDebt,
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
health: currentHealth,
|
health: currentHealth,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -47,6 +47,12 @@ test('Return basic insights', async () => {
|
|||||||
staleCount: 0,
|
staleCount: 0,
|
||||||
rating: 100,
|
rating: 100,
|
||||||
},
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
activeCount: 0,
|
||||||
|
potentiallyStaleCount: 0,
|
||||||
|
staleCount: 0,
|
||||||
|
rating: 0,
|
||||||
|
},
|
||||||
leadTime: { features: [], projectAverage: 0 },
|
leadTime: { features: [], projectAverage: 0 },
|
||||||
members: { currentMembers: 0, change: 0 },
|
members: { currentMembers: 0, change: 0 },
|
||||||
});
|
});
|
||||||
|
@ -93,6 +93,10 @@ export class ProjectInsightsService {
|
|||||||
activeCount,
|
activeCount,
|
||||||
potentiallyStaleCount,
|
potentiallyStaleCount,
|
||||||
staleCount,
|
staleCount,
|
||||||
|
technicalDebt: overview.technicalDebt,
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
rating: overview.health,
|
rating: overview.health,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -101,7 +105,14 @@ export class ProjectInsightsService {
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
archived: boolean = false,
|
archived: boolean = false,
|
||||||
userId?: number,
|
userId?: number,
|
||||||
): Promise<{ health: number; features: IFeatureOverview[] }> {
|
): Promise<{
|
||||||
|
technicalDebt: number;
|
||||||
|
features: IFeatureOverview[];
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
health: number;
|
||||||
|
}> {
|
||||||
const [project, features] = await Promise.all([
|
const [project, features] = await Promise.all([
|
||||||
this.projectStore.get(projectId),
|
this.projectStore.get(projectId),
|
||||||
this.featureStrategiesStore.getFeatureOverview({
|
this.featureStrategiesStore.getFeatureOverview({
|
||||||
@ -113,6 +124,7 @@ export class ProjectInsightsService {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
health: project?.health || 0,
|
health: project?.health || 0,
|
||||||
|
technicalDebt: 100 - (project?.health || 0),
|
||||||
features: features,
|
features: features,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -151,9 +163,23 @@ export class ProjectInsightsService {
|
|||||||
return {
|
return {
|
||||||
stats,
|
stats,
|
||||||
featureTypeCounts,
|
featureTypeCounts,
|
||||||
health,
|
technicalDebt: {
|
||||||
|
rating: health.technicalDebt,
|
||||||
|
activeCount: health.activeCount,
|
||||||
|
potentiallyStaleCount: health.potentiallyStaleCount,
|
||||||
|
staleCount: health.staleCount,
|
||||||
|
},
|
||||||
leadTime,
|
leadTime,
|
||||||
members,
|
members,
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
health: {
|
||||||
|
rating: health.rating,
|
||||||
|
activeCount: health.activeCount,
|
||||||
|
potentiallyStaleCount: health.potentiallyStaleCount,
|
||||||
|
staleCount: health.staleCount,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,9 @@ export class ProjectStatusService {
|
|||||||
health: {
|
health: {
|
||||||
current: currentHealth,
|
current: currentHealth,
|
||||||
},
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
current: 100 - currentHealth,
|
||||||
|
},
|
||||||
lifecycleSummary,
|
lifecycleSummary,
|
||||||
staleFlags: {
|
staleFlags: {
|
||||||
total: staleFlagCount,
|
total: staleFlagCount,
|
||||||
|
@ -18,12 +18,16 @@ export type ProjectForUi = {
|
|||||||
|
|
||||||
export type ProjectForInsights = {
|
export type ProjectForInsights = {
|
||||||
id: string;
|
id: string;
|
||||||
health: number;
|
technicalDebt: number;
|
||||||
memberCount: number;
|
memberCount: number;
|
||||||
featureCount: number;
|
featureCount: number;
|
||||||
staleFeatureCount: number;
|
staleFeatureCount: number;
|
||||||
potentiallyStaleFeatureCount: number;
|
potentiallyStaleFeatureCount: number;
|
||||||
avgTimeToProduction: number;
|
avgTimeToProduction: number;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
health: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IProjectReadModel {
|
export interface IProjectReadModel {
|
||||||
|
@ -42,6 +42,7 @@ const mapProjectForInsights = (row): ProjectForInsights => {
|
|||||||
Number(row.potentially_stale_feature_count) || 0,
|
Number(row.potentially_stale_feature_count) || 0,
|
||||||
memberCount: Number(row.number_of_users) || 0,
|
memberCount: Number(row.number_of_users) || 0,
|
||||||
avgTimeToProduction: row.avg_time_to_prod_current_window || 0,
|
avgTimeToProduction: row.avg_time_to_prod_current_window || 0,
|
||||||
|
technicalDebt: 100 - (row.health || 0),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1280,6 +1280,7 @@ export default class ProjectService {
|
|||||||
featureNaming: project.featureNaming,
|
featureNaming: project.featureNaming,
|
||||||
defaultStickiness: project.defaultStickiness,
|
defaultStickiness: project.defaultStickiness,
|
||||||
health: project.health || 0,
|
health: project.health || 0,
|
||||||
|
technicalDebt: 100 - (project.health || 0),
|
||||||
favorite: favorite,
|
favorite: favorite,
|
||||||
updatedAt: project.updatedAt,
|
updatedAt: project.updatedAt,
|
||||||
createdAt: project.createdAt,
|
createdAt: project.createdAt,
|
||||||
@ -1338,6 +1339,7 @@ export default class ProjectService {
|
|||||||
linkTemplates: project.linkTemplates,
|
linkTemplates: project.linkTemplates,
|
||||||
defaultStickiness: project.defaultStickiness,
|
defaultStickiness: project.defaultStickiness,
|
||||||
health: project.health || 0,
|
health: project.health || 0,
|
||||||
|
technicalDebt: 100 - (project.health || 0),
|
||||||
favorite: favorite,
|
favorite: favorite,
|
||||||
updatedAt: project.updatedAt,
|
updatedAt: project.updatedAt,
|
||||||
archivedAt: project.archivedAt,
|
archivedAt: project.archivedAt,
|
||||||
|
@ -26,6 +26,7 @@ export const healthOverviewSchema = {
|
|||||||
'mode',
|
'mode',
|
||||||
'members',
|
'members',
|
||||||
'health',
|
'health',
|
||||||
|
'technicalDebt',
|
||||||
'environments',
|
'environments',
|
||||||
'features',
|
'features',
|
||||||
],
|
],
|
||||||
@ -75,9 +76,17 @@ export const healthOverviewSchema = {
|
|||||||
},
|
},
|
||||||
health: {
|
health: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description:
|
description: 'Use `technicalDebt` instead.',
|
||||||
'The overall [health rating](https://docs.getunleash.io/reference/technical-debt#project-status) of the project.',
|
|
||||||
example: 95,
|
example: 95,
|
||||||
|
deprecated: true,
|
||||||
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
type: 'number',
|
||||||
|
example: 25,
|
||||||
|
minimum: 0,
|
||||||
|
maximum: 100,
|
||||||
|
description:
|
||||||
|
"An indicator of the [project's technical debt](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
||||||
},
|
},
|
||||||
environments: {
|
environments: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
@ -28,6 +28,7 @@ export const personalDashboardProjectDetailsSchema = {
|
|||||||
'staleFlags',
|
'staleFlags',
|
||||||
'potentiallyStaleFlags',
|
'potentiallyStaleFlags',
|
||||||
'health',
|
'health',
|
||||||
|
'technicalDebt',
|
||||||
],
|
],
|
||||||
properties: {
|
properties: {
|
||||||
avgHealthCurrentWindow: {
|
avgHealthCurrentWindow: {
|
||||||
@ -76,8 +77,17 @@ export const personalDashboardProjectDetailsSchema = {
|
|||||||
health: {
|
health: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
description: "The project's current health score",
|
description: 'Use `technicalDebt` instead.',
|
||||||
example: 80,
|
example: 80,
|
||||||
|
deprecated: true,
|
||||||
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
type: 'integer',
|
||||||
|
example: 25,
|
||||||
|
minimum: 0,
|
||||||
|
maximum: 100,
|
||||||
|
description:
|
||||||
|
"An indicator of the [project's technical debt](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -84,6 +84,7 @@ export const personalDashboardSchema = {
|
|||||||
'id',
|
'id',
|
||||||
'name',
|
'name',
|
||||||
'health',
|
'health',
|
||||||
|
'technicalDebt',
|
||||||
'memberCount',
|
'memberCount',
|
||||||
'featureCount',
|
'featureCount',
|
||||||
],
|
],
|
||||||
@ -102,8 +103,16 @@ export const personalDashboardSchema = {
|
|||||||
type: 'integer',
|
type: 'integer',
|
||||||
example: 50,
|
example: 50,
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
|
deprecated: true,
|
||||||
|
description: 'Use `technicalDebt` instead.',
|
||||||
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
type: 'integer',
|
||||||
|
example: 25,
|
||||||
|
minimum: 0,
|
||||||
|
maximum: 100,
|
||||||
description:
|
description:
|
||||||
"An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
"An indicator of the [project's technical debt](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
||||||
},
|
},
|
||||||
memberCount: {
|
memberCount: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
|
@ -8,7 +8,14 @@ export const projectInsightsSchema = {
|
|||||||
$id: '#/components/schemas/projectInsightsSchema',
|
$id: '#/components/schemas/projectInsightsSchema',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ['stats', 'leadTime', 'featureTypeCounts', 'health', 'members'],
|
required: [
|
||||||
|
'stats',
|
||||||
|
'leadTime',
|
||||||
|
'featureTypeCounts',
|
||||||
|
'health',
|
||||||
|
'technicalDebt',
|
||||||
|
'members',
|
||||||
|
],
|
||||||
description:
|
description:
|
||||||
'A high-level overview of a project insights. It contains information such as project statistics, overall health, types of flags, members overview, change requests overview.',
|
'A high-level overview of a project insights. It contains information such as project statistics, overall health, types of flags, members overview, change requests overview.',
|
||||||
properties: {
|
properties: {
|
||||||
@ -18,6 +25,7 @@ export const projectInsightsSchema = {
|
|||||||
},
|
},
|
||||||
health: {
|
health: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
deprecated: true,
|
||||||
required: [
|
required: [
|
||||||
'rating',
|
'rating',
|
||||||
'activeCount',
|
'activeCount',
|
||||||
@ -28,7 +36,7 @@ export const projectInsightsSchema = {
|
|||||||
rating: {
|
rating: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
description:
|
description:
|
||||||
"An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
"An indicator of the [project's technical debt](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
||||||
example: 95,
|
example: 95,
|
||||||
},
|
},
|
||||||
activeCount: {
|
activeCount: {
|
||||||
@ -48,7 +56,44 @@ export const projectInsightsSchema = {
|
|||||||
example: 10,
|
example: 10,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
description: 'Health summary of the project',
|
description:
|
||||||
|
'Use `technicalDebt` instead. Summary of the project health',
|
||||||
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
type: 'object',
|
||||||
|
required: [
|
||||||
|
'rating',
|
||||||
|
'activeCount',
|
||||||
|
'potentiallyStaleCount',
|
||||||
|
'staleCount',
|
||||||
|
],
|
||||||
|
properties: {
|
||||||
|
rating: {
|
||||||
|
type: 'integer',
|
||||||
|
description:
|
||||||
|
"An indicator of the [project's technical debt](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
||||||
|
example: 25,
|
||||||
|
minimum: 0,
|
||||||
|
maximum: 100,
|
||||||
|
},
|
||||||
|
activeCount: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'The number of active feature flags.',
|
||||||
|
example: 12,
|
||||||
|
},
|
||||||
|
potentiallyStaleCount: {
|
||||||
|
type: 'number',
|
||||||
|
description:
|
||||||
|
'The number of potentially stale feature flags.',
|
||||||
|
example: 5,
|
||||||
|
},
|
||||||
|
staleCount: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'The number of stale feature flags.',
|
||||||
|
example: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Summary of the projects technical debt',
|
||||||
},
|
},
|
||||||
leadTime: {
|
leadTime: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -84,8 +84,16 @@ export const projectOverviewSchema = {
|
|||||||
health: {
|
health: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
example: 50,
|
example: 50,
|
||||||
|
deprecated: true,
|
||||||
|
description: 'Use `technicalDebt` instead.',
|
||||||
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
type: 'number',
|
||||||
|
example: 25,
|
||||||
|
minimum: 0,
|
||||||
|
maximum: 100,
|
||||||
description:
|
description:
|
||||||
"An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
"An indicator of the [project's technical debt](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
||||||
},
|
},
|
||||||
environments: {
|
environments: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
@ -28,8 +28,16 @@ export const projectSchema = {
|
|||||||
health: {
|
health: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
example: 50,
|
example: 50,
|
||||||
|
description: 'Use `technicalDebt` instead.',
|
||||||
|
deprecated: true,
|
||||||
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
type: 'number',
|
||||||
|
example: 25,
|
||||||
|
minimum: 0,
|
||||||
|
maximum: 100,
|
||||||
description:
|
description:
|
||||||
"An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
"An indicator of the [project's technical debt](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100",
|
||||||
},
|
},
|
||||||
featureCount: {
|
featureCount: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
@ -6,6 +6,9 @@ test('projectStatusSchema', () => {
|
|||||||
health: {
|
health: {
|
||||||
current: 50,
|
current: 50,
|
||||||
},
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
current: 50,
|
||||||
|
},
|
||||||
lifecycleSummary: {
|
lifecycleSummary: {
|
||||||
initial: {
|
initial: {
|
||||||
currentFlags: 0,
|
currentFlags: 0,
|
||||||
|
@ -32,6 +32,7 @@ export const projectStatusSchema = {
|
|||||||
'activityCountByDate',
|
'activityCountByDate',
|
||||||
'resources',
|
'resources',
|
||||||
'health',
|
'health',
|
||||||
|
'technicalDebt',
|
||||||
'lifecycleSummary',
|
'lifecycleSummary',
|
||||||
'staleFlags',
|
'staleFlags',
|
||||||
],
|
],
|
||||||
@ -57,6 +58,21 @@ export const projectStatusSchema = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
technicalDebt: {
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: false,
|
||||||
|
required: ['current'],
|
||||||
|
description: "Information about the project's health rating",
|
||||||
|
properties: {
|
||||||
|
current: {
|
||||||
|
type: 'integer',
|
||||||
|
minimum: 0,
|
||||||
|
maximum: 100,
|
||||||
|
description: `The project's current health score, based on the ratio of healthy flags to stale and potentially stale flags.`,
|
||||||
|
example: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
resources: {
|
resources: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
|
@ -342,7 +342,7 @@ export interface IProjectHealth {
|
|||||||
features: IFeatureOverview[];
|
features: IFeatureOverview[];
|
||||||
members: number;
|
members: number;
|
||||||
version: number;
|
version: number;
|
||||||
health: number;
|
technicalDebt: number;
|
||||||
favorite?: boolean;
|
favorite?: boolean;
|
||||||
updatedAt?: Date;
|
updatedAt?: Date;
|
||||||
createdAt: Date | undefined;
|
createdAt: Date | undefined;
|
||||||
@ -351,6 +351,10 @@ export interface IProjectHealth {
|
|||||||
featureLimit?: number;
|
featureLimit?: number;
|
||||||
featureNaming?: IFeatureNaming;
|
featureNaming?: IFeatureNaming;
|
||||||
defaultStickiness: string;
|
defaultStickiness: string;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
health: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProjectOnboardingStatus =
|
export type ProjectOnboardingStatus =
|
||||||
@ -366,7 +370,7 @@ export interface IProjectOverview {
|
|||||||
featureTypeCounts: IFeatureTypeCount[];
|
featureTypeCounts: IFeatureTypeCount[];
|
||||||
members: number;
|
members: number;
|
||||||
version: number;
|
version: number;
|
||||||
health: number;
|
technicalDebt: number;
|
||||||
favorite?: boolean;
|
favorite?: boolean;
|
||||||
updatedAt?: Date;
|
updatedAt?: Date;
|
||||||
archivedAt?: Date;
|
archivedAt?: Date;
|
||||||
@ -378,6 +382,10 @@ export interface IProjectOverview {
|
|||||||
defaultStickiness: string;
|
defaultStickiness: string;
|
||||||
onboardingStatus: ProjectOnboardingStatus;
|
onboardingStatus: ProjectOnboardingStatus;
|
||||||
linkTemplates?: IProjectLinkTemplate[];
|
linkTemplates?: IProjectLinkTemplate[];
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
health: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IProjectHealthReport extends IProjectHealth {
|
export interface IProjectHealthReport extends IProjectHealth {
|
||||||
|
Loading…
Reference in New Issue
Block a user