Zum Inhalt

Schnittstellen der Berechnungsengine

Status: verbindlich
Spezifikationsversion: 1.1.0
Modellbezug: 0.6.2
Implementierungsbezug: frontend-mvp-0.2.5
Stand: 2026-07-05

1. Zweck und Rang

Diese Datei ist die führende Wahrheit für Übergänge zwischen Eingabewegen, Enrichment, Szenarioauflösung, Berechnungsengine, Speicherung, Vergleich und Reporting. Formeln stehen ausschließlich in docs/calculations/model-specification.md. Feldverträge stehen in docs/specification/data-quality-and-validation/data-model.md.

2. Rechenkette

PropertyInput
-> PropertyInput-Validierung
-> ScenarioInput[]
-> AnnualProjectionRow[]
-> ScenarioResult[]
-> AnalysisResult

Einzelanalyse und Batch-Vollanalyse verwenden dieselbe Single-Property-Engine. Identische PropertyInputs und identische versionierte Konfigurationen liefern identische Ergebnisse.

3. Zulässige Eingaben

Nur ein normalisiertes und validiertes PropertyInput darf an die Szenarioauflösung übergeben werden.

Rohdaten oder Formularzustand
-> Normalisierung
-> PropertyInput
-> Validierung
-> Szenarioauflösung
-> Engine

Nicht zulässig:

DOM-Zugriff innerhalb der Szenarioauflösung
Berechnung direkt aus Formularfeldern
Berechnung direkt aus Roh- oder Importdaten
stille Ergänzung nicht versionierter Annahmen nach dem PropertyInput-Snapshot

4. Auflösung der Base-Annahmen

Priorität:

1. finaler manueller Expert-Override
2. manuelle Eingabe
3. bewusst übernommener Schätz- oder Importwert
4. Profilwert
5. Objektprofil-Anpassung auf Profil- oder Defaultwert
6. globaler Default
7. missing

Regeln:

value_status = final -> keine Objektprofil- oder Szenarioänderung
manuelle Eingabe wird nicht still ersetzt
Objektprofil-Anpassung wirkt nur auf Profil- oder Defaultwerte
bereits object_type_adjusted markierte Werte werden nicht erneut angepasst
Base enthält kein Szenario-Delta

derived, estimated, imported und scraped dürfen nicht objektprofilverändert werden.

5. Szenario-Policy

fixed
scenario_adjustable
sensitivity_only

Nur scenario_adjustable erhält Best- oder Stress-Deltas. ETF-Rendite ist sensitivity_only und bleibt in Best, Base und Stress identisch.

Die Policy wird aus fachlichem Status und Herkunft bestimmt:

vertragliche Ist-Miete -> fixed
geschätzte Marktmiete -> scenario_adjustable
verbindliches Finanzierungsangebot -> fixed
indikativer Marktzinssatz -> scenario_adjustable
finaler Wert -> fixed

6. Szenariosteuerung

6.1 Preset

PropertyInput.scenarios.control_mode = preset
-> versionierte scenario-presets.json-Deltas

6.2 Eigene Slider

Nutzer stellt Slider ein
-> formToPropertyInput liest die Werte
-> PropertyInput.scenarios.control_mode = custom_sliders
-> PropertyInput.scenarios.controls speichert alle Sliderwerte
-> buildScenarioInputs berechnet daraus Best/Base/Stress

Base bleibt unverändert. Best und Stress werden symmetrisch gemäß Modell-Spezifikation erzeugt. Die Sliderwerte sind Bestandteil des gebundenen PropertyInput-Snapshots und damit reproduzierbar.

6.3 Expert Overrides

PropertyInput.scenarios.overrides.Best
PropertyInput.scenarios.overrides.Stress

Base- und ETF-Overrides sind nicht zulässig. Overrides wirken nur auf scenario_adjustable-Felder.

7. Einzelanalyse

Formular
-> formToPropertyInput
-> PropertyInput-Validierung
-> propertyInputToBaseInput
-> buildScenarioInputs
-> calculateAnalysis
-> AnalysisResult

Ein einziger aktiver Controller orchestriert diesen Pfad. Eine Berechnung wird erst durch bewusste Nutzeraktion zu einem PropertyRecord.

8. Batch

Pre-Screening verarbeitet normalisierte Objektgrunddaten ohne persönliche Finanzierung. Die Vollanalyse ergänzt ein versioniertes Finanzierungsprofil, erzeugt ein vollständiges PropertyInput und ruft dieselbe Engine wie die Einzelanalyse auf.

Die Batch-Schicht enthält keine eigenen Projektions-, KPI-, Assessment- oder Ratingformeln.

9. RentEstimate

published RentReferenceDataset innerhalb seines Scope
-> RentReferenceLookup
-> RentEstimate
-> bewusste Übernahme oder transparenter Enrichment-Schritt
-> PropertyInput.rental.monthly_cold_rent
-> Engine

Die Engine berechnet keine Marktmiete. Sie erhält:

rent_basis
origin
confidence
confidence_level
scenario_policy
RentEstimateReference

Kanonische Dataset-Felder:

rent_reference_dataset_id
rent_reference_dataset_version
rent_reference_dataset_scope_id

10. ScenarioResult

Jedes Szenario liefert:

scenario_name
projection
kpis
kpi_assessments
scenario_assessment
scenario_rating
plausibility_checks
warnings

scenario_rating dient nur dem Case-Vergleich. Es wird nicht in das Investment Rating eingespeist.

11. AnalysisResult

Zusätzliche Regeln:

property_input ist der unveränderbare Eingabesnapshot des Rechenlaufs
property_input_id stimmt mit property_input.meta.property_input_id überein
Base-KPIs werden in base_summary_kpis gespiegelt
Stress bestimmt die Robustness-Komponente
InvestmentRating wird genau einmal auf AnalysisResult-Ebene erzeugt

Ein AnalysisResult darf nicht nachträglich mit einem erneut aus dem Formular erzeugten PropertyInput kombiniert werden.

12. Datenqualität

Ein Rechenlauf darf Projektionen und KPIs erzeugen, wenn die Datenqualität noch nicht ausreichend ist.

fehlender Score oder Score < 50
-> InvestmentRating = UNRATED
-> alle ScenarioRatings = UNRATED

Die Engine darf nicht auf 100 oder einen anderen Ersatzscore zurückfallen. Datenqualität verändert keine Finanzformel.

13. CAPEX

Die Engine erhält explizit:

recurring_capex_method
recurring_capex_pct_of_gross_rent
recurring_capex_fixed_pa
special_capex[]

Die Methodenwahl steuert genau eine Berechnungsmethode. Das nicht aktive Methodenfeld ist null, abwesend oder 0.

14. Plausibilitätschecks

Jeder Check enthält:

code
severity
message
affected_fields optional

Zulässige Severity:

info
warning
critical

Schwellen und Codes stehen ausschließlich in der Modell-Spezifikation oder einer dort ausdrücklich referenzierten versionierten Konfiguration.

15. Speicherung

AnalysisResult
-> bewusste Nutzeraktion
-> PropertyRecord

Ein PropertyRecord speichert exakt den an das AnalysisResult gebundenen PropertyInput-Snapshot sowie Szenarioergebnisse, KPIs, Investment Rating, Case Ratings, Plausibilitätsprüfungen, Datenqualität, Versionen und Analyseherkunft.

Das Formular wird beim Speichern nicht erneut als Recheninput interpretiert. object_id gehört zum PropertyRecord und wird nicht still in den berechneten PropertyInput-Snapshot geschrieben.

16. Öffnen und Neuberechnen

PropertyRecord öffnen
-> gespeicherten Snapshot anzeigen
-> gespeicherte Eingaben ohne Rechenlauf ins Formular laden
-> Änderungen als unberechnet markieren
-> neue Berechnung nur durch bewusste Nutzeraktion

Alte Ergebnisse werden nicht still überschrieben.

17. Reports und Vergleiche

Reportvorschau aus aktuellem AnalysisResult-Snapshot
Gespeicherter Report aus PropertyRecord-Snapshot
Vergleich ausschließlich aus PropertyRecord-Snapshots

Reports und Vergleiche dürfen vorhandene Werte sortieren, gruppieren, formatieren, differenzieren und erklären. Sie dürfen keine Fachformeln, Schwellen, Plausibilitätschecks, Case Ratings oder Investment Ratings neu erzeugen.

18. Legacy-Kompatibilität

Zulässige Lese-Aliase stehen ausschließlich in docs/specification/data-quality-and-validation/data-model.md. Neue Ergebnisse schreiben nur kanonische Felder. Alte Snapshots werden nicht still verändert.

19. Fehlerbehandlung

calculated
calculated_with_warnings
not_calculated
failed

not_calculated ist ein Batch-Arbeitsstatus und kein AnalysisResult-Status. Ein fehlerhaftes Batch-Objekt beendet nicht den Gesamtlauf.

20. Versionierung

Jeder Rechenlauf speichert:

Modellversion
Engine-Version
PropertyInput-Schemaversion
AnalysisResult-Schemaversion
weitere Schemaversionen, sofern betroffen
Default-Version
Szenariopreset-Version
Objektprofil-Version
Datenqualitäts-Methodenversion

Bei einer Mietschätzung werden zusätzlich RentEstimate-ID, Dataset-ID, Dataset-Version, Dataset-Scope und Confidence-Methodenversion gespeichert.

21. Mindesttests

Einzel- und Batch-Vollanalyse sind bei identischem PropertyInput identisch.
Szenarioauflösung liest kein DOM.
Sliderwerte werden im PropertyInput gespeichert und reproduzierbar angewendet.
Base bleibt bei custom_sliders unverändert.
Finale Werte bleiben unverändert.
Objektprofil-Anpassungen wirken nur auf Profil- oder Defaultwerte.
Nur scenario_adjustable-Felder ändern sich zwischen Szenarien.
ETF-Rendite bleibt zwischen Best, Base und Stress identisch.
CAPEX-Methode steuert genau eine Berechnungsmethode.
Fehlende Datenqualität erzeugt UNRATED und keinen Ersatzscore.
Jeder Case erhält ein ScenarioRating.
Nur AnalysisResult erhält das InvestmentRating.
Darlehen ohne Kapitaldienst führt zu RED.
Null-Eigenkapitalfälle folgen den expliziten Schwellen.
PropertyRecords speichern exakt den berechneten Eingabesnapshot.
Reports und Vergleiche verwenden Snapshots und rechnen nicht neu.
Legacy-Aliase werden nur gelesen.