'use strict'; const knex = require('./knex'); const { HttpError } = require('./errors'); async function addAlert(alert, sessionUser) { if (!sessionUser) { throw new HttpError('You are not authenthicated', 401); } if (!alert.actors?.length > 0 && !alert.tags?.length > 0 && !alert.entity) { throw new HttpError('Alert must contain at least one actor, tag or entity', 400); } const [alertId] = await knex('alerts') .insert({ user_id: sessionUser.id, notify: alert.notify, email: alert.email, }) .returning('id'); await Promise.all([ alert.actors?.length > 0 && knex('alerts_actors') .insert(alert.actors.map(actorId => ({ alert_id: alertId, actor_id: actorId, }))), alert.tags?.length > 0 && knex('alerts_tags') .insert(alert.tags.map(tagId => ({ alert_id: alertId, tag_id: tagId, }))), alert.stashes?.length > 0 && knex('alerts_stashes') .insert(alert.stashes.map(stashId => ({ alert_id: alertId, stash_id: stashId, }))), alert.entity && knex('alerts_entities').insert({ alert_id: alertId, entity_id: alert.entity, }), ]); return alertId; } async function removeAlert(alertId) { await knex('alerts').where('id', alertId).delete(); } async function notify(scenes) { const releases = await knex.raw(` SELECT alerts.id as alert_id, alerts.notify, alerts.email, releases.id as scene_id, users.id as user_id FROM releases CROSS JOIN alerts LEFT JOIN users ON users.id = alerts.user_id LEFT JOIN releases_tags ON releases_tags.release_id = releases.id /* match updated IDs from input */ WHERE (releases.id = ANY(:sceneIds)) /* match tags */ AND (NOT EXISTS (SELECT alerts_tags.alert_id FROM alerts_tags WHERE alerts_tags.alert_id = alerts.id) OR (SELECT array_agg(releases_tags.tag_id) FROM releases_tags WHERE releases_tags.release_id = releases.id GROUP BY releases_tags.release_id) @> (SELECT array_agg(alerts_tags.tag_id) FROM alerts_tags WHERE alerts_tags.alert_id = alerts.id GROUP BY alerts_tags.alert_id)) /* match actors */ AND (NOT EXISTS (SELECT alerts_actors.alert_id FROM alerts_actors WHERE alerts_actors.alert_id = alerts.id) OR (SELECT array_agg(releases_actors.actor_id) FROM releases_actors WHERE releases_actors.release_id = releases.id GROUP BY releases_actors.release_id) @> (SELECT array_agg(alerts_actors.actor_id) FROM alerts_actors WHERE alerts_actors.alert_id = alerts.id GROUP BY alerts_actors.alert_id)) /* match entity */ AND ((NOT EXISTS (SELECT alerts_entities.entity_id FROM alerts_entities WHERE alerts_entities.alert_id = alerts.id)) OR (releases.entity_id = ANY(array( /* include children of entities */ WITH RECURSIVE included AS ( SELECT entities.* FROM alerts_entities LEFT JOIN entities ON entities.id = alerts_entities.entity_id WHERE alerts_entities.alert_id = alerts.id UNION ALL SELECT entities.* FROM entities INNER JOIN included ON included.id = entities.parent_id ) SELECT included.id FROM included GROUP BY included.id )))) GROUP BY releases.id, users.id, alerts.id; `, { sceneIds: scenes.map(scene => scene.id), }); const notifications = releases.rows.filter(alert => alert.notify); await knex('notifications') .insert(notifications.map(notification => ({ user_id: notification.user_id, alert_id: notification.alert_id, scene_id: notification.scene_id, }))); return releases.rows; } async function updateNotification(notificationId, notification, sessionUser) { await knex('notifications') .where('user_id', sessionUser.id) .where('id', notificationId) .update({ seen: notification.seen, }); } async function updateNotifications(notification, sessionUser) { console.log(notification, sessionUser.id); await knex('notifications') .where('user_id', sessionUser.id) .update({ seen: notification.seen, }); } module.exports = { addAlert, removeAlert, notify, updateNotification, updateNotifications, };