Transaction username mongodb mutation (#14231)

* migrate newest usernames in transactions

* fix lint

* change the parameters
This commit is contained in:
negue
2022-09-21 21:42:39 +02:00
committed by GitHub
parent 6e5cac88fc
commit e9ee2d3fdd
6 changed files with 104 additions and 5 deletions

View File

@@ -0,0 +1,97 @@
/* eslint-disable no-console */
import { model as UserModel } from '../../../website/server/models/user';
import { TransactionModel } from '../../../website/server/models/transaction';
const MIGRATION_NAME = '20220915_transactions_user_name';
/* transaction config */
const transactionPerRun = 500;
const progressCount = 1000;
const transactionQuery = {
migration: { $ne: MIGRATION_NAME }, // skip already migrated entries
'transactionType': { $in: ['gift_send', 'gift_receive'] },
};
let count = 0;
async function updateTransaction (transaction, userNameMap) {
count++;
const set = {
migration: MIGRATION_NAME,
};
if (userNameMap.has(transaction.reference)) {
set['referenceText'] = userNameMap.get(transaction.reference);
} else {
set['referenceText'] = 'Account not found';
}
if (count % progressCount === 0) {
console.warn(`${count} ${transaction._id}`);
}
return TransactionModel.updateOne({
_id: transaction._id
}, { $set: set }).exec();
}
export default async function processTransactions () {
const fields = {
_id: 1,
reference: 1,
referenceText: 1,
};
const userNameMap = new Map();
while (true) { // eslint-disable-line no-constant-condition
const foundTransactions = await TransactionModel // eslint-disable-line no-await-in-loop
.find(transactionQuery)
.limit(transactionPerRun)
.sort({reference: 1})
.select(fields)
.lean()
.exec();
if (foundTransactions.length === 0) {
console.warn('All appropriate transactions found and modified.');
console.warn(`\n${count} transactions processed\n`);
break;
}
// check for unknown users and load the names
const userIdsToLoad = [];
for (const foundTransaction of foundTransactions) {
const userId = foundTransaction.reference;
if (userNameMap.has(userId)) {
continue;
}
userIdsToLoad.push(userId);
}
const users = await UserModel // eslint-disable-line no-await-in-loop
.find({
_id: { $in: userIdsToLoad }
})
.select({
_id: 1,
'auth.local.username': 1,
})
.lean()
.exec();
for (const user of users) {
const localUserName = user.auth?.local?.username;
if (!localUserName) {
console.warn(`\nNo Username found for ID: ${user._id}\n`);
continue;
}
userNameMap.set(user._id, localUserName)
}
await Promise.all(foundTransactions.map(t => updateTransaction(t, userNameMap))); // eslint-disable-line no-await-in-loop
}
};

View File

@@ -1,7 +1,7 @@
import { authWithHeaders } from '../../middlewares/auth';
import { chatReporterFactory } from '../../libs/chatReporting/chatReporterFactory';
import { ensurePermission } from '../../middlewares/ensureAccessRight';
import { model as Transaction } from '../../models/transaction';
import { TransactionModel as Transaction } from '../../models/transaction';
const api = {};

View File

@@ -2,7 +2,7 @@ import { authWithHeaders } from '../../middlewares/auth';
import * as userLib from '../../libs/user';
import { verifyDisplayName } from '../../libs/user/validation';
import common from '../../../common';
import { model as Transaction } from '../../models/transaction';
import { TransactionModel as Transaction } from '../../models/transaction';
const api = {};

View File

@@ -1,7 +1,7 @@
import mongoose from 'mongoose';
import validator from 'validator';
import baseModel from '../libs/baseModel';
import { model as Transaction } from './transaction';
import { TransactionModel as Transaction } from './transaction';
export const schema = new mongoose.Schema({
planId: String,

View File

@@ -17,6 +17,7 @@ export const schema = new Schema({
userId: {
$type: String, ref: 'User', required: true, validate: [v => validator.isUUID(v), 'Invalid uuid for Transaction.'],
},
migration: String,
}, {
strict: true,
minimize: false, // So empty objects are returned
@@ -34,9 +35,10 @@ schema.plugin(baseModel, {
'referenceText',
'amount',
'currentAmount',
'migration',
], // Nothing can be set from the client
timestamps: true,
_id: false, // using custom _id
});
export const model = mongoose.model('Transaction', schema);
export const TransactionModel = mongoose.model('Transaction', schema);

View File

@@ -23,7 +23,7 @@ import amazonPayments from '../../libs/payments/amazon'; // eslint-disable-line
import stripePayments from '../../libs/payments/stripe'; // eslint-disable-line import/no-cycle
import paypalPayments from '../../libs/payments/paypal'; // eslint-disable-line import/no-cycle
import { model as NewsPost } from '../newsPost';
import { model as Transaction } from '../transaction';
import { TransactionModel as Transaction } from '../transaction';
const { daysSince } = common;