export database

This commit is contained in:
Artyom Ashirov 2024-11-16 19:18:50 +03:00
parent 44ae5a6631
commit e3f2e87fcc
4 changed files with 947 additions and 14 deletions

864
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
"dev": "nodemon src/index.js"
},
"dependencies": {
"archiver": "^7.0.1",
"axios": "^1.7.7",
"bip39": "^3.1.0",
"bitcoinjs-lib": "^6.1.6",

View File

@ -0,0 +1,83 @@
import config from '../config/config.js';
import fs from "fs";
import db from "../config/database.js";
import archiver from "archiver";
export default class AdminDumpHandler {
constructor(bot) {
this.bot = bot;
this.userStates = new Map();
}
isAdmin(userId) {
return config.ADMIN_IDS.includes(userId.toString());
}
async handleDump(msg) {
const chatId = msg.chat.id;
const keyboard = {
inline_keyboard: [
[
{text: '📥 Import dump', callback_data: 'import_database'},
{text: '📤 Export dump', callback_data: 'export_database'},
],
[{text: '« Back', callback_data: 'admin_menu'}]
]
}
await this.bot.sendMessage(chatId, 'Choose an option', {reply_markup: keyboard});
}
async exportDatabase(callbackQuery) {
const chatId = callbackQuery.message.chat.id;
const tables = [
"categories",
"crypto_wallets",
"locations",
"products",
"purchases",
"transactions",
"users"
]
const dumpPath = "./dump"
try {
fs.rmdirSync(dumpPath, {recursive: true, force: true});
fs.rmSync(`${dumpPath}/dump.zip`);
} catch (e) {
}
fs.mkdirSync(dumpPath);
for (const table of tables) {
const result = await db.runAsync(`SELECT * FROM ${table}`);
const tableData = JSON.stringify(result);
fs.writeFileSync(`${dumpPath}/${table}.json`, tableData);
}
const archive = archiver('zip', {zlib: { level: 9 } });
archive.directory(dumpPath, false);
const output = fs.createWriteStream('./dump.zip');
archive.pipe(output);
await archive.finalize();
output.on('close', () => {
this.bot.sendDocument(chatId, './dump.zip', {caption: 'Database dump'});
});
}
async importDatabase(callbackQuery) {
}
async confirmImport(callbackQuery) {
}
}

View File

@ -11,6 +11,7 @@ import AdminProductHandler from './handlers/adminProductHandler.js';
import ErrorHandler from './utils/errorHandler.js';
import User from './models/User.js';
import AdminUserLocationHandler from "./handlers/adminUserLocationHandler.js";
import AdminDumpHandler from "./handlers/adminDumpHandler.js";
// Debug logging function
const logDebug = (action, functionName) => {
@ -39,6 +40,7 @@ const adminUserHandler = new AdminUserHandler(bot);
const adminLocationHandler = new AdminLocationHandler(bot);
const adminUserLocationHandler = new AdminUserLocationHandler(bot);
const adminProductHandler = new AdminProductHandler(bot);
const adminDumpHandler = new AdminDumpHandler(bot);
// Start command - Create user profile
bot.onText(/\/start/, async (msg) => {
@ -135,6 +137,11 @@ bot.on('message', async (msg) => {
await adminLocationHandler.handleViewLocations(msg);
}
break;
case '💾 Database Backup':
if (adminHandler.isAdmin(msg.from.id)) {
await adminDumpHandler.handleDump(msg);
}
break;
}
} catch (error) {
await ErrorHandler.handleError(bot, msg.chat.id, error, 'message handler');
@ -330,6 +337,12 @@ bot.on('callback_query', async (callbackQuery) => {
logDebug(action, 'handleEditUserDistrict');
await adminUserLocationHandler.handleEditUserDistrict(callbackQuery)
}
// Dump manage
else if (action === "export_database") {
await adminDumpHandler.exportDatabase(callbackQuery);
return;
}
await bot.answerCallbackQuery(callbackQuery.id);
} catch (error) {
await ErrorHandler.handleError(bot, msg.chat.id, error, 'callback query');