fix(sync): не стирать тарифы при ошибке загрузки прайс-листа
Ошибка запроса тарифов превращалась в пустой список: active_tariffs удалялись, а следующий успешный синк объявлял все тарифы новыми. Пустой ответ теперь оставляет старый список, замена идёт в транзакции. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
01a771407d
commit
78f413324a
6 files changed
+285
-261
No files matched your search
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { getCurrentSpaceId, getDb, schema } from '@cfdm/db'
|
import { getCurrentSpaceId, getDb, getSqlite, schema } from '@cfdm/db'
|
||||||
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
||||||
|
|
||||||
import type { BillmanagerSyncAccount } from './context.js'
|
import type { BillmanagerSyncAccount } from './context.js'
|
||||||
@@ -355,74 +355,77 @@ export async function syncFromBillmanager(
|
|||||||
|
|
||||||
let tariffsCount = 0
|
let tariffsCount = 0
|
||||||
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
||||||
if (fetchTariffs) {
|
// Fetch errors come back as [] — keep the old list instead of wiping it (and re-announcing all as new).
|
||||||
const existingTariffIds = new Set(
|
if (fetchTariffs && tariffItems.length > 0) {
|
||||||
db
|
getSqlite().transaction(() => {
|
||||||
.select({ id: schema.activeTariffs.id })
|
const existingTariffIds = new Set(
|
||||||
.from(schema.activeTariffs)
|
db
|
||||||
|
.select({ id: schema.activeTariffs.id })
|
||||||
|
.from(schema.activeTariffs)
|
||||||
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
|
.all()
|
||||||
|
.map((r) => r.id),
|
||||||
|
)
|
||||||
|
const syncedAt = new Date().toISOString()
|
||||||
|
db.delete(schema.activeTariffs)
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
.all()
|
.run()
|
||||||
.map((r) => r.id),
|
|
||||||
)
|
|
||||||
const syncedAt = new Date().toISOString()
|
|
||||||
db.delete(schema.activeTariffs)
|
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
|
||||||
.run()
|
|
||||||
|
|
||||||
for (const t of tariffItems) {
|
for (const t of tariffItems) {
|
||||||
const dcKey = t.datacenterKey ?? ''
|
const dcKey = t.datacenterKey ?? ''
|
||||||
const dcName = t.datacenterName ?? ''
|
const dcName = t.datacenterName ?? ''
|
||||||
const tariffId = dcKey
|
const tariffId = dcKey
|
||||||
? `tariff-bm-${accountId}-${t.externalId}-${dcKey}`
|
? `tariff-bm-${accountId}-${t.externalId}-${dcKey}`
|
||||||
: `tariff-bm-${accountId}-${t.externalId}`
|
: `tariff-bm-${accountId}-${t.externalId}`
|
||||||
if (!existingTariffIds.has(tariffId)) {
|
if (!existingTariffIds.has(tariffId)) {
|
||||||
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
||||||
|
}
|
||||||
|
db.insert(schema.activeTariffs)
|
||||||
|
.values({
|
||||||
|
spaceId: getCurrentSpaceId(),
|
||||||
|
id: tariffId,
|
||||||
|
providerAccountId: accountId,
|
||||||
|
providerId,
|
||||||
|
externalId: t.externalId,
|
||||||
|
datacenterKey: dcKey,
|
||||||
|
datacenterName: dcName,
|
||||||
|
name: t.name || '',
|
||||||
|
desc: t.desc || '',
|
||||||
|
vcpu: t.vcpu || 0,
|
||||||
|
ramGb: t.ramGb || 0,
|
||||||
|
diskGb: t.diskGb || 0,
|
||||||
|
diskType: t.diskType || 'SSD',
|
||||||
|
virtualization: t.virtualization || 'KVM',
|
||||||
|
channel: t.channel || '',
|
||||||
|
location: t.location || '',
|
||||||
|
country: t.country || '',
|
||||||
|
cpuModel: t.cpuModel || '',
|
||||||
|
orderAvailable: t.orderAvailable ? 1 : 0,
|
||||||
|
price: t.price || '',
|
||||||
|
syncedAt,
|
||||||
|
})
|
||||||
|
.run()
|
||||||
|
tariffsCount++
|
||||||
}
|
}
|
||||||
db.insert(schema.activeTariffs)
|
|
||||||
.values({
|
|
||||||
spaceId: getCurrentSpaceId(),
|
|
||||||
id: tariffId,
|
|
||||||
providerAccountId: accountId,
|
|
||||||
providerId,
|
|
||||||
externalId: t.externalId,
|
|
||||||
datacenterKey: dcKey,
|
|
||||||
datacenterName: dcName,
|
|
||||||
name: t.name || '',
|
|
||||||
desc: t.desc || '',
|
|
||||||
vcpu: t.vcpu || 0,
|
|
||||||
ramGb: t.ramGb || 0,
|
|
||||||
diskGb: t.diskGb || 0,
|
|
||||||
diskType: t.diskType || 'SSD',
|
|
||||||
virtualization: t.virtualization || 'KVM',
|
|
||||||
channel: t.channel || '',
|
|
||||||
location: t.location || '',
|
|
||||||
country: t.country || '',
|
|
||||||
cpuModel: t.cpuModel || '',
|
|
||||||
orderAvailable: t.orderAvailable ? 1 : 0,
|
|
||||||
price: t.price || '',
|
|
||||||
syncedAt,
|
|
||||||
})
|
|
||||||
.run()
|
|
||||||
tariffsCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.keys(slist).length > 0) {
|
if (Object.keys(slist).length > 0) {
|
||||||
const datacenters = Array.isArray(slist.datacenter) ? JSON.stringify(slist.datacenter) : '[]'
|
const datacenters = Array.isArray(slist.datacenter) ? JSON.stringify(slist.datacenter) : '[]'
|
||||||
const periods = Array.isArray(slist.period) ? JSON.stringify(slist.period) : '[]'
|
const periods = Array.isArray(slist.period) ? JSON.stringify(slist.period) : '[]'
|
||||||
db.insert(schema.tariffSyncOptions)
|
db.insert(schema.tariffSyncOptions)
|
||||||
.values({
|
.values({
|
||||||
spaceId: getCurrentSpaceId(),
|
spaceId: getCurrentSpaceId(),
|
||||||
providerAccountId: accountId,
|
providerAccountId: accountId,
|
||||||
datacenters,
|
datacenters,
|
||||||
periods,
|
periods,
|
||||||
syncedAt,
|
syncedAt,
|
||||||
})
|
})
|
||||||
.onConflictDoUpdate({
|
.onConflictDoUpdate({
|
||||||
target: schema.tariffSyncOptions.providerAccountId,
|
target: schema.tariffSyncOptions.providerAccountId,
|
||||||
set: { datacenters, periods, syncedAt },
|
set: { datacenters, periods, syncedAt },
|
||||||
})
|
})
|
||||||
.run()
|
.run()
|
||||||
}
|
}
|
||||||
|
})()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fetchVpsPayments) {
|
if (!fetchVpsPayments) {
|
||||||
|
|||||||
@@ -162,4 +162,13 @@ describe('syncFromFourvps', () => {
|
|||||||
const ids = (getSqlite().prepare(`SELECT id FROM vps ORDER BY id`).all() as { id: string }[]).map((r) => r.id)
|
const ids = (getSqlite().prepare(`SELECT id FROM vps ORDER BY id`).all() as { id: string }[]).map((r) => r.id)
|
||||||
expect(ids).toEqual(['manual-12', 'vps-4vps-acc-4vps-100'])
|
expect(ids).toEqual(['manual-12', 'vps-4vps-acc-4vps-100'])
|
||||||
})
|
})
|
||||||
|
it('keeps tariffs when the tariff fetch fails and does not re-announce them', async () => {
|
||||||
|
await syncFromFourvps(account)
|
||||||
|
vi.mocked(fetchTarifList).mockRejectedValueOnce(new Error('timeout'))
|
||||||
|
await syncFromFourvps(account)
|
||||||
|
const count = getSqlite().prepare(`SELECT COUNT(*) as c FROM active_tariffs`).get() as { c: number }
|
||||||
|
expect(count.c).toBe(1)
|
||||||
|
const third = await syncFromFourvps(account)
|
||||||
|
expect(third.newTariffs).toEqual([])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { getCurrentSpaceId, getDb, schema } from '@cfdm/db'
|
import { getCurrentSpaceId, getDb, getSqlite, schema } from '@cfdm/db'
|
||||||
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
||||||
|
|
||||||
import type { FourvpsSyncAccount } from './context.js'
|
import type { FourvpsSyncAccount } from './context.js'
|
||||||
@@ -223,56 +223,59 @@ export async function syncFromFourvps(
|
|||||||
|
|
||||||
let tariffsCount = 0
|
let tariffsCount = 0
|
||||||
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
||||||
if (fetchTariffs) {
|
// Fetch errors come back as [] — keep the old list instead of wiping it (and re-announcing all as new).
|
||||||
const existingTariffIds = new Set(
|
if (fetchTariffs && tariffItems.length > 0) {
|
||||||
db
|
getSqlite().transaction(() => {
|
||||||
.select({ id: schema.activeTariffs.id })
|
const existingTariffIds = new Set(
|
||||||
.from(schema.activeTariffs)
|
db
|
||||||
|
.select({ id: schema.activeTariffs.id })
|
||||||
|
.from(schema.activeTariffs)
|
||||||
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
|
.all()
|
||||||
|
.map((r) => r.id),
|
||||||
|
)
|
||||||
|
const syncedAt = new Date().toISOString()
|
||||||
|
db.delete(schema.activeTariffs)
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
.all()
|
|
||||||
.map((r) => r.id),
|
|
||||||
)
|
|
||||||
const syncedAt = new Date().toISOString()
|
|
||||||
db.delete(schema.activeTariffs)
|
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
|
||||||
.run()
|
|
||||||
|
|
||||||
for (const t of tariffItems) {
|
|
||||||
const dcKey = t.datacenterKey ?? ''
|
|
||||||
const dcName = t.datacenterName ?? ''
|
|
||||||
const tariffId = dcKey
|
|
||||||
? `tariff-4vps-${accountId}-${t.externalId}-${dcKey}`
|
|
||||||
: `tariff-4vps-${accountId}-${t.externalId}`
|
|
||||||
if (!existingTariffIds.has(tariffId)) {
|
|
||||||
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
|
||||||
}
|
|
||||||
db.insert(schema.activeTariffs)
|
|
||||||
.values({
|
|
||||||
spaceId: getCurrentSpaceId(),
|
|
||||||
id: tariffId,
|
|
||||||
providerAccountId: accountId,
|
|
||||||
providerId,
|
|
||||||
externalId: t.externalId,
|
|
||||||
datacenterKey: dcKey,
|
|
||||||
datacenterName: dcName,
|
|
||||||
name: t.name || '',
|
|
||||||
desc: t.desc || '',
|
|
||||||
vcpu: t.vcpu || 0,
|
|
||||||
ramGb: t.ramGb || 0,
|
|
||||||
diskGb: t.diskGb || 0,
|
|
||||||
diskType: t.diskType || 'NVMe',
|
|
||||||
virtualization: t.virtualization || 'KVM',
|
|
||||||
channel: t.channel || '',
|
|
||||||
location: t.location || '',
|
|
||||||
country: t.country || '',
|
|
||||||
cpuModel: t.cpuModel || '',
|
|
||||||
orderAvailable: t.orderAvailable ? 1 : 0,
|
|
||||||
price: t.price || '',
|
|
||||||
syncedAt,
|
|
||||||
})
|
|
||||||
.run()
|
.run()
|
||||||
tariffsCount++
|
|
||||||
}
|
for (const t of tariffItems) {
|
||||||
|
const dcKey = t.datacenterKey ?? ''
|
||||||
|
const dcName = t.datacenterName ?? ''
|
||||||
|
const tariffId = dcKey
|
||||||
|
? `tariff-4vps-${accountId}-${t.externalId}-${dcKey}`
|
||||||
|
: `tariff-4vps-${accountId}-${t.externalId}`
|
||||||
|
if (!existingTariffIds.has(tariffId)) {
|
||||||
|
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
||||||
|
}
|
||||||
|
db.insert(schema.activeTariffs)
|
||||||
|
.values({
|
||||||
|
spaceId: getCurrentSpaceId(),
|
||||||
|
id: tariffId,
|
||||||
|
providerAccountId: accountId,
|
||||||
|
providerId,
|
||||||
|
externalId: t.externalId,
|
||||||
|
datacenterKey: dcKey,
|
||||||
|
datacenterName: dcName,
|
||||||
|
name: t.name || '',
|
||||||
|
desc: t.desc || '',
|
||||||
|
vcpu: t.vcpu || 0,
|
||||||
|
ramGb: t.ramGb || 0,
|
||||||
|
diskGb: t.diskGb || 0,
|
||||||
|
diskType: t.diskType || 'NVMe',
|
||||||
|
virtualization: t.virtualization || 'KVM',
|
||||||
|
channel: t.channel || '',
|
||||||
|
location: t.location || '',
|
||||||
|
country: t.country || '',
|
||||||
|
cpuModel: t.cpuModel || '',
|
||||||
|
orderAvailable: t.orderAvailable ? 1 : 0,
|
||||||
|
price: t.price || '',
|
||||||
|
syncedAt,
|
||||||
|
})
|
||||||
|
.run()
|
||||||
|
tariffsCount++
|
||||||
|
}
|
||||||
|
})()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fetchVpsData) {
|
if (!fetchVpsData) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { getCurrentSpaceId, getDb, schema } from '@cfdm/db'
|
import { getCurrentSpaceId, getDb, getSqlite, schema } from '@cfdm/db'
|
||||||
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
||||||
|
|
||||||
import type { RuvdsSyncAccount } from './context.js'
|
import type { RuvdsSyncAccount } from './context.js'
|
||||||
@@ -286,56 +286,59 @@ export async function syncFromRuvds(
|
|||||||
|
|
||||||
let tariffsCount = 0
|
let tariffsCount = 0
|
||||||
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
||||||
if (fetchTariffs) {
|
// Fetch errors come back as [] — keep the old list instead of wiping it (and re-announcing all as new).
|
||||||
const existingTariffIds = new Set(
|
if (fetchTariffs && tariffItems.length > 0) {
|
||||||
db
|
getSqlite().transaction(() => {
|
||||||
.select({ id: schema.activeTariffs.id })
|
const existingTariffIds = new Set(
|
||||||
.from(schema.activeTariffs)
|
db
|
||||||
|
.select({ id: schema.activeTariffs.id })
|
||||||
|
.from(schema.activeTariffs)
|
||||||
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
|
.all()
|
||||||
|
.map((r) => r.id),
|
||||||
|
)
|
||||||
|
const syncedAt = new Date().toISOString()
|
||||||
|
db.delete(schema.activeTariffs)
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
.all()
|
|
||||||
.map((r) => r.id),
|
|
||||||
)
|
|
||||||
const syncedAt = new Date().toISOString()
|
|
||||||
db.delete(schema.activeTariffs)
|
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
|
||||||
.run()
|
|
||||||
|
|
||||||
for (const t of tariffItems) {
|
|
||||||
const dcKey = t.datacenterKey ?? ''
|
|
||||||
const dcName = t.datacenterName ?? ''
|
|
||||||
const tariffId = dcKey
|
|
||||||
? `tariff-ruvds-${accountId}-${t.externalId}-${dcKey}`
|
|
||||||
: `tariff-ruvds-${accountId}-${t.externalId}`
|
|
||||||
if (!existingTariffIds.has(tariffId)) {
|
|
||||||
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
|
||||||
}
|
|
||||||
db.insert(schema.activeTariffs)
|
|
||||||
.values({
|
|
||||||
spaceId: getCurrentSpaceId(),
|
|
||||||
id: tariffId,
|
|
||||||
providerAccountId: accountId,
|
|
||||||
providerId,
|
|
||||||
externalId: t.externalId,
|
|
||||||
datacenterKey: dcKey,
|
|
||||||
datacenterName: dcName,
|
|
||||||
name: t.name || '',
|
|
||||||
desc: t.desc || '',
|
|
||||||
vcpu: t.vcpu || 0,
|
|
||||||
ramGb: t.ramGb || 0,
|
|
||||||
diskGb: t.diskGb || 0,
|
|
||||||
diskType: t.diskType || 'NVMe',
|
|
||||||
virtualization: t.virtualization || 'KVM',
|
|
||||||
channel: t.channel || '',
|
|
||||||
location: t.location || '',
|
|
||||||
country: t.country || '',
|
|
||||||
cpuModel: t.cpuModel || '',
|
|
||||||
orderAvailable: t.orderAvailable ? 1 : 0,
|
|
||||||
price: t.price || '',
|
|
||||||
syncedAt,
|
|
||||||
})
|
|
||||||
.run()
|
.run()
|
||||||
tariffsCount++
|
|
||||||
}
|
for (const t of tariffItems) {
|
||||||
|
const dcKey = t.datacenterKey ?? ''
|
||||||
|
const dcName = t.datacenterName ?? ''
|
||||||
|
const tariffId = dcKey
|
||||||
|
? `tariff-ruvds-${accountId}-${t.externalId}-${dcKey}`
|
||||||
|
: `tariff-ruvds-${accountId}-${t.externalId}`
|
||||||
|
if (!existingTariffIds.has(tariffId)) {
|
||||||
|
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
||||||
|
}
|
||||||
|
db.insert(schema.activeTariffs)
|
||||||
|
.values({
|
||||||
|
spaceId: getCurrentSpaceId(),
|
||||||
|
id: tariffId,
|
||||||
|
providerAccountId: accountId,
|
||||||
|
providerId,
|
||||||
|
externalId: t.externalId,
|
||||||
|
datacenterKey: dcKey,
|
||||||
|
datacenterName: dcName,
|
||||||
|
name: t.name || '',
|
||||||
|
desc: t.desc || '',
|
||||||
|
vcpu: t.vcpu || 0,
|
||||||
|
ramGb: t.ramGb || 0,
|
||||||
|
diskGb: t.diskGb || 0,
|
||||||
|
diskType: t.diskType || 'NVMe',
|
||||||
|
virtualization: t.virtualization || 'KVM',
|
||||||
|
channel: t.channel || '',
|
||||||
|
location: t.location || '',
|
||||||
|
country: t.country || '',
|
||||||
|
cpuModel: t.cpuModel || '',
|
||||||
|
orderAvailable: t.orderAvailable ? 1 : 0,
|
||||||
|
price: t.price || '',
|
||||||
|
syncedAt,
|
||||||
|
})
|
||||||
|
.run()
|
||||||
|
tariffsCount++
|
||||||
|
}
|
||||||
|
})()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fetchVpsData) {
|
if (!fetchVpsData) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { getCurrentSpaceId, getDb, schema } from '@cfdm/db'
|
import { getCurrentSpaceId, getDb, getSqlite, schema } from '@cfdm/db'
|
||||||
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
||||||
|
|
||||||
import type { UserApiSyncAccount } from './context.js'
|
import type { UserApiSyncAccount } from './context.js'
|
||||||
@@ -274,56 +274,59 @@ export async function syncFromUserApi(
|
|||||||
|
|
||||||
let tariffsCount = 0
|
let tariffsCount = 0
|
||||||
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
||||||
if (fetchTariffs) {
|
// Fetch errors come back as [] — keep the old list instead of wiping it (and re-announcing all as new).
|
||||||
const existingTariffIds = new Set(
|
if (fetchTariffs && tariffItems.length > 0) {
|
||||||
db
|
getSqlite().transaction(() => {
|
||||||
.select({ id: schema.activeTariffs.id })
|
const existingTariffIds = new Set(
|
||||||
.from(schema.activeTariffs)
|
db
|
||||||
|
.select({ id: schema.activeTariffs.id })
|
||||||
|
.from(schema.activeTariffs)
|
||||||
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
|
.all()
|
||||||
|
.map((r) => r.id),
|
||||||
|
)
|
||||||
|
const syncedAt = new Date().toISOString()
|
||||||
|
db.delete(schema.activeTariffs)
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
.all()
|
|
||||||
.map((r) => r.id),
|
|
||||||
)
|
|
||||||
const syncedAt = new Date().toISOString()
|
|
||||||
db.delete(schema.activeTariffs)
|
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
|
||||||
.run()
|
|
||||||
|
|
||||||
for (const t of tariffItems) {
|
|
||||||
const dcKey = t.datacenterKey ?? ''
|
|
||||||
const dcName = t.datacenterName ?? ''
|
|
||||||
const tariffId = dcKey
|
|
||||||
? `tariff-${idPrefix}-${accountId}-${t.externalId}-${dcKey}`
|
|
||||||
: `tariff-${idPrefix}-${accountId}-${t.externalId}`
|
|
||||||
if (!existingTariffIds.has(tariffId)) {
|
|
||||||
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
|
||||||
}
|
|
||||||
db.insert(schema.activeTariffs)
|
|
||||||
.values({
|
|
||||||
spaceId: getCurrentSpaceId(),
|
|
||||||
id: tariffId,
|
|
||||||
providerAccountId: accountId,
|
|
||||||
providerId,
|
|
||||||
externalId: t.externalId,
|
|
||||||
datacenterKey: dcKey,
|
|
||||||
datacenterName: dcName,
|
|
||||||
name: t.name || '',
|
|
||||||
desc: t.desc || '',
|
|
||||||
vcpu: t.vcpu || 0,
|
|
||||||
ramGb: t.ramGb || 0,
|
|
||||||
diskGb: t.diskGb || 0,
|
|
||||||
diskType: t.diskType || 'NVMe',
|
|
||||||
virtualization: t.virtualization || 'KVM',
|
|
||||||
channel: t.channel || '',
|
|
||||||
location: t.location || '',
|
|
||||||
country: t.country || '',
|
|
||||||
cpuModel: t.cpuModel || '',
|
|
||||||
orderAvailable: t.orderAvailable ? 1 : 0,
|
|
||||||
price: t.price || '',
|
|
||||||
syncedAt,
|
|
||||||
})
|
|
||||||
.run()
|
.run()
|
||||||
tariffsCount++
|
|
||||||
}
|
for (const t of tariffItems) {
|
||||||
|
const dcKey = t.datacenterKey ?? ''
|
||||||
|
const dcName = t.datacenterName ?? ''
|
||||||
|
const tariffId = dcKey
|
||||||
|
? `tariff-${idPrefix}-${accountId}-${t.externalId}-${dcKey}`
|
||||||
|
: `tariff-${idPrefix}-${accountId}-${t.externalId}`
|
||||||
|
if (!existingTariffIds.has(tariffId)) {
|
||||||
|
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
||||||
|
}
|
||||||
|
db.insert(schema.activeTariffs)
|
||||||
|
.values({
|
||||||
|
spaceId: getCurrentSpaceId(),
|
||||||
|
id: tariffId,
|
||||||
|
providerAccountId: accountId,
|
||||||
|
providerId,
|
||||||
|
externalId: t.externalId,
|
||||||
|
datacenterKey: dcKey,
|
||||||
|
datacenterName: dcName,
|
||||||
|
name: t.name || '',
|
||||||
|
desc: t.desc || '',
|
||||||
|
vcpu: t.vcpu || 0,
|
||||||
|
ramGb: t.ramGb || 0,
|
||||||
|
diskGb: t.diskGb || 0,
|
||||||
|
diskType: t.diskType || 'NVMe',
|
||||||
|
virtualization: t.virtualization || 'KVM',
|
||||||
|
channel: t.channel || '',
|
||||||
|
location: t.location || '',
|
||||||
|
country: t.country || '',
|
||||||
|
cpuModel: t.cpuModel || '',
|
||||||
|
orderAvailable: t.orderAvailable ? 1 : 0,
|
||||||
|
price: t.price || '',
|
||||||
|
syncedAt,
|
||||||
|
})
|
||||||
|
.run()
|
||||||
|
tariffsCount++
|
||||||
|
}
|
||||||
|
})()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fetchVpsData) {
|
if (!fetchVpsData) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { getCurrentSpaceId, getDb, schema } from '@cfdm/db'
|
import { getCurrentSpaceId, getDb, getSqlite, schema } from '@cfdm/db'
|
||||||
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
import { findSyncedVps } from '../providers/find-synced-vps.js'
|
||||||
|
|
||||||
import type { VeespSyncAccount } from './context.js'
|
import type { VeespSyncAccount } from './context.js'
|
||||||
@@ -275,56 +275,59 @@ export async function syncFromVeesp(
|
|||||||
|
|
||||||
let tariffsCount = 0
|
let tariffsCount = 0
|
||||||
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
const newTariffs: { name: string; price: string; providerId: string }[] = []
|
||||||
if (fetchTariffs) {
|
// Fetch errors come back as [] — keep the old list instead of wiping it (and re-announcing all as new).
|
||||||
const existingTariffIds = new Set(
|
if (fetchTariffs && tariffItems.length > 0) {
|
||||||
db
|
getSqlite().transaction(() => {
|
||||||
.select({ id: schema.activeTariffs.id })
|
const existingTariffIds = new Set(
|
||||||
.from(schema.activeTariffs)
|
db
|
||||||
|
.select({ id: schema.activeTariffs.id })
|
||||||
|
.from(schema.activeTariffs)
|
||||||
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
|
.all()
|
||||||
|
.map((r) => r.id),
|
||||||
|
)
|
||||||
|
const syncedAt = new Date().toISOString()
|
||||||
|
db.delete(schema.activeTariffs)
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
||||||
.all()
|
|
||||||
.map((r) => r.id),
|
|
||||||
)
|
|
||||||
const syncedAt = new Date().toISOString()
|
|
||||||
db.delete(schema.activeTariffs)
|
|
||||||
.where(eq(schema.activeTariffs.providerAccountId, accountId))
|
|
||||||
.run()
|
|
||||||
|
|
||||||
for (const t of tariffItems) {
|
|
||||||
const dcKey = t.datacenterKey ?? ''
|
|
||||||
const dcName = t.datacenterName ?? ''
|
|
||||||
const tariffId = dcKey
|
|
||||||
? `tariff-veesp-${accountId}-${t.externalId}-${dcKey}`
|
|
||||||
: `tariff-veesp-${accountId}-${t.externalId}`
|
|
||||||
if (!existingTariffIds.has(tariffId)) {
|
|
||||||
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
|
||||||
}
|
|
||||||
db.insert(schema.activeTariffs)
|
|
||||||
.values({
|
|
||||||
spaceId: getCurrentSpaceId(),
|
|
||||||
id: tariffId,
|
|
||||||
providerAccountId: accountId,
|
|
||||||
providerId,
|
|
||||||
externalId: t.externalId,
|
|
||||||
datacenterKey: dcKey,
|
|
||||||
datacenterName: dcName,
|
|
||||||
name: t.name || '',
|
|
||||||
desc: t.desc || '',
|
|
||||||
vcpu: t.vcpu || 0,
|
|
||||||
ramGb: t.ramGb || 0,
|
|
||||||
diskGb: t.diskGb || 0,
|
|
||||||
diskType: t.diskType || 'NVMe',
|
|
||||||
virtualization: t.virtualization || 'KVM',
|
|
||||||
channel: t.channel || '',
|
|
||||||
location: t.location || '',
|
|
||||||
country: t.country || '',
|
|
||||||
cpuModel: t.cpuModel || '',
|
|
||||||
orderAvailable: t.orderAvailable ? 1 : 0,
|
|
||||||
price: t.price || '',
|
|
||||||
syncedAt,
|
|
||||||
})
|
|
||||||
.run()
|
.run()
|
||||||
tariffsCount++
|
|
||||||
}
|
for (const t of tariffItems) {
|
||||||
|
const dcKey = t.datacenterKey ?? ''
|
||||||
|
const dcName = t.datacenterName ?? ''
|
||||||
|
const tariffId = dcKey
|
||||||
|
? `tariff-veesp-${accountId}-${t.externalId}-${dcKey}`
|
||||||
|
: `tariff-veesp-${accountId}-${t.externalId}`
|
||||||
|
if (!existingTariffIds.has(tariffId)) {
|
||||||
|
newTariffs.push({ name: t.name || '', price: t.price || '', providerId })
|
||||||
|
}
|
||||||
|
db.insert(schema.activeTariffs)
|
||||||
|
.values({
|
||||||
|
spaceId: getCurrentSpaceId(),
|
||||||
|
id: tariffId,
|
||||||
|
providerAccountId: accountId,
|
||||||
|
providerId,
|
||||||
|
externalId: t.externalId,
|
||||||
|
datacenterKey: dcKey,
|
||||||
|
datacenterName: dcName,
|
||||||
|
name: t.name || '',
|
||||||
|
desc: t.desc || '',
|
||||||
|
vcpu: t.vcpu || 0,
|
||||||
|
ramGb: t.ramGb || 0,
|
||||||
|
diskGb: t.diskGb || 0,
|
||||||
|
diskType: t.diskType || 'NVMe',
|
||||||
|
virtualization: t.virtualization || 'KVM',
|
||||||
|
channel: t.channel || '',
|
||||||
|
location: t.location || '',
|
||||||
|
country: t.country || '',
|
||||||
|
cpuModel: t.cpuModel || '',
|
||||||
|
orderAvailable: t.orderAvailable ? 1 : 0,
|
||||||
|
price: t.price || '',
|
||||||
|
syncedAt,
|
||||||
|
})
|
||||||
|
.run()
|
||||||
|
tariffsCount++
|
||||||
|
}
|
||||||
|
})()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fetchVpsData) {
|
if (!fetchVpsData) {
|
||||||
|
|||||||
Reference in new issue
Block a user