service = $service; } /** * GET /api/v1/browse * Public browse feed powered by authoritative artworks table. */ public function index(Request $request) { $perPage = min(max((int) $request->get('per_page', 24), 1), 100); $sort = (string) $request->get('sort', 'latest'); $paginator = $this->service->browsePublicArtworks($perPage, $sort); return ArtworkListResource::collection($paginator); } /** * GET /api/v1/browse/{content_type} * Browse by content type slug. */ public function byContentType(Request $request, string $contentTypeSlug) { $perPage = min(max((int) $request->get('per_page', 24), 1), 100); $sort = (string) $request->get('sort', 'latest'); try { $paginator = $this->service->getArtworksByContentType($contentTypeSlug, $perPage, $sort); } catch (ModelNotFoundException $e) { abort(404); } if ($paginator->count() === 0) { return response()->json(['message' => 'Gone'], 410); } return ArtworkListResource::collection($paginator); } /** * GET /api/v1/browse/{content_type}/{category_path} * Browse by content type + category path (slug segments). */ public function byCategoryPath(Request $request, string $contentTypeSlug, string $categoryPath) { $perPage = min(max((int) $request->get('per_page', 24), 1), 100); $sort = (string) $request->get('sort', 'latest'); $slugs = array_merge([ strtolower($contentTypeSlug), ], array_values(array_filter(explode('/', trim($categoryPath, '/'))))); try { $paginator = $this->service->getArtworksByCategoryPath($slugs, $perPage, $sort); } catch (ModelNotFoundException $e) { abort(404); } if ($paginator->count() === 0) { return response()->json(['message' => 'Gone'], 410); } return ArtworkListResource::collection($paginator); } }