findOrFail($request->route('organisation')); return inertia('applications/Index', [ 'applications' => $organisation->applications, ]); } public function create(Request $request): Response { $organisation = Organisation::findOrFail($request->route('organisation')); return inertia('applications/Create', [ 'sourceProviders' => $organisation->sourceProviders()->get(), 'repositoryTypes' => RepositoryType::toArray(), ]); } public function store(StoreApplicationRequest $request): RedirectResponse { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->create([ 'name' => $request->string('name')->toString(), 'source_provider_id' => $this->sourceProviderIdFor($organisation, $request->integer('source_provider_id') ?: null), 'repository_url' => $request->string('repository_url')->toString(), 'repository_type' => $request->enum('repository_type', RepositoryType::class), 'default_branch' => $request->string('default_branch')->toString(), ]); app(GenerateDeployKey::class)->execute($application); app(CreateLaravelEnvironment::class)->execute($application->refresh(), $request->string('environment_name')->toString()); return redirect() ->route('applications.show', ['organisation' => $organisation->id, 'application' => $application->id]) ->with('success', 'Application created. Add the deploy key to your repository before verifying access.'); } public function show(Request $request): Response { $id = $request->route('application'); $organisation = Organisation::findOrFail($request->route('organisation')); $application = Application::with([ 'environments.buildArtifacts' => fn ($query) => $query->latest()->limit(5), 'environments.operations' => fn ($query) => $query->latest()->limit(1), 'environments.services.replicas', 'environments.services.endpoints', 'environments.services.slices', 'environments.attachments.service', 'environments.variables', 'organisation', 'sourceProvider', ])->whereBelongsTo($organisation)->findOrFail($id); return inertia('applications/Show', [ 'application' => $application, 'deploymentRequirements' => [ 'registryRequired' => $organisation->servers()->count() > 1 && $organisation->registries()->doesntExist(), 'registryCount' => $organisation->registries()->count(), 'serverCount' => $organisation->servers()->count(), ], 'servers' => inertia()->optional(function () use ($application) { return $application ->organisation ?->servers() ->where('status', ServerStatus::ACTIVE) ->with('services') ->get() ?? []; }), ]); } public function edit(Request $request): Response { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); return inertia('applications/Edit', [ 'application' => $application, 'repositoryTypes' => RepositoryType::toArray(), 'sourceProviders' => $organisation->sourceProviders()->get(), ]); } public function update(UpdateApplicationRequest $request): RedirectResponse { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); $application->update([ 'name' => $request->string('name')->toString(), 'source_provider_id' => $this->sourceProviderIdFor($organisation, $request->integer('source_provider_id') ?: null), 'repository_type' => $request->enum('repository_type', RepositoryType::class), 'repository_url' => $request->string('repository_url')->toString(), 'default_branch' => $request->string('default_branch')->toString(), ]); return redirect() ->route('applications.show', [ 'organisation' => $organisation->id, 'application' => $application->id, ]) ->with('success', 'Application updated.'); } public function destroy(Request $request): RedirectResponse { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); $application->delete(); return redirect() ->route('applications.index', ['organisation' => $organisation->id]) ->with('success', 'Application deleted.'); } public function verifyRepository(Request $request): RedirectResponse { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); if (! app(VerifyRepositoryAccess::class)->execute($application)) { return back()->with('error', 'Repository access could not be verified.'); } return back()->with('success', 'Repository access verified.'); } public function rotateDeployKey(Request $request, GenerateDeployKey $generateDeployKey): RedirectResponse { $organisation = Organisation::findOrFail($request->route('organisation')); $application = $organisation->applications()->findOrFail($request->route('application')); $generateDeployKey->execute($application); return back()->with('success', 'Deploy key rotated. Install the new public key before verifying access.'); } private function sourceProviderIdFor(Organisation $organisation, ?int $sourceProviderId): ?int { if ($sourceProviderId === null) { return null; } return $organisation->sourceProviders()->findOrFail($sourceProviderId)->id; } }