validate([ 'file' => ['nullable', 'file', 'max:51200', 'mimetypes:image/jpeg,image/png,image/webp,image/gif,video/mp4,video/quicktime,video/webm'], 'asset' => ['nullable', 'file', 'max:51200', 'mimetypes:image/jpeg,image/png,image/webp,image/gif,video/mp4,video/quicktime,video/webm'], 'label' => ['nullable', 'string', 'max:250'], ]); $file = $request->file('file') ?? $request->file('asset'); if ($file === null) { return response()->json([ 'message' => 'Field file atau asset wajib diisi.', ], 422); } $owner = $this->resolveOwner(); try { $mime = (string) $file->getMimeType(); $type = Str::startsWith($mime, 'video/') ? 'video' : 'image'; $ext = strtolower((string) $file->getClientOriginalExtension()); if ($ext === '') { $ext = $type === 'video' ? 'mp4' : 'jpg'; } $folder = $type === 'video' ? 'social_assets/videos' : 'social_assets/images'; $filename = now()->format('Ymd_His').'_'.$owner->id.'_'.Str::lower(Str::random(8)).'.'.$ext; $storedPath = $file->storeAs($folder, $filename, 'public'); $publicUrl = $hfMedia->offloadPublicRelativePath($storedPath); $asset = SocialMediaAsset::query()->create([ 'user_id' => $owner->id, 'type' => $type, 'provider' => 'upload_api', 'prompt' => trim((string) ($data['label'] ?? '')), 'url' => $publicUrl, 'thumbnail_url' => $type === 'image' ? $publicUrl : null, 'meta' => [ 'source' => 'api_upload', 'mime' => $mime, 'original_name' => $file->getClientOriginalName(), 'size_bytes' => $file->getSize(), 'stored_path' => $storedPath, ], ]); return response()->json([ 'message' => ucfirst($type).' uploaded successfully.', 'asset' => [ 'id' => $asset->id, 'type' => $asset->type, 'url' => $asset->url, 'thumbnail_url' => $asset->thumbnail_url, 'label' => $asset->prompt, 'owner_email' => $owner->email, ], ], 201); } catch (\Throwable $e) { return response()->json([ 'message' => $e->getMessage(), ], 500); } } private function resolveOwner(): User { $ownerEmail = trim((string) config('services.huggingface.media_owner_email', '')); $owner = null; if ($ownerEmail !== '') { $owner = User::query()->where('email', $ownerEmail)->first(); } $owner ??= User::query()->orderBy('id')->first(); if (! $owner) { throw new RuntimeException('Belum ada user owner untuk media upload. Jalankan seeder atau set HF_MEDIA_OWNER_EMAIL dengan user yang valid.'); } return $owner; } }