Commit Graph

7 Commits

Author SHA1 Message Date
Benjamin Sutter d200d4e930 feat(agenten): Runde 4 — «Meine Agenten» mit fünf digitalen Mitarbeitenden
Setzt das Umsetzungsbriefing Runde 4 im bestehenden Frontend um.

Informationsarchitektur
- «Teamübersicht» heisst «Meine Agenten»; ihr bisheriger Inhalt (Kreisgrafik,
  Auswertung, Verbindungszusammenfassung) ist entfallen.
- Personalverwaltung, Bearbeitungsverlauf und Kanäle & Systeme sind jetzt
  Reiter derselben Seite (?section=), gestaltet wie die Auswahl im
  Bearbeitungsverlauf. Es wird nur der gewählte Bereich gerendert.
- Die alten Unterseitenpfade leiten um, damit Lesezeichen nicht brechen.

Agentenbestand
- Reto und Lea vollständig entfernt — aus Navigation, Dossiers, Protokoll,
  Verbindungen, Vorgängen und Porträtbestand.
- Retos Aufgaben liegen bei Bruno: Nachbereitung, WhatsApp-Anruf,
  Protokoll und Kundennotiz, Ablage im CRM.
- Livia ist «Exposé Master»: Lageberichte, Inserate, Angebotsbroschüren.
- Sidebar führt Ferdi, Bruno, Livia, Nora, Sina mit Porträt und Funktion.

Agentenseiten
- Ein gemeinsamer AgentWorkspaceHero auf allen fünf Seiten.
- Ferdi: Auswertungskarten, Priorität und Typfarben entfallen; Fälligkeit nur
  bei fünf Tagen oder weniger rot; Objektlinks nach «Meine Objekte»; neu die
  Terminplanung im verbundenen Kalender mit typgerechtem PDF-Ausschnitt.
- Sina: reduzierte, filter- und sortierbare Objektübersicht; Detailansicht
  direkt editierbar, leere Pflichtfelder rot umrandet.
- Nora: Signale ohne Prozentsätze und Konfidenzstufen, nur belegbare Angaben;
  Mehrfachauswahl leitet Objekte an Livia weiter.
- Livia: aktive und archivierte Leads, Arbeitsbereich gleitet an den oberen
  Rand; dreistufiger Exposé-Prozess Hochladen → Exposé → Export.
- Bruno: neue Seite mit Auftragsliste und Vor-/Nachbereitungs-Drawer;
  Glocke warnt bei Besichtigung unter 24 Stunden ohne Bericht.

Datenschicht
- Neu: Kalender, Exposé-Leads, Exposé-Entwürfe, Besichtigungsaufträge —
  je Domain, Provider, Service und Hook.
- IAIService um generateExposeText erweitert; der Entwurf nutzt ausschliesslich
  erfasste Objektdaten und meldet Lücken, statt sie zu füllen.
- Alle Objektverweise zeigen auf reale Einträge aus «Meine Objekte»; neue
  Detailroute /supply/properties/:propertyId.

Offen: Chat, Kalender, CRM und DMS sind Frontend-Simulation ohne Anbindung.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 14:43:16 +02:00
Benjamin Sutter e169f8e310 feat(matching): annuity-based fit-out cost in score + fix unapplied DQ/confidence modifiers
Mieterausbau / fit-out economics — surface true total cost of occupancy:
- Annuity calc (annuityFactor + effectiveAnnualBurdenPerSqm) replaces straight-line ÷5; FITOUT_ANNUITY_RATE=5%
- New hardFacts.fitOutByLandlord: "Wer baut aus?" toggle in NewListing — landlord-borne fit-out is priced into rent (no surcharge), tenant-borne SHELL/BASIC adds annuitized cost minus MAB
- scoreBudget now compares effective annual burden (rent + fit-out annuity) vs budget instead of cold rent only; FULL/PREMIUM and landlord-borne unchanged
- FitOutCostPanel + CompareTableBody compute annuitized, tenant-aware burden
- Central FIT_OUT_LABELS with industry/international vocabulary (Rohbau·Core&Shell, Edelrohbau·CAT A, etc.)
- Activate existing generateFitOutAdvice via useFitOutAdvice hook + new FitOutAdvicePanel (MIETERAUSBAU/BKZ/MAB-Amortisation + negotiation tip), shown for tenant-borne SHELL/BASIC
- MAB field only asked when tenant builds out (optional) — one new toggle, no extra data burden for property managers

Fix: DQ/confidence modifiers were computed but never applied to finalScore (hardcoded 0 in output) — now folded into rawFinal and exposed. Trust-first: weak data quality lowers the score. Resolves 3 pre-existing red tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 18:19:58 +02:00
Benjamin Sutter da50f3b5ea feat: premium redesign — DM Serif, refined palette, flat score badges
- Design tokens (ds.ts, theme.ts, scoreTheme.ts): new warm palette
  (#152642 navy, #f9f8f6 warm white, #e8e7e4 borders, #b8975a gold accent),
  flat score tier badges replacing CSS gradients, Inter + DM Serif Display typography
- Card components: white-background cards, DM Serif score numbers, max-2 badge
  chips with +N overflow tooltip, editorial score badge positioning
- Layout shell: gold left-accent nav active state, 64px top bar, outlined
  workspace chip, DM Serif page titles
- Shared atoms: GenericBadge (outlined/solid variants), ResultFilterBar
  (simplified chip styles), DecisionContextPanel (dot metrics, no left accent)
- Global replacement (118 files): #1e3a5f→#152642, #e2e8f0→#e8e7e4,
  #f4f6f9→#f9f8f6 — all handled via Node.js for proper UTF-8 safety

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:26:30 +02:00
Benjamin Sutter 87ea4c4dfc fix: clear stale search criteria on text edit, fix Zürich false-positive, improve cost breakdown and fit-out labels
- AISearch: clear parsed criteria when user manually edits text input so stale locations (e.g. Zürich) no longer persist after retyping
- needParser: fix ZURICH_SIGNALS substring bug — "kreis N" now uses word-boundary regex so "umkreis 22" no longer matches "kreis 2"
- CompareTableBody: row 9 shows full cost breakdown (Miete + NK + amortised fit-out) using FITOUT_AMORTIZATION_YEARS from constants
- FitOutCostPanel: replace local AMORTIZATION_YEARS with FITOUT_AMORTIZATION_YEARS from constants.ts (single source of truth)
- constants.ts: add FITOUT_AMORTIZATION_YEARS = 5 — change here to affect all cost calculations
- PropertyIntelligenceCard: translate raw fitOut enum to German labels (Rohbau/Grundausbau/Vollausbau/Premium-Ausbau) with explanatory tooltips; add tooltip on contract duration chip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 17:32:25 +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 7f090a48ff refactor: replace hardcoded hex colors with design tokens across priority components
- Add DS_COLORS.heat, DS_COLORS.futureCard, INQUIRY_STATUS_META tokens to ds.ts
- Eliminate 4 duplicate RESULT_TYPE_META / TYPE_META constants (now all use ds.ts)
- Eliminate 3 duplicate scoreColor / SCORE_COLOR functions (now all use matchScoreHex)
- HeatBadge: use DS_COLORS.heat.VERY_HOT / HOT tokens
- FutureAvailabilityCard: use DS_COLORS.futureCard.controlled / signal tokens
- IntelligenceMatchCard: import RESULT_TYPE_META from ds.ts, remove primary override
- MatchScoreDisplay: replace local scoreColor() with matchScoreHex()
- CompareColumnHeader: remove local TYPE_META + SCORE_COLOR, use ds.ts + utils.ts
- CompareTableBody: import RESULT_TYPE_META + matchScoreHex, fix #7c3aed → token
- compareUtils: remove TYPE_META + SCORE_COLOR, use dataQualityHex in scoreBar
- Anfragen + AnfragenInquiryItem: deduplicate STATUS_CONFIG → INQUIRY_STATUS_META
- Anfragen: #1e3a5f → 'primary.main', KI alert → futureCard.controlled tokens
- AnfragenMessageBubble: own-message bubble → 'primary.main', AI bubble → tokens
- ScoreBreakdownPanel: #1e3a5f → 'primary.main', #6d28d9 → futureCard.controlled
- ESLint: add warn rule against new hex colors in component sx props

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 13:02:01 +02:00
Benjamin Sutter c6055f0611 refactor: extract CompareTableBody from Compare.tsx (441 → 147 lines)
Move 18 inline table row definitions into CompareTableBody component

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 01:13:59 +02:00