portfolio · diese Website
Die Startseite des Portfolios im dunklen Modus: ein Band mit Technologie-Tags, die Überschrift, eine kurze Vorstellung und die Buttons zu den Projekten und zu mehr über mich.

Überblick

Die Website, die du gerade liest: vorab als statisches HTML gerendert, auf Englisch, Deutsch und Rumänisch, mit einer eigenen Analytics-API, die nur Besuche von Lesern zählt, die zugestimmt haben.

Eine Recruiterin öffnet auf dem Smartphone einen Link zum deutschen Lebenslauf, JavaScript ist blockiert. Der ganze Lebenslauf kommt trotzdem auf Deutsch an, weil hinter der Adresse eine Datei liegt, die ihn bereits enthält.

  • Vier Fallstudien, den Lebenslauf und die rechtlichen Seiten auf Englisch, Deutsch oder Rumänisch lesen
  • Den Lebenslauf als PDF herunterladen, im Browser erzeugt
  • Zwischen dunkel und hell wechseln, die Auswahl bleibt beim nächsten Besuch erhalten
Alles, was ein Leser tut, funktioniert ohne die API; gezählt wird erst, wenn er zustimmt.
Auf einen Blick
RolleAlleinentwickler: Design, Frontend, API und Deployment
AufbauEine vorgerenderte Angular-22-Website, eine Analytics-API auf .NET 10 und ein Admin-Dashboard
SprachenEnglisch, Deutsch und Rumänisch, jede als eigener Build
Seiten27 Seiten echtes HTML: neun Routen in drei Sprachen
Tests636 Frontend-Specs, 572 Browsertests, 193 Backend-Testmethoden
Öffentliches RepositoryDer vollständige Quellcode der Website, die du gerade liest

Architektur

Eine statische Website, die für sich allein funktioniert, und eine API, auf die sie verzichten kann.

Links der gestrichelten Linie liegt alles, was weiterläuft, während die API schläft.
  • Jede Route wird beim Build vorgerendert. Der Host ist also ein Ordner voller Dateien, ohne eigenen Server.
  • Jede Sprache ist ein eigener Build in einem eigenen Ordner, etwa /de-DE/cv, weil Azure Static Web Apps nicht nach dem Query-String routen kann.
  • Die Angular-App ist in data, core, shared, layout und features geschichtet, der Pfeil zeigt in eine Richtung, und kein Feature importiert ein anderes.
  • Die API skaliert auf null, und die Seite wartet nie auf sie: Antwortet sie nicht, fehlt eben der Besucherzähler.

Domänendesign

Die Inhalte sind typisierte Daten. Eine Fallstudie, die die Form verletzt, kompiliert nicht.

Typisierte Inhalte hinein, ein Ordner voller Dateien heraus. Fehlt eine Übersetzung, stoppt ng build.
  • Jeder Text, den ein Leser sieht, trägt eine feste Message-ID, damit bei einer neuen Extraktion keine Übersetzung verwaist.
  • Eine fehlende Übersetzung lässt den Build fehlschlagen, statt still auf Englisch zurückzufallen.
  • Unterhalb der Features kommen Inhalte aus ihrer eigenen Datei und nie über das Barrel, sonst landet jede Fallstudie im ersten Download.

Daten- und Kontrollfluss

Ein Besuch, von der Adresse bis zum Besucherzähler.

Die Seite hat alles, was sie braucht, bevor die erste Anfrage an die API geht.

Teststrategie

Eine Spec neben jeder Einheit und Browsertests gegen den Build, den der Host ausliefert.

  • Der Testlauf schlägt fehl, wenn eine Komponente, ein Service, eine Direktive, eine Pipe oder ein Util keine Spec daneben hat.
  • Playwright steuert den Produktions-Build auf Desktop und Smartphone, ausgeliefert mit den Routen, Headern und der CSP des Hosts.
  • Jeder Browsertest schlägt bei einem Konsolenfehler, einer nicht abgefangenen Exception oder einem Request fehl, der die Website verlässt.
  • Die .NET-Projekte bauen mit StyleCop und Warnungen als Fehler, und die Domäne referenziert kein einziges Paket. So sichert der Compiler die Abhängigkeitsrichtung.

Was ich ändern würde

  • Die Fallstudien sind TypeScript. Ein Tippfehler darin kostet einen Build und ein Deployment.
  • Der Entwicklungsserver lokalisiert jeweils nur eine Sprache. Für eine deutsche Seite ist deshalb ein zweiter Befehl nötig.
  • Der Host erlaubt nur eine 404-Seite, also holt ein kleines Skript an ihrer Stelle die richtige Sprache. Ein Host mit einer 404 pro Ordner bräuchte das nicht.
  • Die Feature-Grenzen in der Lint-Konfiguration sind von Hand aufgelistet: Für ein neues Feature muss auch die Konfiguration angepasst werden.