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

This commit is contained in:
2026-08-21 01:14:32 +02:00
parent 95100d3a78
commit fb852e33e5
4 changed files with 92 additions and 14 deletions

View File

@@ -356,11 +356,14 @@ final class AnalyticsService
$price = $latestPriceByCurrency[$currency] ?? $this->convertLatestPrice($latestPriceByCurrency, $currency, $latest);
$requiredDoge = ($price && $targetAmount !== null) ? $targetAmount / $price : null;
$remainingDogeAtUpload = $requiredDoge !== null ? $requiredDoge - (float) ($latest['coins_total_effective'] ?? $latest['coins_total']) : null;
$targetDailyRate = is_numeric($latest['doge_per_day_since_last_payout'] ?? null)
? (float) $latest['doge_per_day_since_last_payout']
: null;
$remainingDaysAtUpload = (
$remainingDogeAtUpload !== null &&
$latest['doge_per_day_interval'] !== null &&
(float) $latest['doge_per_day_interval'] > 0
) ? $remainingDogeAtUpload / (float) $latest['doge_per_day_interval'] : null;
$targetDailyRate !== null &&
$targetDailyRate > 0
) ? $remainingDogeAtUpload / $targetDailyRate : null;
$targetEtaAt = null;
if ($remainingDaysAtUpload !== null) {
if ($remainingDaysAtUpload <= 0) {
@@ -378,8 +381,8 @@ final class AnalyticsService
$remainingDays = $targetEtaAt !== null
? max(0.0, ($this->utcTimestamp($targetEtaAt) - time()) / 86400)
: null;
$remainingDoge = ($remainingDays !== null && $latest['doge_per_day_interval'] !== null)
? max(0.0, $remainingDays * (float) $latest['doge_per_day_interval'])
$remainingDoge = ($remainingDays !== null && $targetDailyRate !== null)
? max(0.0, $remainingDays * $targetDailyRate)
: $remainingDogeAtUpload;
$targetSummary[] = array_merge($target, [
@@ -392,6 +395,7 @@ final class AnalyticsService
'remaining_doge' => $this->roundOrNull($remainingDoge, 6),
'remaining_doge_at_upload' => $this->roundOrNull($remainingDogeAtUpload, 6),
'remaining_days_at_upload' => $this->roundOrNull($remainingDaysAtUpload, 4),
'target_daily_rate' => $this->roundOrNull($targetDailyRate, 6),
'remaining_days' => $this->roundOrNull($remainingDays, 4),
'target_eta_at' => $targetEtaAt,
'status' => $remainingDays !== null && $remainingDays <= 0 ? 'reached' : 'open',
@@ -1683,15 +1687,60 @@ final class AnalyticsService
$amount = is_numeric($miner['settled_value_amount'] ?? null) ? (float) $miner['settled_value_amount'] : null;
$currency = strtoupper(trim((string) ($miner['settled_value_currency'] ?? '')));
$spentAmount = is_numeric($miner['total_cost_amount'] ?? null) ? (float) $miner['total_cost_amount'] : null;
$spentCurrency = strtoupper(trim((string) ($miner['currency'] ?? '')));
// Old entries predate the settlement columns. The spent crypto amount itself
// remains the authoritative fixed amount when it matches the requested asset.
if ($spentAmount !== null && $spentCurrency !== '' && $spentCurrency === strtoupper(trim($targetCurrency))) {
$matched = true;
$total += $spentAmount;
continue;
}
if ($amount === null) {
$referenceAmount = is_numeric($miner['reference_price_amount'] ?? null)
? (float) $miner['reference_price_amount']
: null;
$referenceCurrency = strtoupper(trim((string) ($miner['reference_price_currency'] ?? '')));
if ($referenceAmount !== null && $referenceCurrency !== '' && $referenceCurrency !== $spentCurrency) {
$amount = $referenceAmount;
$currency = $referenceCurrency;
} elseif ($spentAmount !== null) {
$amount = $spentAmount * 0.07;
$currency = 'USD';
}
}
// The agreed legacy fallback is deliberately explicit: no current FX rate
// may alter a historic fallback value in USD or EUR.
$target = strtoupper(trim($targetCurrency));
$hasHistoricalSnapshot = is_numeric($miner['settled_fx_fetch_id'] ?? null) && (int) $miner['settled_fx_fetch_id'] > 0;
if (!$hasHistoricalSnapshot && $spentAmount !== null && $amount !== null && $currency === 'USD' && abs($amount - ($spentAmount * 0.07)) < 0.00000001 && $target === 'EUR') {
$matched = true;
$total += $spentAmount * 0.068;
continue;
}
if ($amount === null || $currency === '') {
continue;
}
if ($currency === strtoupper(trim($targetCurrency))) {
$matched = true;
$total += $amount;
continue;
}
$historicalFxContext = [
'fx_fetch_id' => $miner['settled_fx_fetch_id'] ?? null,
'measured_at' => $miner['purchased_at'] ?? null,
];
$converted = $this->convertAmount($amount, $currency, $targetCurrency, $historicalFxContext);
// Legacy records without a linked snapshot still remain visible. New records
// never use this fallback because their snapshot reference is mandatory.
if ($converted === null && !$hasHistoricalSnapshot) {
$converted = $this->convertAmount($amount, $currency, $targetCurrency, $fxContext);
}
if ($converted === null) {
continue;
}