feat: initial action implementations

This commit is contained in:
Wyatt Johnson
2018-09-06 16:24:34 -06:00
parent 53e548d77a
commit 1bd841ec01
6 changed files with 416 additions and 14 deletions
+67 -5
View File
@@ -1,13 +1,21 @@
import { Db } from "mongodb";
import { Omit } from "talk-common/types";
import { GQLACTION_ITEM_TYPE } from "talk-server/graph/tenant/schema/__generated__/types";
import {
CreateActionInput,
createActions,
generateActionCounts,
} from "talk-server/models/actions";
import { retrieveAsset } 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";
@@ -47,7 +55,7 @@ export async function create(
}
// Run the comment through the moderation phases.
const { status, metadata } = await processForModeration({
const { actions, status, metadata } = await processForModeration({
asset,
tenant,
comment: input,
@@ -55,17 +63,71 @@ export async function create(
req,
});
// TODO: (wyattjoh) use the actions somehow.
const comment = await createComment(mongo, tenant.id, {
// Create the comment!
let comment = await createComment(mongo, tenant.id, {
...input,
status,
action_counts: {},
metadata,
});
if (actions.length > 0) {
// The actions coming from the moderation phases didn't know the item_id
// at the time, and we didn't want the repetitive nature of adding the
// item_type each time, so this mapping function adds them!
const inputs = actions.map(
(action): CreateActionInput => ({
...action,
item_id: comment.id,
item_type: GQLACTION_ITEM_TYPE.COMMENTS,
})
);
// Insert and handle creating the actions.
comment = await addCommentActions(mongo, tenant, comment, inputs);
}
if (input.parent_id) {
// TODO: update reply count of parent.
// TODO: (wyattjoh) update reply count of parent.
}
return comment;
}
async function addCommentActions(
mongo: Db,
tenant: Tenant,
comment: Readonly<Comment>,
inputs: CreateActionInput[]
): Promise<Readonly<Comment>> {
// 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.
const upsertedActions = results
.filter(({ wasUpserted }) => wasUpserted)
.map(({ action }) => action);
if (upsertedActions.length > 0) {
// Compute the action counts.
const actionCounts = generateActionCounts(...upsertedActions);
// Update the comment action counts here.
const updatedComment = await updateCommentActionCounts(
mongo,
tenant.id,
comment.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;
@@ -1,6 +1,6 @@
import { Omit, Promiseable } from "talk-common/types";
import { GQLCOMMENT_STATUS } from "talk-server/graph/tenant/schema/__generated__/types";
import { Action } from "talk-server/models/actions";
import { CreateActionInput } from "talk-server/models/actions";
import { Asset } from "talk-server/models/asset";
import { Comment } from "talk-server/models/comment";
import { Tenant } from "talk-server/models/tenant";
@@ -9,14 +9,10 @@ import { Request } from "talk-server/types/express";
import { moderationPhases } from "./phases";
// TODO: (wyattjoh) move into actions module once we have action methods.
export type CreateAction = Omit<
Action,
"id" | "item_type" | "item_id" | "created_at"
>;
export type ModerationAction = Omit<CreateActionInput, "item_id" | "item_type">;
export interface PhaseResult {
actions: CreateAction[];
actions: ModerationAction[];
status: GQLCOMMENT_STATUS;
metadata: Record<string, any>;
}