Files
property-match/src/domain/need.ts
T
Benjamin Sutter 7a0909e36a feat: saved profiles — per-profile notifications, real match scores, action buttons
- Add per-profile notification config (toggle, score threshold, email) with Accordion UI in SavedNeedDetail
- NotificationButton: badge only lights up for unseen matches, dismisses on open (localStorage), uses per-profile minScore
- SavedNeedDetail: replace deterministicMatchScore with real match data (useMatchesByNeed), sort by score desc, deduplicate by property
- SavedProfilesTab & SavedNeedCard: top score bar now shows best real match score instead of criteria confidence
- "Treffer" count uses per-profile notificationConfig.minScore (≥80 default) consistently across card, panel, and notification badge
- Extract PropertyMatchRow to own file with Anfrage/Merken/Vergleichen/Details→/Zur Einheit→ action buttons
- Details → navigates to /demand/results/:matchId using real match ID format (m__propId__prop__needId)
- Add InquiryQuickDialog + AddToPipelineDialog to AISearch.tsx so dialogs work from SavedProfilesTab
- Org-isolation: useNeeds filters by organizationId, org-mobimo gets 4 own search profiles
- Mock data: all 18 org-wincasa need names changed to descriptive profile names; 4 new org-mobimo needs added
- useUpdateNeed mutation hook for updating need fields (notificationConfig etc.)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 20:53:49 +02:00

120 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { AssetType, MatchStatus } from './enums'
export interface AreaRange {
min: number
max: number
}
export interface BudgetRange {
minPerSqm?: number
maxPerSqm: number
maxMonthlyTotal?: number
currency: string
}
export interface Timing {
earliestMoveIn: string
latestMoveIn: string
contractDurationMonths?: number
flexibleTiming: boolean
}
export interface WeightingProfile {
area: number
location: number
budget: number
timing: number
prestige: number
accessibility: number
expansionPotential: number
flexibility: number
visibility: number
footfall: number
talentAccess: number
esg: number
taxEnvironment: number
[key: string]: number
}
export interface SoftFactorPreferences {
minPrestige?: number
minAccessibility?: number
requireParking?: boolean
maxPublicTransportMinutes?: number
preferredEsgRating?: string
requireHighVisibility?: boolean
}
export interface SizeRange {
minSqm: number
maxSqm: number
}
export interface MustHaveCriterion {
criterion: string
description?: string
weight?: number // 01, how much a miss hurts the score
}
export interface WeightedPreference {
criterion: string
weight: number // 01
idealValue?: string | number
description?: string
}
export interface NotificationConfig {
enabled: boolean
minScore: number // 0100, default 80
emailAddress?: string
}
export interface Need {
id: string
companyName: string
contactName?: string
assetType: AssetType
requiredArea: AreaRange
// F004 additions
desiredLocation?: string[] // preferred city/district list
sizeRange?: SizeRange // structured alias for requiredArea
mustHaveCriteria?: MustHaveCriterion[]
weightedPreferences?: WeightedPreference[]
status?: MatchStatus | 'ACTIVE' | 'INACTIVE' | 'DRAFT' | 'CLOSED'
preferredLocations: string[]
excludedLocations?: string[]
budgetRange: BudgetRange
timing: Timing
mustCriteriaText?: string[] // legacy — prefer mustHaveCriteria
// Structured requirement flags
requireGroundFloor?: boolean
requiredFitOut?: 'BASIC' | 'FULL' | 'PREMIUM'
requiredParkingMin?: number
requireAirConditioning?: boolean
requireLoadingDock?: boolean
requireBarrierFree?: boolean
minCeilingHeightM?: number
minContractDurationMonths?: number
searchRadius?: number
isAnonymous?: boolean
requiresDivisibility?: boolean
minDivisibleUnit?: number
fitOutBudgetMaxPerSqm?: number
softFactors?: SoftFactorPreferences
weightingProfile: WeightingProfile
confidenceInCriteria: number
extractedFromText?: string
notes?: string
notificationConfig?: NotificationConfig
organizationId?: string
createdAt: string
updatedAt: string
}
export type CreateNeedInput = Omit<Need, 'id' | 'createdAt' | 'updatedAt'>
export type UpdateNeedInput = Partial<CreateNeedInput>