feat(supply): per-unit fit-out/cost-bearer/MAB/parking with object fallback (resolveUnitFacts)

- unit: add fitOutByLandlord, mieterausbaubeitragPerSqm, parkingSpots (parking = allocation from object pool)
- lib/unitFacts.resolveUnitFacts: single resolver (unit value ?? object value) used by scorer + card adapter
- matchSyncService: pre-market unit scored via resolved facts (fit-out, MAB, cost-bearer, parking allocation)
- matchCardAdapter: fit-out label/viability/investment via resolveUnitFacts
- UnitStructurePanel: consolidate ALL per-unit overrides into the one expandable row editor (price, availability, Ausbaustandard, Wer-baut-aus, MAB, parking allocation); show parking on row
- PreMarketUnitGrid/Panel: drop the duplicate per-unit fit-out select (now in the unit editor)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-06-20 23:44:56 +02:00
parent 647493bf3c
commit fd6ed105bb
7 changed files with 144 additions and 71 deletions
-23
View File
@@ -27,9 +27,6 @@ export function PreMarketPanel({ p }: { p: Property }) {
}
return init
})
const [unitFitOut, setUnitFitOut] = useState<Record<string, string>>(() =>
Object.fromEntries((p.units ?? []).map(u => [u.id, u.fitOut ?? ''])),
)
const [unitSaving, setUnitSaving] = useState<Record<string, boolean>>({})
const queryClient = useQueryClient()
const updateProperty = useUpdateProperty()
@@ -99,23 +96,6 @@ export function PreMarketPanel({ p }: { p: Property }) {
}
}
async function saveUnitFitOut(unitId: string, fitOut: string) {
setUnitFitOut(prev => ({ ...prev, [unitId]: fitOut }))
setUnitSaving(prev => ({ ...prev, [unitId]: true }))
try {
await MockupUnitProvider.update(unitId, {
fitOut: (fitOut || undefined) as 'SHELL' | 'BASIC' | 'FULL' | 'PREMIUM' | undefined,
})
await queryClient.invalidateQueries({ queryKey: ['property', p.id] })
await queryClient.invalidateQueries({ queryKey: ['properties'] })
await queryClient.invalidateQueries({ queryKey: ['matches'] })
} catch {
showToast('Fehler beim Speichern des Ausbaustandards.', 'error')
} finally {
setUnitSaving(prev => ({ ...prev, [unitId]: false }))
}
}
return (
<>
<Divider sx={{ my: 2 }} />
@@ -213,9 +193,6 @@ export function PreMarketPanel({ p }: { p: Property }) {
unitSaving={unitSaving}
setUnitStates={setUnitStates}
saveUnit={saveUnit}
propertyFitOut={p.hardFacts?.fitOut}
unitFitOut={unitFitOut}
saveUnitFitOut={saveUnitFitOut}
/>
)}