Benjamin Sutter
a825672197
feat: collapsible filter bar, compact property cards, offer wizard field selection
...
- Properties page: collapsible decision/filter strip (localStorage state), slim
single-row Datenpflege status bar (chips + button), 4-column card grid
- PropertyIntelligenceCard: reduced image height (160→120px), tighter body padding
- OfferWizard (latente Anfragen): new "Felder wählen" step between property
selection and PDF preview; uses ReportObjectFieldSelector per property
- MockPdfPreview: adds second PDF page showing selected properties side by side
with photo, title, location and all chosen hard/soft fact fields
- offerWizardStore: adds select_fields step type and fieldSelections state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-26 15:36:32 +02:00
Benjamin Sutter
36570c5bdc
fix: resolve all TypeScript errors and refactor oversized components
...
- Fix MUI v9 API: PaperProps/InputLabelProps/inputProps → slotProps in 6 components
- Add ExternalMarketResult alias, PropertyUnit import, OPERATIONS workspace config
- Fix TradeOff.description → .concern, ScoreFactor.label → .criterion
- Make schattenmarktRelease.leadTimeMonths optional, fix mock-data enum values
- Fix useMatchDetailData query typing, weightingService missing WeightProfile keys
- Split Pipeline/Compare/MatchDetail/IntelligenceMatchCard into sub-components
- Fix all test fixtures (CreateNeedInput, CreatePropertyInput, TradeOffInput, etc.)
- Add vercel.json for deployment, zero tsc errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-26 00:08:35 +02:00
Benjamin Sutter
e1f4beb898
refactor: architecture compliance pass — DS tokens, hook boundary, god component split, AI hardening
...
- DS token migration: Anfragen.tsx + child components (AnfragenInquiryItem, AnfragenMessageBubble)
fully migrated; DS_TEXT.brandDark added; scoreTheme.ts moved to src/lib/ with re-export proxy
- Hook boundary: Results.tsx no longer calls needService directly — routes through useNeeds()
with optional refetchOnMount/gcTime overrides
- NewListing.tsx (440L) split into useNewListingForm hook + 8 section components under
src/components/new-listing/; page shell reduced to 121 lines
- AI hardening: Zod .strict() on all schemas, AIProvenance extended with schemaVersion/
fallbackReason/traceId/latencyMs, AITraceStore stats with p50/p90/p99 + failure breakdowns,
MockAIService buildFollowUpQuestions with priority ordering + area-ambiguity detection,
prompt templates updated (LIGHT_INDUSTRIAL, budget unit, ambiguity detection, decimal precision)
- Tests: all 154 passing; fixed test regression caused by OfferEmailResponseSchema body min(50)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 16:10:39 +02:00
Benjamin Sutter
e36c5bc979
refactor(arch): eliminate direct service calls in components — route all through hooks
...
New hook files:
- useAuth.ts: useLogin, useSwitchDemoRole, useSwitchOrganization
- useAI.ts: useParseNeed, useGenerateOfferEmail, useGenerateDecisionBrief, useParseListingText
- useAssistant.ts: useAssistantSuggestions (useQuery), useAssistantAnswer (useMutation)
- useOfferReport.ts: useOfferReportByInquiry, useCreateOfferReport, useUpdateOfferReport, useGenerateOfferReportPdf
- useInquiryReport.ts: useInquiryReportByInquiry, useCreateInquiryReport, useUpdateInquiryReport, useFinalizeInquiryReport
- useMarketReport.ts: useMarketReport
- useWeighting.ts: useDefaultWeights (synchronous wrapper)
- useUnitMatches.ts: useUnitMatchesMap, useUnitBundle, useBundleMatches (useMemo wrappers)
Extended hooks: useProperties (add update/create/remove mutations),
useNeeds (add useCreateNeed), useMatches (add useNeedMatchesForProperty,
useAdditionalMatchesForInquiry), useReviewQueue (add useCreateReviewTask)
Updated 21 components/pages: all direct service imports replaced with hooks.
Deliberate exception: getRecommendedActions in DataQuality.tsx (pure sync utility, no provider access).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 14:56:32 +02:00
Benjamin Sutter
f487435a94
fix: correct rent unit labels and monthly/annual calculation consistency
...
- NeedAlignmentPanel: display budget row in monthly (CHF/m²/Mt.) to match
the Preis section, use exact division (no Math.round) to avoid 13×12≠152
- MatchDetailPropertySections + PropertyDetailPublicSections: replace
Math.round(rentPricePerSqm/12) with exact division; show 2 decimal places
when monthly is not a whole number (e.g. CHF 12.67 instead of CHF 13)
- Add /Jahr suffix to all 15 displays showing rentPricePerSqm or maxPerSqm
without a time unit across results, compare, match-detail, supply, and
anfragencenter components
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 14:35:20 +02:00
Benjamin Sutter
a3fc213916
refactor: extract helpers from ReminderDetailDrawer + OfferCreationWizard
...
- ReminderDetailDrawer (340→257 lines): constants + SectionTitle/DateRow/ActivityEntry → reminderDetailHelpers.tsx
- OfferCreationWizard (350→276 lines): PDF step JSX → OfferWizardPdfStep.tsx
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-24 01:10:31 +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
14badd1ca8
feat: all 4 UX priorities — wizard, examples, onboarding, pipeline
...
- Offer wizard: 4→3 steps by merging 'Prüfen' into PDF review step
- Search mask: quick-select chips for area ranges, budget, and city presets
- Onboarding: WelcomeDialog (3 slides, localStorage) on first visit
- Deal Pipeline: Kanban board (6 stages, 8 mock items, advance-to-next-stage)
added to demand workspace navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-18 22:09:06 +02:00
Benjamin Sutter
a75818b983
feat: full responsive layout — mobile sidebar, stacked panels, fullscreen drawers
...
- AppShell: permanent sidebar on desktop, temporary drawer + hamburger on mobile (<md)
- TopBar: hamburger icon on mobile, AI-Assistent als Icon-Button auf kleinen Screens
- MatchDetail: Sidebar stacks below content on mobile, key facts wrap, px responsive
- Properties: Drawer fullscreen (100vw) on mobile, 650px on desktop
- ActiveInquiriesTab: mobile shows list → tap opens detail with back button
- LatentInquiriesTab: mobile sequential navigation (list → detail → own properties), tablet 2-col, desktop 3-col
- PublicNeedList: fullWidth prop for mobile layout
- InquiryDetailPanel: property card stacks below chat on mobile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-18 21:24:00 +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