[CORL-649] Migrations (#2597)

* feat: added migration framework

* chore: added premod user status migration

* feat: enhanced error handling of migrations

* fix: added missing argument from abstract method

* fix: another templating blunder

* fix: removed debug code

* feat: enhanced migration tracking

* fix: remove skipping migrations

* feat: moved indexing to migration system

* fix: linting
This commit is contained in:
Wyatt Johnson
2019-10-01 16:00:27 +00:00
committed by GitHub
parent b3b26bd9f3
commit c045f52daa
40 changed files with 1038 additions and 469 deletions
+4 -86
View File
@@ -33,19 +33,15 @@ import logger from "coral-server/logger";
import {
Connection,
ConnectionInput,
createCollection,
createConnectionOrderVariants,
createIndexFactory,
Query,
resolveConnection,
} from "coral-server/models/helpers";
import { TenantResource } from "coral-server/models/tenant";
import { DigestibleTemplate } from "coral-server/queue/tasks/mailer/templates";
import { users as collection } from "coral-server/services/mongodb/collections";
import { getLocalProfile, hasLocalProfile } from "./helpers";
const collection = createCollection<User>("users");
export interface LocalProfile {
type: "local";
id: string;
@@ -297,10 +293,8 @@ export interface UserStatus {
/**
* premod stores whether a user is set to mandatory premod and history of
* premod status.
*
* FIXME: (wyattjoh) set defaults during migration
*/
premod?: PremodStatus;
premod: PremodStatus;
}
/**
@@ -436,80 +430,6 @@ export interface User extends TenantResource {
deletedAt?: Date;
}
export async function createUserIndexes(mongo: Db) {
const createIndex = createIndexFactory(collection(mongo));
// UNIQUE { id }
await createIndex({ tenantID: 1, id: 1 }, { unique: true });
// UNIQUE - PARTIAL { email }
await createIndex(
{ tenantID: 1, email: 1 },
{ unique: true, partialFilterExpression: { email: { $exists: true } } }
);
// UNIQUE { profiles.type, profiles.id }
await createIndex(
{ tenantID: 1, "profiles.type": 1, "profiles.id": 1 },
{
unique: true,
partialFilterExpression: { "profiles.id": { $exists: true } },
}
);
// { profiles }
await createIndex(
{ tenantID: 1, profiles: 1, email: 1 },
{
partialFilterExpression: { profiles: { $exists: true } },
background: true,
}
);
// TEXT { id, username, email, createdAt }
await createIndex(
{
tenantID: 1,
id: "text",
username: "text",
email: "text",
createdAt: -1,
},
{ background: true }
);
const variants = createConnectionOrderVariants<Readonly<User>>(
[{ createdAt: -1 }],
{ background: true }
);
// User Connection pagination.
// { ...connectionParams }
await variants(createIndex, {
tenantID: 1,
});
// Role based User Connection pagination.
// { role, ...connectionParams }
await variants(createIndex, {
tenantID: 1,
role: 1,
});
// Suspension based User Connection pagination.
await variants(createIndex, {
tenantID: 1,
"status.suspension.history.from.start": 1,
"status.suspension.history.from.finish": 1,
});
// Ban based User Connection pagination.
await variants(createIndex, {
tenantID: 1,
"status.ban.active": 1,
});
}
function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, 10);
}
@@ -1460,8 +1380,7 @@ export async function premodUser(
// Check to see if the user is already banned.
const premod = consolidateUserPremodStatus(user.status.premod);
// FIXME: (wyattjoh) once migration has been performed, remove check
if (premod && premod.active) {
if (premod.active) {
throw new UserAlreadyPremoderated();
}
@@ -1873,8 +1792,7 @@ export function consolidateUserSuspensionStatus(
export interface ConsolidatedUserStatus {
suspension: ConsolidatedSuspensionStatus;
ban: ConsolidatedBanStatus;
// FIXME: (wyattjoh) once migration has been performed, make required
premod?: ConsolidatedPremodStatus;
premod: ConsolidatedPremodStatus;
}
export function consolidateUserStatus(