feat(operations): fresh platform-operations implementation

Full rewrite of the installer (incl. the finish step), self-update pipeline,
settings store, cron webhook, dashboard/bootstrap surface, environment
manager, wizard login, config endpoint and shared helpers. Byte-compatible
public interfaces and observable behavior, including documented legacy
quirks; verified by the pilot behavioral suite and the full test suite.
This commit is contained in:
Darko Gjorgjijoski
2026-08-20 18:30:12 +02:00
parent a1828fac52
commit 7db2a8d094
31 changed files with 2869 additions and 0 deletions
@@ -0,0 +1,41 @@
<?php
namespace App\Platform\Operations\Installation\Http\Middleware;
use App\Platform\Operations\Installation\Application\InstallationState;
use App\Platform\Operations\Models\Setting;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Keeps the application proper out of reach until the setup wizard is done.
*
* The question "is this instance installed?" is answered against a database
* that may not exist yet, so every failure mode -- no connection, no schema,
* no settings row -- is read as "not installed" and sends the visitor to the
* wizard rather than to a stack trace.
*/
class EnsureInstalled
{
public function handle(Request $request, Closure $next): Response
{
return $this->isInstalled()
? $next($request)
: redirect('/installation');
}
/**
* A finished install means the schema is in place and the wizard wrote its
* completion marker. The marker is only looked up once the schema exists.
*/
private function isInstalled(): bool
{
try {
return InstallationState::isDbCreated()
&& Setting::getSetting('profile_complete') === 'COMPLETED';
} catch (\Exception) {
return false;
}
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Platform\Operations\Installation\Http\Middleware;
use App\Platform\Operations\Installation\Application\InstallationState;
use App\Platform\Operations\Models\Setting;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* The mirror image of the installed gate, guarding the wizard itself: once the
* instance is live nobody gets to walk through setup a second time.
*/
class RedirectIfInstalled
{
public function handle(Request $request, Closure $next): Response
{
if ($this->wizardAlreadyFinished()) {
return redirect('login');
}
return $next($request);
}
/**
* Reading the completion marker needs the settings table, which the wizard
* itself creates -- so a failure here just means setup is still running and
* the request is allowed through.
*/
private function wizardAlreadyFinished(): bool
{
if (! InstallationState::isDbCreated()) {
return false;
}
try {
return Setting::getSetting('profile_complete') === 'COMPLETED';
} catch (\Exception) {
return false;
}
}
}