unleash-server
Version:
Unleash is an enterprise ready feature toggles service. It provides different strategies for handling feature toggles.
103 lines • 4.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const date_fns_1 = require("date-fns");
class ProjectHealthService {
constructor({ projectStore, featureTypeStore, featureToggleStore, }, { getLogger }, featureToggleService, favoritesService) {
this.logger = getLogger('services/project-health-service.ts');
this.projectStore = projectStore;
this.featureTypeStore = featureTypeStore;
this.featureToggleStore = featureToggleStore;
this.featureTypes = new Map();
this.healthRatingTimer = setInterval(() => this.setHealthRating(), (0, date_fns_1.hoursToMilliseconds)(1)).unref();
this.featureToggleService = featureToggleService;
this.favoritesService = favoritesService;
}
// TODO: duplicate from project-service.
async getProjectOverview(projectId, archived = false, userId) {
const project = await this.projectStore.get(projectId);
const environments = await this.projectStore.getEnvironmentsForProject(projectId);
const features = await this.featureToggleService.getFeatureOverview({
projectId,
archived,
userId,
});
const members = await this.projectStore.getMembersCountByProject(projectId);
const favorite = await this.favoritesService.isFavoriteProject({
project: projectId,
userId,
});
return {
name: project.name,
description: project.description,
health: project.health,
favorite: favorite,
updatedAt: project.updatedAt,
environments,
features,
members,
version: 1,
};
}
async getProjectHealthReport(projectId) {
const overview = await this.getProjectOverview(projectId, false, undefined);
return {
...overview,
potentiallyStaleCount: await this.potentiallyStaleCount(overview.features),
activeCount: this.activeCount(overview.features),
staleCount: this.staleCount(overview.features),
};
}
async potentiallyStaleCount(features) {
const today = new Date().valueOf();
if (this.featureTypes.size === 0) {
const types = await this.featureTypeStore.getAll();
types.forEach((type) => {
this.featureTypes.set(type.name.toLowerCase(), type.lifetimeDays);
});
}
return features.filter((feature) => {
const diff = today - feature.createdAt.valueOf();
const featureTypeExpectedLifetime = this.featureTypes.get(feature.type);
return (!feature.stale &&
diff >= featureTypeExpectedLifetime * (0, date_fns_1.hoursToMilliseconds)(24));
}).length;
}
activeCount(features) {
return features.filter((f) => !f.stale).length;
}
staleCount(features) {
return features.filter((f) => f.stale).length;
}
async calculateHealthRating(project) {
const toggles = await this.featureToggleStore.getAll({
project: project.id,
archived: false,
});
const activeToggles = toggles.filter((feature) => !feature.stale);
const staleToggles = toggles.length - activeToggles.length;
const potentiallyStaleToggles = await this.potentiallyStaleCount(activeToggles);
return this.getHealthRating(toggles.length, staleToggles, potentiallyStaleToggles);
}
getHealthRating(toggleCount, staleToggleCount, potentiallyStaleCount) {
const startPercentage = 100;
const stalePercentage = (staleToggleCount / toggleCount) * 100 || 0;
const potentiallyStalePercentage = (potentiallyStaleCount / toggleCount) * 100 || 0;
const rating = Math.round(startPercentage - stalePercentage - potentiallyStalePercentage);
return rating;
}
async setHealthRating() {
const projects = await this.projectStore.getAll();
await Promise.all(projects.map(async (project) => {
const newHealth = await this.calculateHealthRating(project);
await this.projectStore.updateHealth({
id: project.id,
health: newHealth,
});
}));
}
destroy() {
clearInterval(this.healthRatingTimer);
}
}
exports.default = ProjectHealthService;
//# sourceMappingURL=project-health-service.js.map