import { ObjectId } from 'mongodb' import { POST, QRequestController, SECURE, } from './../../modules/RequestController' export default class VersionsController extends QRequestController { @POST @SECURE({ allow: ['admin', 'manager'] }) async create() { const name = this.body.name const backupCollectionName = 'system_backups' const exclude = [backupCollectionName, 'crm', 'users'] const collections = (await this.db.listCollections().toArray()) .map((c) => c.name) .filter((name) => !exclude.includes(name) && !name.includes('system_')) /* Создаем версию */ const version = await this.createVersion(collections, name) /* Сохраняем в базе */ await this.db.collection(backupCollectionName).insertOne(version) return this.answer(true) } @POST @SECURE({ allow: ['admin', 'manager'] }) async list() { /* Запрашиваем все версии */ const versions = (await this.db .collection('system_backups') .find({}) .sort({ date: -1 }) .project({ collections: 0 }) .toArray()) as any[] /* Получаем ids создателей */ const ids = [...new Set(versions.map((v: any) => v.creator))].map( (id) => new ObjectId(id) ) /* Получаем аккаунты создателей */ const creators: any[] = await this.db .collection('users') .find({ _id: { $in: ids } }) .project({ name: 1 }) .toArray() /* Загоняем имена пользователей в versions */ for (const version of versions) { const user = creators.find((c) => c._id.toString() === version.creator) version.creatorName = user ? user.name : 'Пользователь удален' } return this.answer(true, versions) } @POST @SECURE({ allow: ['admin', 'manager'] }) async remove() { const _id = new ObjectId(this.body._id) const backupCollectionName = 'system_backups' /* Находим и удаляем точку восстановления */ await this.db.collection(backupCollectionName).findOneAndDelete({ _id }) return this.answer(true) } @POST @SECURE({ allow: ['admin', 'manager'] }) async rename() { const _id = new ObjectId(this.body._id) const name = this.body.name const backupCollectionName = 'system_backups' /* Находим и переименовываем точку восстановления */ await this.db .collection(backupCollectionName) .findOneAndUpdate({ _id }, { $set: { name } }) return this.answer(true) } @POST @SECURE({ allow: ['admin', 'manager'] }) async restore() { const _id = new ObjectId(this.body._id) const backupCollectionName = 'system_backups' /* Находим точку восстановления */ const version = await this.db .collection(backupCollectionName) .findOne({ _id }) if (!version) return this.answer(false, undefined, 'Точка восстановления не найдена') /* Восстанавливаем */ for (const collectionData of version.collections) { const collection = this.db.collection(collectionData.name) const count = await collection.countDocuments() if (count) { await collection.drop() } await collection.insertMany(collectionData.documents) } return this.answer(true) } async createVersion(collections: string[], name: string) { const collectionsArray = [] for (const collection of collections) { const documents = await this.db.collection(collection).find().toArray() collectionsArray.push({ name: collection, documents }) } return { date: new Date().toISOString(), creator: this.req?.session?.auth?._id, collections: collectionsArray, name, } } }