Server : LiteSpeed System : Linux server335.web-hosting.com 4.18.0-553.62.1.lve.el8.x86_64 #1 SMP Mon Jul 21 17:50:35 UTC 2025 x86_64 User : cardxfeb ( 2452) PHP Version : 8.1.34 Disable Function : NONE Directory : /home/cardxfeb/public_html/app/Services/ |
<?php
namespace App\Services;
use App\Models\Vcard;
use App\Models\User;
use Illuminate\Support\Facades\Log;
class AiCardGeneratorService
{
public function __construct(
protected SocialScraperService $scraper,
protected LlmAnalyzerService $llm
) {}
/**
* Full AI generation pipeline with MULTI-SOURCE support.
* $sources can be a single URL string or an array of URLs.
*/
public function generate(User $user, string|array $sources, Vcard $vcard): array
{
// Normalize to array
if (is_string($sources)) {
$sources = [$sources];
}
$sources = array_filter($sources, fn($s) => !empty(trim($s)));
try {
// Step 1: Fetch from ALL sources in parallel (sequential for shared hosting)
Log::info("[AiCardGen] Fetching " . count($sources) . " sources for user#{$user->id}");
$multiSourceData = $this->scraper->fetchMultiple($sources);
$socialCount = count($multiSourceData['social'] ?? []);
$corporateCount = count($multiSourceData['corporate'] ?? []);
Log::info("[AiCardGen] Fetched: {$socialCount} social, {$corporateCount} corporate sources");
// Step 2: LLM multi-source analysis
$region = config('app.region', 'BR');
$aiResult = $this->llm->analyzeMultiple($multiSourceData, $region);
Log::info("[AiCardGen] LLM result: template_id={$aiResult['template_id']}, confidence={$aiResult['confidence']}");
// Step 3: Apply to VCard
$updateData = [
'ai_status' => 'completed',
'ai_data' => json_encode($aiResult, JSON_UNESCAPED_UNICODE),
'template_id' => $aiResult['template_id'],
];
// Only fill fields if VCard doesn't already have them
if (empty($vcard->name) && !empty($aiResult['name'])) {
$updateData['name'] = $aiResult['name'];
}
if (empty($vcard->description) && !empty($aiResult['bio'])) {
$updateData['description'] = $aiResult['bio'];
}
if (empty($vcard->occupation) && !empty($aiResult['profession'])) {
$updateData['occupation'] = $aiResult['profession'];
}
if (empty($vcard->company) && !empty($aiResult['company'])) {
$updateData['company'] = $aiResult['company'];
}
$vcard->update($updateData);
return [
'success' => true,
'vcard_id' => $vcard->id,
'template_id' => $aiResult['template_id'],
'completion_pct' => 90,
'sources_used' => count($sources),
'confidence' => $aiResult['confidence'] ?? 'medium',
'ai_result' => $aiResult,
];
} catch (\Exception $e) {
Log::error("[AiCardGen] Failed for user#{$user->id}: " . $e->getMessage());
$vcard->update(['ai_status' => 'failed']);
return ['success' => false, 'vcard_id' => $vcard->id, 'error' => $e->getMessage()];
}
}
}