Skip to content

Commit

Permalink
refactor(notifications): queries and pages api
Browse files Browse the repository at this point in the history
  • Loading branch information
mthmcalixto committed May 20, 2024
1 parent 8311bd8 commit c6fad81
Show file tree
Hide file tree
Showing 15 changed files with 392 additions and 355 deletions.
20 changes: 5 additions & 15 deletions infra/migrations/1714326942609_user-notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,14 @@ exports.up = (pgm) => {
type: 'varchar(30)',
notNull: true,
},
from_id: {
type: 'uuid',
event_type: {
type: 'varchar(50)',
notNull: true,
},
to_id: {
recipient_id: {
type: 'uuid',
notNull: true,
},
to_username: {
type: 'varchar(30)',
notNull: true,
},
to_email: {
type: 'varchar(254)',
notNull: true,
},
body_reply_line: {
type: 'varchar',
notNull: true,
Expand All @@ -38,7 +30,7 @@ exports.up = (pgm) => {
type: 'varchar',
default: 'unread',
notNull: true,
check: "status IN ('unread', 'read')",
check: "status IN ('unread', 'read', 'draft')",
},
created_at: {
type: 'timestamp with time zone',
Expand All @@ -53,6 +45,4 @@ exports.up = (pgm) => {
});
};

exports.down = (pgm) => {
pgm.dropTable('user_notifications');
};
exports.down = false;
1 change: 0 additions & 1 deletion models/authorization.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ function filterInput(user, feature, input, target) {
password: input.password,
description: input.description,
notifications: input.notifications,
notifications_id: input.notifications_id,
};
}

Expand Down
100 changes: 43 additions & 57 deletions models/notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import email from 'infra/email.js';
import webserver from 'infra/webserver.js';
import authorization from 'models/authorization.js';
import content from 'models/content.js';
import { NotificationWeb } from 'models/notifications';
import { webNotify } from 'models/notifications';
import { NotificationEmail } from 'models/transactional';
import user from 'models/user.js';

async function commonData(createdContent) {
async function prepareData(createdContent) {
const anonymousUser = user.createAnonymous();
const secureCreatedContent = authorization.filterOutput(anonymousUser, 'read:content', createdContent);

Expand All @@ -19,11 +19,11 @@ async function commonData(createdContent) {
if (parentContent.owner_id !== secureCreatedContent.owner_id) {
const parentContentUser = await user.findOneById(parentContent.owner_id);

if (parentContentUser.notifications === false) {
return null;
if (!parentContentUser.notifications) {
return;
}

const childContentUrl = getChildContendUrl(secureCreatedContent);
const childContentUrl = getChildContentUrl(secureCreatedContent);
const rootContent = parentContent.parent_id
? await content.findOne({
where: {
Expand All @@ -35,30 +35,41 @@ async function commonData(createdContent) {

const secureRootContent = authorization.filterOutput(anonymousUser, 'read:content', rootContent);

const subject = getSubject({
const details = getDetails({
createdContent: secureCreatedContent,
rootContent: secureRootContent,
});

const bodyReplyLine = getBodyReplyLine({
createdContent: secureCreatedContent,
rootContent: secureRootContent,
});
return {
parentContentUser,
childContentUrl,
...details,
secureCreatedContent,
};
}
}

const typeNotification = getTypeNotification({
createdContent: secureCreatedContent,
rootContent: secureRootContent,
});
function getDetails({ createdContent, rootContent }) {
const sanitizedRootContentTitle =
rootContent.title.length > 55 ? `${rootContent.title.substring(0, 55)}...` : rootContent.title;

return { parentContentUser, childContentUrl, subject, typeNotification, bodyReplyLine, secureCreatedContent };
}
const subject = `"${createdContent.owner_username}" comentou em "${sanitizedRootContentTitle}"`;

const bodyReplyLine =
createdContent.parent_id === rootContent.id
? `"${createdContent.owner_username}" respondeu à sua publicação "${rootContent.title}".`
: `"${createdContent.owner_username}" respondeu ao seu comentário na publicação "${rootContent.title}".`;

const type = createdContent.parent_id === rootContent.id ? 'root_content' : 'child_content';

return { subject, bodyReplyLine, type };
}

async function sendReplyEmailToParentUser(createdContent) {
const commonDataResult = await commonData(createdContent);
if (!commonDataResult) return;
const data = await prepareData(createdContent);
if (!data) return;

const { parentContentUser, childContentUrl, subject, bodyReplyLine } = commonDataResult;
const { parentContentUser, childContentUrl, subject, bodyReplyLine } = data;

const { html, text } = NotificationEmail({
username: parentContentUser.username,
Expand All @@ -78,52 +89,27 @@ async function sendReplyEmailToParentUser(createdContent) {
});
}

async function sendReplyNotificationWebToParentUser(createdContent) {
const commonDataResult = await commonData(createdContent);
if (!commonDataResult) return;
async function sendReplyWebToParentUser(createdContent) {
const data = await prepareData(createdContent);
if (!data) return;

const { parentContentUser, childContentUrl, bodyReplyLine, secureCreatedContent, typeNotification } =
commonDataResult;
const { parentContentUser, childContentUrl, bodyReplyLine, secureCreatedContent, type } = data;

await NotificationWeb.send({
from: secureCreatedContent.owner_id,
type: typeNotification,
to_id: parentContentUser.id,
to_email: parentContentUser.email,
to_username: parentContentUser.username,
bodyReplyLine,
contentLink: childContentUrl,
await webNotify.send({
sender_id: secureCreatedContent.owner_id,
recipient_id: parentContentUser.id,
type: 'alert',
event_type: type,
body_reply_line: bodyReplyLine,
content_link: childContentUrl,
});
}

function getSubject({ createdContent, rootContent }) {
const sanitizedRootContentTitle =
rootContent.title.length > 55 ? `${rootContent.title.substring(0, 55)}...` : rootContent.title;

return `"${createdContent.owner_username}" comentou em "${sanitizedRootContentTitle}"`;
}

function getBodyReplyLine({ createdContent, rootContent }) {
if (createdContent.parent_id === rootContent.id) {
return `"${createdContent.owner_username}" respondeu à sua publicação "${rootContent.title}".`;
}

return `"${createdContent.owner_username}" respondeu ao seu comentário na publicação "${rootContent.title}".`;
}

function getChildContendUrl({ owner_username, slug }) {
function getChildContentUrl({ owner_username, slug }) {
return `${webserver.host}/${owner_username}/${slug}`;
}

function getTypeNotification({ createdContent, rootContent }) {
if (createdContent.parent_id === rootContent.id) {
return 'post';
}

return 'comment';
}

export default Object.freeze({
sendReplyEmailToParentUser,
sendReplyNotificationWebToParentUser,
sendReplyWebToParentUser,
});
4 changes: 2 additions & 2 deletions models/notifications/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default as NotificationWeb } from './web';
export { default as NotificationWebManage } from './web/manage';
export { default as webNotify } from './web';
export { default as webNotifyQueries } from './web/queries';
46 changes: 16 additions & 30 deletions models/notifications/web/index.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,25 @@
import database from 'infra/database';

async function send({ from, type, to_id, to_username, to_email, bodyReplyLine, contentLink }) {
const notificationOptions = {
from: from,
type: type,
to_id: to_id,
to_username: to_username,
to_email: to_email,
bodyReplyLine: bodyReplyLine,
contentLink: contentLink,
async function send({ type, event_type, recipient_id, body_reply_line, content_link }) {
const query = {
text: `
INSERT INTO
user_notifications (type, event_type, recipient_id, body_reply_line, content_link)
VALUES
($1, $2, $3, $4, $5)
RETURNING
*
;`,
values: [type, event_type, recipient_id, body_reply_line, content_link],
};

await sendNotificationWeb(notificationOptions);
const results = await database.query(query);

async function sendNotificationWeb({ from, type, to_id, to_username, to_email, bodyReplyLine, contentLink }) {
const query = {
text: `
INSERT INTO
user_notifications (from_id, type, to_id, to_username, to_email, body_reply_line, content_link)
VALUES
($1, $2, $3, $4, $5, $6, $7)
RETURNING
*
;`,
values: [from, type, to_id, to_username, to_email, bodyReplyLine, contentLink],
};

const results = await database.query(query);

if (results.rowCount === 0) {
return false;
}

return results.rows[0];
if (results.rowCount === 0) {
return;
}

return results.rows[0];
}

export default Object.freeze({
Expand Down
Loading

0 comments on commit c6fad81

Please sign in to comment.