mirror of
https://github.com/wassname/talk.git
synced 2026-08-01 13:00:55 +08:00
[next] Moderation Queues (#2098)
* fix: edit comment fix for reactions * feat: Comment Queue Counts - Removed "remove flag" - Rearranged moderation services - Rearranged comment counts on stories - Added moderation queue counts to stories - Added comments edge - Improved Cursor/Connection types - Improved count updators for stories * feat: added shared comment counts and queues - Added new AugmentedRedis type - Added more log calls - Update counts in shared counter as well - Return a Query level Moderation Queue * fix: fixed test
This commit is contained in:
@@ -2,8 +2,10 @@ import { GQLCOMMENT_FLAG_REASON } from "talk-server/graph/tenant/schema/__genera
|
||||
import {
|
||||
ACTION_TYPE,
|
||||
CommentAction,
|
||||
CreateActionInput,
|
||||
decodeActionCounts,
|
||||
encodeActionCounts,
|
||||
filterDuplicateActions,
|
||||
validateAction,
|
||||
} from "talk-server/models/action/comment";
|
||||
|
||||
@@ -119,3 +121,36 @@ describe("#validateAction", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("#filterDuplicateActions", () => {
|
||||
it("removes duplicate action items", () => {
|
||||
const actions: CreateActionInput[] = [
|
||||
{
|
||||
storyID: "1",
|
||||
actionType: ACTION_TYPE.FLAG,
|
||||
reason: GQLCOMMENT_FLAG_REASON.COMMENT_DETECTED_BANNED_WORD,
|
||||
commentID: "1",
|
||||
commentRevisionID: "1",
|
||||
userID: null,
|
||||
},
|
||||
{
|
||||
storyID: "1",
|
||||
actionType: ACTION_TYPE.FLAG,
|
||||
reason: GQLCOMMENT_FLAG_REASON.COMMENT_DETECTED_BANNED_WORD,
|
||||
commentID: "1",
|
||||
commentRevisionID: "1",
|
||||
userID: null,
|
||||
},
|
||||
{
|
||||
storyID: "1",
|
||||
actionType: ACTION_TYPE.FLAG,
|
||||
reason: GQLCOMMENT_FLAG_REASON.COMMENT_DETECTED_SUSPECT_WORD,
|
||||
commentID: "1",
|
||||
commentRevisionID: "1",
|
||||
userID: null,
|
||||
},
|
||||
];
|
||||
|
||||
expect(filterDuplicateActions(actions)).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Joi from "joi";
|
||||
import { camelCase, pick } from "lodash";
|
||||
import { camelCase, isEqual, omit, pick, uniqWith } from "lodash";
|
||||
import { Db } from "mongodb";
|
||||
import uuid from "uuid";
|
||||
|
||||
@@ -76,11 +76,9 @@ export interface CommentAction extends TenantResource {
|
||||
reason?: FLAG_REASON;
|
||||
|
||||
/**
|
||||
* storyID represents the identifier for the item's associated item. In
|
||||
* the case of a REACTION left on a Comment, this ID would be the Stories ID.
|
||||
* In the case of a FLAG left on a User, this ID would be null.
|
||||
* storyID represents the ID of the Story where the comment was left on.
|
||||
*/
|
||||
storyID?: string;
|
||||
storyID: string;
|
||||
|
||||
/**
|
||||
* userID is the ID of the User that left this Action. In the event that the
|
||||
@@ -159,6 +157,12 @@ export interface CreateActionResultObject {
|
||||
wasUpserted: boolean;
|
||||
}
|
||||
|
||||
export function filterDuplicateActions<T extends {}>(actions: T[]): T[] {
|
||||
return uniqWith(actions, (first, second) =>
|
||||
isEqual(omit(first, "metadata"), omit(second, "metadata"))
|
||||
);
|
||||
}
|
||||
|
||||
export async function createAction(
|
||||
mongo: Db,
|
||||
tenantID: string,
|
||||
@@ -351,7 +355,7 @@ export const ACTION_COUNT_JOIN_CHAR = "__";
|
||||
* @param actions list of actions to generate the action counts from
|
||||
*/
|
||||
export function encodeActionCounts(
|
||||
...actions: CommentAction[]
|
||||
...actions: Array<Pick<CommentAction, "actionType" | "reason">>
|
||||
): EncodedCommentActionCounts {
|
||||
const actionCounts: EncodedCommentActionCounts = {};
|
||||
|
||||
@@ -394,7 +398,9 @@ export function invertEncodedActionCounts(
|
||||
* encodeActionCountKeys encodes the action into string keys which represents
|
||||
* the groupings as seen in `EncodedActionCounts`.
|
||||
*/
|
||||
function encodeActionCountKeys(action: CommentAction): string[] {
|
||||
function encodeActionCountKeys(
|
||||
action: Pick<CommentAction, "actionType" | "reason">
|
||||
): string[] {
|
||||
const keys = [action.actionType as string];
|
||||
if (action.reason) {
|
||||
keys.push(
|
||||
@@ -495,7 +501,7 @@ function createEmptyActionCounts(): GQLActionCounts {
|
||||
}
|
||||
|
||||
export function mergeCommentActionCounts(
|
||||
actionCounts: EncodedCommentActionCounts[]
|
||||
...actionCounts: EncodedCommentActionCounts[]
|
||||
): EncodedCommentActionCounts {
|
||||
const mergedActionCounts: EncodedCommentActionCounts = {};
|
||||
|
||||
@@ -504,7 +510,7 @@ export function mergeCommentActionCounts(
|
||||
if (key in mergedActionCounts) {
|
||||
mergedActionCounts[key] += count;
|
||||
} else {
|
||||
mergedActionCounts[key] += 1;
|
||||
mergedActionCounts[key] = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Omit, Sub } from "talk-common/types";
|
||||
import { GQLCOMMENT_STATUS } from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
import {
|
||||
Connection,
|
||||
Cursor,
|
||||
ConnectionInput,
|
||||
getPageInfo,
|
||||
nodesToEdges,
|
||||
} from "talk-server/models/connection";
|
||||
@@ -107,16 +107,14 @@ export async function retrieveCommentModerationActions(
|
||||
return result.toArray();
|
||||
}
|
||||
|
||||
export interface ConnectionInput {
|
||||
first: number;
|
||||
after?: Cursor;
|
||||
filter?: CommentModerationActionFilter;
|
||||
}
|
||||
export type CommentModerationActionConnectionInput = ConnectionInput<
|
||||
CommentModerationAction
|
||||
>;
|
||||
|
||||
export async function retrieveCommentModerationActionConnection(
|
||||
mongo: Db,
|
||||
tenantID: string,
|
||||
input: ConnectionInput
|
||||
input: CommentModerationActionConnectionInput
|
||||
): Promise<Readonly<Connection<Readonly<CommentModerationAction>>>> {
|
||||
// Create the query.
|
||||
const query = new Query(collection(mongo)).where({ tenantID });
|
||||
@@ -130,7 +128,7 @@ export async function retrieveCommentModerationActionConnection(
|
||||
}
|
||||
|
||||
async function retrieveConnection(
|
||||
input: ConnectionInput,
|
||||
input: CommentModerationActionConnectionInput,
|
||||
query: Query<CommentModerationAction>
|
||||
): Promise<Readonly<Connection<Readonly<CommentModerationAction>>>> {
|
||||
// Apply the cursor to the query. Currently only supporting sorting by the
|
||||
|
||||
Reference in New Issue
Block a user