Files
vps-tracker/server/routes/sync.js
T
Denozordec 196c5be532 Enhance database management and synchronization features
- Added new backup and restore functionality for JSON and SQLite database formats.
- Implemented notification settings for low balance alerts and sync digests in the settings page.
- Updated database schema to include new columns for balance alert thresholds and notification preferences.
- Refactored synchronization logic to provide detailed summaries and improved error handling.
- Enhanced user interface for managing accounts and settings, including new input fields for balance alerts.
- Improved sync log display to include summary information for better tracking of synchronization results.
2026-03-20 23:11:58 +07:00

110 lines
3.7 KiB
JavaScript

import { Router } from 'express'
import { getDb } from '../db.js'
import { fetchDashboardInfo, testConnection } from '../adapters/billmanager/index.js'
import { runBillmanagerAccountSync } from '../sync-account-job.js'
const router = Router()
router.post('/test-connection', async (req, res) => {
try {
const { apiBaseUrl, apiCredentials } = req.body || {}
if (!apiBaseUrl?.trim() || !apiCredentials?.trim()) {
return res.status(400).json({ ok: false, error: 'Укажите URL и учётные данные' })
}
const result = await testConnection(apiBaseUrl.trim(), apiCredentials.trim())
res.json(result)
} catch (err) {
res.status(500).json({ ok: false, error: err.message || 'Ошибка проверки' })
}
})
router.get('/status', (req, res) => {
try {
const db = getDb()
const rows = db.prepare(`
SELECT id, accountId, startedAt, finishedAt, status, vpsCount, paymentsCount, error, summary
FROM sync_log ORDER BY startedAt DESC LIMIT 50
`).all()
res.json(
rows.map((row) => {
let summaryParsed = null
if (row.summary) {
try {
summaryParsed = JSON.parse(row.summary)
} catch {
summaryParsed = null
}
}
return { ...row, summary: summaryParsed }
}),
)
} catch (err) {
res.status(500).json({ error: err.message })
}
})
router.get('/:accountId/balance', async (req, res) => {
try {
const db = getDb()
const { accountId } = req.params
const row = db.prepare('SELECT * FROM provider_accounts WHERE id = ?').get(accountId)
if (!row) {
return res.status(404).json({ error: 'Account not found' })
}
if (row.apiType !== 'billmanager') {
return res.status(400).json({ error: 'Account is not configured for BILLmanager API' })
}
if (!row.apiBaseUrl?.trim() || !row.apiCredentials?.trim()) {
return res.status(400).json({ error: 'API URL and credentials are required' })
}
const info = await fetchDashboardInfo(row.apiBaseUrl, row.apiCredentials.trim(), { fallbackCurrency: row.currency })
db.run(
'UPDATE provider_accounts SET balance_api=?, balance_currency=?, balance_updated_at=?, enoughmoneyto=? WHERE id=?',
info.balance,
info.currency || 'RUB',
new Date().toISOString(),
info.enoughmoneyto || '',
accountId,
)
res.json({ ok: true, balance: info })
} catch (err) {
console.error('Balance fetch error:', err)
res.status(500).json({ ok: false, error: err.message || 'Failed to fetch balance' })
}
})
router.post('/:accountId', async (req, res) => {
try {
const db = getDb()
const { accountId } = req.params
const { onlyTariffs = false } = req.body || {}
const row = db.prepare('SELECT * FROM provider_accounts WHERE id = ?').get(accountId)
if (!row) {
return res.status(404).json({ error: 'Account not found' })
}
if (row.apiType !== 'billmanager') {
return res.status(400).json({ error: 'Account is not configured for BILLmanager API' })
}
if (!row.apiBaseUrl?.trim() || !row.apiCredentials?.trim()) {
return res.status(400).json({ error: 'API URL and credentials are required' })
}
const opts = onlyTariffs ? { skipVpsPayments: true } : { skipTariffs: true }
const result = await runBillmanagerAccountSync(row, opts)
res.json({
ok: true,
synced: {
vpsCount: result.vpsCount,
paymentsCount: result.paymentsCount,
tariffsCount: result.tariffsCount ?? 0,
},
})
} catch (err) {
console.error('Sync error:', err)
res.status(500).json({ ok: false, error: err.message || 'Sync failed' })
}
})
export default router