routing architecture - smart-village-solutions/sva-studio GitHub Wiki
Dieses Dokument beschreibt die aktuelle Routing-Architektur im SVA Studio Monorepo: Aufbau, Verantwortlichkeiten, Server/Client-Trennung, Auth-Integration und Plugin-Erweiterbarkeit.
Die Routing-Architektur ist auf folgende Ziele ausgelegt:
- Type-safe Routing mit TanStack Router.
-
Eine öffentliche Routing-Schnittstelle über
@sva/routing. - Code-basierte produktive Seitenrouten ohne app-lokale Parallel-Registrierung.
- Saubere Server/Client-Grenze, damit server-only Module nicht in den Client-Bundle gelangen.
- Erweiterbarkeit durch statisch registrierte SDK-Plugins und einen kanonischen Build-time-Registry-Vertrag.
- Gezielte Routing-Observability für Guard-Denials, Plugin-Anomalien und serverseitige Dispatch-Fehler ohne Browser-Noise.
- Deklarative Admin-Ressourcen für CRUD-artige Host-Flächen statt verteilter Einzelverdrahtung.
Abgedeckt:
-
packages/routingals kanonische Routing-Library -
packages/auth-runtimefür Auth-Runtime-Pfade und Server-Handler sowie IAM-Zielpackages für Fachhandler -
apps/sva-studio-reactfür Root-Shell, Router-Erzeugung und Seiten-Bindings - statisch registrierte Plugin-Routen über
PluginDefinition - statisch registrierte Admin-Ressourcen über
AdminResourceDefinition - konsolidierte Build-time-Materialisierung über
createBuildTimeRegistry(...)
Nicht abgedeckt:
- UI-Design der einzelnen Seiten
- Auth-Session-Interna (siehe Auth-Doku)
- produktive Browser-Telemetrie für normale Navigationen
packages/auth-runtime
-> authRoutePaths
-> runtime handlers
packages/routing
-> getClientRouteFactories()
-> getServerRouteFactories()
-> getPluginRouteFactories()
-> Admin-Ressourcen-Materialisierung
-> routePaths / Guards / Search-Normalisierung
apps/sva-studio-react
routing/app-route-bindings.tsx
routes/__root.tsx
router.tsx
packages/plugin-news
-> PluginDefinition
@sva/sdk
-> createBuildTimeRegistry()
Result:
build-time registry + route factories from @sva/routing -> runtime route tree
Exports:
-
@sva/routing:getClientRouteFactories()getPluginRouteFactories()routePaths- Search-Normalisierung für routing-relevante Search-Params
-
@sva/routing/server:getServerRouteFactories()- serverseitige Auth-Handler-Factories
Warum diese Trennung:
- Client-Bundles sollen keine Node-/Server-Abhängigkeiten laden.
- Auth-Handler leben serverseitig in
@sva/auth-runtime. - Die App soll Routing konsumieren, nicht selbst zusammensetzen.
Path-Single-Source:
packages/auth-runtime/src/routes.ts- Re-Export über
@sva/routing
Client-safe Variante:
- erzeugt TanStack-Routen ohne Handler
- dient der vollständigen Route-Registrierung im Client
Server-Variante:
- setzt
server.handlers - resolved Handler lazy aus
@sva/auth-runtime/runtime-routesbzw.@sva/auth-runtime/runtime-health
Die App hält nur noch die Bindung zwischen kanonischen Routen und React-Seiten-Komponenten:
- statische Seiten-Komponenten
- Wrapper für parametrisierte Detailseiten
- Lazy-Loading für größere Admin-Seiten
Die Datei enthält keine Pfad- oder Guard-Definitionen.
Die App registriert CRUD-artige Admin-Flächen deklarativ über AdminResourceDefinition.
- Die Ressource beschreibt
resourceId,basePath,titleKey, Guard-Referenz und Seiten-Bindings. - Hosteigene Admin-Ressourcen wie
contentbehalten ihre unqualifizierteresourceId; plugin-beigestellte Admin-Ressourcen verwenden dagegen<pluginId>.<name>. -
@sva/routingleitet daraus die kanonischen Pfade/admin/<resource>,/admin/<resource>/newund/admin/<resource>/$idab. - Legacy-Einstiege bleiben nur als explizite Alias-Routen im Host-Routing bestehen; aktuell redirectet
/content*auf/admin/content*.
Ablauf in getRouter():
- Die App importiert
appRouteBindings. - Die App erzeugt in
src/lib/plugins.tseinen Build-time-Registry-Snapshot übercreateBuildTimeRegistry(...). - Der Snapshot enthält normalisierte Plugin-Beiträge, die registrierten Admin-Ressourcen und plugin-spezifische Audit-Event-Definitionen.
- Server und Client laden isomorph die passende Factory-Menge aus
@sva/routing. - Die App materialisiert diese Factories gegen
rootRoute. createRouter({ routeTree, ... })
Damit bleibt die Route-Komposition zentralisiert, während die App weiterhin die Seiten selbst rendert.
- erstellt
createRootRoute(...) - definiert Shell, Head, Error- und NotFound-Verhalten
- initialisiert serverseitig benötigte SDK-Bausteine nur im SSR-Kontext
Plugins exportieren PluginDefinition-Objekte.
- Die Host-App registriert Plugins statisch und verdichtet ihre Build-time-Beiträge in einen kanonischen Registry-Snapshot.
-
@sva/routingmaterialisiert die Plugin-Routen zentral. - Plugin-Guards werden auf die kanonischen Guard-Regeln des Hosts gemappt.
- Plugin-beigestellte registrierte Host-Identifier werden bereits vor der Routing-Materialisierung gegen den Namespace-Vertrag
<pluginId>.<name>validiert. - Nicht unterstützte Plugin-Guard-Mappings erzeugen genau ein
routing.plugin.guard_unsupported-Ereignis bei der Factory-Erstellung. Erfolgreiche Guard-Mappings bleiben still.
Auth-Endpunkte werden als TanStack Server Route Handler registriert und delegieren in @sva/auth-runtime:
-
/auth/login->loginHandler() -
/auth/callback->callbackHandler(request) -
/auth/me->meHandler(request) -
/auth/logout->logoutHandler(request)
Die eigentliche Business-Logik verbleibt im Auth-Package; das Routing-Package bleibt ein Integrations-Layer.
@sva/routing besitzt einen expliziten, optional injizierten Diagnostics-Hook für routing-relevante Entscheidungen und Anomalien.
- Client-shared Routing-Dateien bleiben frei von SDK-Runtime-Imports.
- Ohne Hook bleibt Browser-Routing standardmäßig still.
- Guard-Denials emittieren
routing.guard.access_denied. - Unbekannte Plugin-Guard-Mappings emittieren
routing.plugin.guard_unsupported. -
auth.routes.server.tsbindet serverseitige Ereignisse an den SDK-Logger und harmonisiert Fehler und405-Fälle auf:routing.handler.error_caughtrouting.handler.method_not_allowedrouting.logger.fallback_activated
Der Event-Vertrag nutzt nur Safe-Felder. Geloggt werden Template-Pfade statt aufgelöster IDs, keine Token-URLs, keine Stack-Traces und keine erfolgreichen Standardnavigationen.
- Routen werden als Factories mit
RootRoute-Typen gebaut. - Pfade und Search-Normalisierung sind zentralisiert.
-
@tanstack/react-routerstellt typed navigation/loader APIs bereit.
Regeln:
- Server-Handler nur in
@sva/routing/serverund serverseitigen Auth-Factories verwenden. - Keine server-only Imports in client-exponierten Route-Dateien.
- Lazy imports für Auth-Handler verhindern versehentliche Client-Bundle-Leaks.
apps/sva-studio-react/src/routeTree.gen.ts bleibt ein generiertes Integrationsartefakt für TanStack Start.
Wichtig:
- Produktive Seitenrouten werden nicht mehr file-based definiert.
- Das generierte File dient nur noch der TanStack-Start-Integration.
- Die fachliche Routing-Wahrheit liegt in
@sva/routing.
- Neue Seitenrouten ausschließlich in
@sva/routingdefinieren. - Server-Handler nur in server-spezifischen Factories oder
createServerFnkapseln. - Shared Pfade als
const+ Typ in zentralen Modulen definieren. - Seiten-Komponenten nur über die App-Route-Bindings einspeisen.
- Plugin-Routen ausschließlich über
PluginDefinition.routesbeschreiben und zentral im Routing-Paket materialisieren. - Neue CRUD-artige Admin-Flächen über
AdminResourceDefinitionregistrieren statt einzelne Host-Routen ad hoc zu ergänzen.
- Keine server-only Imports in client-safe Routing-Modulen.
- Keine duplizierten Auth-Path-Strings in App-Code.
- Keine app-lokale Parallel-Registrierung produktiver Seitenrouten.
- Keine Demo- oder Sandbox-Routen in das Produkt-Routing mischen.
- Keine parallelen Legacy-Top-Level-Pfade ohne expliziten Alias-/Redirect-Vertrag im Host-Routing einführen.
- File-based Routing bleibt technisch vorhanden, ist aber nicht mehr die fachliche Quelle der Seitenrouten.
- Seiten-Bindings bleiben absichtlich in der App, damit UI-Komponenten nicht in das Routing-Paket gezogen werden.
- Strikte Import-Disziplin bleibt entscheidend; sonst drohen Bundling-/Hydration-Probleme.
packages/routing/src/index.tspackages/routing/src/index.server.tspackages/routing/src/app.routes.tspackages/routing/src/route-paths.tspackages/routing/src/auth.routes.tspackages/routing/src/auth.routes.server.tsapps/sva-studio-react/src/router.tsxapps/sva-studio-react/src/routing/app-route-bindings.tsxapps/sva-studio-react/src/routes/__root.tsxapps/sva-studio-react/src/routeTree.gen.ts