2023-01-31 13:08:20 +01:00
|
|
|
import { hoursToMilliseconds } from 'date-fns';
|
|
|
|
import type { IProjectHealthReport } from 'lib/types';
|
|
|
|
import type { IFeatureType } from 'lib/types/stores/feature-type-store';
|
|
|
|
|
2023-02-02 12:01:16 +01:00
|
|
|
type IPartialFeatures = Array<{
|
|
|
|
stale?: boolean;
|
|
|
|
createdAt?: Date;
|
|
|
|
type?: string;
|
|
|
|
}>;
|
|
|
|
|
2023-01-31 13:08:20 +01:00
|
|
|
const getPotentiallyStaleCount = (
|
2023-02-02 12:01:16 +01:00
|
|
|
features: IPartialFeatures,
|
2023-01-31 13:08:20 +01:00
|
|
|
featureTypes: IFeatureType[],
|
|
|
|
) => {
|
|
|
|
const today = new Date().valueOf();
|
|
|
|
|
|
|
|
return features.filter((feature) => {
|
|
|
|
const diff = today - feature.createdAt?.valueOf();
|
|
|
|
const featureTypeExpectedLifetime = featureTypes.find(
|
|
|
|
(t) => t.id === feature.type,
|
|
|
|
)?.lifetimeDays;
|
|
|
|
|
|
|
|
return (
|
|
|
|
!feature.stale &&
|
2023-02-02 12:01:16 +01:00
|
|
|
featureTypeExpectedLifetime !== null &&
|
2023-01-31 13:08:20 +01:00
|
|
|
diff >= featureTypeExpectedLifetime * hoursToMilliseconds(24)
|
|
|
|
);
|
|
|
|
}).length;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const calculateProjectHealth = (
|
2023-02-02 12:01:16 +01:00
|
|
|
features: IPartialFeatures,
|
2023-01-31 13:08:20 +01:00
|
|
|
featureTypes: IFeatureType[],
|
|
|
|
): Pick<
|
|
|
|
IProjectHealthReport,
|
|
|
|
'staleCount' | 'potentiallyStaleCount' | 'activeCount'
|
|
|
|
> => ({
|
|
|
|
potentiallyStaleCount: getPotentiallyStaleCount(features, featureTypes),
|
|
|
|
activeCount: features.filter((f) => !f.stale).length,
|
|
|
|
staleCount: features.filter((f) => f.stale).length,
|
|
|
|
});
|
|
|
|
|
2023-02-02 12:01:16 +01:00
|
|
|
export const calculateHealthRating = (
|
|
|
|
features: IPartialFeatures,
|
2023-01-31 13:08:20 +01:00
|
|
|
featureTypes: IFeatureType[],
|
|
|
|
): number => {
|
|
|
|
const { potentiallyStaleCount, activeCount, staleCount } =
|
|
|
|
calculateProjectHealth(features, featureTypes);
|
|
|
|
const toggleCount = activeCount + staleCount;
|
|
|
|
|
|
|
|
const startPercentage = 100;
|
|
|
|
const stalePercentage = (staleCount / toggleCount) * 100 || 0;
|
|
|
|
const potentiallyStalePercentage =
|
|
|
|
(potentiallyStaleCount / toggleCount) * 100 || 0;
|
|
|
|
const rating = Math.round(
|
|
|
|
startPercentage - stalePercentage - potentiallyStalePercentage,
|
|
|
|
);
|
|
|
|
|
|
|
|
return rating;
|
|
|
|
};
|