95 lines
3.0 KiB
PHP
95 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Temporal\ExternalApiSync;
|
|
|
|
use App\Models\Product;
|
|
use App\Temporal\Shared\FaultSimulator;
|
|
use Illuminate\Support\Str;
|
|
use Temporal\Activity;
|
|
|
|
class ExternalApiSyncActivity implements ExternalApiSyncActivityInterface
|
|
{
|
|
private const PAGE_SIZE = 10;
|
|
private const TOTAL_SIMULATED_RECORDS = 50;
|
|
|
|
public function refreshToken(array $simulationConfig = []): string
|
|
{
|
|
FaultSimulator::maybeApply($simulationConfig, 'refreshToken');
|
|
|
|
// Simulate OAuth token refresh
|
|
usleep(200000);
|
|
|
|
return 'tok_' . Str::random(32);
|
|
}
|
|
|
|
public function fetchPage(string $cursor, string $token, array $simulationConfig = []): array
|
|
{
|
|
FaultSimulator::maybeApply($simulationConfig, 'fetchPage');
|
|
|
|
Activity::heartbeat(['cursor' => $cursor, 'token_prefix' => substr($token, 0, 8)]);
|
|
|
|
// Simulate API latency
|
|
usleep(150000);
|
|
|
|
$offset = (int) $cursor;
|
|
$records = [];
|
|
|
|
for ($i = $offset; $i < min($offset + self::PAGE_SIZE, self::TOTAL_SIMULATED_RECORDS); $i++) {
|
|
$records[] = [
|
|
'external_id' => 'EXT-' . str_pad((string) ($i + 1), 5, '0', STR_PAD_LEFT),
|
|
'name' => 'Synced Product ' . ($i + 1),
|
|
'description' => 'Product synced from external API',
|
|
'price' => round(mt_rand(500, 50000) / 100, 2),
|
|
'stock' => mt_rand(10, 500),
|
|
'category' => ['Electronics', 'Clothing', 'Home & Garden', 'Sports'][array_rand(['Electronics', 'Clothing', 'Home & Garden', 'Sports'])],
|
|
];
|
|
}
|
|
|
|
$nextOffset = $offset + self::PAGE_SIZE;
|
|
$hasMore = $nextOffset < self::TOTAL_SIMULATED_RECORDS;
|
|
|
|
return [
|
|
'records' => $records,
|
|
'nextCursor' => (string) $nextOffset,
|
|
'hasMore' => $hasMore,
|
|
'attempt' => Activity::getInfo()->attempt,
|
|
];
|
|
}
|
|
|
|
public function transformAndStore(array $records, array $simulationConfig = []): array
|
|
{
|
|
FaultSimulator::maybeApply($simulationConfig, 'transformAndStore');
|
|
|
|
$stored = 0;
|
|
$skipped = 0;
|
|
|
|
foreach ($records as $record) {
|
|
$sku = 'SYNC-' . $record['external_id'];
|
|
|
|
try {
|
|
Product::updateOrCreate(
|
|
['sku' => $sku],
|
|
[
|
|
'name' => $record['name'],
|
|
'description' => $record['description'],
|
|
'price' => $record['price'],
|
|
'stock_quantity' => $record['stock'],
|
|
'category' => $record['category'],
|
|
'status' => 'active',
|
|
'imported_at' => now(),
|
|
]
|
|
);
|
|
$stored++;
|
|
} catch (\Throwable) {
|
|
$skipped++;
|
|
}
|
|
}
|
|
|
|
return [
|
|
'stored' => $stored,
|
|
'skipped' => $skipped,
|
|
'attempt' => Activity::getInfo()->attempt,
|
|
];
|
|
}
|
|
}
|