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

@@ -410,6 +410,20 @@ final class MiningRepository
return $this->normalizeRows($stmt->fetchAll() ?: []);
}
public function listAllMeasurements(string $projectKey): array
{
$stmt = $this->pdo->prepare(
'SELECT * FROM ' . $this->table('measurements') . '
WHERE project_key = :project_key AND owner_sub = :owner_sub
ORDER BY measured_at ASC'
);
$stmt->execute([
'project_key' => $projectKey,
'owner_sub' => $this->ownerSub,
]);
return $this->normalizeRows($stmt->fetchAll() ?: []);
}
public function createMeasurement(string $projectKey, array $payload): array
{
$this->debug?->add('db.createMeasurement.start', [
@@ -979,6 +993,137 @@ final class MiningRepository
return $this->normalizeRows($stmt->fetchAll() ?: []);
}
public function listAllFxRates(): array
{
$stmt = $this->pdo->query(
'SELECT
r.id,
r.fetch_id,
f.base_currency,
r.currency_code AS target_currency,
r.current_value AS rate,
f.rate_date,
f.provider,
f.fetched_at
FROM ' . $this->table('fx_rates') . ' r
INNER JOIN ' . $this->table('fx_fetches') . ' f ON f.id = r.fetch_id
ORDER BY f.fetched_at ASC, f.id ASC, r.currency_code ASC'
);
return $this->normalizeRows($stmt->fetchAll() ?: []);
}
public function restoreFxFetch(string $baseCurrency, string $provider, string $rateDate, ?string $fetchedAt, array $rates): array
{
$baseCurrency = strtoupper(trim($baseCurrency));
$provider = trim($provider) !== '' ? trim($provider) : 'currencyapi';
$fetchedAt = trim((string) $fetchedAt) !== '' ? (string) $fetchedAt : $this->currentUtcTimestamp();
if ($rates === []) {
return ['fetch' => null, 'rates' => []];
}
$currenciesToEnsure = [
[
'code' => substr($baseCurrency, 0, 10),
'name' => $baseCurrency,
'symbol' => substr($baseCurrency, 0, 8),
'is_active' => 1,
'is_crypto' => $this->isCryptoCode($baseCurrency) ? 1 : 0,
'sort_order' => 1000,
],
];
foreach (array_keys($rates) as $currencyCode) {
$normalizedCurrencyCode = strtoupper(trim((string) $currencyCode));
if ($normalizedCurrencyCode === '') {
continue;
}
$currenciesToEnsure[] = [
'code' => substr($normalizedCurrencyCode, 0, 10),
'name' => $normalizedCurrencyCode,
'symbol' => substr($normalizedCurrencyCode, 0, 8),
'is_active' => 1,
'is_crypto' => $this->isCryptoCode($normalizedCurrencyCode) ? 1 : 0,
'sort_order' => 1000,
];
}
$this->saveCurrencies($currenciesToEnsure);
if ($this->driver === 'pgsql') {
$fetchStmt = $this->pdo->prepare(
'INSERT INTO ' . $this->table('fx_fetches') . ' (
provider, base_currency, rate_date, fetched_at
) VALUES (
:provider, :base_currency, :rate_date, :fetched_at
)
RETURNING *'
);
$fetchStmt->execute([
'provider' => $provider,
'base_currency' => $baseCurrency,
'rate_date' => $rateDate,
'fetched_at' => $fetchedAt,
]);
$fetch = $this->normalizeRow($fetchStmt->fetch() ?: []);
} else {
$fetchStmt = $this->pdo->prepare(
'INSERT INTO ' . $this->table('fx_fetches') . ' (
provider, base_currency, rate_date, fetched_at
) VALUES (
:provider, :base_currency, :rate_date, :fetched_at
)'
);
$fetchStmt->execute([
'provider' => $provider,
'base_currency' => $baseCurrency,
'rate_date' => $rateDate,
'fetched_at' => $fetchedAt,
]);
$fetchId = (int) $this->pdo->lastInsertId();
$fetchLookup = $this->pdo->prepare('SELECT * FROM ' . $this->table('fx_fetches') . ' WHERE id = :id LIMIT 1');
$fetchLookup->execute(['id' => $fetchId]);
$fetch = $this->normalizeRow($fetchLookup->fetch() ?: []);
}
$placeholders = [];
$params = ['fetch_id' => $fetch['id']];
$savedRates = [];
$index = 0;
foreach ($rates as $currencyCode => $rate) {
if (!is_numeric($rate)) {
continue;
}
$codeKey = 'currency_code_' . $index;
$valueKey = 'current_value_' . $index;
$targetCurrency = strtoupper(trim((string) $currencyCode));
if ($targetCurrency === '') {
continue;
}
$placeholders[] = "(:fetch_id, :{$codeKey}, :{$valueKey})";
$params[$codeKey] = $targetCurrency;
$params[$valueKey] = (float) $rate;
$savedRates[] = [
'fetch_id' => $fetch['id'],
'base_currency' => $baseCurrency,
'target_currency' => $targetCurrency,
'rate' => (float) $rate,
'rate_date' => $rateDate,
'provider' => $provider,
'fetched_at' => $fetch['fetched_at'] ?? $fetchedAt,
];
$index++;
}
if ($placeholders !== []) {
$insert = $this->pdo->prepare('INSERT INTO ' . $this->table('fx_rates') . ' (fetch_id, currency_code, current_value) VALUES ' . implode(', ', $placeholders));
$insert->execute($params);
}
return [
'fetch' => $fetch,
'rates' => $savedRates,
];
}
public function getLatestMeasurementRate(string $baseCurrency, string $targetCurrency): ?array
{
$stmt = $this->pdo->prepare(