From 3c640f87d32bfb2c5768642dbc2df53c8d5eb5c8 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Mon, 24 Sep 2018 14:07:44 -0600 Subject: [PATCH] fix: cleanup of comments service --- .../server/graph/tenant/mutators/comment.ts | 5 +- src/core/server/services/comments/actions.ts | 197 ++++++++++++++++ src/core/server/services/comments/index.ts | 220 +----------------- 3 files changed, 202 insertions(+), 220 deletions(-) create mode 100644 src/core/server/services/comments/actions.ts diff --git a/src/core/server/graph/tenant/mutators/comment.ts b/src/core/server/graph/tenant/mutators/comment.ts index 734e724b5..0867ee5e3 100644 --- a/src/core/server/graph/tenant/mutators/comment.ts +++ b/src/core/server/graph/tenant/mutators/comment.ts @@ -7,14 +7,13 @@ import { GQLDeleteCommentReactionInput, GQLEditCommentInput, } from "talk-server/graph/tenant/schema/__generated__/types"; +import { create, edit } from "talk-server/services/comments"; import { - create, createFlag, createReaction, deleteFlag, deleteReaction, - edit, -} from "talk-server/services/comments"; +} from "talk-server/services/comments/actions"; export default (ctx: TenantContext) => ({ create: (input: GQLCreateCommentInput) => diff --git a/src/core/server/services/comments/actions.ts b/src/core/server/services/comments/actions.ts new file mode 100644 index 000000000..f8313c913 --- /dev/null +++ b/src/core/server/services/comments/actions.ts @@ -0,0 +1,197 @@ +import { Db } from "mongodb"; + +import { GQLCOMMENT_FLAG_REPORTED_REASON } from "talk-server/graph/tenant/schema/__generated__/types"; +import { + ACTION_ITEM_TYPE, + ACTION_TYPE, + CreateActionInput, + createActions, + deleteAction, + DeleteActionInput, + encodeActionCounts, + invertEncodedActionCounts, +} from "talk-server/models/action"; +import { updateAssetActionCounts } from "talk-server/models/asset"; +import { + retrieveComment, + updateCommentActionCounts, +} from "talk-server/models/comment"; +import { Comment } from "talk-server/models/comment"; +import { Tenant } from "talk-server/models/tenant"; +import { User } from "talk-server/models/user"; + +export async function addCommentActions( + mongo: Db, + tenant: Tenant, + comment: Readonly, + inputs: CreateActionInput[] +): Promise> { + // Create each of the actions, returning each of the action results. + const results = await createActions(mongo, tenant.id, inputs); + + // Get the actions that were upserted, we only want to increment the action + // counts of actions that were just created. + const upsertedActions = results + .filter(({ wasUpserted }) => wasUpserted) + .map(({ action }) => action); + + if (upsertedActions.length > 0) { + // Compute the action counts. + const actionCounts = encodeActionCounts(...upsertedActions); + + // Update the comment action counts here. + const updatedComment = await updateCommentActionCounts( + mongo, + tenant.id, + comment.id, + actionCounts + ); + + // Update the Asset with the updated action counts. + await updateAssetActionCounts( + mongo, + tenant.id, + comment.asset_id, + actionCounts + ); + + // Check to see if there was an actual comment returned (there should + // have been, we just created it!). + if (!updatedComment) { + // TODO: (wyattjoh) return a better error. + throw new Error("could not update comment action counts"); + } + + return updatedComment; + } + + return comment; +} + +async function addCommentAction( + mongo: Db, + tenant: Tenant, + input: CreateActionInput +): Promise> { + const comment = await retrieveComment(mongo, tenant.id, input.item_id); + if (!comment) { + // TODO: replace to match error returned by the models/comments.ts + throw new Error("comment not found"); + } + + return addCommentActions(mongo, tenant, comment, [input]); +} + +export async function removeCommentAction( + mongo: Db, + tenant: Tenant, + input: DeleteActionInput +): Promise> { + // Get the Comment that we are leaving the Action on. + const comment = await retrieveComment(mongo, tenant.id, input.item_id); + if (!comment) { + // TODO: replace to match error returned by the models/comments.ts + throw new Error("comment not found"); + } + + // Create each of the actions, returning each of the action results. + const { wasDeleted, action } = await deleteAction(mongo, tenant.id, input); + if (wasDeleted) { + // Compute the action counts, and invert them (because we're deleting an + // action). + const actionCounts = invertEncodedActionCounts(encodeActionCounts(action!)); + + // Update the comment action counts here. + const updatedComment = await updateCommentActionCounts( + mongo, + tenant.id, + comment.id, + actionCounts + ); + + // Update the Asset with the updated action counts. + await updateAssetActionCounts( + mongo, + tenant.id, + comment.asset_id, + actionCounts + ); + + // Check to see if there was an actual comment returned. + if (!updatedComment) { + // TODO: (wyattjoh) return a better error. + throw new Error("could not update comment action counts"); + } + + return updatedComment; + } + + return comment; +} + +export type CreateCommentReaction = Pick; + +export async function createReaction( + mongo: Db, + tenant: Tenant, + author: User, + input: CreateCommentReaction +) { + return addCommentAction(mongo, tenant, { + action_type: ACTION_TYPE.REACTION, + item_type: ACTION_ITEM_TYPE.COMMENTS, + item_id: input.item_id, + user_id: author.id, + }); +} + +export type DeleteCommentReaction = Pick; + +export async function deleteReaction( + mongo: Db, + tenant: Tenant, + author: User, + input: DeleteCommentReaction +) { + return removeCommentAction(mongo, tenant, { + action_type: ACTION_TYPE.REACTION, + item_type: ACTION_ITEM_TYPE.COMMENTS, + item_id: input.item_id, + user_id: author.id, + }); +} + +export type CreateCommentFlag = Pick & { + reason: GQLCOMMENT_FLAG_REPORTED_REASON; +}; + +export async function createFlag( + mongo: Db, + tenant: Tenant, + author: User, + input: CreateCommentFlag +) { + return addCommentAction(mongo, tenant, { + action_type: ACTION_TYPE.FLAG, + reason: input.reason, + item_type: ACTION_ITEM_TYPE.COMMENTS, + item_id: input.item_id, + user_id: author.id, + }); +} + +export type DeleteCommentFlag = Pick; + +export async function deleteFlag( + mongo: Db, + tenant: Tenant, + author: User, + input: DeleteCommentFlag +) { + return removeCommentAction(mongo, tenant, { + action_type: ACTION_TYPE.FLAG, + item_type: ACTION_ITEM_TYPE.COMMENTS, + item_id: input.item_id, + user_id: author.id, + }); +} diff --git a/src/core/server/services/comments/index.ts b/src/core/server/services/comments/index.ts index 947ac4ae9..6388df472 100644 --- a/src/core/server/services/comments/index.ts +++ b/src/core/server/services/comments/index.ts @@ -1,32 +1,18 @@ import { Db } from "mongodb"; import { Omit } from "talk-common/types"; -import { GQLCOMMENT_FLAG_REPORTED_REASON } from "talk-server/graph/tenant/schema/__generated__/types"; +import { ACTION_ITEM_TYPE, CreateActionInput } from "talk-server/models/action"; +import { retrieveAsset } from "talk-server/models/asset"; import { - ACTION_ITEM_TYPE, - ACTION_TYPE, - CreateActionInput, - createActions, - deleteAction, - DeleteActionInput, - encodeActionCounts, - invertEncodedActionCounts, -} from "talk-server/models/action"; -import { - retrieveAsset, - updateAssetActionCounts, -} from "talk-server/models/asset"; -import { - Comment, createComment, CreateCommentInput, editComment, EditCommentInput, retrieveComment, - updateCommentActionCounts, } from "talk-server/models/comment"; import { Tenant } from "talk-server/models/tenant"; import { User } from "talk-server/models/user"; +import { addCommentActions } from "talk-server/services/comments/actions"; import { processForModeration } from "talk-server/services/comments/moderation"; import { Request } from "talk-server/types/express"; @@ -177,203 +163,3 @@ export async function edit( return comment; } - -async function addCommentActions( - mongo: Db, - tenant: Tenant, - comment: Readonly, - inputs: CreateActionInput[] -): Promise> { - // Create each of the actions, returning each of the action results. - const results = await createActions(mongo, tenant.id, inputs); - - // Get the actions that were upserted, we only want to increment the action - // counts of actions that were just created. - const upsertedActions = results - .filter(({ wasUpserted }) => wasUpserted) - .map(({ action }) => action); - - if (upsertedActions.length > 0) { - // Compute the action counts. - const actionCounts = encodeActionCounts(...upsertedActions); - - // Update the comment action counts here. - const updatedComment = await updateCommentActionCounts( - mongo, - tenant.id, - comment.id, - actionCounts - ); - - // Update the Asset with the updated action counts. - await updateAssetActionCounts( - mongo, - tenant.id, - comment.asset_id, - actionCounts - ); - - // Check to see if there was an actual comment returned (there should - // have been, we just created it!). - if (!updatedComment) { - // TODO: (wyattjoh) return a better error. - throw new Error("could not update comment action counts"); - } - - return updatedComment; - } - - return comment; -} - -async function deleteCommentAction( - mongo: Db, - tenant: Tenant, - comment: Readonly, - input: DeleteActionInput -): Promise> { - // Create each of the actions, returning each of the action results. - const { wasDeleted, action } = await deleteAction(mongo, tenant.id, input); - if (wasDeleted) { - // Compute the action counts, and invert them (because we're deleting an - // action). - const actionCounts = invertEncodedActionCounts(encodeActionCounts(action!)); - - // Update the comment action counts here. - const updatedComment = await updateCommentActionCounts( - mongo, - tenant.id, - comment.id, - actionCounts - ); - - // Update the Asset with the updated action counts. - await updateAssetActionCounts( - mongo, - tenant.id, - comment.asset_id, - actionCounts - ); - - // Check to see if there was an actual comment returned. - if (!updatedComment) { - // TODO: (wyattjoh) return a better error. - throw new Error("could not update comment action counts"); - } - - return updatedComment; - } - - return comment; -} - -export type CreateCommentReaction = Pick; - -export async function createReaction( - mongo: Db, - tenant: Tenant, - author: User, - input: CreateCommentReaction -) { - // Get the Comment that we are leaving the Action on. - let comment = await retrieveComment(mongo, tenant.id, input.item_id); - if (!comment) { - // TODO: replace to match error returned by the models/comments.ts - throw new Error("comment not found"); - } - - // Add the comment actions, and return the Comment that we just updated. - comment = await addCommentActions(mongo, tenant, comment, [ - { - action_type: ACTION_TYPE.REACTION, - item_type: ACTION_ITEM_TYPE.COMMENTS, - item_id: input.item_id, - user_id: author.id, - }, - ]); - - return comment; -} - -export type DeleteCommentReaction = Pick; - -export async function deleteReaction( - mongo: Db, - tenant: Tenant, - author: User, - input: DeleteCommentReaction -) { - // Get the Comment that we are leaving the Action on. - let comment = await retrieveComment(mongo, tenant.id, input.item_id); - if (!comment) { - // TODO: replace to match error returned by the models/comments.ts - throw new Error("comment not found"); - } - - // Add the comment actions, and return the Comment that we just updated. - comment = await deleteCommentAction(mongo, tenant, comment, { - action_type: ACTION_TYPE.REACTION, - item_type: ACTION_ITEM_TYPE.COMMENTS, - item_id: input.item_id, - user_id: author.id, - }); - - return comment; -} - -export type CreateCommentFlag = Pick & { - reason: GQLCOMMENT_FLAG_REPORTED_REASON; -}; - -export async function createFlag( - mongo: Db, - tenant: Tenant, - author: User, - input: CreateCommentFlag -) { - // Get the Comment that we are leaving the Action on. - let comment = await retrieveComment(mongo, tenant.id, input.item_id); - if (!comment) { - // TODO: replace to match error returned by the models/comments.ts - throw new Error("comment not found"); - } - - // Add the comment actions, and return the Comment that we just updated. - comment = await addCommentActions(mongo, tenant, comment, [ - { - action_type: ACTION_TYPE.FLAG, - reason: input.reason, - item_type: ACTION_ITEM_TYPE.COMMENTS, - item_id: input.item_id, - user_id: author.id, - }, - ]); - - return comment; -} - -export type DeleteCommentFlag = Pick; - -export async function deleteFlag( - mongo: Db, - tenant: Tenant, - author: User, - input: DeleteCommentFlag -) { - // Get the Comment that we are leaving the Action on. - let comment = await retrieveComment(mongo, tenant.id, input.item_id); - if (!comment) { - // TODO: replace to match error returned by the models/comments.ts - throw new Error("comment not found"); - } - - // Add the comment actions, and return the Comment that we just updated. - comment = await deleteCommentAction(mongo, tenant, comment, { - action_type: ACTION_TYPE.FLAG, - item_type: ACTION_ITEM_TYPE.COMMENTS, - item_id: input.item_id, - user_id: author.id, - }); - - return comment; -}