Importer
All checks were successful
Deploy / deploy-staging (push) Successful in 6s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-04-11 03:02:39 +02:00
parent 394935a53b
commit 7400caa687
3 changed files with 282 additions and 21 deletions

View File

@@ -388,13 +388,16 @@ final class Router
'project' => $this->repository()->getProject($projectKey),
'settings' => $this->safeRead(fn () => $this->repository()->getSettings($projectKey)),
'currencies' => $this->safeRead(fn () => $this->repository()->listCurrencies(), []),
'currency_aliases' => $this->safeRead(fn () => $this->repository()->listCurrencyAliases(), []),
'cost_plans' => $this->safeRead(fn () => $this->repository()->listCostPlans($projectKey), []),
'measurements' => $this->safeRead(fn () => $this->repository()->listMeasurements($projectKey, 5000), []),
'measurements' => $this->safeRead(fn () => $this->repository()->listAllMeasurements($projectKey), []),
'measurement_rates' => $this->safeRead(fn () => $this->repository()->listMeasurementRates($projectKey), []),
'payouts' => $this->safeRead(fn () => $this->repository()->listPayouts($projectKey), []),
'targets' => $this->safeRead(fn () => $this->repository()->listTargets($projectKey), []),
'dashboards' => $this->safeRead(fn () => $this->repository()->listDashboards($projectKey), []),
'miner_offers' => $this->safeRead(fn () => $this->repository()->listMinerOffers($projectKey), []),
'purchased_miners' => $this->safeRead(fn () => $this->repository()->listPurchasedMiners($projectKey), []),
'fx_rates' => $this->safeRead(fn () => $this->repository()->listAllFxRates(), []),
];
$result = $this->schemaManager()->rebuildSchemaDirect();
@@ -415,10 +418,17 @@ final class Router
'name' => $currency['name'],
'symbol' => $currency['symbol'] ?? null,
'is_active' => !empty($currency['is_active']) ? 1 : 0,
'is_crypto' => !empty($currency['is_crypto']) ? 1 : 0,
'sort_order' => (int) ($currency['sort_order'] ?? 0),
]);
}
foreach ($backup['currency_aliases'] as $alias) {
if (!empty($alias['alias_code']) && !empty($alias['currency_code'])) {
$this->repository()->saveCurrencyAlias((string) $alias['alias_code'], (string) $alias['currency_code']);
}
}
if (is_array($backup['settings'])) {
$this->repository()->saveSettings($projectKey, [
'baseline_measured_at' => $backup['settings']['baseline_measured_at'],
@@ -429,6 +439,8 @@ final class Router
'crypto_currency' => $backup['settings']['crypto_currency'] ?? 'DOGE',
'display_timezone' => $backup['settings']['display_timezone'] ?? 'Europe/Berlin',
'fx_max_age_hours' => $backup['settings']['fx_max_age_hours'] ?? 3,
'module_theme_mode' => $backup['settings']['module_theme_mode'] ?? 'inherit',
'module_theme_accent' => $backup['settings']['module_theme_accent'] ?? 'teal',
'preferred_currencies' => $backup['settings']['preferred_currencies'] ?? ['DOGE', 'USD', 'EUR'],
]);
}
@@ -450,6 +462,21 @@ final class Router
]);
}
$measurementRatesByOldId = [];
foreach ($backup['measurement_rates'] as $rate) {
$oldMeasurementId = (int) ($rate['measurement_id'] ?? 0);
if ($oldMeasurementId > 0) {
$measurementRatesByOldId[$oldMeasurementId][] = [
'base_currency' => $rate['base_currency'] ?? null,
'quote_currency' => $rate['quote_currency'] ?? null,
'rate' => $rate['rate'] ?? null,
'provider' => $rate['provider'] ?? 'derived',
];
}
}
$measurementIdMap = [];
$restoredMeasurementRates = 0;
foreach ($backup['measurements'] as $measurement) {
$created = $this->repository()->createMeasurementIfNotExists($projectKey, [
'measured_at' => $measurement['measured_at'],
@@ -464,7 +491,17 @@ final class Router
'ocr_flags' => $measurement['ocr_flags'] ?? null,
]);
if (is_array($created)) {
$this->captureMeasurementRates($projectKey, $created);
$oldMeasurementId = (int) ($measurement['id'] ?? 0);
$newMeasurementId = (int) ($created['id'] ?? 0);
if ($oldMeasurementId > 0 && $newMeasurementId > 0) {
$measurementIdMap[$oldMeasurementId] = $newMeasurementId;
}
if ($oldMeasurementId > 0 && isset($measurementRatesByOldId[$oldMeasurementId])) {
$this->repository()->replaceMeasurementRates($newMeasurementId, $projectKey, $measurementRatesByOldId[$oldMeasurementId]);
$restoredMeasurementRates += count($measurementRatesByOldId[$oldMeasurementId]);
} else {
$this->captureMeasurementRates($projectKey, $created);
}
}
}
@@ -477,12 +514,36 @@ final class Router
]);
}
$minerOfferIdMap = [];
foreach ($backup['miner_offers'] as $offer) {
$savedOffer = $this->repository()->saveMinerOffer($projectKey, [
'label' => $offer['label'],
'runtime_months' => $offer['runtime_months'] ?? null,
'mining_speed_value' => $offer['mining_speed_value'] ?? null,
'mining_speed_unit' => $offer['mining_speed_unit'] ?? null,
'bonus_speed_value' => $offer['bonus_speed_value'] ?? null,
'bonus_speed_unit' => $offer['bonus_speed_unit'] ?? null,
'base_price_amount' => $offer['base_price_amount'] ?? $offer['reference_price_amount'] ?? $offer['usd_reference_amount'] ?? $offer['price_amount'],
'base_price_currency' => $offer['base_price_currency'] ?? $offer['reference_price_currency'] ?? (is_numeric($offer['usd_reference_amount'] ?? null) ? 'USD' : ($offer['price_currency'] ?? null)),
'payment_type' => $offer['payment_type'] ?? (!empty($offer['price_currency']) && in_array(strtoupper((string) $offer['price_currency']), ['ADA','ARB','BNB','BTC','DAI','DOGE','DOT','ETH','LINK','LTC','SOL','USDC','USDT','XRP'], true) ? 'crypto' : 'fiat'),
'auto_renew' => !empty($offer['auto_renew']) ? 1 : 0,
'note' => $offer['note'] ?? null,
'is_active' => !empty($offer['is_active']) ? 1 : 0,
]);
$oldOfferId = (int) ($offer['id'] ?? 0);
$newOfferId = (int) ($savedOffer['id'] ?? 0);
if ($oldOfferId > 0 && $newOfferId > 0) {
$minerOfferIdMap[$oldOfferId] = $newOfferId;
}
}
foreach ($backup['targets'] as $target) {
$oldOfferId = (int) ($target['miner_offer_id'] ?? 0);
$this->repository()->saveTarget($projectKey, [
'label' => $target['label'],
'target_amount_fiat' => $target['target_amount_fiat'],
'currency' => $target['currency'],
'miner_offer_id' => $target['miner_offer_id'] ?? null,
'miner_offer_id' => $oldOfferId > 0 ? ($minerOfferIdMap[$oldOfferId] ?? null) : null,
'is_active' => !empty($target['is_active']) ? 1 : 0,
'sort_order' => (int) ($target['sort_order'] ?? 0),
]);
@@ -500,26 +561,10 @@ final class Router
]);
}
foreach ($backup['miner_offers'] as $offer) {
$this->repository()->saveMinerOffer($projectKey, [
'label' => $offer['label'],
'runtime_months' => $offer['runtime_months'] ?? null,
'mining_speed_value' => $offer['mining_speed_value'] ?? null,
'mining_speed_unit' => $offer['mining_speed_unit'] ?? null,
'bonus_speed_value' => $offer['bonus_speed_value'] ?? null,
'bonus_speed_unit' => $offer['bonus_speed_unit'] ?? null,
'base_price_amount' => $offer['base_price_amount'] ?? $offer['reference_price_amount'] ?? $offer['usd_reference_amount'] ?? $offer['price_amount'],
'base_price_currency' => $offer['base_price_currency'] ?? $offer['reference_price_currency'] ?? (is_numeric($offer['usd_reference_amount'] ?? null) ? 'USD' : ($offer['price_currency'] ?? null)),
'payment_type' => $offer['payment_type'] ?? (!empty($offer['price_currency']) && in_array(strtoupper((string) $offer['price_currency']), ['ADA','ARB','BNB','BTC','DAI','DOGE','DOT','ETH','LINK','LTC','SOL','USDC','USDT','XRP'], true) ? 'crypto' : 'fiat'),
'auto_renew' => !empty($offer['auto_renew']) ? 1 : 0,
'note' => $offer['note'] ?? null,
'is_active' => !empty($offer['is_active']) ? 1 : 0,
]);
}
foreach ($backup['purchased_miners'] as $miner) {
$oldOfferId = (int) ($miner['miner_offer_id'] ?? 0);
$this->repository()->restorePurchasedMiner($projectKey, [
'miner_offer_id' => null,
'miner_offer_id' => $oldOfferId > 0 ? ($minerOfferIdMap[$oldOfferId] ?? null) : null,
'purchased_at' => $miner['purchased_at'],
'label' => $miner['label'],
'runtime_months' => $miner['runtime_months'] ?? null,
@@ -538,15 +583,49 @@ final class Router
]);
}
$fxRatesByFetch = [];
foreach ($backup['fx_rates'] as $rate) {
$fetchId = (int) ($rate['fetch_id'] ?? 0);
$targetCurrency = strtoupper(trim((string) ($rate['target_currency'] ?? '')));
if ($fetchId <= 0 || $targetCurrency === '' || !is_numeric($rate['rate'] ?? null)) {
continue;
}
if (!isset($fxRatesByFetch[$fetchId])) {
$fxRatesByFetch[$fetchId] = [
'base_currency' => $rate['base_currency'] ?? '',
'provider' => $rate['provider'] ?? 'currencyapi',
'rate_date' => $rate['rate_date'] ?? date('Y-m-d'),
'fetched_at' => $rate['fetched_at'] ?? null,
'rates' => [],
];
}
$fxRatesByFetch[$fetchId]['rates'][$targetCurrency] = (float) $rate['rate'];
}
$restoredFxRates = 0;
foreach ($fxRatesByFetch as $fetch) {
$restored = $this->repository()->restoreFxFetch(
(string) $fetch['base_currency'],
(string) $fetch['provider'],
(string) $fetch['rate_date'],
is_string($fetch['fetched_at'] ?? null) ? $fetch['fetched_at'] : null,
$fetch['rates']
);
$restoredFxRates += count($restored['rates'] ?? []);
}
return array_merge($result, [
'restored' => [
'measurements' => count($backup['measurements']),
'measurement_rates' => $restoredMeasurementRates,
'purchased_miners' => count($backup['purchased_miners']),
'cost_plans' => count($backup['cost_plans']),
'payouts' => count($backup['payouts']),
'targets' => count($backup['targets']),
'dashboards' => count($backup['dashboards']),
'miner_offers' => count($backup['miner_offers']),
'currency_aliases' => count($backup['currency_aliases']),
'fx_rates' => $restoredFxRates,
],
]);
}