Manche IT-Leitung fragt zuerst nach dem Stack – nicht aus Neugier, sondern um zu wissen, ob eine Plattform in fünf Jahren noch wartbar ist und ob sich das eigene Team darin zurechtfände. Hier ist er.
Der Stack
| Schicht | Technik |
|---|---|
| Laufzeit | .NET 10 (LTS), C#; ein modularer Monolith – ein Prozess, klar getrennte Module |
| Datenbank | PostgreSQL 18; ein Schema je Modul; Row-Level Security für die Mandantentrennung |
| Datenzugriff | EF Core für Schreibpfade, SQL für Lesepfade; Migrationen versioniert im Code |
| Nachrichten und Hintergrundarbeit | Wolverine: Handler, dauerhafte Nachrichten mit Postgres-gestütztem Outbox/Inbox, Sagas, geplante Aufträge; Transport RabbitMQ (lokal, On-Premises) oder Azure Service Bus |
| Schnittstelle | HTTP/JSON, Minimal API; OpenAPI-3-Beschreibung, generiert aus dem Code; Fehler als Problem Details (RFC 9457) |
| Oberfläche | React 19, TypeScript, Vite – eine statische Single-Page-Anwendung, die ausschließlich über die Schnittstelle spricht |
| Anmeldung | Microsoft Entra ID (OpenID Connect, MSAL) für Menschen; API-Schlüssel für Systeme |
| Telemetrie | OpenTelemetry (Traces, Metriken, Logs) → Azure Monitor; Serilog |
| Tests | Unit-Tests je Modul, Integrationstests gegen echte Container (Testcontainers), Architekturtests, die Modulgrenzen erzwingen |
| Infrastruktur | Azure, vollständig als Bicep beschrieben; Container-Images aus einer privaten Registry; Azure DevOps Pipelines |
| Lokale Entwicklung | .NET Aspire orchestriert Datenbank, Warteschlange und Speicher auf dem Entwicklerrechner |
Warum ein modularer Monolith
Die Plattform ist in Module geschnitten – Sendungen, Vorgänge, Dokumente, E-Mail, Kalender, Carrier, Verträge, Auswertung, Mandanten, Benutzer –, jedes mit eigener Domäne, eigenem Schema und eigenen Endpunkten. Module sprechen über Nachrichten und Ereignisse miteinander, nicht über direkte Aufrufe; Architekturtests brechen den Build, wenn ein Modul in ein anderes hineingreift.
Trotzdem läuft alles in einem Prozess. Das ist eine bewusste Entscheidung gegen Microservices: eine Transaktion statt verteilter Konsistenz, ein Deployment statt eines Orchestrierungsproblems, ein Änderungsprotokoll in derselben Transaktion wie die Änderung. Sollte ein Modul eines Tages eigene Skalierung brauchen, ist die Grenze bereits gezogen.
Bewusst nicht im Einsatz
Keine Bibliotheken mit kommerziellem Lizenzrisiko im Kern (kein MediatR, kein MassTransit, kein FluentAssertions), kein Dapr, kein eigener Identitätsanbieter mit Passwörtern. Weniger Abhängigkeiten sind weniger Angriffsfläche und weniger Überraschungen bei Lizenzänderungen.
Oberfläche
Die Anwendung ist für die tägliche Arbeit am Desktop-Browser gebaut: Tastaturführung für alle wichtigen Aktionen, eine Kommandozeile (Cmd/Strg + K), Kontextpanel statt Seitenwechsel, dunkles und helles Erscheinungsbild. Sie läuft in den aktuellen Versionen von Chrome, Edge, Firefox und Safari; eine Installation auf dem Rechner ist nicht nötig. Die Oberfläche selbst enthält keine Daten – sie holt alles über die Schnittstelle, mit dem Token des angemeldeten Benutzers.