feat: Objekt→Einheit architecture — unit-level pre-market, property detail page, click-through from cards

- Domain: PropertyUnit extended with propertyId + schattenmarktRelease per unit
- Domain: FutureAvailabilityResult carries resolved property + unit
- useSchattenmarktSignals: generates unit-level signals (schattenmarkt-{propId}-{unitId})
- useUnifiedResults: resolves backing property + unit on FUTURE_AVAILABILITY fast path
- IUnitProvider + MockupUnitProvider: first-class unit access and mutation
- matchCardAdapter: maps preMarketUnit, preMarketAllUnits, propertyId, unitId to ViewModel
- IntelligenceMatchCard: PRE-MARKET VERIFIED shows unit info strip + "Zur Einheit →" button
- PropertyDetailView: unit-level toggles + date pickers inside PreMarketPanel
- New page: /demand/property/:propertyId with unit table, status chips, inquiry form
- App.tsx: demand route /demand/property/:propertyId registered
- Mock data: prop-001/007/037 units updated with correct lease dates + unit-level schattenmarktRelease

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-20 19:47:59 +02:00
parent 66aabde1dc
commit d902feb6c0
14 changed files with 578 additions and 18 deletions
+7
View File
@@ -0,0 +1,7 @@
import type { PropertyUnit } from '../domain/property'
export interface IUnitProvider {
getByPropertyId(propertyId: string): Promise<PropertyUnit[]>
getById(unitId: string): Promise<PropertyUnit | null>
update(unitId: string, data: Partial<PropertyUnit>): Promise<PropertyUnit>
}
+28
View File
@@ -0,0 +1,28 @@
import type { IUnitProvider } from './IUnitProvider'
import type { PropertyUnit } from '../domain/property'
import { propertyStore } from './MockupPropertyProvider'
function getAllUnits(): PropertyUnit[] {
return propertyStore.flatMap(p =>
(p.units ?? []).map(u => ({ ...u, propertyId: u.propertyId ?? p.id })),
)
}
export const MockupUnitProvider: IUnitProvider = {
async getByPropertyId(propertyId: string) {
const prop = propertyStore.find(p => p.id === propertyId)
return (prop?.units ?? []).map(u => ({ ...u, propertyId }))
},
async getById(unitId: string) {
return getAllUnits().find(u => u.id === unitId) ?? null
},
async update(unitId: string, data: Partial<PropertyUnit>) {
for (const prop of propertyStore) {
const idx = (prop.units ?? []).findIndex(u => u.id === unitId)
if (idx === -1) continue
prop.units![idx] = { ...prop.units![idx], ...data }
return prop.units![idx]
}
throw new Error(`Unit ${unitId} not found`)
},
}