1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-26 13:48:33 +02:00

chore(AI): healthToTechDebt flag cleanup (#10346)

Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
Co-authored-by: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com>
This commit is contained in:
unleash-bot[bot] 2025-07-11 14:15:55 +02:00 committed by GitHub
parent cae5be4ad0
commit 96f59bccfa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 69 additions and 251 deletions

View File

@ -18,7 +18,6 @@ import { allOption } from 'component/common/ProjectSelect/ProjectSelect';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { WidgetTitle } from './components/WidgetTitle/WidgetTitle.tsx';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { useUiFlag } from 'hooks/useUiFlag.ts';
export interface IChartsProps {
flagTrends: InstanceInsightsSchema['flagTrends'];
@ -39,6 +38,7 @@ export interface IChartsProps {
potentiallyStale: number;
averageUsers: number;
averageHealth?: string;
technicalDebt?: string;
flagsPerUser?: string;
medianTimeToProduction?: number;
};
@ -105,7 +105,6 @@ export const InsightsCharts: FC<IChartsProps> = ({
const showAllProjects = projects[0] === allOption.id;
const isOneProjectSelected = projects.length === 1;
const { isEnterprise } = useUiConfig();
const healthToDebtEnabled = useUiFlag('healthToTechDebt');
const lastUserTrend = userTrends[userTrends.length - 1];
const lastFlagTrend = flagTrends[flagTrends.length - 1];
@ -186,20 +185,15 @@ export const InsightsCharts: FC<IChartsProps> = ({
<StyledWidgetStats width={350} padding={0}>
<HealthStats
value={summary.averageHealth}
technicalDebt={summary.technicalDebt}
healthy={summary.active}
stale={summary.stale}
potentiallyStale={summary.potentiallyStale}
title={
<WidgetTitle
title={
healthToDebtEnabled
? 'Technical debt'
: 'Health'
}
title={'Technical debt'}
tooltip={
healthToDebtEnabled
? 'Percentage of stale and potentially stale flags.'
: 'Percentage of flags that are not stale or potentially stale.'
'Percentage of stale and potentially stale flags.'
}
/>
}

View File

@ -6,7 +6,6 @@ import type { TooltipState } from 'component/insights/components/LineChart/Chart
import { HorizontalDistributionChart } from 'component/insights/components/HorizontalDistributionChart/HorizontalDistributionChart';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { getTechnicalDebtColor } from 'utils/getTechnicalDebtColor.ts';
import { useUiFlag } from 'hooks/useUiFlag';
const StyledTooltipItemContainer = styled(Paper)(({ theme }) => ({
padding: theme.spacing(2),
@ -19,22 +18,6 @@ const StyledItemHeader = styled(Box)(({ theme }) => ({
alignItems: 'center',
}));
const getHealthBadgeColor = (health?: number | null) => {
if (health === undefined || health === null) {
return 'info';
}
if (health >= 75) {
return 'success';
}
if (health >= 50) {
return 'warning';
}
return 'error';
};
const getTechnicalDebtBadgeColor = (technicalDebt?: number | null) => {
if (technicalDebt === undefined || technicalDebt === null) {
return 'info';
@ -108,8 +91,6 @@ const Distribution = ({ stale = 0, potentiallyStale = 0, total = 0 }) => {
export const HealthTooltip: FC<{ tooltip: TooltipState | null }> = ({
tooltip,
}) => {
const healthToTechDebtEnabled = useUiFlag('healthToTechDebt');
const data = tooltip?.dataPoints.map((point) => {
return {
label: point.label,
@ -148,9 +129,7 @@ export const HealthTooltip: FC<{ tooltip: TooltipState | null }> = ({
color='textSecondary'
component='span'
>
{healthToTechDebtEnabled
? 'Technical debt'
: 'Project health'}
Technical debt
</Typography>
</StyledItemHeader>
<StyledItemHeader>
@ -163,21 +142,13 @@ export const HealthTooltip: FC<{ tooltip: TooltipState | null }> = ({
</Typography>
<strong>{point.title}</strong>
</Typography>
{healthToTechDebtEnabled ? (
<Badge
color={getTechnicalDebtBadgeColor(
point.value.technicalDebt,
)}
>
{point.value.technicalDebt}%
</Badge>
) : (
<Badge
color={getHealthBadgeColor(point.value.health)}
>
{point.value.health}%
</Badge>
)}
<Badge
color={getTechnicalDebtBadgeColor(
point.value.technicalDebt,
)}
>
{point.value.technicalDebt}%
</Badge>
</StyledItemHeader>{' '}
<Divider
sx={(theme) => ({ margin: theme.spacing(1.5, 0) })}

View File

@ -14,7 +14,6 @@ import {
import { useTheme } from '@mui/material';
import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends';
import { usePlaceholderData } from 'component/insights/hooks/usePlaceholderData';
import { useUiFlag } from 'hooks/useUiFlag.ts';
interface IProjectHealthChartProps {
projectFlagTrends: GroupedDataByProject<
@ -46,7 +45,6 @@ export const ProjectHealthChart: FC<IProjectHealthChartProps> = ({
const projectsData = useProjectChartData(projectFlagTrends);
const theme = useTheme();
const placeholderData = usePlaceholderData();
const healthToTechDebtEnabled = useUiFlag('healthToTechDebt');
const aggregateHealthData = useMemo(() => {
const labels = Array.from(
@ -85,18 +83,12 @@ export const ProjectHealthChart: FC<IProjectHealthChartProps> = ({
return {
datasets: [
{
label: healthToTechDebtEnabled
? 'Technical debt'
: 'Health',
label: 'Technical debt',
data: weeks.map((item) => ({
health: item.total ? calculateHealth(item) : undefined,
...(healthToTechDebtEnabled
? {
technicalDebt: item.total
? calculateTechDebt(item)
: undefined,
}
: {}),
technicalDebt: item.total
? calculateTechDebt(item)
: undefined,
date: item.date,
total: item.total,
stale: item.stale,
@ -132,9 +124,7 @@ export const ProjectHealthChart: FC<IProjectHealthChartProps> = ({
? {}
: {
parsing: {
yAxisKey: healthToTechDebtEnabled
? 'technicalDebt'
: 'health',
yAxisKey: 'technicalDebt',
xAxisKey: 'date',
},
plugins: {

View File

@ -1,7 +1,6 @@
import type { FC, ReactNode } from 'react';
import { Box, Divider, Link, styled } from '@mui/material';
import { ReactComponent as InstanceHealthIcon } from 'assets/icons/instance-health.svg';
import { useUiFlag } from 'hooks/useUiFlag';
interface IHealthStatsProps {
value?: string | number;
@ -73,8 +72,6 @@ export const HealthStats: FC<IHealthStatsProps> = ({
potentiallyStale,
title,
}) => {
const healthToDebtEnabled = useUiFlag('healthToTechDebt');
return (
<StyledContainer>
<StyledHeader>
@ -84,12 +81,8 @@ export const HealthStats: FC<IHealthStatsProps> = ({
<StyledSection>
<StyledStatsRow>
<StyledIcon />
{healthToDebtEnabled ? 'Technical debt' : 'Instance health'}
{healthToDebtEnabled ? (
<StyledMainValue>{`${technicalDebt}%`}</StyledMainValue>
) : (
<StyledMainValue>{`${value || 0}%`}</StyledMainValue>
)}
Technical debt
<StyledMainValue>{`${technicalDebt}%`}</StyledMainValue>
</StyledStatsRow>
</StyledSection>
<Divider />
@ -112,9 +105,7 @@ export const HealthStats: FC<IHealthStatsProps> = ({
target='_blank'
rel='noreferrer'
>
{healthToDebtEnabled
? 'What affects technical debt?'
: 'What affects instance health?'}
What affects technical debt?
</Link>
</ExplanationRow>
</FlagsSection>

View File

@ -23,7 +23,6 @@ import {
StyledWidgetContent,
StyledWidgetStats,
} from '../InsightsCharts.styles';
import { useUiFlag } from 'hooks/useUiFlag';
export const PerformanceInsights: FC = () => {
const statePrefix = 'performance-';
@ -48,8 +47,6 @@ export const PerformanceInsights: FC = () => {
state[`${statePrefix}to`]?.values[0],
);
const healthToTechDebtEnabled = useUiFlag('healthToTechDebt');
const projects = state[`${statePrefix}project`]?.values ?? [allOption.id];
const showAllProjects = projects[0] === allOption.id;
@ -135,21 +132,12 @@ export const PerformanceInsights: FC = () => {
stale={summary.stale}
potentiallyStale={summary.potentiallyStale}
title={
healthToTechDebtEnabled ? (
<WidgetTitle
title='Technical debt'
tooltip={
'Percentage of flags that are stale or potentially stale.'
}
/>
) : (
<WidgetTitle
title='Health'
tooltip={
'Percentage of flags that are not stale or potentially stale.'
}
/>
)
<WidgetTitle
title='Technical debt'
tooltip={
'Percentage of flags that are stale or potentially stale.'
}
/>
}
/>
</StyledWidgetStats>

View File

@ -39,13 +39,10 @@ import { ActionBox } from './ActionBox.tsx';
import useLoading from 'hooks/useLoading';
import { NoProjectsContactAdmin } from './NoProjectsContactAdmin.tsx';
import { AskOwnerToAddYouToTheirProject } from './AskOwnerToAddYouToTheirProject.tsx';
import { useUiFlag } from 'hooks/useUiFlag.ts';
const ActiveProjectDetails: FC<{
project: PersonalDashboardSchemaProjectsItem;
}> = ({ project }) => {
const healthToTechDebtEnabled = useUiFlag('healthToTechDebt');
const techicalDebt = project.technicalDebt;
return (
<Box sx={{ display: 'flex', gap: 2 }}>
@ -67,10 +64,10 @@ const ActiveProjectDetails: FC<{
</Box>
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
<Typography variant='subtitle2' color='primary'>
{healthToTechDebtEnabled ? techicalDebt : project.health}%
{techicalDebt}%
</Typography>
<Typography variant='caption' color='text.secondary'>
{healthToTechDebtEnabled ? 'technical debt' : 'health'}
technical debt
</Typography>
</Box>
</Box>

View File

@ -18,7 +18,7 @@ const setupLongRunningProject = () => {
id: 'projectId',
memberCount: 10,
featureCount: 100,
health: 80,
techicalDebt: 20,
name: 'projectName',
},
],
@ -40,7 +40,7 @@ const setupLongRunningProject = () => {
potentiallyStaleFlags: 14,
staleFlags: 13,
activeFlags: 12,
health: 81,
technicalDebt: 19,
},
latestEvents: [{ summary: 'someone created a flag', id: 0 }],
roles: [{ name: 'Member' }],
@ -84,7 +84,7 @@ const setupNewProject = () => {
id: 'projectId',
memberCount: 3,
featureCount: 0,
health: 100,
technicalDebt: 0,
name: 'projectName',
},
],
@ -142,10 +142,10 @@ test('Render personal dashboard for a long running project', async () => {
await screen.findByText('projectName');
await screen.findByText('10'); // members
await screen.findByText('100'); // features
await screen.findAllByText('80%'); // health
await screen.findAllByText('20%'); // technical debt
await screen.findByText('Project health');
await screen.findByText('70%'); // avg health past window
await screen.findByText('Technical debt');
await screen.findByText('30%'); // avg technical debt past window
await screen.findByText('someone created a flag');
await screen.findByText('Member');
await screen.findByText('myFlag');
@ -161,7 +161,7 @@ test('Render personal dashboard for a new project', async () => {
await screen.findByText('projectName');
await screen.findByText('3'); // members
await screen.findByText('0'); // features
await screen.findByText('100%'); // health
await screen.findByText('0%'); // technical debt
await screen.findByText('Create a feature flag');
await screen.findByText('Connect an SDK');

View File

@ -4,7 +4,6 @@ import { Link } from 'react-router-dom';
import Lightbulb from '@mui/icons-material/LightbulbOutlined';
import type { PersonalDashboardProjectDetailsSchemaInsights } from 'openapi';
import { ActionBox } from './ActionBox.tsx';
import { useUiFlag } from 'hooks/useUiFlag.ts';
const PercentageScore = styled('span')(({ theme }) => ({
fontWeight: theme.typography.fontWeightBold,
@ -58,42 +57,24 @@ const ProjectHealthMessage: FC<{
insights: PersonalDashboardProjectDetailsSchemaInsights;
project: string;
}> = ({ trend, insights, project }) => {
const healthToTechDebtEnabled = useUiFlag('healthToTechDebt');
const { avgHealthCurrentWindow, avgHealthPastWindow, health } = insights;
const improveMessage = healthToTechDebtEnabled
? 'Remember to archive your stale feature flags to keep the technical debt low.'
: 'Remember to archive your stale feature flags to keep the project health growing.';
const { avgHealthCurrentWindow, avgHealthPastWindow } = insights;
const improveMessage =
'Remember to archive your stale feature flags to keep the technical debt low.';
const keepDoingMessage =
'This indicates that you are doing a good job of archiving your feature flags.';
const avgCurrentTechnicalDebt = 100 - (avgHealthCurrentWindow ?? 0);
const avgPastTechnicalDebt = 100 - (avgHealthPastWindow ?? 0);
if (trend === 'improved') {
if (healthToTechDebtEnabled) {
return (
<>
<Typography>
On average, your project technical debt went down from{' '}
<PercentageScore>
{avgPastTechnicalDebt}%
</PercentageScore>{' '}
to{' '}
<PercentageScore>
{avgCurrentTechnicalDebt}%
</PercentageScore>{' '}
during the last 4 weeks.
</Typography>
<Typography>{keepDoingMessage}</Typography>
</>
);
}
return (
<>
<Typography>
On average, your project health went up from{' '}
<PercentageScore>{avgHealthPastWindow}%</PercentageScore> to{' '}
<PercentageScore>{avgHealthCurrentWindow}%</PercentageScore>{' '}
On average, your project technical debt went down from{' '}
<PercentageScore>{avgPastTechnicalDebt}%</PercentageScore>{' '}
to{' '}
<PercentageScore>
{avgCurrentTechnicalDebt}%
</PercentageScore>{' '}
during the last 4 weeks.
</Typography>
<Typography>{keepDoingMessage}</Typography>
@ -102,31 +83,15 @@ const ProjectHealthMessage: FC<{
}
if (trend === 'declined') {
if (healthToTechDebtEnabled) {
return (
<>
<Typography>
On average, your project technical debt went up from{' '}
<PercentageScore>
{avgPastTechnicalDebt}%
</PercentageScore>{' '}
to{' '}
<PercentageScore>
{avgCurrentTechnicalDebt}%
</PercentageScore>{' '}
during the last 4 weeks.
</Typography>
<Typography>{improveMessage}</Typography>
</>
);
}
return (
<>
<Typography>
On average, your project health went down from{' '}
<PercentageScore>{avgHealthPastWindow}%</PercentageScore> to{' '}
<PercentageScore>{avgHealthCurrentWindow}%</PercentageScore>{' '}
On average, your project technical debt went up from{' '}
<PercentageScore>{avgPastTechnicalDebt}%</PercentageScore>{' '}
to{' '}
<PercentageScore>
{avgCurrentTechnicalDebt}%
</PercentageScore>{' '}
during the last 4 weeks.
</Typography>
<Typography>{improveMessage}</Typography>
@ -135,62 +100,31 @@ const ProjectHealthMessage: FC<{
}
if (trend === 'consistent') {
if (healthToTechDebtEnabled) {
return (
<>
<Typography>
On average, your project technical debt has remained at{' '}
<PercentageScore>
{avgCurrentTechnicalDebt}%
</PercentageScore>{' '}
during the last 4 weeks.
</Typography>
<Typography>{keepDoingMessage}</Typography>
</>
);
}
return (
<>
<Typography>
On average, your project health has remained at{' '}
<PercentageScore>{avgHealthCurrentWindow}%</PercentageScore>{' '}
On average, your project technical debt has remained at{' '}
<PercentageScore>
{avgCurrentTechnicalDebt}%
</PercentageScore>{' '}
during the last 4 weeks.
</Typography>
<Typography>
{avgHealthCurrentWindow && avgHealthCurrentWindow >= 75
? keepDoingMessage
: improveMessage}
</Typography>
<Typography>{keepDoingMessage}</Typography>
</>
);
}
if (trend === 'unknown') {
if (healthToTechDebtEnabled) {
return (
<>
<Typography>
Your current project technical debt is{' '}
<PercentageScore>
{avgCurrentTechnicalDebt}%
</PercentageScore>
.
</Typography>
<Typography>{improveMessage}</Typography>
</>
);
}
return (
<>
<Typography>
Your current health score is{' '}
<PercentageScore>{health}%</PercentageScore>.
</Typography>
<Typography>
{health >= 75 ? keepDoingMessage : improveMessage}
Your current project technical debt is{' '}
<PercentageScore>
{avgCurrentTechnicalDebt}%
</PercentageScore>
.
</Typography>
<Typography>{improveMessage}</Typography>
</>
);
}
@ -202,7 +136,6 @@ export const ProjectSetupComplete: FC<{
project: string;
insights: PersonalDashboardProjectDetailsSchemaInsights;
}> = ({ project, insights }) => {
const healthToTechDebtEnabled = useUiFlag('healthToTechDebt');
const projectHealthTrend = determineProjectHealthTrend(insights);
return (
@ -211,9 +144,7 @@ export const ProjectSetupComplete: FC<{
<>
<Lightbulb color='primary' />
<Typography sx={{ fontWeight: 'bold' }} component='h4'>
{healthToTechDebtEnabled
? 'Technical debt'
: 'Project health'}
Technical debt
</Typography>
</>
}

View File

@ -6,7 +6,6 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { HealthGridTile } from './ProjectHealthGrid.styles';
import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber';
import { getTechnicalDebtColor } from 'utils/getTechnicalDebtColor.ts';
import { useUiFlag } from 'hooks/useUiFlag';
const ChartRadius = 40;
const ChartStrokeWidth = 13;
@ -82,17 +81,6 @@ const UnhealthyFlagBox = ({ flagCount }: { flagCount: number }) => {
);
};
const useHealthColor = (healthRating: number) => {
const theme = useTheme();
if (healthRating <= 24) {
return theme.palette.error.main;
}
if (healthRating <= 74) {
return theme.palette.warning.border;
}
return theme.palette.success.border;
};
const useTechnicalDebtColor = (techicalDebt: number) => {
const theme = useTheme();
switch (getTechnicalDebtColor(techicalDebt)) {
@ -115,22 +103,18 @@ const Wrapper = styled(HealthGridTile)(({ theme }) => ({
export const ProjectHealth = () => {
const projectId = useRequiredPathParam('projectId');
const {
data: { health, technicalDebt, staleFlags },
data: { technicalDebt, staleFlags },
} = useProjectStatus(projectId);
const { isOss } = useUiConfig();
const theme = useTheme();
const healthToDebtEnabled = useUiFlag('healthToTechDebt');
const circumference = 2 * Math.PI * ChartRadius;
const healthRating = health.current;
const gapLength = 0.3;
const filledLength = 1 - gapLength;
const offset = 0.75 - gapLength / 2;
const healthLength = (healthRating / 100) * circumference * 0.7;
const technicalDebtLength =
((technicalDebt.current || 0) / 100) * circumference * 0.7;
const healthColor = useHealthColor(healthRating);
const technicalDebtColor = useTechnicalDebtColor(
technicalDebt.current || 0,
);
@ -155,17 +139,9 @@ export const ProjectHealth = () => {
cy='50'
r={ChartRadius}
fill='none'
stroke={
healthToDebtEnabled
? technicalDebtColor
: healthColor
}
stroke={technicalDebtColor}
strokeWidth={ChartStrokeWidth}
strokeDasharray={
healthToDebtEnabled
? `${technicalDebtLength} ${circumference - technicalDebtLength}`
: `${healthLength} ${circumference - healthLength}`
}
strokeDasharray={`${technicalDebtLength} ${circumference - technicalDebtLength}`}
strokeDashoffset={offset * circumference}
/>
<text
@ -176,32 +152,18 @@ export const ProjectHealth = () => {
fill={theme.palette.text.primary}
fontSize={theme.typography.h1.fontSize}
>
{healthToDebtEnabled
? technicalDebt.current || 0
: healthRating}
%
{technicalDebt.current || 0}%
</text>
</StyledSVG>
</SVGWrapper>
<TextContainer>
<Typography>
{healthToDebtEnabled ? (
<>
Your current technical debt rating is{' '}
{technicalDebt.current}%.
</>
) : (
<>
Your current project health rating is{' '}
{healthRating}%.
</>
)}
Your current technical debt rating is{' '}
{technicalDebt.current}%.
</Typography>
{!isOss() && (
<Link to={`/insights?project=IS%3A${projectId}`}>
{healthToDebtEnabled
? 'View technical debt over time'
: 'View health over time'}
View technical debt over time
</Link>
)}
</TextContainer>

View File

@ -87,7 +87,6 @@ export type UiFlags = {
customMetrics?: boolean;
lifecycleMetrics?: boolean;
createFlagDialogCache?: boolean;
healthToTechDebt?: boolean;
improvedJsonDiff?: boolean;
impactMetrics?: boolean;
crDiffView?: boolean;

View File

@ -56,7 +56,6 @@ export type IFlagKey =
| 'edgeObservability'
| 'reportUnknownFlags'
| 'lifecycleMetrics'
| 'healthToTechDebt'
| 'customMetrics'
| 'impactMetrics'
| 'createFlagDialogCache'
@ -269,10 +268,6 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_LIFECYCLE_METRICS,
false,
),
healthToTechDebt: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_HEALTH_TO_TECH_DEBT,
false,
),
createFlagDialogCache: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_CREATE_FLAG_DIALOG_CACHE,
false,