Commit Graph

20 Commits

Author SHA1 Message Date
Benjamin Sutter 99e99d66c5 feat: unit-level matching architecture — match against Einheiten, not Objekte
- domain/property: add getEffectiveUnits() — returns explicit units or synthesises
  one from property-level data so all properties work uniformly at unit level
- domain/match: add unitId? field — every Match references a specific unit
- domain/unifiedResult: add unit? to VerifiedPortfolioResult + ExternalMarketResult
- MockupNeedProvider: generateSyntheticMatches iterates getEffectiveUnits(prop);
  computeScore uses unit-level areaSqm + rentPricePerSqm; resultId for PRE-MARKET
  signals matches useSchattenmarktSignals signal ID format
- useUnifiedResults: resolve unit from match.unitId for VERIFIED_PORTFOLIO/EXTERNAL_MARKET
- matchCardAdapter: unit now extracted for all result types; unitId from match.unitId
- IntelligenceMatchCard: regular cards show unit chip (floor + label + m²) when a
  named unit is known — only adds context, never shows for synthetic/whole-property units

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 20:03:54 +02:00
Benjamin Sutter d902feb6c0 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>
2026-05-20 19:47:59 +02:00
Benjamin Sutter b0ad6643ff feat: Future Availability — Logiktrennung Supply/Demand + Markt-Leads
EXPANSION-Signale (Unternehmen sucht Fläche) sind Nachfragesignale und
gehören nicht in den Demand-Feed. Neue Architektur:

- signalDirection: 'SUPPLY' | 'DEMAND' auf FutureSignal-Domain
- SUPPLY-Signale: POSSIBLE_MOVE_OUT / CONSTRUCTION_PROJECT (Crawler)
  und LEASE_EXPIRY+isVerified (Verwaltung ERP) → Demand-Feed wie bisher
- DEMAND-Signale: EXPANSION → aus Demand-Feed gefiltert
- Neues useMarketLeads-Hook + /supply/market-leads Seite für Verwaltung:
  zeigt EXPANSION-Signale als potenzielle Mieter mit Portfolio-Matching
- Alle 15 Signale in futureSignals.ts inhaltlich bereinigt und
  mit korrekter signalDirection versehen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 15:56:29 +02:00
Benjamin Sutter 5fe15bac62 feat: Future Availability Intelligence — rebrand & card redesign
Replaces "Schattenmarkt" branding with professional Future Availability
Intelligence throughout the UI. Two distinct card types: Pre-Market
(LEASE_EXPIRY + verified, green accent) and Market Signal (probabilistic,
blue accent). Professioneller Data-Header replaces dark purple gradient.
New detail panel sections: Erkannte Marktindikatoren, Strategische
Interpretation, Bestätigt/Nicht bestätigt. All 15 mock signals enriched
with concrete Swiss CRE market indicators and strategic interpretations.
Signal quality shown as 4-dot indicator (Hoch/Mittel/Niedrig).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 13:06:16 +02:00
Benjamin Sutter 9f391d17cb feat: Reminder Manager + Schattenmarkt-Freigabe + mock data overhaul
- Add Reminder Manager page (/supply/reminder-manager) with KPI bar,
  filter bar, list/card feed, and detail drawer (7 sections incl.
  activity log, snooze, complete, dismiss actions)
- Add Schattenmarkt-Freigabe toggle on PropertyDetailView: Verwaltung
  can opt-in properties for early market exposure before contract expiry
- Auto-generate FutureSignal cards via useSchattenmarktSignals hook
  when leaseEndDate - leadTimeMonths <= MOCK_TODAY
- Fix useUnifiedResults: use property.resultType as fallback (was
  defaulting everything to VERIFIED_PORTFOLIO)
- Fix demand Results: hide VERIFIED_PORTFOLIO from non-manager users
  even when showOwnProperties toggle was previously enabled
- Fix AppShell: redirect to allowed workspace on user role switch
- Fix 3 wrong match scores (match-002: 93→62, match-009: 86→55,
  match-017: 87→52)
- Add 7 new match records (match-050–056) for need-001, need-002,
  need-011
- Add need-011 (Retail Bern Innenstadt)
- Add prop-031–036 (EXTERNAL_MARKET / MAISON_WORK / FUTURE_AVAILABILITY)
- Fix duplicate image URLs across all properties
- Add signal-011 (Bern Altstadt, Mode Boutique) + propertyId to
  signal-001

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 11:52:24 +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 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 fdf4de37db feat: Aktivitätslog tab in PropertyDetailView — per-property timeline
Adds a new "Aktivitätslog" tab (9th tab) to the supply-side property
drawer. Shows match approvals/rejections, need registrations, data
quality flags, and governance actions linked to this specific property.
Only visible to Verwaltung users in their own property view.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:12:50 +02:00
Benjamin Sutter c4c29ef7d3 feat: F030 Anfragencenter — Aktive & Latente Anfragen + Angebot-Wizard
Neuer Menüpunkt «Anfragencenter» (ehemals «Eingehende Bedarfe»):

Aktive Anfragen:
- Split-View: Anfrageliste (Liste/Grid-Toggle) + Chat-Detailansicht
- Chat-Verlauf mit Sender-Styling (Mieter links, Supply rechts)
- Antwortformular mit Betreff, Nachricht, Anhänge, Statuswechsel
- Zugehörige Property Card neben dem Chat

Latente Anfragen:
- Drei-Spalten-Layout: Need-Liste | Need-Detail | Eigene Objekte
- Need Cards mit AI-Zusammenfassung, Must-Haves, Präferenzen
- Eigene Portfolio-Objekte sortiert nach deterministischem Match-Score
- Checkbox-Selektion für Angebotsauswahl

Angebot-Wizard (4 Schritte):
- Schritt 1: Objekte auswählen (mit Score-Vorschau)
- Schritt 2: PDF-Vorschau + editierbare Textfelder
- Schritt 3: Angebot prüfen & bestätigen
- Schritt 4: Nachricht an Suchenden mit KI-generierter Mail

Architektur:
- Domain: Inquiry, LatentNeed, OfferDraft Types
- Provider: IInquiryProvider, ILatentNeedProvider, IOfferProvider + Mockups
- Services: inquiryService, latentNeedService, offerService
- Hooks: useInquiries, useLatentNeeds, useOffers (TanStack Query)
- Store: offerWizardStore (Zustand, lokaler Wizard-State)
- 27 neue Komponenten, alle Loading/Empty/Error States

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:03:05 +02:00
Benjamin Sutter 71f4b1eeb6 feat: F019 AI monitoring layer — output transparency & governance workspace
Full 2-panel workspace at /ops/ai-monitoring: metrics strip (total, failed,
pending, approval rate, top prompt version, active model), filterable output
table by type/status/error, and detail panel with output preview, prompt
versioning, error details, and role-aware review actions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:11:35 +02:00
Benjamin Sutter 5d3323617c feat: F018 human review queue — 2-panel governance workspace
Replaces the old ad-hoc ReviewQueue page with a full governance-compliant
workflow: filterable task list, detail panel with confidence/risk context,
role-aware approve/reject/escalate/more-data actions, and persistent notes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:03:34 +02:00
Benjamin Sutter 2e68638246 feat: F016 future availability workspace
2-panel workspace at /supply/future-availability: filterable signal list with FutureSignalCard (type/sensitivity/review badges + mandatory disclaimer) and collapsible detail panel with full evidence, review workflow (IN_REVIEW→APPROVED/REJECTED), shortlist action, and review task creation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 21:19:52 +02:00
Benjamin Sutter 65130efca7 feat: F015 shortlist management
3-panel Shortlists page with left list, center detail, right decision brief panel. AddToShortlistDialog wired into result feed cards and match detail. Full DRAFT→REVIEW_READY→FINALIZED workflow, AI-generated decision brief draft, duplicate prevention, and compare-view integration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 21:10:06 +02:00
Benjamin Sutter cb18f3c381 feat: F021 market intelligence & signal discovery
Signal domain types, mock data (8 signals), provider interface + MockupMarketIntelligenceProvider, marketIntelligenceService, TanStack Query hooks, 10 ops components (SignalInbox, MarketSignalCard, MarketSignalFilterBar, MarketSignalSkeleton, MarketSignalEmptyState, SignalConfidenceBadge, SourceReliabilityBadge, SensitivityWarningPanel, SignalConversionPanel, SignalEvidenceList), MarketIntelligence page wired into AppShell nav and App router.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:07:58 +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 46acca9e62 feat: F006 supply dashboard — KPI grid, strong matches, data quality, future signals, review tasks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:08:49 +02:00
Benjamin Sutter c65e565dc7 feat: F023 signal-to-match pipeline & shadow market decision flow 2026-05-15 15:52:53 +02:00
Benjamin Sutter fce0f684af feat: F022 source acquisition, crawling & connector abstraction 2026-05-15 15:32:53 +02:00
Benjamin Sutter 5ef8b9d69d feat(services): F005 – complete service layer
New domain types:
- shortlist.ts: Shortlist, ShortlistItem, CreateShortlistInput
- review.ts: ReviewQueueItem, ReviewPriority, ReviewQueueStatus

New mock data:
- shortlists.ts: 2 sample shortlists
- reviewQueue.ts: 3 pending review items

New providers (interface + mockup):
- IShortlistProvider / MockupShortlistProvider (with 150ms latency)
- IReviewProvider / MockupReviewProvider (priority-sorted, with latency)
- IDashboardProvider / MockupDashboardProvider (computed from all mock data)

New services:
- reviewService: getQueue, approve, reject, assign
- shortlistService: CRUD + addItem/removeItem
- authService: wraps sessionStore, swappable for real auth
- dashboardService: getStats(organizationId?)

Enhancements:
- types.ts: typed ServiceErrorCode + ServiceError, Pagination alias
- aiService.ts: openRouterAIService stub (throws ai_generation_failed)
- lib/mockUtils.ts: mockDelay(ms) utility

New hooks:
- useUnifiedResults(needId?): joins matches+properties+signals → UnifiedMatchResult[]
- useReviewQueue: + useApproveReviewItem + useRejectReviewItem
- useMatchDetail, usePropertyDetail, useNeedProfiles aliases

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:12:06 +02:00
Benjamin Sutter 3b45b0c121 feat(F020): frontend infrastructure foundation
- src/lib/constants.ts: centralized route paths, labels, thresholds
- src/lib/utils.ts: formatting, color helpers, math utils
- src/hooks/: useProperties, useMatches, useFutureSignals, useNeeds
- src/components/scores/MatchScoreRing
- src/components/data-quality/DataQualityBar
- src/components/future-signals/SignalTypeBadge
- src/components/cards/SourceTypeBadge
- src/provider/AuthProvider (placeholder, swappable)
- main.tsx: AuthProvider + centralized stale time

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 10:50:26 +02:00