export type SignalCategory = 'development' | 'demand' | 'supply' | 'negotiation' export interface PropertyMarketSignal { id: string category: SignalCategory title: string body: string source?: string sourceUrl?: string date?: string confidence?: number } // Key market performance indicators for a given radius. // Base values are stored at 5 km; other radii are computed via getKpisForRadius(). export interface MarketKpis { vacancyRatePct: number // % of comparable properties currently vacant activePlatformSearches: number // active search requests on the platform avgVacancyMonths: number // average months comparable properties remain vacant demandSupplyRatio: number // demand / supply ratio (> 1 = more demand than supply) comparableListings: number // number of comparable active listings } /** Scale base KPIs (at 5 km) for a larger radius. */ export function getKpisForRadius(base: MarketKpis, radiusKm: number): MarketKpis { const f = radiusKm / 5 return { vacancyRatePct: +Math.min(35, base.vacancyRatePct + (f - 1) * 1.8).toFixed(1), activePlatformSearches: Math.round(base.activePlatformSearches * f * 0.85), avgVacancyMonths: +Math.min(24, base.avgVacancyMonths * (1 + (f - 1) * 0.12)).toFixed(1), demandSupplyRatio: +Math.max(0.3, base.demandSupplyRatio / (1 + (f - 1) * 0.18)).toFixed(1), comparableListings: Math.round(base.comparableListings * f * 1.1), } } export interface MarketReport { propertyId: string generatedAt: string assetTypeLabel: string // e.g. "Büro" kpis: MarketKpis // base values at 5 km radius signals: PropertyMarketSignal[] }