feat(ai-edits): add output storage backfill flow and coverage
This commit is contained in:
@@ -20,6 +20,8 @@ use App\Support\ApiError;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
@@ -492,6 +494,11 @@ class EventPublicAiEditController extends BaseController
|
||||
'storage_disk' => $output->storage_disk,
|
||||
'storage_path' => $output->storage_path,
|
||||
'provider_url' => $output->provider_url,
|
||||
'url' => $this->resolveOutputUrl(
|
||||
$output->storage_disk,
|
||||
$output->storage_path,
|
||||
$output->provider_url
|
||||
),
|
||||
'mime_type' => $output->mime_type,
|
||||
'width' => $output->width,
|
||||
'height' => $output->height,
|
||||
@@ -502,4 +509,41 @@ class EventPublicAiEditController extends BaseController
|
||||
])->values(),
|
||||
];
|
||||
}
|
||||
|
||||
private function resolveOutputUrl(?string $storageDisk, ?string $storagePath, ?string $providerUrl): ?string
|
||||
{
|
||||
$resolvedStoragePath = $this->normalizeOptionalString($storagePath);
|
||||
if ($resolvedStoragePath !== null) {
|
||||
if (Str::startsWith($resolvedStoragePath, ['http://', 'https://'])) {
|
||||
return $resolvedStoragePath;
|
||||
}
|
||||
|
||||
$disk = $this->resolveStorageDisk($storageDisk);
|
||||
|
||||
try {
|
||||
return Storage::disk($disk)->url($resolvedStoragePath);
|
||||
} catch (\Throwable $exception) {
|
||||
Log::debug('Falling back to raw AI output storage path', [
|
||||
'disk' => $disk,
|
||||
'path' => $resolvedStoragePath,
|
||||
'error' => $exception->getMessage(),
|
||||
]);
|
||||
|
||||
return '/'.ltrim($resolvedStoragePath, '/');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->normalizeOptionalString($providerUrl);
|
||||
}
|
||||
|
||||
private function resolveStorageDisk(?string $disk): string
|
||||
{
|
||||
$candidate = trim((string) ($disk ?: config('filesystems.default', 'public')));
|
||||
|
||||
if ($candidate === '' || ! config("filesystems.disks.{$candidate}")) {
|
||||
return (string) config('filesystems.default', 'public');
|
||||
}
|
||||
|
||||
return $candidate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ use App\Support\TenantMemberPermissions;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
@@ -561,6 +563,11 @@ class AiEditController extends Controller
|
||||
'storage_disk' => $output->storage_disk,
|
||||
'storage_path' => $output->storage_path,
|
||||
'provider_url' => $output->provider_url,
|
||||
'url' => $this->resolveOutputUrl(
|
||||
$output->storage_disk,
|
||||
$output->storage_path,
|
||||
$output->provider_url
|
||||
),
|
||||
'mime_type' => $output->mime_type,
|
||||
'width' => $output->width,
|
||||
'height' => $output->height,
|
||||
@@ -571,4 +578,41 @@ class AiEditController extends Controller
|
||||
])->values(),
|
||||
];
|
||||
}
|
||||
|
||||
private function resolveOutputUrl(?string $storageDisk, ?string $storagePath, ?string $providerUrl): ?string
|
||||
{
|
||||
$resolvedStoragePath = $this->normalizeOptionalString($storagePath);
|
||||
if ($resolvedStoragePath !== null) {
|
||||
if (Str::startsWith($resolvedStoragePath, ['http://', 'https://'])) {
|
||||
return $resolvedStoragePath;
|
||||
}
|
||||
|
||||
$disk = $this->resolveStorageDisk($storageDisk);
|
||||
|
||||
try {
|
||||
return Storage::disk($disk)->url($resolvedStoragePath);
|
||||
} catch (\Throwable $exception) {
|
||||
Log::debug('Falling back to raw AI output storage path', [
|
||||
'disk' => $disk,
|
||||
'path' => $resolvedStoragePath,
|
||||
'error' => $exception->getMessage(),
|
||||
]);
|
||||
|
||||
return '/'.ltrim($resolvedStoragePath, '/');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->normalizeOptionalString($providerUrl);
|
||||
}
|
||||
|
||||
private function resolveStorageDisk(?string $disk): string
|
||||
{
|
||||
$candidate = trim((string) ($disk ?: config('filesystems.default', 'public')));
|
||||
|
||||
if ($candidate === '' || ! config("filesystems.disks.{$candidate}")) {
|
||||
return (string) config('filesystems.default', 'public');
|
||||
}
|
||||
|
||||
return $candidate;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user