feat: Reale Jahresbelastung, must-have fixes, fitOut data coverage

Reale Jahresbelastung (Change 6):
- FitOutCostPanel zeigt Jahresmiete + amortisierte Ausbaukosten für alle fitOut-Werte
- FULL/PREMIUM: Ausbau CHF 0 (bezugsfertig), SHELL/BASIC: CRB/BKP-Richtwerte amortisiert über 5 J.
- Match-Card-Chip zeigt geschätzte Investition (orange wenn >100k)
- FitOutInvestment-Typ + calcFitOutInvestment() in fitOutUtils.ts
- BackendAIService + MockAIService mit generateFitOutAdvice (IAIService-Interface)

Must-have Kriterien (Nicht prüfbar Fix):
- ÖV-Anbindung: Minutengrenze aus Freitext extrahiert, gegen publicTransportMinutes geprüft
- Mindestfläche: m²-Wert aus Freitext extrahiert, gegen areaSqm geprüft
- Ausbaugrad: neues Keyword-Rule für FULL/PREMIUM

fitOut-Datenpflege:
- fitOut-Werte zu 32 fehlenden Properties ergänzt (Logistik=SHELL, Standard=BASIC, Modern=FULL)
- MAB-Werte (200/150/250 CHF/m²) zu 3 BASIC-Objekten hinzugefügt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-06-06 20:09:55 +02:00
parent a825672197
commit b2530f9e20
40 changed files with 1755 additions and 733 deletions
+14
View File
@@ -1,5 +1,7 @@
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { propertyService } from '../services/propertyService'
import { unitService } from '../services/unitService'
import type { PropertyUnit } from '../domain/property'
import { matchService } from '../services/matchService'
import { futureSignalService } from '../services/futureSignalService'
import type { AssetType, ResultType } from '../domain/enums'
@@ -89,6 +91,18 @@ export function useCreateProperty() {
})
}
export function useUpdateUnit(propertyId: string) {
const queryClient = useQueryClient()
return useMutation({
mutationFn: ({ unitId, data }: { unitId: string; data: Partial<PropertyUnit> }) =>
unitService.update(unitId, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['properties'] })
queryClient.invalidateQueries({ queryKey: ['property', propertyId] })
},
})
}
export function useRemoveProperty() {
const queryClient = useQueryClient()
return useMutation({