feat: Steuerlast-Kriterium, ImmoScout-Layout, Gold/Silver/Bronze-Trennung

- Flächensuche: Flexibilität durch Steuerlast (taxEnvironment) ersetzt
- MatchDetail: Bild als Hero-Banner oben, Karte eingebettet im Inhalt darunter
- Ergebnisliste: Gold/Silber/Bronze-Abschnitte mit farbigen Trennlinien
- ScoreBreakdown: KI-Steuerlast-Link zur kantonalen Steuerrechner-Seite
- Beispieldaten: alle Objekte mit passenden Bildern versehen
- locationIntelligence: taxCalculatorUrl pro Kanton ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-18 14:14:10 +02:00
parent 5b917bd619
commit 05ac0083b2
13 changed files with 495 additions and 91 deletions
@@ -10,6 +10,7 @@ import type {
MatchCardAction,
MatchCardReason,
} from '../../components/match-card/MatchCardViewModel'
import { getCityIntelligence } from '../../lib/locationIntelligence'
const HARD_CRITERIA = new Set(['area', 'location', 'budget', 'timing'])
@@ -76,6 +77,9 @@ export function buildMatchCardViewModel(
const reasons = buildReasons(match.positiveFactors)
const cityIntel = city ? getCityIntelligence(city) : null
const taxCalculatorUrl = cityIntel?.taxCalculatorUrl
const dataQualityScore =
property?.dataQuality?.score ?? signal?.confidenceScore ?? 0.5
@@ -104,6 +108,7 @@ export function buildMatchCardViewModel(
? (signal?.disclaimer ?? 'Probabilistisches Signal kein bestätigtes Objekt')
: undefined,
explainabilitySummary: match.explainabilitySummary,
taxCalculatorUrl,
isReviewRequired: match.status === 'PENDING_REVIEW',
isStaleData: false,
}
+1 -1
View File
@@ -22,7 +22,7 @@ function resolveProfile(need: Need, property: Property): ScoringWeightProfile {
if (!np) return base
// Apply need's custom core weights, then renormalize the full profile to 1.00
const CORE = ['area', 'location', 'budget', 'timing', 'prestige', 'accessibility', 'expansionPotential', 'flexibility']
const CORE = ['area', 'location', 'budget', 'timing', 'prestige', 'accessibility', 'expansionPotential', 'taxEnvironment']
for (const key of CORE) {
if (typeof np[key] === 'number') base[key] = np[key]
}