Zum Inhalt

ADR-001: Tech Stack und MVP-Architektur

Status: Angenommen
Datum: 2026-06-30
Version: 0.1

1. Kontext

Immohai ist eine private Web-App zur schnellen, transparenten und fundierten Bewertung von Immobilieninvestitionen.

Die App soll zunächst keine öffentliche SaaS-Plattform werden. Der Fokus liegt auf einer persönlichen, nachvollziehbaren Entscheidungsunterstützung für Immobilienkäufe.

Die zentrale fachliche Frage lautet:

Lohnt sich der Kauf dieser Immobilie im Vergleich zu einer ETF-Alternative, und wie robust ist diese Einschätzung unter Best-, Base- und Stress-Annahmen?

Die fachliche Wahrheit liegt in der Spezifikation:

docs/specification/model-and-calculations/calculations.md
docs/specification/data-quality-and-validation/data-model.md
docs/specification/user-interface-and-reporting/reporting.md
docs/specification/data-quality-and-validation/validation.md

Der erste technische Schritt ist nicht der Aufbau einer komplexen Plattform, sondern ein stabiler, nachvollziehbarer Frontend-MVP mit sauber getrennter Berechnungslogik.

2. Entscheidung

Für den ersten MVP wird Immohai als statische Frontend-App umgesetzt.

Gewählter Start-Stack:

Frontend: HTML, CSS, JavaScript
Dokumentation: MkDocs Material
Deployment: Docker Compose
Webserver App: Nginx Container
Webserver Docs: MkDocs Container
Reverse Proxy: Host-Nginx
HTTPS: Certbot / Let's Encrypt

Aktive Docker-Compose-Services:

immohai-web
immohai-docs

Lokale Ports auf dem Server:

Immohai App: 127.0.0.1:8200
Immohai Doku: 127.0.0.1:8201

Öffentliche URLs:

https://immohai.ohaisoft.com
https://docs.immohai.ohaisoft.com

3. MVP-Architektur

Der erste MVP folgt dieser Architektur:

Browser
  -> statisches Frontend
  -> JavaScript-Berechnungslogik
  -> Ergebnisdarstellung im Browser

Es gibt im ersten MVP bewusst:

kein Backend
keine Datenbank
kein Login
keine SaaS-Struktur
keine externe API
kein Scraping
keine Monte-Carlo-Simulation
keine PDF-Erzeugung

4. Begründung

Der statische Frontend-MVP ist für den aktuellen Projektstand die richtige Wahl, weil:

die fachliche Berechnungslogik zuerst stabilisiert werden muss
Quick Mode schnell nutzbar werden soll
keine Benutzerdaten gespeichert werden müssen
keine Datenbank für den ersten Erkenntnisgewinn nötig ist
keine Backend-Komplexität vor der fachlichen Stabilität entstehen soll
Deployment einfach bleibt
Änderungen klein und nachvollziehbar bleiben

Der erste Mehrwert entsteht durch:

saubere Eingaben
transparente Annahmen
nachvollziehbare Jahresprojektion
Cashflow vor Steuer
ETF-Vergleich
Best/Base/Stress-Szenarien
Ampelbewertung

Nicht durch frühe Plattformfunktionen.

5. Architekturprinzipien

5.1 Spezifikation vor Code

Neue fachliche Logik wird zuerst in der Spezifikation dokumentiert.

Danach wird sie in Code umgesetzt.

Spezifikation -> Modellkonfiguration -> Berechnungslogik -> UI -> Tests

5.2 Ein Berechnungsmodell

Immohai verwendet ein Berechnungsmodell mit zwei Eingabetiefen.

Quick Mode
Expert Mode

Es gibt keine separate vereinfachte Parallelberechnung.

Quick Mode ergänzt fehlende Werte über Defaults.

Expert Mode macht Annahmen sichtbar und überschreibbar.

5.3 Trennung von UI und Fachlogik

Die UI darf keine eigene Fachlogik enthalten.

Zielstruktur im Frontend:

frontend/
├── index.html
└── assets/
    ├── css/
    │   └── styles.css
    └── js/
        ├── app.js
        ├── calculations.js
        ├── scenarios.js
        └── formatters.js

Rollen:

app.js = UI-Logik und Event Handling
calculations.js = reine Berechnungsfunktionen
scenarios.js = Defaults, Annahmenprofile und Szenarioaufbau
formatters.js = Formatierung von EUR, Prozenten, Faktoren und Jahreswerten

5.4 Maschinenlesbare Konfiguration vorbereiten

Annahmen und Defaults sollen später nicht hart in der UI versteckt werden.

Geplante Struktur:

model/
├── config/
│   ├── default-assumptions.json
│   ├── object-types.json
│   └── scenario-presets.json
├── schema/
│   └── property-input.schema.json
└── test-cases/
    └── baseline-property.json

Grundsatz:

Markdown = fachliche Begründung
JSON = Annahmen und Defaults
Code = Berechnung
Tests = Kontrolle

6. Spätere Zielarchitektur

Wenn der deterministische Kern stabil ist, kann Immohai erweitert werden.

Möglicher späterer Stack:

Frontend: React / Vite oder weiter statisch
Backend: FastAPI
Database: PostgreSQL
Calculation Engine: Python
Monte Carlo: Python-Modul oder Backend-Service
Reports: HTML / Print / PDF

Mögliches Zielbild:

Browser / Frontend
  -> API Backend
  -> Calculation Engine
  -> Database
  -> Reporting / Export
  -> Monte Carlo Service

Diese Zielarchitektur ist vorbereitet, aber nicht Teil des ersten MVP.

7. Konsequenzen

7.1 Vorteile

geringe Komplexität
schneller MVP
einfache Bereitstellung
keine Datenbankmigrationen
keine Authentifizierung nötig
saubere Konzentration auf Berechnungslogik
leichtere manuelle Prüfung

7.2 Nachteile

keine dauerhafte Speicherung im ersten MVP
kein Multi-User-Konzept
keine zentrale Backend-API
Monte Carlo zunächst nicht integriert
Batch-Analyse nur vorbereitet, nicht umgesetzt
PDF-Reports zunächst nicht enthalten

Diese Nachteile sind akzeptiert, weil sie für den ersten Erkenntnisgewinn nicht entscheidend sind.

8. Abgrenzung zum Developer Playbook

Allgemeine Infrastruktur- und Setup-Themen gehören nicht in diese ADR.

Dazu gehören insbesondere:

Ubuntu-Grundinstallation
Docker-Installation
Nginx-Grundlagen
Certbot-Grundlagen
Firewall
SSH
Git-Grundlagen
VS-Code-Setup
allgemeine Deployment-Patterns

Diese Themen werden im Developer Playbook dokumentiert.

Immohai dokumentiert nur die konkrete App-Architektur und die konkrete Anwendung der Infrastruktur für dieses Projekt.

9. Status

Diese Entscheidung gilt für den ersten MVP.

Sie kann später durch neue ADRs ergänzt werden, insbesondere bei Einführung von:

Backend
Datenbank
Monte Carlo
Objektspeicherung
Import / Batch-Analyse
PDF-Reporting
Frontend-Framework

Mögliche spätere ADRs:

ADR-002: Frontend-MVP ohne Backend
ADR-003: Spezifikation als fachliche Wahrheit
ADR-004: Quick Mode und Expert Mode
ADR-005: Batch-Analyse über Single-Property-Engine
ADR-006: Einführung FastAPI Backend
ADR-007: Einführung PostgreSQL