route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); $environment = $application->environments()->findOrFail($request->route('environment')); return inertia('environment-attachments/Create', [ 'application' => $application, 'environment' => $environment, 'services' => $organisation->services() ->whereIn('type', [ServiceType::POSTGRES->value, ServiceType::VALKEY->value, ServiceType::CADDY->value]) ->orderBy('name') ->get(['id', 'name', 'type', 'category']), 'roles' => array_values(EnvironmentAttachmentRole::toArray()), 'compatibility' => [ EnvironmentAttachmentRole::DATABASE->value => [ServiceType::POSTGRES->value], EnvironmentAttachmentRole::CACHE->value => [ServiceType::VALKEY->value], EnvironmentAttachmentRole::QUEUE->value => [ServiceType::VALKEY->value], EnvironmentAttachmentRole::GATEWAY->value => [ServiceType::CADDY->value], ], ]); } public function store(StoreEnvironmentAttachmentRequest $request): RedirectResponse { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); $environment = $application->environments()->findOrFail($request->route('environment')); $service = $organisation->services()->findOrFail($request->integer('service_id')); $attachment = app(AttachManagedService::class)->execute( environment: $environment, service: $service, role: $request->enum('role', EnvironmentAttachmentRole::class), name: $request->filled('name') ? $request->string('name')->toString() : null, envPrefix: $request->filled('env_prefix') ? $request->string('env_prefix')->toString() : null, isPrimary: $request->boolean('is_primary', true), ); if ($request->enum('role', EnvironmentAttachmentRole::class) === EnvironmentAttachmentRole::GATEWAY && $attachment->serviceSlice) { $attachment->serviceSlice->update([ 'config' => [ ...($attachment->serviceSlice->config ?? []), 'domain' => $request->filled('domain') ? $request->string('domain')->toString() : null, 'path_prefix' => $request->filled('path_prefix') ? $request->string('path_prefix')->toString() : '/', 'tls_enabled' => $request->boolean('tls_enabled', true), ], ]); } return redirect() ->route('environments.show', [ 'organisation' => $organisation->id, 'application' => $application->id, 'environment' => $environment->id, ]) ->with('success', 'Managed service attached.'); } public function edit(Request $request): Response { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); $environment = $application->environments()->findOrFail($request->route('environment')); $attachment = $environment->attachments() ->with(['service', 'serviceSlice']) ->findOrFail($request->route('attachment')); return inertia('environment-attachments/Edit', [ 'application' => $application, 'environment' => $environment, 'attachment' => $attachment, 'roles' => array_values(EnvironmentAttachmentRole::toArray()), ]); } public function update(UpdateEnvironmentAttachmentRequest $request): RedirectResponse { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); $environment = $application->environments()->findOrFail($request->route('environment')); $attachment = $environment->attachments()->findOrFail($request->route('attachment')); $attachment->update([ 'role' => $request->enum('role', EnvironmentAttachmentRole::class), 'env_prefix' => $request->filled('env_prefix') ? $request->string('env_prefix')->toString() : null, 'is_primary' => $request->boolean('is_primary'), ]); if ($attachment->serviceSlice && $request->enum('role', EnvironmentAttachmentRole::class) === EnvironmentAttachmentRole::GATEWAY) { $attachment->serviceSlice->update([ 'config' => [ ...($attachment->serviceSlice->config ?? []), 'domain' => $request->filled('domain') ? $request->string('domain')->toString() : null, 'path_prefix' => $request->filled('path_prefix') ? $request->string('path_prefix')->toString() : '/', 'tls_enabled' => $request->boolean('tls_enabled', true), 'certificate_status' => $request->filled('certificate_status') ? $request->string('certificate_status')->toString() : null, ], ]); } return redirect() ->route('environments.show', [ 'organisation' => $organisation->id, 'application' => $application->id, 'environment' => $environment->id, ]) ->with('success', 'Attachment updated.'); } public function destroy(Request $request): RedirectResponse { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); $environment = $application->environments()->findOrFail($request->route('environment')); $attachment = $environment->attachments()->findOrFail($request->route('attachment')); $attachment->delete(); return redirect() ->route('environments.show', [ 'organisation' => $organisation->id, 'application' => $application->id, 'environment' => $environment->id, ]) ->with('success', 'Attachment detached.'); } }