/** * Скрипт для массового создания Legacy Deployments * * Что делает: * 1. Получает всех beneficiaries из WellNuo DB * 2. Для каждого без валидного legacy_deployment_id: * - Вызывает set_deployment в Legacy API * - Получает deployment_id из ответа * - Сохраняет в beneficiary_deployments.legacy_deployment_id */ const https = require('https'); const { Client } = require('pg'); require('dotenv').config(); // Legacy API credentials const LEGACY_API = { host: 'eluxnetworks.net', path: '/function/well-api/api', user: process.env.LEGACY_API_USERNAME || 'robster', password: process.env.LEGACY_API_PASSWORD || 'rob2' }; // WellNuo DB credentials const DB_CONFIG = { host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT || '5432'), database: process.env.DB_NAME, user: process.env.DB_USER, password: process.env.DB_PASSWORD, connectionTimeoutMillis: 15000, ssl: { rejectUnauthorized: false } }; // 1x1 pixel JPEG (minimal photo for API) const MINI_PHOTO = '/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAn/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCwAB//2Q=='; // Helper: Login to Legacy API and get token async function legacyLogin() { return new Promise((resolve, reject) => { const querystring = require('querystring'); const data = querystring.stringify({ function: 'credentials', user_name: LEGACY_API.user, ps: LEGACY_API.password, clientId: '001', nonce: Date.now().toString() }); const options = { hostname: LEGACY_API.host, path: LEGACY_API.path, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(data) } }; const req = https.request(options, (res) => { let body = ''; res.on('data', (chunk) => body += chunk); res.on('end', () => { try { const result = JSON.parse(body); if (result.access_token) { resolve(result.access_token); } else { reject(new Error('No token in login response: ' + body)); } } catch (e) { reject(new Error('Invalid JSON: ' + body.substring(0, 200))); } }); }); req.on('error', reject); req.write(data); req.end(); }); } // Helper: make Legacy API request with token function legacyRequest(token, params) { return new Promise((resolve, reject) => { const querystring = require('querystring'); const data = querystring.stringify({ user_name: LEGACY_API.user, token: token, ...params }); const options = { hostname: LEGACY_API.host, path: LEGACY_API.path, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(data) } }; const req = https.request(options, (res) => { let body = ''; res.on('data', (chunk) => body += chunk); res.on('end', () => { try { resolve(JSON.parse(body)); } catch (e) { resolve({ error: 'Invalid JSON', raw: body.substring(0, 200) }); } }); }); req.on('error', reject); req.write(data); req.end(); }); } // Create deployment in Legacy API async function createLegacyDeployment(token, beneficiaryId, beneficiaryName) { // Format name for Legacy API (needs exactly 2 words) const nameParts = (beneficiaryName || 'User').trim().split(/\s+/); let firstName, lastName; if (nameParts.length === 1) { firstName = nameParts[0]; lastName = 'User'; } else { firstName = nameParts[0]; lastName = nameParts.slice(1).join(' ').substring(0, 20); } const timestamp = Date.now(); const beneficiaryUsername = 'b' + beneficiaryId + '_' + timestamp; const password = Math.random().toString(36).substring(2, 15); const uniqueEmail = 'b' + beneficiaryId + '_' + timestamp + '@wellnuo.app'; const result = await legacyRequest(token, { function: 'set_deployment', deployment: 'NEW', beneficiary_name: firstName + ' ' + lastName, beneficiary_email: uniqueEmail, beneficiary_user_name: beneficiaryUsername, beneficiary_password: password, beneficiary_address: 'test', beneficiary_photo: MINI_PHOTO, firstName: firstName, lastName: lastName, first_name: firstName, last_name: lastName, new_user_name: beneficiaryUsername, phone_number: '+10000000000', key: password, signature: 'WellNuo', gps_age: '0', wifis: '[]', devices: '[]' }); return result; } async function main() { console.log('='.repeat(70)); console.log('СОЗДАНИЕ LEGACY DEPLOYMENTS ДЛЯ ВСЕХ BENEFICIARIES'); console.log('='.repeat(70)); console.log(); // 1. Login to Legacy API console.log('1. Авторизация в Legacy API...'); let token; try { token = await legacyLogin(); console.log(' ✅ Получен токен'); } catch (error) { console.error(' ❌ ОШИБКА:', error.message); process.exit(1); } console.log(); // 2. Get existing deployments from Legacy API console.log('2. Получаем существующие deployments из Legacy API...'); const existingDeployments = await legacyRequest(token, { function: 'deployments_list', first: '0', last: '500' }); const existingIds = new Set(); if (existingDeployments.result_list) { existingDeployments.result_list.forEach(d => existingIds.add(d.deployment_id)); console.log(' Существующие IDs: ' + [...existingIds].sort((a,b) => a-b).join(', ')); } console.log(); // 3. Connect to WellNuo DB console.log('3. Подключаемся к WellNuo DB...'); const client = new Client(DB_CONFIG); try { await client.connect(); console.log(' ✅ Подключено'); console.log(); // Get all beneficiaries with their deployments const result = await client.query(` SELECT b.id as beneficiary_id, b.name as beneficiary_name, bd.id as deployment_id, bd.legacy_deployment_id FROM beneficiaries b LEFT JOIN beneficiary_deployments bd ON b.id = bd.beneficiary_id ORDER BY b.id `); console.log('4. Найдено ' + result.rows.length + ' записей в БД'); console.log(); // Filter: need to create deployment for those with NULL or invalid legacy_deployment_id const needsCreation = result.rows.filter(row => { if (row.legacy_deployment_id === null) return true; if (!existingIds.has(row.legacy_deployment_id)) return true; return false; }); console.log('5. Нужно создать deployments для ' + needsCreation.length + ' beneficiaries:'); console.log('-'.repeat(70)); const created = []; const failed = []; for (const row of needsCreation) { const name = (row.beneficiary_name || 'Unknown').substring(0, 20); process.stdout.write(' #' + row.beneficiary_id + ' (' + name + ')... '); try { const response = await createLegacyDeployment(token, row.beneficiary_id, row.beneficiary_name); if (response.deployment_id && response.deployment_id > 0) { console.log('✅ deployment_id=' + response.deployment_id); // Update database if (row.deployment_id) { await client.query( 'UPDATE beneficiary_deployments SET legacy_deployment_id = $1 WHERE id = $2', [response.deployment_id, row.deployment_id] ); } created.push({ beneficiaryId: row.beneficiary_id, deploymentId: row.deployment_id, legacyDeploymentId: response.deployment_id }); } else { console.log('❌ No deployment_id: ' + JSON.stringify(response).substring(0, 100)); failed.push({ beneficiaryId: row.beneficiary_id, error: 'No deployment_id' }); } // Small delay to not overwhelm API await new Promise(r => setTimeout(r, 300)); } catch (error) { console.log('❌ Error: ' + error.message); failed.push({ beneficiaryId: row.beneficiary_id, error: error.message }); } } console.log(); console.log('='.repeat(70)); console.log('РЕЗУЛЬТАТЫ:'); console.log(' ✅ Создано: ' + created.length); console.log(' ❌ Ошибок: ' + failed.length); console.log(); if (created.length > 0) { console.log('Созданные deployments:'); for (const c of created) { console.log(' Beneficiary #' + c.beneficiaryId + ' → legacy_deployment_id=' + c.legacyDeploymentId); } } if (failed.length > 0) { console.log(); console.log('Ошибки:'); for (const f of failed) { console.log(' Beneficiary #' + f.beneficiaryId + ': ' + f.error); } } } catch (error) { console.error(' ❌ ОШИБКА БД:', error.message); } finally { await client.end(); } console.log(); console.log('='.repeat(70)); console.log('Готово!'); } main().catch(console.error);