Added rudimentary entity health overview.

This commit is contained in:
2025-09-15 05:07:02 +02:00
parent 37b40f1744
commit 32202d8ab5
6 changed files with 248 additions and 9 deletions

View File

@@ -19,6 +19,11 @@ export function curateEntity(entity, context) {
isIndependent: entity.independent,
hasLogo: entity.has_logo,
parent: curateEntity(entity.parent, context),
tags: context?.tags?.map((tag) => ({
id: tag.id,
name: tag.name,
slug: tag.slug,
})),
children: context?.children?.filter((child) => child.parent_id === entity.id).map((child) => curateEntity({ ...child, parent: entity }, { parent: entity })) || [],
affiliate: entity.affiliate ? {
id: entity.affiliate.id,
@@ -75,11 +80,18 @@ export async function fetchEntities(options = {}) {
.offset((options.page - 1) * options.limit)
.limit(options.limit || 1000);
return entities.map((entityEntry) => curateEntity(entityEntry));
const entitiesTags = await knex('entities_tags')
.select('entity_id', 'tags.*')
.leftJoin('tags', 'tags.id', 'tag_id')
.whereIn('entity_id', entities.map((entity) => entity.id));
return entities.map((entityEntry) => curateEntity(entityEntry, {
tags: entitiesTags.filter((tag) => tag.entity_id === entityEntry.id),
}));
}
export async function fetchEntitiesById(entityIds, options = {}, reqUser) {
const [entities, children, alerts] = await Promise.all([
const [entities, children, tags, alerts] = await Promise.all([
knex('entities')
.select(
'entities.*',
@@ -99,6 +111,10 @@ export async function fetchEntitiesById(entityIds, options = {}, reqUser) {
.whereIn('entities.parent_id', entityIds)
.whereNot('type', 'info')
.orderBy('slug') : [],
knex('entities_tags')
.select('entity_id', 'tags.*')
.leftJoin('tags', 'tags.id', 'tag_id')
.whereIn('entity_id', entityIds),
reqUser
? knex('alerts_users_entities')
.where('user_id', reqUser.id)
@@ -125,6 +141,7 @@ export async function fetchEntitiesById(entityIds, options = {}, reqUser) {
return curateEntity(entity, {
append: options.append,
children: children.filter((channel) => channel.parent_id === entity.id),
tags: tags.filter((tag) => tag.entity_id === entity.id),
alerts: alerts.filter((alert) => alert.entity_id === entity.id),
});
}).filter(Boolean);
@@ -158,3 +175,30 @@ export async function cacheEntityIds() {
logger.info('Cached entity IDs by slug');
}
const sortMap = {
releases: knex.raw('count(releases.id)'),
latest: 'latest_release_date',
};
export async function fetchEntityHealths(options) {
const entities = await knex('entities')
.select(
'entities.*',
knex.raw('max(effective_date) as latest_release_date'),
knex.raw('count(releases.id) as total_releases'),
)
.leftJoin('releases', 'releases.entity_id', 'entities.id')
.orderBy(sortMap[options.sort] || options.sort || sortMap.releases, options.order || 'desc')
.groupBy('entities.id');
const curatedEntities = entities.map((entity) => ({
...curateEntity(entity),
totalReleases: entity.total_releases,
latestReleaseDate: entity.latest_release_date,
}));
return {
entities: curatedEntities,
};
}