From d1ce73e7ff037d4932c9b04e9d608bb1f851f47d Mon Sep 17 00:00:00 2001 From: Nyan Lin Paing <117423022+LinPaing21@users.noreply.github.com> Date: Thu, 3 Sep 2026 00:30:50 +0700 Subject: [PATCH] Fix EV company logo upload to use public disk Logos were being written to the default filesystem disk, which resolves to storage/app/private and isn't web-servable, so the frontend couldn't load the image. Store logos on the public disk (storage/app/public, symlinked to public/storage) instead, and resolve logoUrl() against that disk explicitly. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_015HaT8a5ZWh45JkjTLPWeaP --- .../Resources/EvCompanies/Schemas/EvCompanyForm.php | 4 +++- app-modules/catalog/src/Models/EvCompany.php | 9 +++++---- app-modules/catalog/tests/Feature/CatalogReadApiTest.php | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app-modules/catalog/src/Filament/Resources/EvCompanies/Schemas/EvCompanyForm.php b/app-modules/catalog/src/Filament/Resources/EvCompanies/Schemas/EvCompanyForm.php index 3527407..2451807 100644 --- a/app-modules/catalog/src/Filament/Resources/EvCompanies/Schemas/EvCompanyForm.php +++ b/app-modules/catalog/src/Filament/Resources/EvCompanies/Schemas/EvCompanyForm.php @@ -32,7 +32,9 @@ class EvCompanyForm ->required() ->maxLength(255), FileUpload::make('logo') - ->image(), + ->image() + ->disk('public') + ->directory('logos'), Toggle::make('is_active') ->required() ->default(true), diff --git a/app-modules/catalog/src/Models/EvCompany.php b/app-modules/catalog/src/Models/EvCompany.php index c595c29..fa74fe1 100644 --- a/app-modules/catalog/src/Models/EvCompany.php +++ b/app-modules/catalog/src/Models/EvCompany.php @@ -78,9 +78,10 @@ class EvCompany extends Model /** * `logo` is stored as the disk-relative path Filament's FileUpload * writes (e.g. "logos/xxx.png"), not a URL — API consumers need a full - * absolute URL to render it directly. Guards against the disk itself - * already returning an absolute URL (e.g. an s3 disk), so this stays - * correct if the storage disk ever changes from local. + * absolute URL to render it directly. Logos are always written to the + * "public" disk (storage/app/public, symlinked to public/storage) so + * the frontend can actually reach the image, regardless of what the + * app's default filesystem disk is configured to. */ public function logoUrl(): Attribute { @@ -90,7 +91,7 @@ class EvCompany extends Model return null; } - $url = Storage::disk(config('filesystems.default'))->url($this->logo); + $url = Storage::disk('public')->url($this->logo); return str($url)->startsWith(['http://', 'https://']) ? $url : url($url); }, diff --git a/app-modules/catalog/tests/Feature/CatalogReadApiTest.php b/app-modules/catalog/tests/Feature/CatalogReadApiTest.php index 3b3e837..e39bdb5 100644 --- a/app-modules/catalog/tests/Feature/CatalogReadApiTest.php +++ b/app-modules/catalog/tests/Feature/CatalogReadApiTest.php @@ -26,7 +26,7 @@ test('returns the company logo as a full absolute url', function () { $this->withHeader('Authorization', "Bearer {$this->token}") ->getJson('/api/v1/companies') ->assertSuccessful() - ->assertJsonFragment(['logo' => url(Storage::disk(config('filesystems.default'))->url($company->logo))]); + ->assertJsonFragment(['logo' => url(Storage::disk('public')->url($company->logo))]); }); test('returns a null logo when the company has none', function () {