index.php
Pfad: public/index.php
Ext: php
Größe: 5981 Bytes
Geändert: 2026-07-16T10:16:51+02:00
Frühere Version vom 2026-07-16T10:16:51+02:00 · zur aktuellen Fassung
<?php
declare(strict_types=1);
/**
* Einstiegspunkt und Composition Root von demo.karlkratz.com.
* Verdrahtet die hexagonalen Schichten und dispatcht die Anfrage.
* Security: Whitelist-Router (unbekannt -> 404, falsche Methode -> 405);
* Pfadparameter nur ueber PDO-Prepared-Statements; alle Ausgaben escaped;
* gespeicherter Inhalt beim Rendern escaped und beim Speichern per DOM-Walk
* auf die Whitelist reduziert; Security-Header auf Caddy-Ebene; kein Inline-JS.
*/
use Demo\Autoloader;
use Demo\Application\Dokumentation\ListeDokumentation;
use Demo\Application\Dokumentation\SpeichereInhalt;
use Demo\Application\Dokumentation\ZeigeDokumentation;
use Demo\Application\Dokumentation\ListeDokumentationVersionen;
use Demo\Application\Dokumentation\ZeigeDokumentationVersion;
use Demo\Application\Code\ListeCodeDateien;
use Demo\Application\Code\ListeCodeDateiVersionen;
use Demo\Application\Code\SynchronisiereCodeDateien;
use Demo\Application\Code\ZeigeCodeDatei;
use Demo\Application\Code\ZeigeCodeDateiVersion;
use Demo\Application\Health\GetHealth;
use Demo\Application\Prozess\ListeProzesse;
use Demo\Application\Abgleich\PruefeKatalog;
use Demo\Application\Prozess\ZeigeProzess;
use Demo\Infrastructure\Code\CodeDateiScanner;
use Demo\Infrastructure\Config\CredentialsProvider;
use Demo\Infrastructure\Content\HtmlToMarkdown;
use Demo\Infrastructure\Content\MarkdownToHtml;
use Demo\Infrastructure\Flow\FlussLayout;
use Demo\Infrastructure\Flow\SvgFluss;
use Demo\Infrastructure\Http\DokuDetailAction;
use Demo\Infrastructure\Http\DokuListeAction;
use Demo\Infrastructure\Http\DokuSpeichernAction;
use Demo\Infrastructure\Http\HealthAction;
use Demo\Infrastructure\Http\ProzessDetailAction;
use Demo\Infrastructure\Http\AbgleichAction;
use Demo\Infrastructure\Http\ProzessListeAction;
use Demo\Infrastructure\Http\HomeAction;
use Demo\Infrastructure\Http\Navigation;
use Demo\Infrastructure\Http\Routen;
use Demo\Infrastructure\Http\Response;
use Demo\Infrastructure\Http\Router;
use Demo\Infrastructure\Http\CodeListeAction;
use Demo\Infrastructure\Http\CodeDetailAction;
use Demo\Infrastructure\Http\CodeFehlerAntwort;
use Demo\Infrastructure\Http\TemplateRenderer;
use Demo\Infrastructure\Persistence\PdoConnectionFactory;
use Demo\Infrastructure\Persistence\PostgresDokumentationRepository;
use Demo\Infrastructure\Persistence\PostgresDokumentationHistorie;
use Demo\Infrastructure\Persistence\PostgresCodeDateiRepository;
use Demo\Infrastructure\Persistence\PostgresCodeDateiHistorie;
use Demo\Infrastructure\Persistence\PostgresHealthProbe;
use Demo\Infrastructure\Persistence\PostgresArtefaktKatalog;
use Demo\Infrastructure\Persistence\PostgresProzessRepository;
use Demo\Infrastructure\Persistence\ProzessDetailLader;
use Demo\Infrastructure\Reconcile\SystemRealitaet;
require dirname(__DIR__) . '/src/Autoloader.php';
(new Autoloader(dirname(__DIR__) . '/src'))->register();
$credentialsDir = (string) ($_SERVER['APP_CREDENTIALS_DIR'] ?? getenv('APP_CREDENTIALS_DIR'));
$credentials = (new CredentialsProvider($credentialsDir))->database();
$pdoFactory = new PdoConnectionFactory($credentials);
$view = new TemplateRenderer(dirname(__DIR__) . '/src/Infrastructure/Http/view');
$nav = new Navigation();
$routen = new Routen();
$home = new HomeAction($view, $nav);
$health = new HealthAction(new GetHealth(new PostgresHealthProbe($pdoFactory)));
$dokuRepo = new PostgresDokumentationRepository($pdoFactory);
$dokuHistorie = new PostgresDokumentationHistorie($pdoFactory);
$dokuListe = new DokuListeAction(new ListeDokumentation($dokuRepo), $view, $nav);
$dokuDetail = new DokuDetailAction(
new ZeigeDokumentation($dokuRepo),
new ListeDokumentationVersionen($dokuHistorie),
new ZeigeDokumentationVersion($dokuHistorie),
new MarkdownToHtml(),
$view,
$nav
);
$dokuSpeichern = new DokuSpeichernAction(new SpeichereInhalt($dokuRepo, new HtmlToMarkdown()));
$prozessRepo = new PostgresProzessRepository($pdoFactory, new ProzessDetailLader($pdoFactory));
$prozessListe = new ProzessListeAction(new ListeProzesse($prozessRepo), $view, $nav);
$prozessDetail = new ProzessDetailAction(new ZeigeProzess($prozessRepo), new MarkdownToHtml(), new FlussLayout(), new SvgFluss(), $view, $nav);
$abgleich = new AbgleichAction(new PruefeKatalog(new PostgresArtefaktKatalog($pdoFactory), new SystemRealitaet($pdoFactory, $routen)), $view, $nav);
$codeRepo = new PostgresCodeDateiRepository($pdoFactory);
$codeHistorie = new PostgresCodeDateiHistorie($pdoFactory);
$codeSync = new SynchronisiereCodeDateien($codeRepo);
$codeScanner = new CodeDateiScanner(dirname(__DIR__));
$codeFehler = new CodeFehlerAntwort();
$codeListe = new CodeListeAction(
new ListeCodeDateien($codeRepo),
$codeSync,
$codeScanner,
$view,
$nav,
$codeFehler
);
$codeDetail = new CodeDetailAction(
new ZeigeCodeDatei($codeRepo),
new ListeCodeDateiVersionen($codeHistorie),
new ZeigeCodeDateiVersion($codeHistorie),
$codeSync,
$codeScanner,
$view,
$nav,
$codeFehler
);
$router = new Router();
foreach ($routen->alle() as $route) {
[$methode, $pfad] = explode(' ', $route, 2);
$router->add($methode, $pfad, match ($route) {
'GET /' => $home,
'GET /health' => $health,
'GET /doku' => $dokuListe,
'GET /doku/{slug}' => $dokuDetail,
'GET /doku/{slug}/{version}' => $dokuDetail,
'POST /doku/{slug}' => $dokuSpeichern,
'GET /code' => $codeListe,
'GET /code/{id}' => $codeDetail,
'GET /code/{id}/{version}' => $codeDetail,
'GET /prozesse' => $prozessListe,
'GET /prozesse/{slug}' => $prozessDetail,
'GET /abgleich' => $abgleich,
default => throw new \LogicException('Route nicht verdrahtet: ' . $route),
});
}
$method = (string) ($_SERVER['REQUEST_METHOD'] ?? 'GET');
$path = (string) parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
$router->dispatch($method, $path === '' ? '/' : $path)->send();