Commit Graph

3 Commits

Author SHA1 Message Date
Benjamin Sutter 9f7062d137 feat: UC-A/B/C demo — 50 mock properties, district scoring, gold/silver cards visible
- Add 50 mock properties (prop-050–099) tuned for UC-A (Fahrradhändler RETAIL),
  UC-B (Umzugsfirma OFFICE Zürich-West) and UC-C (Vermögensverwalter PREMIUM)
- District-aware scoreLocation: district match→100, city-only→70 when need
  specifies districts, canton→60, no match→35; fixes UC-C prop-001 over-scoring
- mustHaveScorer: add klimatisierung keyword; parking minimum count logic
- Soft factor scale fix: integer 0–100 values no longer multiplied ×100
- footfall: map passerbyFrequency string (HIGH→85, MEDIUM_HIGH→68…) before
  enrichment fallback so RETAIL properties score correctly
- Parser: Kreis list extraction ("Kreis 3, 4, 5, und 8" → 4 district entries),
  neighbourhood→district map (Seefeld, Bahnhofstrasse), prestige signals
- Results: remove VERIFIED_PORTFOLIO role gate — all users see portfolio cards,
  enabling gold (85+) and silver (70–84) cards for every demo use case
- Fix flash of wrong cards on NeedBuilder nav (effectiveNeedId not activeNeed?.id)
- needs.ts: UC-A preferredLocations now includes Kreis 3/4/5/8 entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 20:31:30 +02:00
Benjamin Sutter 3756675b6f feat: add Maison Work source type, rename ExternalMarket to Direktinserat, hide own portfolio from demand search by default
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 23:02:05 +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