Compare commits

...

2 Commits

Author SHA1 Message Date
DebaucheryLibrarian 652c389840 0.19.1 2024-05-28 03:12:35 +02:00
DebaucheryLibrarian b9afde051e Improved notification efficiency. 2024-05-28 03:12:33 +02:00
3 changed files with 50 additions and 44 deletions

4
package-lock.json generated
View File

@ -1,11 +1,11 @@
{ {
"name": "traxxx-web", "name": "traxxx-web",
"version": "0.19.0", "version": "0.19.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"version": "0.19.0", "version": "0.19.1",
"dependencies": { "dependencies": {
"@brillout/json-serializer": "^0.5.8", "@brillout/json-serializer": "^0.5.8",
"@dicebear/collection": "^7.0.5", "@dicebear/collection": "^7.0.5",

View File

@ -75,5 +75,5 @@
"postcss-custom-media": "^10.0.2", "postcss-custom-media": "^10.0.2",
"postcss-nesting": "^12.0.2" "postcss-nesting": "^12.0.2"
}, },
"version": "0.19.0" "version": "0.19.1"
} }

View File

@ -150,51 +150,57 @@ export async function fetchNotifications(reqUser, options = {}) {
return []; return [];
} }
const notifications = await knex('notifications') const [notifications, rawUnseen] = await Promise.all([
.select( knex('notifications')
'notifications.*', .select(
'alerts.id as alert_id', 'notifications.*',
knex.raw('coalesce(array_agg(alerts_actors.actor_id) filter (where alerts_actors.id is not null), \'{}\') as alert_actors'), 'alerts.id as alert_id',
knex.raw('coalesce(array_agg(alerts_tags.tag_id) filter (where alerts_tags.id is not null), \'{}\') as alert_tags'), knex.raw('coalesce(array_agg(alerts_actors.actor_id) filter (where alerts_actors.id is not null), \'{}\') as alert_actors'),
knex.raw('coalesce(array_agg(alerts_entities.entity_id) filter (where alerts_entities.id is not null), \'{}\') as alert_entities'), knex.raw('coalesce(array_agg(alerts_tags.tag_id) filter (where alerts_tags.id is not null), \'{}\') as alert_tags'),
knex.raw('coalesce(json_agg(alerts_matches) filter (where alerts_matches.id is not null), \'[]\') as alert_matches'), knex.raw('coalesce(array_agg(alerts_entities.entity_id) filter (where alerts_entities.id is not null), \'{}\') as alert_entities'),
) knex.raw('coalesce(json_agg(alerts_matches) filter (where alerts_matches.id is not null), \'[]\') as alert_matches'),
.leftJoin('alerts', 'alerts.id', 'notifications.alert_id') )
.leftJoin('alerts_actors', 'alerts_actors.alert_id', 'alerts.id') .leftJoin('alerts', 'alerts.id', 'notifications.alert_id')
.leftJoin('alerts_tags', 'alerts_tags.alert_id', 'alerts.id') .leftJoin('alerts_actors', 'alerts_actors.alert_id', 'alerts.id')
.leftJoin('alerts_entities', 'alerts_entities.alert_id', 'alerts.id') .leftJoin('alerts_tags', 'alerts_tags.alert_id', 'alerts.id')
.leftJoin('alerts_matches', 'alerts_matches.alert_id', 'alerts.id') .leftJoin('alerts_entities', 'alerts_entities.alert_id', 'alerts.id')
.where('notifications.user_id', reqUser.id) .leftJoin('alerts_matches', 'alerts_matches.alert_id', 'alerts.id')
.groupBy('notifications.id', 'alerts.id') .where('notifications.user_id', reqUser.id)
.orderBy('created_at', 'desc'); .limit(options.limit)
.groupBy('notifications.id', 'alerts.id')
.orderBy('created_at', 'desc'),
knex('notifications')
.select(knex.raw('count(id)'))
.where('user_id', reqUser.id)
.where('seen', false)
.first(),
]);
const scenes = await fetchScenesById(notifications.map((notification) => notification.scene_id)); const scenes = await fetchScenesById(notifications.map((notification) => notification.scene_id));
const unseen = notifications.filter((notification) => !notification.seen).length; const unseen = Number(rawUnseen.count);
const curatedNotifications = notifications const curatedNotifications = notifications.map((notification) => {
.slice(0, options.limit || 10) const scene = scenes.find((sceneX) => sceneX.id === notification.scene_id);
.map((notification) => {
const scene = scenes.find((sceneX) => sceneX.id === notification.scene_id);
return { return {
id: notification.id, id: notification.id,
sceneId: notification.scene_id, sceneId: notification.scene_id,
scene, scene,
alertId: notification.alert_id, alertId: notification.alert_id,
matchedActors: scene.actors.filter((actor) => notification.alert_actors.includes(actor.id)), matchedActors: scene.actors.filter((actor) => notification.alert_actors.includes(actor.id)),
matchedTags: scene.tags.filter((tag) => notification.alert_tags.includes(tag.id)), matchedTags: scene.tags.filter((tag) => notification.alert_tags.includes(tag.id)),
matchedEntity: [scene.channel, scene.network].find((entity) => notification.alert_entities.includes(entity?.id)) || null, matchedEntity: [scene.channel, scene.network].find((entity) => notification.alert_entities.includes(entity?.id)) || null,
matchedExpressions: notification.alert_matches matchedExpressions: notification.alert_matches
.filter((match) => new RegExp(match.expression, 'ui').test(scene[match.property])) .filter((match) => new RegExp(match.expression, 'ui').test(scene[match.property]))
.map((match) => ({ .map((match) => ({
id: match.id, id: match.id,
property: match.property, property: match.property,
expression: match.expression, expression: match.expression,
})), })),
isSeen: notification.seen, isSeen: notification.seen,
createdAt: notification.created_at, createdAt: notification.created_at,
}; };
}); });
return { return {
notifications: curatedNotifications, notifications: curatedNotifications,