authorize('manage modules'); $response = $client->catalog(); $body = $response->json(); $modules = is_array($body) ? ($body['modules'] ?? $body['data'] ?? null) : null; if (! $response->successful() || ! is_array($modules)) { return response()->json(['error' => 'marketplace_unavailable'], 503); } return ModuleResource::collection(collect($modules)); } public function show(string $module, MarketplaceClient $client) { $this->authorize('manage modules'); $response = $client->module($module); $body = $response->json(); if ($response->status() === 404) { return response()->json(['error' => 'not_found'], 404); } if (! $response->successful() || ! is_array($body) || ! is_array($body['module'] ?? null)) { return response()->json(['error' => 'marketplace_unavailable'], 503); } return (new ModuleResource($body['module'])) ->additional(['meta' => [ 'modules' => ModuleResource::collection( collect($body['meta']['modules'] ?? []) ), ]]); } public function enable(string $module): JsonResponse { $this->authorize('manage modules'); $module = ModelsModule::query() ->where('name', $module) ->where('installed', true) ->firstOrFail(); $installedModule = Module::find($module->name); if ($installedModule === null) { $this->markRuntimeMissing($module); return response()->json([ 'success' => false, 'error' => 'module_runtime_missing', ], 409); } $installedModule->enable(); $module->refresh(); event(new ModuleEnabledEvent($module)); return new JsonResponse(['success' => true]); } public function disable(string $module, DatabaseActivator $activator): JsonResponse { $this->authorize('manage modules'); $module = ModelsModule::query() ->where('name', $module) ->where('installed', true) ->firstOrFail(); $activator->setActiveByName($module->name, false); if (Module::find($module->name) === null) { $this->markRuntimeMissing($module); } else { $module->refresh(); } ModuleDisabledEvent::dispatch($module); return response()->json(['success' => true]); } private function markRuntimeMissing(ModelsModule $module): void { $module->update([ 'installed' => false, 'enabled' => false, 'state' => 'failed', 'last_error' => 'module_runtime_missing', 'last_failed_at' => now(), ]); } }