Files
talk/src/core/server/graph/loaders/Users.ts
T
84bbc3d0c3 [CORL-688] Refactor: Consolidate the tenant and common context together (#2780)
* feat: initial impl

* Create preliminary comment moderation slices

CORL-688

* Move slices logic into stacks

CORL-688

* Create user comment counts

CORL-688

* Create naive mutation that initializes user comment counts

CORL-688

* Use bulk updates in user counts migration

CORL-688

* fix: review

* fix: fixed issue with aggregation

* Migrate creating comment into stacks

CORL-688

* Migrate editing a comment to the stacks

CORL-688

* Break publishing comment status out of updateAllCounts

CORL-688

* review: removed variable scoping in favor of export

* revert: feb8e8196cd448f5cd24f1ca2eb0b91fe9bd43c7

* review: simplification of stacks implementation

This simplifies the stacks implementation to better reuse code related
to count management and event publishing. This can be used to great
effect with the upcomming events PR #2738.

* Consolidate the tenant and common context together

CORL-688

* review: removed variable scoping in favor of export

* revert: feb8e8196cd448f5cd24f1ca2eb0b91fe9bd43c7

* review: simplification of stacks implementation

This simplifies the stacks implementation to better reuse code related
to count management and event publishing. This can be used to great
effect with the upcomming events PR #2738.

* fix: check if authorID is null before update user counts

CORL-688

* Consolidate common/tenant context supporting files

CORL-688

* feat: renamed TenantContext -> GraphContext

Co-authored-by: Wyatt Johnson <accounts+github@wyattjoh.ca>
2020-01-08 17:07:25 +00:00

133 lines
3.2 KiB
TypeScript

import DataLoader from "dataloader";
import { defaultTo } from "lodash";
import Context from "coral-server/graph/context";
import {
GQLUSER_ROLE,
GQLUSER_STATUS,
QueryToUsersArgs,
} from "coral-server/graph/schema/__generated__/types";
import { Connection } from "coral-server/models/helpers";
import {
retrieveManyUsers,
retrieveUserConnection,
User,
UserConnectionInput,
} from "coral-server/models/user";
type UserConnectionFilterInput = UserConnectionInput["filter"];
const roleFilter = (role?: GQLUSER_ROLE): UserConnectionFilterInput => {
if (role) {
return { role };
}
return {};
};
const queryFilter = (query?: string): UserConnectionFilterInput => {
if (query) {
return { $text: { $search: JSON.stringify(query) } };
}
return {};
};
const statusFilter = (
now: Date,
status?: GQLUSER_STATUS
): UserConnectionFilterInput => {
switch (status) {
case GQLUSER_STATUS.ACTIVE:
return {
"status.ban.active": false,
"status.premod.active": false,
"status.suspension.history": {
$not: {
$elemMatch: {
"from.start": {
$lte: now,
},
"from.finish": {
$gt: now,
},
},
},
},
};
case GQLUSER_STATUS.BANNED:
return { "status.ban.active": true };
case GQLUSER_STATUS.PREMOD:
return { "status.premod.active": true };
case GQLUSER_STATUS.SUSPENDED:
return {
"status.suspension.history": {
$elemMatch: {
"from.start": {
$lte: now,
},
"from.finish": {
$gt: now,
},
},
},
};
default:
return {};
}
};
/**
* primeUsersFromConnection will prime a given context with the users retrieved
* via a connection.
*
* @param ctx graph context to use to prime the loaders.
*/
const primeUsersFromConnection = (ctx: Context) => (
connection: Readonly<Connection<Readonly<User>>>
) => {
if (!ctx.disableCaching) {
// For each of the nodes, prime the user loader.
connection.nodes.forEach(user => {
ctx.loaders.Users.user.prime(user.id, user);
});
}
return connection;
};
export default (ctx: Context) => {
const user = new DataLoader<string, User | null>(
ids => retrieveManyUsers(ctx.mongo, ctx.tenant.id, ids),
{
// Disable caching for the DataLoader if the Context is designed to be
// long lived.
cache: !ctx.disableCaching,
}
);
if (ctx.user && !ctx.disableCaching) {
// Prime the current logged in user in the dataloader cache.
user.prime(ctx.user.id, ctx.user);
}
return {
user,
connection: ({ first, after, role, query, status }: QueryToUsersArgs) =>
retrieveUserConnection(ctx.mongo, ctx.tenant.id, {
first: defaultTo(first, 10),
after,
filter: {
// Merge the role filters into the query.
...roleFilter(role),
// Merge the query filters into the query.
...queryFilter(query),
// Merge the status filters into the query.
...statusFilter(ctx.now, status),
},
}).then(primeUsersFromConnection(ctx)),
};
};