Benjamin Sutter
|
6515acb7f0
|
feat: unified error handling + AI service modularisation
Error handling (Prompt 2):
- src/services/errors.ts: AppError class, normalizeError(), throwServiceError() helper
- 6 services wrapped with try/catch (property, match, need, shortlist, futureSignal, inquiry)
- inquiryService aligned from custom ServiceResult<T> to standard ServiceResponse types
- Results, MatchCenter, FutureAvailability pages show <ErrorState onRetry> on query failure
AI modularisation (Prompt 3):
- src/services/aiService.ts reduced from 755 → 19 lines (barrel re-export)
- src/services/ai/IAIService.ts: typed interface + all response types
- src/services/ai/mock/: needParser, compareBuilder, decisionBrief, listingParser, MockAIService
- src/services/ai/openrouter/OpenRouterAIService.ts: model-agnostic skeleton
- src/services/ai/prompts/: 4 prompt template files (needParsing, matchExplanation, compareSummary, decisionBrief)
- src/services/ai/index.ts: factory selects Mock or OpenRouter via VITE_USE_REAL_AI flag
- All existing import paths unchanged — zero call-site modifications
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-24 00:32:01 +02:00 |
|
Benjamin Sutter
|
13553f60a0
|
fix: close spec gaps — delete InquiryStatusBadge, extend match reasons, full field keys
- Delete InquiryStatusBadge.tsx (dead code after Part A read/unread migration)
- AdditionalPropertyMatch: add reasons[] + topUncertainty from positiveFactors/tradeoffs
- AdditionalMatchCard: render green reasons and amber uncertainty below match score
- ReportObjectFieldKey: add breakoutOptionDate, roomHeight, floorLoad, deliveryAccess,
goodsLift, passengerLift, internet, microLocation, competitionEnvironment,
infrastructure, marketSignals, negotiationHints, missingData (now 45 keys)
- ReportObjectFieldSelector: regroup into 5 spec-aligned groups (Basisdaten,
Miet-/Vertragsdaten, Technische Hard Facts, Soft Factors, Marktinformationen)
- LatentInquiryReportPreview: add labels for all new field keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-19 19:57:16 +02:00 |
|
Benjamin Sutter
|
b4d398270f
|
feat: Anfragencenter Parts A–E — read/unread, prep wizard, offer flow, report preview
- Part A: Replace InquiryStatus badges with WhatsApp-style unread indicators
(isRead, unreadCount, lastReadAt on Inquiry; markThreadAsRead in service + hook)
- Part B: RelatedPropertyCardPanel — reposition "Objekt ansehen", add "Weitere
Matches" section via matchService.getAdditionalMatchesForInquiry
- Part C: PreparationWizard 4-step dialog — property selection, report generation
progress, field editing + ReportObjectFieldSelector, PDF preview + finalize
- Part D: OfferCreationWizard 4-step dialog triggered from first tenant message —
data capture, field editing, viewing appointments, PDF generation + attach to reply
- Part E: LatentInquiryReportPreview (2-page A4 doc), ReportObjectFieldSelector
(5 accordion groups, 35+ optional fields), mapImageUrl on Property domain
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-19 19:20:13 +02:00 |
|
Benjamin Sutter
|
920ce8eb09
|
feat: Verwaltungszugang refactor — lease data, 3-tab detail, market signals
- Dashboard: remove QuickActionPanel, StrongMatchOverview, FutureSignalWidget,
DataQualityWidget, header buttons, Marktchancen nav; KpiGrid → 4 cards
- Property domain: 9 new fields (leaseTerm, leaseStartDate/End, breakoutOption,
currentTenant, importedFrom, importedAt, lastUpdatedAt)
- Mock data: annual CHF/m²/Jahr prices (×12), Swiss images, tenant/lease data
for all 10 VERIFIED_PORTFOLIO properties; need budgets updated to annual
- PropertyTable: swap columns — add Aktueller Mieter, Mietlaufzeit,
Breakoutoption, Breakoutoption Zeitpunkt; remove Verfügbarkeit, Konfidenz, Quelle
- PropertyDetailView: 3 tabs (Übersicht, Matchability, Marktsignale) with
inline edit mode, NeedMatchCard list, PropertyMarketSignalsTab
- New: marketReport domain + mock data + service, NeedMatchCard,
PropertyMarketSignalsTab with 4 sections + PDF button
- matchService: getNeedMatchesForProperty(propertyId, {minScore})
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-19 15:43:52 +02:00 |
|
Benjamin Sutter
|
7cf8d8ba72
|
feat: F012 match detail view
Full decision analysis page at /demand/results/:matchId:
- MatchDetailHeader: score, badges, CTA (compare/shortlist), back button
- ExecutiveSummaryPanel: 4-row summary (fit, top reason, tradeoff, next step)
- PropertyOverviewPanel: key facts grid; signal-aware for FUTURE_AVAILABILITY
- NeedAlignmentPanel: comparison table with fit indicators (MATCH/PARTIAL/NO_MATCH)
- ScoreBreakdownPanel: hard/soft scores + modifiers + total (sidebar)
- TradeoffPanel: severity-coded list with mitigation hints
- RiskPanel: risks sorted CRITICAL→LOW with category chips
- MissingInformationPanel: priority-grouped with per-item CTAs
- SourceProvenancePanel: source type, label, URL, freshness
- FutureAvailabilityContextPanel: mandatory disclaimer + signal metadata
- NextActionsPanel: engine-ranked actions + standard actions (sidebar)
- Details button on result cards now navigates to match detail
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-16 13:55:46 +02:00 |
|
Benjamin Sutter
|
3152de004c
|
feat: F009 matching engine V1 — deterministic multi-criteria scoring
domain/scoring.ts: HARD_FILTER thresholds, DATA_QUALITY/CONFIDENCE modifier tables, ScoringWeightProfile type, DEFAULT_SCORING_PROFILES for Office/Retail/Light Industrial/Logistics/Production/Default (all sum to 1.00), HARD/SOFT_CRITERION_KEYS, MatchEngineOutput type.
features/matching/scoreCalculator.ts: applyHardFilters (asset type mismatch, area < 85% min, budget > 150%, excluded region → hard exclude; occupied → severe penalty), scoreArea/Location/Budget/Timing as ScoreFactor, scoreSoftFactor for 9 keys mapped to property.softFactors, calcDataQualityModifier/calcConfidenceModifier, calculateScore (resolves profile from need.weightingProfile + default, runs filters, computes normalized hard/soft scores, applies modifiers, classifies positive/negative factors, assembles MatchEngineOutput).
features/matching/tradeOffAnalyzer.ts: analyzeTradeOffs (6 patterns: location-vs-budget, area-vs-budget, timing-vs-dataQuality, prestige-vs-flexibility, futureSignal-vs-location, accessibility-vs-commute), analyzeRisks (future signal, data quality, budget, occupied, low confidence, missing critical fields), identifyMissingData (rentPricePerSqm, availabilityDate, softFactors, hardFacts, need.budgetRange).
features/matching/rankingEngine.ts: matchStrengthFromScore (>=78 STRONG, >=52 MODERATE, else WEAK), generateNextBestActions (score-based, future signal SCHEDULE, missing data VERIFY), buildFullMatch → full Match entity with ScoreBreakdown + explainabilitySummary + uncertaintyIndicators, rankMatches (score desc → resultType order → confidence desc), computeRankedMatches batch helper.
services/matchService.ts: computeMatch(need, property) and computeMatchesForNeed(needId) wired to engine.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-16 12:54:45 +02:00 |
|
Benjamin Sutter
|
3cd2e83b25
|
feat: F007 property repository & detail view
- useProperties: added usePropertyById, usePropertyMatches, usePropertySignals hooks
- propertyService.getProperties(), matchService.getMatchesForProperty(),
futureSignalService.getSignalsForProperty() added
- PropertyFilterBar: asset type chips, availability select, sort select, search
- PropertyTable: sortable columns, row selection highlight, loading skeletons,
empty/error states, Eye/Plus/Bookmark actions
- PropertyCard: decision-object card with header, primary, matchability,
data quality and action zones; card states (selected, compareSelected,
stale, low-confidence)
- PropertyDetailView: 7-tab detail panel (Übersicht, Hard Facts, Soft Factors,
Matchability, Datenqualität, Quelle, Signale) with low-quality banner,
missing field UX, data update CTA
- PropertyDetailSkeleton: loading state
- Properties page: two-panel layout (table + sliding detail panel)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-15 16:53:51 +02:00 |
|
Benjamin Sutter
|
7b7be0b436
|
feat: F006 supply dashboard — complete spec implementation
- dataQualityService with getPortfolioQualitySummary()
- Service methods: getDashboardPropertiesSummary, getStrongMatches,
getSignalSummary, getDashboardTasks added to respective services
- dashboardService uses Promise.allSettled for partial error resilience
- KpiCard: onClick + Tooltip support
- KpiGrid: navigate actions and tooltips per card
- StrongMatchMiniCard: Match Center, Prüfung, Vergleichen action buttons
- FutureSignalWidget: time horizon distribution (0–6, 6–12, 12–24 Mo.)
- SupplyDashboard: DashboardHeader, empty state, error state,
partial widget errors, permission-based rendering per UserRole
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-05-15 16:31:54 +02:00 |
|
Benjamin Sutter
|
9e827c50f9
|
Initial commit
|
2026-05-15 00:48:18 +02:00 |
|