Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diminui idas ao banco de dados na criação e edição de conteúdos, e na edição de usuários #1729

Merged
merged 8 commits into from
Jun 25, 2024
103 changes: 47 additions & 56 deletions models/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,20 +273,14 @@ async function create(postedContent, options = {}) {

checkRootContentTitle(validContent);

const parentContent = validContent.parent_id
? await checkIfParentIdExists(validContent, {
transaction: options.transaction,
})
: null;

injectIdAndPath(validContent, parentContent);

populatePublishedAtValue(null, validContent);

const newContent = await runInsertQuery(validContent, {
transaction: options.transaction,
});

throwIfParentIsNotInPath(newContent);

await creditOrDebitTabCoins(null, newContent, {
eventId: options.eventId,
transaction: options.transaction,
Expand All @@ -310,10 +304,22 @@ async function create(postedContent, options = {}) {
const query = {
text: `
WITH
parent AS (
SELECT
owner_id,
CASE
WHEN id IS NULL THEN ARRAY[]::uuid[]
ELSE ARRAY_APPEND(path, id)
END AS child_path
FROM (SELECT 1) AS dummy
LEFT JOIN contents
ON id = $2
),
inserted_content as (
INSERT INTO
contents (id, parent_id, owner_id, slug, title, body, status, source_url, published_at, path)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
SELECT $1, $2, $3, $4, $5, $6, $7, $8, $9, parent.child_path
FROM parent
RETURNING *
)
SELECT
Expand All @@ -330,11 +336,14 @@ async function create(postedContent, options = {}) {
inserted_content.published_at,
inserted_content.deleted_at,
inserted_content.path,
users.username as owner_username
users.username as owner_username,
parent.owner_id as parent_owner_id
FROM
inserted_content
INNER JOIN
users ON inserted_content.owner_id = users.id
LEFT JOIN
parent ON true
;`,
values: [
content.id,
Expand All @@ -346,7 +355,6 @@ async function create(postedContent, options = {}) {
content.status,
content.source_url,
content.published_at,
content.path,
],
};

Expand All @@ -359,18 +367,6 @@ async function create(postedContent, options = {}) {
}
}

function injectIdAndPath(validContent, parentContent) {
validContent.id = uuidV4();

if (parentContent) {
validContent.path = [...parentContent.path, parentContent.id];
}

if (!parentContent) {
validContent.path = [];
}
}

function populateSlug(postedContent) {
if (!postedContent.slug) {
postedContent.slug = getSlug(postedContent.title) || uuidV4();
Expand Down Expand Up @@ -405,17 +401,8 @@ function populateStatus(postedContent) {
postedContent.status = postedContent.status || 'draft';
}

async function checkIfParentIdExists(content, options) {
const existingContent = await findOne(
{
where: {
id: content.parent_id,
},
},
options,
);

if (!existingContent) {
function throwIfParentIsNotInPath(newContent) {
aprendendofelipe marked this conversation as resolved.
Show resolved Hide resolved
if (newContent.parent_id && newContent.path.at(-1) !== newContent.parent_id) {
throw new ValidationError({
message: `Você está tentando criar um comentário em um conteúdo que não existe.`,
action: `Utilize um "parent_id" que aponte para um conteúdo existente.`,
Expand All @@ -425,8 +412,6 @@ async function checkIfParentIdExists(content, options) {
key: 'parent_id',
});
}

return existingContent;
}

function parseQueryErrorToCustomError(error) {
Expand All @@ -446,6 +431,7 @@ function parseQueryErrorToCustomError(error) {

function validateCreateSchema(content) {
const cleanValues = validator(content, {
id: 'required',
parent_id: 'optional',
owner_id: 'required',
slug: 'required',
Expand Down Expand Up @@ -558,23 +544,26 @@ async function creditOrDebitTabCoins(oldContent, newContent, options = {}) {
});
}

// We should not credit if the content has little or no value.
// Expected 5 or more words with 5 or more characters.
Rafatcb marked this conversation as resolved.
Show resolved Hide resolved
if (newContent.body.split(/[a-z]{5,}/i, 6).length < 6) return;

if (newContent.parent_id) {
const parentContent = await findOne(
{
where: {
id: newContent.parent_id,
},
},
options,
);
let parentOwnerId = newContent.parent_owner_id;

if (parentOwnerId === undefined) {
const queryParent = {
text: `SELECT owner_id FROM contents WHERE id = $1;`,
values: [newContent.parent_id],
};
const parentQueryResult = await database.query(queryParent, options);
const parentContent = parentQueryResult.rows[0];
parentOwnerId = parentContent.owner_id;
}

// We should not credit if the parent content is from the same user.
if (parentContent.owner_id === newContent.owner_id) return;
if (parentOwnerId === newContent.owner_id) return;
}

// We should not credit if the content has little or no value.
// Expected 5 or more words with 5 or more characters.
if (newContent.body.split(/[a-z]{5,}/i, 6).length < 6) return;
}

if (userEarnings > 0) {
Expand Down Expand Up @@ -611,14 +600,16 @@ async function creditOrDebitTabCoins(oldContent, newContent, options = {}) {
async function update(contentId, postedContent, options = {}) {
const validPostedContent = validateUpdateSchema(postedContent);

const oldContent = await findOne(
{
where: {
id: contentId,
const oldContent =
options.oldContent ??
(await findOne(
{
where: {
id: contentId,
},
},
},
options,
);
options,
));

const newContent = { ...oldContent, ...validPostedContent };

Expand Down
22 changes: 0 additions & 22 deletions models/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,6 @@ async function create(object, options = {}) {
return results.rows[0];
}

// Currently it only update "metadata" column.
async function updateMetadata(eventId, object, options = {}) {
object = validateObject(object);

const query = {
text: `
UPDATE
events
SET
metadata = $1
WHERE
id = $2
RETURNING *
;`,
values: [object.metadata, eventId],
};

const results = await database.query(query, options);
return results.rows[0];
}

function validateObject(object) {
const cleanObject = validator(object, {
event: 'required',
Expand All @@ -45,5 +24,4 @@ function validateObject(object) {

export default Object.freeze({
create,
updateMetadata,
});
16 changes: 4 additions & 12 deletions pages/api/v1/contents/[username]/[slug]/index.public.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,29 +150,21 @@ async function patchHandler(request, response) {
type: contentToBeUpdated.parent_id ? 'update:content:text_child' : 'update:content:text_root',
originatorUserId: request.context.user.id,
originatorIp: request.context.clientIp,
metadata: {
id: contentToBeUpdated.id,
},
},
{
transaction: transaction,
},
);

const updatedContent = await content.update(contentToBeUpdated.id, filteredBodyValues, {
oldContent: contentToBeUpdated,
eventId: currentEvent.id,
transaction: transaction,
});

await event.updateMetadata(
currentEvent.id,
{
metadata: {
id: updatedContent.id,
},
},
{
transaction: transaction,
},
);

await transaction.query('COMMIT');
await transaction.release();

Expand Down
17 changes: 5 additions & 12 deletions pages/api/v1/contents/index.public.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import nextConnect from 'next-connect';
import { randomUUID as uuidV4 } from 'node:crypto';

import { ForbiddenError } from 'errors';
import database from 'infra/database.js';
Expand Down Expand Up @@ -133,6 +134,7 @@ async function postHandler(request, response) {
}

secureInputValues.owner_id = userTryingToCreate.id;
secureInputValues.id = uuidV4();

const transaction = await database.transaction();

Expand All @@ -144,6 +146,9 @@ async function postHandler(request, response) {
type: secureInputValues.parent_id ? 'create:content:text_child' : 'create:content:text_root',
originatorUserId: request.context.user.id,
originatorIp: request.context.clientIp,
metadata: {
id: secureInputValues.id,
},
},
{
transaction: transaction,
Expand All @@ -155,18 +160,6 @@ async function postHandler(request, response) {
transaction: transaction,
});

await event.updateMetadata(
currentEvent.id,
{
metadata: {
id: createdContent.id,
},
},
{
transaction: transaction,
},
);

await transaction.query('COMMIT');
await transaction.release();

Expand Down
17 changes: 4 additions & 13 deletions pages/api/v1/users/[username]/index.public.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,24 +112,15 @@ async function patchHandler(request, response) {
try {
await transaction.query('BEGIN');

const currentEvent = await event.create(
{
type: 'update:user',
originatorUserId: request.context.user.id,
originatorIp: request.context.clientIp,
},
{
transaction: transaction,
},
);

const updatedUser = await user.update(targetUsername, secureInputValues, {
transaction: transaction,
});

await event.updateMetadata(
currentEvent.id,
await event.create(
{
type: 'update:user',
originatorUserId: request.context.user.id,
originatorIp: request.context.clientIp,
metadata: getEventMetadata(targetUser, updatedUser),
},
{
Expand Down
12 changes: 6 additions & 6 deletions tests/orchestrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,19 @@ async function findSessionByToken(token) {
}

async function createContent(contentObject) {
const contentId = contentObject?.id || randomUUID();

const currentEvent = await event.create({
type: contentObject?.parent_id ? 'create:content:text_child' : 'create:content:text_root',
originatorUserId: contentObject?.owner_id,
metadata: {
id: contentId,
},
});

const createdContent = await content.create(
{
id: contentId,
parent_id: contentObject?.parent_id || undefined,
owner_id: contentObject?.owner_id || undefined,
title: contentObject?.title || undefined,
Expand All @@ -197,12 +203,6 @@ async function createContent(contentObject) {
},
);

await event.updateMetadata(currentEvent.id, {
metadata: {
id: createdContent.id,
},
});

return createdContent;
}

Expand Down
Loading