From ec038242bfb732efb7d172329b21669e2965c0fb Mon Sep 17 00:00:00 2001 From: Denozordec Date: Sat, 21 Mar 2026 01:01:09 +0700 Subject: [PATCH] feat: consolidate provider API sources with heuristic support Updated the database migration logic to consolidate provider API sources from both accounts and heuristic methods for BILLmanager URLs. Replaced direct calls to `consolidateProviderApiFromAccounts` with `consolidateAllProviderApiSources` in relevant routes to ensure comprehensive API data handling. --- server/db/migrations.js | 57 +++++++++++++++++++++++++++++++++++++--- server/routes/backup.js | 4 +-- server/routes/migrate.js | 4 +-- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/server/db/migrations.js b/server/db/migrations.js index 97efb2a..2ebbcf5 100644 --- a/server/db/migrations.js +++ b/server/db/migrations.js @@ -35,8 +35,11 @@ export function consolidateProviderApiFromAccounts(db) { db, `SELECT apiBaseUrl FROM provider_accounts WHERE providerId = ? - AND lower(trim(COALESCE(apiType, ''))) = 'billmanager' AND length(trim(COALESCE(apiBaseUrl, ''))) > 0 + AND ( + lower(trim(COALESCE(apiType, ''))) = 'billmanager' + OR instr(lower(trim(COALESCE(apiBaseUrl, ''))), 'billmgr') > 0 + ) ORDER BY id`, [pid], ) @@ -51,13 +54,59 @@ export function consolidateProviderApiFromAccounts(db) { db.run(`UPDATE providers SET apiType = ?, apiBaseUrl = ? WHERE id = ?`, 'billmanager', apiBaseUrl, pid) db.run( `UPDATE provider_accounts SET apiType = '', apiBaseUrl = '' - WHERE providerId = ? AND lower(trim(COALESCE(apiType, ''))) = 'billmanager' - AND length(trim(COALESCE(apiBaseUrl, ''))) > 0`, + WHERE providerId = ? + AND length(trim(COALESCE(apiBaseUrl, ''))) > 0 + AND ( + lower(trim(COALESCE(apiType, ''))) = 'billmanager' + OR instr(lower(trim(COALESCE(apiBaseUrl, ''))), 'billmgr') > 0 + )`, pid, ) } } +/** + * Раньше URL BILLmanager часто указывали в «Сайт» хостера или в panelUrl аккаунта, без apiType/apiBaseUrl. + */ +export function heuristicBillmanagerProviderApi(db) { + const tryBillmgrUrl = (raw) => { + const t = String(raw || '').trim() + if (!t) return '' + if (!/^https?:\/\//i.test(t)) return '' + if (!/billmgr/i.test(t)) return '' + return t.replace(/\/+$/, '') + } + + const provRows = selectAllObjects(db, 'SELECT id, website, apiType, apiBaseUrl FROM providers') + for (const prov of provRows) { + if (String(prov.apiType || '').trim() || String(prov.apiBaseUrl || '').trim()) continue + + let url = tryBillmgrUrl(prov.website) + if (!url) { + const accRows = selectAllObjects( + db, + `SELECT panelUrl FROM provider_accounts + WHERE providerId = ? AND length(trim(COALESCE(panelUrl, ''))) > 0 + ORDER BY id`, + [prov.id], + ) + for (const row of accRows) { + url = tryBillmgrUrl(row.panelUrl) + if (url) break + } + } + if (url) { + db.run(`UPDATE providers SET apiType = ?, apiBaseUrl = ? WHERE id = ?`, 'billmanager', url, prov.id) + } + } +} + +/** Перенос API на хостера: с аккаунтов + эвристика по website/panelUrl. */ +export function consolidateAllProviderApiSources(db) { + consolidateProviderApiFromAccounts(db) + heuristicBillmanagerProviderApi(db) +} + export const MIGRATIONS = [ { name: 'provider_accounts_api', @@ -333,7 +382,7 @@ export const MIGRATIONS = [ } catch (e) { if (!String(e.message || e).includes('duplicate column')) throw e } - consolidateProviderApiFromAccounts(db) + consolidateAllProviderApiSources(db) }, }, ] diff --git a/server/routes/backup.js b/server/routes/backup.js index 95b1f52..f4e3e03 100644 --- a/server/routes/backup.js +++ b/server/routes/backup.js @@ -2,7 +2,7 @@ import { Router } from 'express' import express from 'express' import { readFileSync, existsSync } from 'node:fs' import { getDb, saveDb, DB_PATH, reloadDatabaseFromBuffer } from '../db.js' -import { consolidateProviderApiFromAccounts } from '../db/migrations.js' +import { consolidateAllProviderApiSources } from '../db/migrations.js' import { rowToVps } from './vps.js' import { rowToActiveTariff, rowToTariffSyncOptions } from '../utils/row-mappers.js' @@ -162,7 +162,7 @@ function importJsonSnapshot(data) { ) } - consolidateProviderApiFromAccounts(db) + consolidateAllProviderApiSources(db) const settingsList = Array.isArray(data.settings) ? data.settings : data.settings ? [data.settings] : [] for (const s of settingsList) { diff --git a/server/routes/migrate.js b/server/routes/migrate.js index 5c37fb2..54c5f33 100644 --- a/server/routes/migrate.js +++ b/server/routes/migrate.js @@ -1,6 +1,6 @@ import { Router } from 'express' import { getDb, saveDb } from '../db.js' -import { consolidateProviderApiFromAccounts } from '../db/migrations.js' +import { consolidateAllProviderApiSources } from '../db/migrations.js' const router = Router() @@ -72,7 +72,7 @@ router.post('/', (req, res) => { db.run(sql, s.id ?? 'settings-main', s.baseCurrency ?? 'RUB', s.ratesUrl ?? '', s.autoConvert !== false ? 1 : 0, s.ratesUpdatedAt ?? '', s.syncEnabled ? 1 : 0, s.syncIntervalMinutes ?? 60) } } - consolidateProviderApiFromAccounts(db) + consolidateAllProviderApiSources(db) saveDb() res.json({ ok: true })