From b0ad6643ff285ad06a61dae6ae75e712cdf15e65 Mon Sep 17 00:00:00 2001 From: Benjamin Sutter Date: Wed, 20 May 2026 15:56:29 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Future=20Availability=20=E2=80=94=20Log?= =?UTF-8?q?iktrennung=20Supply/Demand=20+=20Markt-Leads?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/App.tsx | 2 + src/components/layout/AppShell.tsx | 1 + src/domain/futureSignal.ts | 6 + src/hooks/useMarketLeads.ts | 37 ++ src/hooks/useUnifiedResults.ts | 4 +- src/mock-data/futureSignals.ts | 525 ++++++++++++++++------------- src/pages/supply/MarketLeads.tsx | 296 ++++++++++++++++ 7 files changed, 626 insertions(+), 245 deletions(-) create mode 100644 src/hooks/useMarketLeads.ts create mode 100644 src/pages/supply/MarketLeads.tsx diff --git a/src/App.tsx b/src/App.tsx index 4df412e..afa83c4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,6 +26,7 @@ const Anfragencenter = lazy(() => import('./pages/supply/Anfragencenter')) const FutureAvailability = lazy(() => import('./pages/supply/FutureAvailability')) const DataQuality = lazy(() => import('./pages/supply/DataQuality')) const ReminderManager = lazy(() => import('./pages/supply/ReminderManager')) +const MarketLeads = lazy(() => import('./pages/supply/MarketLeads')) const AISearch = lazy(() => import('./pages/demand/AISearch')) const Results = lazy(() => import('./pages/demand/Results')) @@ -58,6 +59,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/src/components/layout/AppShell.tsx b/src/components/layout/AppShell.tsx index 8865ce8..e07056b 100644 --- a/src/components/layout/AppShell.tsx +++ b/src/components/layout/AppShell.tsx @@ -84,6 +84,7 @@ const WORKSPACE_CONFIG: Record = { { path: '/supply/dashboard', label: 'Übersicht', icon: LayoutDashboard }, { path: '/supply/properties', label: 'Meine Objekte', icon: Building2 }, { path: '/supply/reminder-manager', label: 'Reminder Manager', icon: BellRing }, + { path: '/supply/market-leads', label: 'Markt-Leads', icon: Target }, { path: '/supply/anfragen', label: 'Anfragencenter', icon: MessageSquare }, { path: '/supply/data-quality', label: 'Datenpflege', icon: CheckSquare }, { path: '/supply/market-intelligence', label: 'Markt Intelligence', icon: Radar }, diff --git a/src/domain/futureSignal.ts b/src/domain/futureSignal.ts index 35d8820..f2cdf00 100644 --- a/src/domain/futureSignal.ts +++ b/src/domain/futureSignal.ts @@ -49,4 +49,10 @@ export interface FutureSignal { strategicInterpretation?: string // "Die Signale deuten auf ..." confirmedFacts?: string[] // ["Region bestätigt", ...] unconfirmedFacts?: string[] // ["Exakte Fläche unbekannt", ...] + + // Signal direction + // SUPPLY = space will become available → shown in demand feed + // DEMAND = company is looking for space → shown as Markt-Lead in Verwaltung + // undefined = treated as SUPPLY (backwards compat for generated signals) + signalDirection?: 'SUPPLY' | 'DEMAND' } diff --git a/src/hooks/useMarketLeads.ts b/src/hooks/useMarketLeads.ts new file mode 100644 index 0000000..2257e6a --- /dev/null +++ b/src/hooks/useMarketLeads.ts @@ -0,0 +1,37 @@ +import { useMemo } from 'react' +import { useFutureSignals } from './useFutureSignals' +import { useProperties } from './useProperties' +import type { FutureSignal } from '../domain/futureSignal' +import type { Property } from '../domain/property' + +export interface MarketLead { + signal: FutureSignal + matchingProperties: Property[] +} + +export function useMarketLeads(): { data: MarketLead[]; isLoading: boolean } { + const { data: signals = [], isLoading: signalsLoading } = useFutureSignals() + const { data: properties = [], isLoading: propertiesLoading } = useProperties() + + const data = useMemo((): MarketLead[] => { + const demandSignals = signals.filter(s => s.signalDirection === 'DEMAND') + + return demandSignals.map(signal => { + const signalCity = signal.locationHint.split(',')[0].trim().toLowerCase() + + const matchingProperties = properties.filter(p => { + if (p.resultType !== 'VERIFIED_PORTFOLIO') return false + const propCity = (p.location?.city ?? '').toLowerCase() + const cityMatch = propCity.includes(signalCity) || signalCity.includes(propCity) + const areaOk = signal.areaSqmEstimate + ? p.areaSqm >= signal.areaSqmEstimate * 0.5 && p.areaSqm <= signal.areaSqmEstimate * 2.2 + : true + return cityMatch && areaOk + }) + + return { signal, matchingProperties } + }) + }, [signals, properties]) + + return { data, isLoading: signalsLoading || propertiesLoading } +} diff --git a/src/hooks/useUnifiedResults.ts b/src/hooks/useUnifiedResults.ts index 29c9bf9..59f5b28 100644 --- a/src/hooks/useUnifiedResults.ts +++ b/src/hooks/useUnifiedResults.ts @@ -37,7 +37,7 @@ export function useUnifiedResults(needId?: string) { // Fast path: explicit FUTURE_AVAILABILITY on the match (no property lookup needed) if (match.resultType === 'FUTURE_AVAILABILITY') { const signal = allSignals.find(s => s.id === refId || s.propertyId === refId) - if (!signal) return [] + if (!signal || signal.signalDirection === 'DEMAND') return [] return [{ matchId: match.id, needId: match.needId, matchScore: match.matchScore, resultType: 'FUTURE_AVAILABILITY', signal, match }] } @@ -51,7 +51,7 @@ export function useUnifiedResults(needId?: string) { if (rt === 'FUTURE_AVAILABILITY') { const signal = allSignals.find(s => s.id === refId || s.propertyId === refId) - if (!signal) return [] + if (!signal || signal.signalDirection === 'DEMAND') return [] return [{ matchId: match.id, needId: match.needId, matchScore: match.matchScore, resultType: 'FUTURE_AVAILABILITY', signal, match }] } diff --git a/src/mock-data/futureSignals.ts b/src/mock-data/futureSignals.ts index a9f3e79..a5ae39f 100644 --- a/src/mock-data/futureSignals.ts +++ b/src/mock-data/futureSignals.ts @@ -1,54 +1,33 @@ import { SignalType, RiskLevel } from '../domain/enums' import type { FutureSignal } from '../domain/futureSignal' -export const mockFutureSignals: FutureSignal[] = [ - // --- signal-001: DataCloud Systems AG — Büroexpansion Zürich-West --- - { - id: 'signal-001', - signalType: SignalType.EXPANSION, - propertyId: 'prop-005', - companyName: 'DataCloud Systems AG', - locationHint: 'Zürich-West / Technopark', - title: 'DataCloud Systems AG sucht ~600 m² Bürofläche in Zürich-West', - areaSqmEstimate: 600, - probability: 0.72, - confidenceScore: 0.68, - timeHorizonMonths: 10, - source: { - type: 'JOB_POSTING', - url: 'https://example.com/jobs/datacloud', - publishedAt: '2025-04-20', - credibility: 'MEDIUM', - }, - sensitivityLevel: 'INTERNAL', - disclaimer: 'Dieses Signal basiert auf AI-Analyse öffentlicher Daten (Stelleninserate, Presseberichte). Es handelt sich um ein probabilistisches Signal, kein bestätigtes Objekt.', - riskLevel: RiskLevel.MEDIUM, - marketIndicator: 'Tech-Sektor Stellenwachstum +38% YoY', - relevanceScore: 0.76, - isVerified: false, - expiresAt: '2026-03-01', - organizationId: 'org-wincasa', - createdAt: '2025-05-01T07:00:00Z', - updatedAt: '2025-05-10T07:00:00Z', - aiSummary: 'KI hat in 90 Tagen 14 Stelleninserate von DataCloud Systems AG auf LinkedIn und Indeed ausgewertet — davon 11 mit explizitem Standort Zürich-West/Technopark und hybridem Arbeitsmodell. Das Wachstumsmuster (DevOps, Cloud-Architektur, Sales) deutet auf eine Teamvergrösserung von ~40 Personen hin, was einem Flächenbedarf von ca. 600 m² entspricht. Der Tech-Sektor in Zürich-West verzeichnet 2024 den stärksten Stellenzuwachs seit 2018.', - marketIndicators: [ - '14 Stelleninserate mit Standort Zürich-West in 90 Tagen', - 'Teamwachstum ~40 Personen (DevOps, Cloud-Architektur, Sales)', - 'Tech-Sektor Zürich-West: +38% Stellenwachstum 2024', - ], - strategicInterpretation: 'DataCloud Systems AG befindet sich in einer klaren Wachstumsphase mit Fokus auf Zürich-West. Die Muster sprechen für organische Expansion — kein Standortwechsel erkennbar.', - confirmedFacts: ['Region Zürich-West aus Inseraten bestätigt', 'Flächentyp Büro plausibel', 'Wachstumstrend seit 6 Monaten vorhanden'], - unconfirmedFacts: ['Exakter Umzugszeitpunkt', 'Ob interner Ausbau am aktuellen Standort geplant', 'Finale Flächengrösse'], - }, +// ───────────────────────────────────────────────────────────────────────────── +// SUPPLY signals — space will become available +// Shown in the demand search feed as Future Availability results +// +// Two sub-types: +// A) Pre-Market (Verwaltung-controlled): LEASE_EXPIRY + isVerified +// Generated dynamically by useSchattenmarktSignals — not in this file +// B) Market Signal (Crawler): POSSIBLE_MOVE_OUT, CONSTRUCTION_PROJECT, etc. +// These are the signals below +// +// DEMAND signals — company is looking for space +// NOT shown in demand feed — shown as Markt-Leads in Verwaltung workspace +// ───────────────────────────────────────────────────────────────────────────── - // --- signal-002: Helvetia Produktion GmbH — möglicher Auszug Reinach BL --- +export const mockFutureSignals: FutureSignal[] = [ + + // ── SUPPLY: Crawler-detected — space becoming available ─────────────────── + + // signal-002: Helvetia Produktion GmbH — möglicher Auszug Reinach BL { id: 'signal-002', signalType: SignalType.POSSIBLE_MOVE_OUT, + signalDirection: 'SUPPLY', companyName: 'Helvetia Produktion GmbH', propertyId: 'prop-006', locationHint: 'Reinach BL, Industriezone Nord', - title: 'Helvetia Produktion GmbH — Standort Reinach unter Restrukturierungsdruck', + title: 'Reinach BL — 3\'200 m² Produktionsfläche könnte frei werden', areaSqmEstimate: 3200, probability: 0.48, confidenceScore: 0.44, @@ -60,7 +39,7 @@ export const mockFutureSignals: FutureSignal[] = [ credibility: 'HIGH', }, sensitivityLevel: 'CONFIDENTIAL', - disclaimer: 'Dieses Signal basiert auf Pressemeldungen zu Restrukturierungsplänen. Kein bestätigter Auszug. Vertraulich behandeln.', + disclaimer: 'Basiert auf Pressemeldungen zur Restrukturierung. Kein bestätigter Auszug. Vertraulich behandeln.', riskLevel: RiskLevel.HIGH, marketIndicator: 'Restrukturierungsankündigung Mutterkonzern', relevanceScore: 0.61, @@ -69,21 +48,22 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-05-03T08:00:00Z', updatedAt: '2025-05-10T08:00:00Z', - aiSummary: 'Drei unabhängige Presseartikel (NZZ, Handelszeitung, Basellandschaftliche Zeitung) berichten über die angekündigte Restrukturierung der Muttergesellschaft mit geplantem Stellenabbau von 8–12% bis Ende 2025. Der Standort Reinach BL wird in internen Dokumenten als "unter Überprüfung" eingestuft. KI-Konfidenz bleibt moderat, da kein Auszugstermin bestätigt wurde.', + aiSummary: 'Drei unabhängige Presseartikel (NZZ, Handelszeitung, Basellandschaftliche Zeitung) berichten über den angekündigten Stellenabbau von 8–12% bis Ende 2025. Der Standort Reinach BL wird in internen Dokumenten als "unter Überprüfung" geführt. Auszugstermin noch nicht bestätigt — frühes Beobachtungsstadium.', marketIndicators: [ '3 unabhängige Presseartikel zu Restrukturierung der Muttergesellschaft', 'Geplanter Stellenabbau 8–12% bis Ende 2025 bestätigt', - 'Standort Reinach BL in internen Dokumenten als «unter Überprüfung» eingestuft', + 'Standort Reinach BL intern als «unter Überprüfung» eingestuft', ], - strategicInterpretation: 'Die Restrukturierung der Muttergesellschaft erhöht die Wahrscheinlichkeit einer Standortschliessung oder -reduktion in Reinach. Kein Auszugstermin bestätigt — frühes Beobachtungsstadium.', - confirmedFacts: ['Restrukturierung der Muttergesellschaft offiziell bestätigt', 'Stellenabbau angekündigt', 'Logistik-Standort Reinach betroffen'], - unconfirmedFacts: ['Ob Standort Reinach geschlossen wird', 'Zeitpunkt des Auszugs', 'Ob Fläche vermietet oder verkauft wird'], + strategicInterpretation: 'Die Restrukturierung erhöht die Wahrscheinlichkeit einer Standortschliessung in Reinach. Kein Auszugstermin bestätigt — Eigentümer sollte Kontakt zum Mieter suchen.', + confirmedFacts: ['Restrukturierung der Muttergesellschaft offiziell bestätigt', 'Stellenabbau angekündigt', 'Standort Reinach betroffen'], + unconfirmedFacts: ['Ob Standort Reinach geschlossen wird', 'Zeitpunkt des Auszugs', 'Ob Fläche vermietet oder verkauft'], }, - // --- signal-003: Bern Wankdorf — Neubau 4'500 m² Büro/Gewerbe --- + // signal-003: Bern Wankdorf — Neubau Büro/Gewerbe { id: 'signal-003', signalType: SignalType.CONSTRUCTION_PROJECT, + signalDirection: 'SUPPLY', locationHint: 'Bern, Wankdorf', title: 'Neubau Wankdorf West — 4\'500 m² Büro/Gewerbe, Fertigstellung Q1 2027', areaSqmEstimate: 4500, @@ -98,7 +78,7 @@ export const mockFutureSignals: FutureSignal[] = [ sensitivityLevel: 'PUBLIC', disclaimer: 'Baubewilligung öffentlich eingesehen. Fertigstellung gemäss Baugesuch Q1 2027. Vermietungsstart noch offen.', riskLevel: RiskLevel.LOW, - marketIndicator: 'Neubau Büro/Gewerbeflächen Wankdorf West', + marketIndicator: 'Neubau Büro-/Gewerbeflächen Wankdorf West', relevanceScore: 0.82, isVerified: true, verifiedBy: 'admin@ideal-sharing.ch', @@ -107,63 +87,26 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-02-12T10:00:00Z', updatedAt: '2025-05-05T09:00:00Z', - aiSummary: 'Baubewilligung Nr. 2025-BW-0142 wurde am 10. Februar 2025 durch das Bauinspektorat Bern rechtskräftig erteilt. Das Projekt umfasst 4\'500 m² gemischte Büro- und Gewerbefläche (EG: Retail/Gewerbe, OG 1–3: Büro). Fertigstellung laut Baugesuch Q1 2027. Investorin ist die Wankdorf Immobilien AG; Vermietungsmandat noch nicht vergeben. Hohe Konfidenz durch amtliche Quelle.', + aiSummary: 'Baubewilligung Nr. 2025-BW-0142 wurde am 10. Februar 2025 durch das Bauinspektorat Bern rechtskräftig erteilt. Das Projekt umfasst 4\'500 m² gemischte Büro- und Gewerbefläche (EG: Retail/Gewerbe, OG 1–3: Büro). Fertigstellung laut Baugesuch Q1 2027. Investorin: Wankdorf Immobilien AG — Vermietungsmandat noch nicht vergeben.', marketIndicators: [ - 'Baubewilligung für 4\'500 m² Büro-/Gewerbefläche öffentlich eingereicht', + 'Baubewilligung für 4\'500 m² Büro-/Gewerbefläche rechtskräftig erteilt', 'Fertigstellung gemäss Baugesuch Q1 2027', - 'Bauherr: Wankdorf Center Entwicklungs AG', + 'Bauherr: Wankdorf Center Entwicklungs AG — Vermietungsstart ca. Q2 2026', ], - strategicInterpretation: 'Baubewilligung öffentlich — hohe Realisierungswahrscheinlichkeit. Vermietungsstart voraussichtlich 6–9 Monate vor Fertigstellung. Standort Wankdorf mit guter ÖV-Anbindung (Tram, Bahn).', - confirmedFacts: ['Baubewilligung erteilt', 'Fläche und Standort bestätigt', 'Fertigstellungsdatum Q1 2027 aus Gesuch'], - unconfirmedFacts: ['Endmietzins', 'Ob Fläche bereits vorvermietet', 'Ausbaustandard'], + strategicInterpretation: 'Hohe Realisierungswahrscheinlichkeit durch erteilte Baubewilligung. Wankdorf hat gute ÖV-Anbindung (Tram, Bahn) und wächst als Business-Quartier. Frühzeitiges Interesse anmelden.', + confirmedFacts: ['Baubewilligung erteilt', 'Fläche 4\'500 m² und Standort bestätigt', 'Fertigstellung Q1 2027 aus Baugesuch'], + unconfirmedFacts: ['Endmietzins pro m²', 'Ob Fläche bereits vorvermietet', 'Ausbaustandard OG'], }, - // --- signal-004: Novabio Pharma AG — Laborexpansion Basel Allschwil --- - { - id: 'signal-004', - signalType: SignalType.EXPANSION, - companyName: 'Novabio Pharma AG', - locationHint: 'Basel, Allschwil', - title: 'Novabio Pharma AG sucht Lab-/Bürofläche im Life-Sciences-Korridor Allschwil', - areaSqmEstimate: 700, - probability: 0.63, - confidenceScore: 0.60, - timeHorizonMonths: 14, - source: { - type: 'COMPANY_REPORT', - url: 'https://example.com/annual/novabio-2025', - publishedAt: '2025-03-28', - credibility: 'HIGH', - }, - sensitivityLevel: 'INTERNAL', - disclaimer: 'Signal basiert auf Geschäftsbericht und Expansionsplänen. Kein bestätigtes Mietobjekt.', - riskLevel: RiskLevel.MEDIUM, - marketIndicator: 'Pharmastandort Basel: +22% Beschäftigte Life-Sciences 2024', - relevanceScore: 0.70, - isVerified: false, - expiresAt: '2026-07-01', - organizationId: 'org-wincasa', - createdAt: '2025-04-02T09:00:00Z', - updatedAt: '2025-05-08T10:00:00Z', - aiSummary: 'Im Geschäftsbericht 2024 kommuniziert Novabio Pharma AG eine "strategische Kapazitätserweiterung im Forschungsbereich Basel-Allschwil bis 2026". Die KI hat ausserdem 6 Inserate für Senior Scientists und Lab-Manager mit Standortangabe Allschwil identifiziert. Der Life-Sciences-Korridor Basel-Allschwil weist 2024 die schweizweit höchste Laborflächen-Nachfrage auf.', - marketIndicators: [ - 'Geschäftsbericht 2024: «strategische Kapazitätserweiterung Basel-Allschwil bis 2026» explizit erwähnt', - '6 Inserate für Senior Scientists und Lab-Manager mit Standort Allschwil in 60 Tagen', - 'Life-Sciences-Korridor Basel-Allschwil: höchste CH-weite Laborflächen-Nachfrage 2024', - ], - strategicInterpretation: 'Novabio Pharma AG kommuniziert Expansion öffentlich — Flächensuche sehr wahrscheinlich. Der Fokus auf Laborpersonal deutet auf kombinierten Lab-/Bürobedarf von 600–800 m² hin.', - confirmedFacts: ['Expansionspläne im Geschäftsbericht bestätigt', 'Region Basel-Allschwil als Zielstandort genannt', 'Einstellungstrend seit Q1 2025 sichtbar'], - unconfirmedFacts: ['Ob Neubau oder Bestandsfläche gesucht', 'Exakter Flächenbedarf Labor vs. Büro', 'Zeitpunkt des Einzugs'], - }, - - // --- signal-005: Finanz & Treuhand AG — möglicher Auszug Zürich-Nord --- + // signal-005: Finanz & Treuhand AG — möglicher Auszug Zürich-Nord { id: 'signal-005', signalType: SignalType.POSSIBLE_MOVE_OUT, + signalDirection: 'SUPPLY', companyName: 'Finanz & Treuhand AG', propertyId: 'prop-023', locationHint: 'Zürich-Nord, Seebach', - title: 'Finanz & Treuhand AG — Kostensenkungssignale deuten auf Standortaufgabe Seebach', + title: 'Zürich-Nord Seebach — 850 m² Bürofläche könnte frei werden', areaSqmEstimate: 850, probability: 0.58, confidenceScore: 0.54, @@ -183,23 +126,24 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-04-12T08:00:00Z', updatedAt: '2025-05-10T09:00:00Z', - aiSummary: 'Marktdatenanalyse zeigt: Die Finanz & Treuhand AG hat ihren LinkedIn-Unternehmenssitz von "Zürich-Nord, Seebach" auf "Zürich, Oerlikon" aktualisiert (Stand April 2025). Gleichzeitig sank die Mitarbeiterzahl laut LinkedIn von 38 auf 31 (-18%) innert 6 Monaten. Beide Indikatoren zusammen ergeben ein Verlagerungssignal. Kein offizieller Auszug bestätigt.', + aiSummary: 'Finanz & Treuhand AG hat den LinkedIn-Unternehmenssitz von "Zürich-Nord, Seebach" auf "Zürich, Oerlikon" aktualisiert (Stand April 2025). Gleichzeitig sank die Mitarbeiterzahl von 38 auf 31 (–18%) in 6 Monaten. Beide Indikatoren zusammen ergeben ein Verlagerungssignal — kein offizieller Auszug bestätigt.', marketIndicators: [ 'LinkedIn-Firmensitz von Seebach auf Oerlikon aktualisiert (April 2025)', - 'Mitarbeiterzahl rückläufig: von 38 auf 31 (-18%) in 6 Monaten', + 'Mitarbeiterzahl rückläufig: von 38 auf 31 (–18%) in 6 Monaten', 'Leerstand Zürich-Nord Q1 2025: +12% gegenüber Vorquartal', ], - strategicInterpretation: 'Adressänderung auf LinkedIn kombiniert mit Stellenabbau ist ein starkes Frühsignal für Standortaufgabe. Frühzeitiger Kontakt mit der Verwaltung des Objekts empfohlen.', + strategicInterpretation: 'Adressänderung auf LinkedIn kombiniert mit Stellenabbau ist ein starkes Frühsignal für Standortaufgabe. Frühzeitiger Kontakt mit Mieter empfohlen.', confirmedFacts: ['Mitarbeiterzahl-Rückgang auf LinkedIn dokumentiert', 'Adressänderung auf LinkedIn publiziert', 'Aktueller Standort Seebach bekannt'], - unconfirmedFacts: ['Ob Mietvertrag gekündigt wurde', 'Zeitpunkt des Auszugs', 'Ob Zusammenschluss mit anderem Standort geplant'], + unconfirmedFacts: ['Ob Mietvertrag bereits gekündigt', 'Zeitpunkt des Auszugs', 'Ob Zusammenschluss mit Oerlikon-Standort geplant'], }, - // --- signal-006: Luzern Inseli — Neubau Büro/Gewerbe am Wasser --- + // signal-006: Luzern Inseli — Neubau Büro/Gewerbe am Wasser { id: 'signal-006', signalType: SignalType.CONSTRUCTION_PROJECT, + signalDirection: 'SUPPLY', locationHint: 'Luzern, Inseli-Quartier', - title: 'Neubau Inseli Luzern — 2\'000 m² Gewerbefläche am Wasser, Q1 2027', + title: 'Neubau Inseli Luzern — 2\'000 m² Gewerbefläche, Fertigstellung Q1 2027', areaSqmEstimate: 2000, probability: 0.78, confidenceScore: 0.74, @@ -219,62 +163,26 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-01-25T11:00:00Z', updatedAt: '2025-05-06T14:00:00Z', + aiSummary: 'Baubewilligung für 2\'000 m² Gewerbe-/Bürofläche am Luzerner Inseli öffentlich eingereicht. Attraktive Wasserlage mit direkter ÖV-Anbindung (Bahnhof 8 Minuten zu Fuss). Nutzungskonzept noch offen — Büro und Gastronomie/Retail im EG wahrscheinlich.', marketIndicators: [ 'Baubewilligung für 2\'000 m² Gewerbe-/Bürofläche am Inseli eingereicht', 'Fertigstellung gemäss Baugesuch ca. Q1 2027', 'Luzern Innenstadt: Büroflächennachfrage 2024 +18% gegenüber Vorjahr', ], - strategicInterpretation: 'Attraktive Wasserlage am Luzerner Inseli mit ÖV-Direktanbindung (Bahnhof 8 Minuten zu Fuss). Nutzungskonzept noch offen — Büro und Gastronomie/Retail im EG wahrscheinlich. Frühzeitiges Interesse anmelden sinnvoll.', + strategicInterpretation: 'Attraktive Wasserlage mit ÖV-Direktanbindung. Nutzungskonzept noch offen — frühzeitiges Interesse anmelden sinnvoll, bevor Vermietungsmandat vergeben wird.', confirmedFacts: ['Baubewilligung öffentlich eingereicht', 'Standort Inseli-Quartier bestätigt', 'Fertigstellung Q1 2027 aus Gesuch'], unconfirmedFacts: ['Endgültige Nutzungsaufteilung (Büro vs. Retail)', 'Mietzinsniveau', 'Ob Vermietungsmandat vergeben'], }, - // --- signal-007: SwissCart E-Commerce GmbH — Logistikexpansion Zug --- - { - id: 'signal-007', - signalType: SignalType.EXPANSION, - companyName: 'SwissCart E-Commerce GmbH', - propertyId: 'prop-026', - locationHint: 'Zug, Industriestrasse', - title: 'SwissCart E-Commerce GmbH sucht Logistikfläche in Zug', - areaSqmEstimate: 580, - probability: 0.66, - confidenceScore: 0.62, - timeHorizonMonths: 9, - source: { - type: 'JOB_POSTING', - url: 'https://example.com/jobs/swisscart-zug', - publishedAt: '2025-04-18', - credibility: 'MEDIUM', - }, - sensitivityLevel: 'INTERNAL', - disclaimer: 'Signal basiert auf massivem Stellenaufbau. Expansion in Zug sehr wahrscheinlich, aber noch kein Mietobjekt identifiziert.', - riskLevel: RiskLevel.MEDIUM, - marketIndicator: 'E-Commerce Zug: Stellenwachstum +55% YoY', - relevanceScore: 0.69, - isVerified: false, - expiresAt: '2026-02-01', - organizationId: 'org-wincasa', - createdAt: '2025-04-20T07:00:00Z', - updatedAt: '2025-05-09T08:00:00Z', - marketIndicators: [ - '9 Stelleninserate für Lager- und Logistikpersonal in Zug in 45 Tagen', - 'E-Commerce-Umsatz CH 2024: +22% — Nachfrage nach Lagerflächen steigt', - 'Zug Industriestrasse: aktuelle Leerstandsquote Lager unter 3%', - ], - strategicInterpretation: 'Massiver Personalaufbau im Logistikbereich deutet auf konkreten Flächenbedarf hin. Zug als Steuerkanton bleibt attraktiver Firmensitz — kein Standortwechsel erwartet, nur Erweiterung.', - confirmedFacts: ['Region Zug aus Inseraten bestätigt', 'Flächentyp Logistik/Lager aus Stellenprofilen ableitbar', 'Wachstumstrend seit Q3 2024 sichtbar'], - unconfirmedFacts: ['Ob zusätzliche Bürofläche benötigt', 'Exakter Flächenbedarf', 'Bevorzugte Strassenlage (Anlieferung)'], - }, - - // --- signal-008: Textilhaus Zürich AG — Retail-Verkleinerung Niederdorf --- + // signal-008: Textilhaus Zürich AG — Retail-Verkleinerung Niederdorf { id: 'signal-008', signalType: SignalType.POSSIBLE_MOVE_OUT, + signalDirection: 'SUPPLY', companyName: 'Textilhaus Zürich AG', propertyId: 'prop-025', locationHint: 'Zürich Niederdorf, Münstergasse', - title: 'Textilhaus Zürich AG — Retailfläche Münstergasse könnte frei werden', + title: 'Zürich Münstergasse — 280 m² Retailfläche könnte frei werden', areaSqmEstimate: 280, probability: 0.55, confidenceScore: 0.50, @@ -294,20 +202,22 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-04-01T10:00:00Z', updatedAt: '2025-05-07T11:00:00Z', + aiSummary: 'Textilhaus Zürich AG zeigt eine Personalreduktion von –25% in 12 Monaten auf LinkedIn. Der Onlineanteil im Schweizer Textilhandel erreichte 2024 erstmals 38% — stationäre Flächen in der Altstadt stehen unter strukturellem Druck.', marketIndicators: [ 'Onlineanteil CH-Textilhandel 2024: 38% — stationäre Verkaufsflächen unter Druck', - 'Mitarbeiterzahl Textilhaus Zürich AG laut LinkedIn: -25% in 12 Monaten', + 'Mitarbeiterzahl Textilhaus Zürich AG laut LinkedIn: –25% in 12 Monaten', 'Stationärer Handel Zürich Altstadt: Leerstandsquote +8% 2024', ], - strategicInterpretation: 'Struktureller Rückgang im stationären Textilhandel trifft kleine Altstadt-Läden besonders. Kombination aus Personalabbau und Branchentrend ergibt ein Verlagerungssignal, das im Auge behalten werden sollte.', + strategicInterpretation: 'Struktureller Rückgang im stationären Textilhandel trifft kleine Altstadt-Läden besonders. Personalabbau und Branchentrend ergeben ein Verlagerungssignal.', confirmedFacts: ['Branchentrend stationärer Handel dokumentiert', 'Aktueller Standort Münstergasse bekannt', 'Personalabbau auf LinkedIn sichtbar'], - unconfirmedFacts: ['Ob Mietvertrag noch läuft oder ausläuft', 'Ob Filialnetz insgesamt verkleinert wird', 'Zeitpunkt eines möglichen Auszugs'], + unconfirmedFacts: ['Ob Mietvertrag noch läuft oder ausläuft', 'Ob Filialnetz insgesamt verkleinert', 'Zeitpunkt eines möglichen Auszugs'], }, - // --- signal-009: Winterthur Zentrum — Neubau Bürofläche --- + // signal-009: Winterthur Zentrum — Neubau Bürofläche { id: 'signal-009', signalType: SignalType.CONSTRUCTION_PROJECT, + signalDirection: 'SUPPLY', locationHint: 'Winterthur, Zentrum Technikum', title: 'Neubau Technikum Winterthur — 1\'200 m² Bürofläche, Baubewilligung erteilt', areaSqmEstimate: 1200, @@ -331,62 +241,26 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-03-05T09:00:00Z', updatedAt: '2025-04-10T10:00:00Z', + aiSummary: 'Baubewilligung rechtskräftig erteilt für 1\'200 m² Bürofläche am Technikum Winterthur. Fertigstellung Q2 2027. Zentrale Lage mit Bahnhof-Nähe. Winterthur Büromarkt: Leerstand Q1 2025 auf historisch tiefem Niveau (4.2%).', marketIndicators: [ 'Baubewilligung für 1\'200 m² Bürofläche am Technikum rechtskräftig erteilt', 'Fertigstellung gemäss Baugesuch Q2 2027', - 'Winterthur Büromarkt: Leerstand Q1 2025 auf historisch tiefem Niveau (4.2%)', + 'Winterthur Büromarkt: Leerstand Q1 2025 historisch tief (4.2%)', ], - strategicInterpretation: 'Amtlich bestätigte Baubewilligung — sehr hohe Realisierungswahrscheinlichkeit. Zentrale Lage am Technikum mit Bahnhof-Nähe. Vermietungsstart erfahrungsgemäss 9–12 Monate vor Fertigstellung.', + strategicInterpretation: 'Amtlich bestätigte Baubewilligung — sehr hohe Realisierungswahrscheinlichkeit. Bahnhof-Nähe und tiefe Leerstandsquote machen Winterthur attraktiv. Vermietungsstart erfahrungsgemäss 9–12 Monate vor Fertigstellung.', confirmedFacts: ['Baubewilligung rechtskräftig erteilt', 'Standort Zentrum Technikum bestätigt', 'Fertigstellung Q2 2027 aus Gesuch'], unconfirmedFacts: ['Ob Vorvermietung bereits läuft', 'Endmietzins pro m²', 'Aufteilung EG/OG'], }, - // --- signal-010: Ostschweiz Digital AG — Büroexpansion St. Gallen --- - { - id: 'signal-010', - signalType: SignalType.EXPANSION, - companyName: 'Ostschweiz Digital AG', - propertyId: 'prop-030', - locationHint: 'St. Gallen, Riethüsli', - title: 'Ostschweiz Digital AG wächst — 480 m² Bürofläche in St. Gallen gesucht', - areaSqmEstimate: 480, - probability: 0.60, - confidenceScore: 0.55, - timeHorizonMonths: 10, - source: { - type: 'JOB_POSTING', - url: 'https://example.com/jobs/ostschweiz-digital', - publishedAt: '2025-04-22', - credibility: 'MEDIUM', - }, - sensitivityLevel: 'INTERNAL', - disclaimer: 'Expansion basiert auf Analyse von Stellenanzeigen und Unternehmensankündigungen. Kein bestätigtes Objekt.', - riskLevel: RiskLevel.MEDIUM, - marketIndicator: 'Digitalwirtschaft Ostschweiz: +28% Beschäftigte 2024', - relevanceScore: 0.62, - isVerified: false, - expiresAt: '2026-03-01', - organizationId: 'org-wincasa', - createdAt: '2025-04-25T08:00:00Z', - updatedAt: '2025-05-10T07:00:00Z', - marketIndicators: [ - '8 Stelleninserate für Software-Entwickler und UX-Designer in St. Gallen in 60 Tagen', - 'Ostschweiz Digital AG: LinkedIn-Mitarbeiterzahl von 22 auf 31 (+41%) in 9 Monaten', - 'Digitalwirtschaft Ostschweiz: +28% Beschäftigte 2024 (IHK-Bericht)', - ], - strategicInterpretation: 'Kontinuierliches Teamwachstum über 9 Monate mit Fokus auf St. Gallen deutet auf organische Expansion hin. Kein Hinweis auf Standortwechsel — Erweiterungsfläche am bisherigen Standort oder Umzug in grössere Einheit möglich.', - confirmedFacts: ['Region St. Gallen aus Inseraten bestätigt', 'Wachstumstrend seit Q3 2024 nachweisbar', 'Flächentyp Büro aus Stellenprofilen ableitbar'], - unconfirmedFacts: ['Ob aktueller Standort Riethüsli oder Neulage', 'Exakter Flächenbedarf', 'Zeitpunkt der Entscheidung'], - }, - - // --- signal-011 (Mode Boutique): Mode Boutique Bern AG — Rückgang Altstadt --- + // signal-011: Mode Boutique Bern AG — Rückgang Altstadt { id: 'signal-011', signalType: SignalType.POSSIBLE_MOVE_OUT, - propertyId: 'prop-035', + signalDirection: 'SUPPLY', companyName: 'Mode Boutique Bern AG', + propertyId: 'prop-035', locationHint: 'Bern Altstadt, Gerechtigkeitsgasse', - title: 'Mode Boutique Bern AG — Retailfläche Gerechtigkeitsgasse unter Druck', + title: 'Bern Gerechtigkeitsgasse — 290 m² Retailfläche unter Druck', areaSqmEstimate: 290, probability: 0.62, confidenceScore: 0.58, @@ -406,21 +280,22 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-04-28T09:00:00Z', updatedAt: '2025-05-15T10:00:00Z', - aiSummary: 'Mode Boutique Bern AG zeigt gemäss LinkedIn-Analyse eine Mitarbeiterreduktion von 12 auf 8 Personen (-33%) innerhalb von 6 Monaten. Das Unternehmen hat ausserdem kürzlich den Sitz auf eine kleinere Adresse in der Berner Innenstadt aktualisiert. Die Kombination aus Stellenabbau und Adressänderung deutet auf eine Verkleinerung des Verkaufsbereichs hin.', + aiSummary: 'Mode Boutique Bern AG zeigt eine Mitarbeiterreduktion von 12 auf 8 Personen (–33%) in 6 Monaten laut LinkedIn. Zusätzlich sank der Passantenverkehr in der Gerechtigkeitsgasse 2024 um 11% (Zählstelle). Kombination deutet auf Verkleinerung hin.', marketIndicators: [ - 'Mitarbeiterreduktion von 12 auf 8 Personen (-33%) in 6 Monaten laut LinkedIn', - 'Berner Altstadt: Frequenzrückgang in der Gerechtigkeitsgasse -11% 2024 (Zählstelle)', + 'Mitarbeiterreduktion von 12 auf 8 Personen (–33%) in 6 Monaten laut LinkedIn', + 'Berner Altstadt: Frequenzrückgang Gerechtigkeitsgasse –11% 2024 (Zählstelle)', 'Stationärer Modehandel Bern: Leerstand +5% 2024', ], - strategicInterpretation: 'Personalabbau zusammen mit sinkendem Passantenaufkommen in der Gerechtigkeitsgasse ergibt ein klares Verkleinerungssignal. Frühzeitige Kontaktaufnahme mit dem Eigentümer sinnvoll.', - confirmedFacts: ['Aktueller Standort Gerechtigkeitsgasse bekannt', 'Personalrückgang auf LinkedIn dokumentiert', 'Bern Altstadt Frequenzdaten verfügbar'], - unconfirmedFacts: ['Ob Mietvertrag ausläuft oder gekündigt wird', 'Ob Standort aufgegeben oder nur verkleinert', 'Zeitpunkt eines möglichen Auszugs'], + strategicInterpretation: 'Personalabbau zusammen mit sinkendem Passantenaufkommen ergibt ein klares Verkleinerungssignal. Frühzeitige Kontaktaufnahme mit dem Eigentümer sinnvoll.', + confirmedFacts: ['Aktueller Standort Gerechtigkeitsgasse bekannt', 'Personalrückgang auf LinkedIn dokumentiert', 'Frequenzdaten Bern Altstadt verfügbar'], + unconfirmedFacts: ['Ob Mietvertrag ausläuft oder gekündigt', 'Ob Standort aufgegeben oder nur verkleinert', 'Zeitpunkt eines möglichen Auszugs'], }, - // --- signal-012: Basel Hafen Klybeck — Logistikneubau --- + // signal-012: Basel Hafen Klybeck — Logistikneubau { id: 'signal-012', signalType: SignalType.CONSTRUCTION_PROJECT, + signalDirection: 'SUPPLY', propertyId: 'prop-024', locationHint: 'Basel, Hafen Klybeck', title: 'Logistikneubau Rheinhafen Basel — 2\'600 m², Fertigstellung Q2 2026', @@ -445,62 +320,26 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-01-18T10:00:00Z', updatedAt: '2025-04-20T14:00:00Z', + aiSummary: 'Baubewilligung für 2\'600 m² Logistikfläche am Klybeck-Hafen rechtskräftig erteilt. Strategischer Standort mit direktem Rheinhafenzugang und Bahnanschluss (Trimodalität). Fertigstellung Q2 2026.', marketIndicators: [ 'Baubewilligung für 2\'600 m² Logistikfläche am Klybeck-Hafen rechtskräftig erteilt', 'Fertigstellung gemäss Baugesuch Q2 2026', - 'Hafenareal Klybeck: Trimodalität Schiene/Wasser/Strasse als USP', + 'Trimodalität Schiene/Wasser/Strasse als USP — Nachfrage nach solchen Standorten konstant hoch', ], - strategicInterpretation: 'Strategisch guter Logistikstandort mit direktem Rheinhafenzugang und Bahnanschluss. Hohe Realisierungssicherheit durch bereits erteilte Bewilligung. Nachfrage nach Hafen-nahen Logistikflächen in Basel konstant hoch.', + strategicInterpretation: 'Strategisch starker Logistikstandort mit direktem Rheinhafenzugang und Bahnanschluss. Hohe Realisierungssicherheit durch erteilte Bewilligung.', confirmedFacts: ['Baubewilligung erteilt und rechtskräftig', 'Standort Klybeck bestätigt', 'Fertigstellung Q2 2026 aus Gesuch', 'Fläche 2\'600 m² bestätigt'], unconfirmedFacts: ['Endmietzins pro m²', 'Ob Kühllager oder Trockenlager', 'Ob Fläche bereits reserviert'], }, - // --- signal-013: Geneva Finance Partners SA — Büroexpansion Genf La Praille --- - { - id: 'signal-013', - signalType: SignalType.EXPANSION, - companyName: 'Geneva Finance Partners SA', - propertyId: 'prop-028', - locationHint: 'Genf, La Praille', - title: 'Geneva Finance Partners SA expandiert — Bürofläche La Praille gesucht', - areaSqmEstimate: 520, - probability: 0.58, - confidenceScore: 0.53, - timeHorizonMonths: 20, - source: { - type: 'COMPANY_REPORT', - url: 'https://example.com/annual/gfp-2025', - publishedAt: '2025-03-05', - credibility: 'MEDIUM', - }, - sensitivityLevel: 'INTERNAL', - disclaimer: 'Expansionspläne aus Jahresbericht. Standort La Praille wahrscheinlich, aber noch nicht definitiv.', - riskLevel: RiskLevel.MEDIUM, - marketIndicator: 'Büroflächennachfrage Genf: +15% 2025', - relevanceScore: 0.60, - isVerified: false, - expiresAt: '2027-01-01', - organizationId: 'org-wincasa', - createdAt: '2025-03-08T11:00:00Z', - updatedAt: '2025-05-07T10:00:00Z', - marketIndicators: [ - 'Jahresbericht 2024: «Expansion des Genfer Teams auf 40 FTE bis 2026» angekündigt', - 'Genf Finanzsektor: +15% Büroflächennachfrage 2025 (CBRE-Bericht)', - '5 neue Inserate für Senior-Portfoliomanager mit Standort Genf in 30 Tagen', - ], - strategicInterpretation: 'Öffentlich kommunizierte Expansion mit klarem Zielhorizont 2026. La Praille als Standort bietet kostengünstigere Büroflächen als Genf Innenstadt bei guter ÖV-Anbindung. Flächensuche dürfte aktiv beginnen.', - confirmedFacts: ['Expansion im Jahresbericht kommuniziert', 'Teamwachstum auf 40 FTE bis 2026 bestätigt', 'Inserate für Genf aktiv'], - unconfirmedFacts: ['Ob La Praille oder andere Lage bevorzugt', 'Exakter Flächenbedarf', 'Ob Büros mit Repräsentationscharakter benötigt'], - }, - - // --- signal-014: Schweizer Grosshandel AG — möglicher Auszug Frenkendorf --- + // signal-014: Schweizer Grosshandel AG — möglicher Auszug Frenkendorf { id: 'signal-014', signalType: SignalType.POSSIBLE_MOVE_OUT, + signalDirection: 'SUPPLY', companyName: 'Schweizer Grosshandel AG', propertyId: 'prop-029', locationHint: 'Frenkendorf BL, Lager Nord', - title: 'Schweizer Grosshandel AG — Lagerfläche Frenkendorf unter Konsolidierungsdruck', + title: 'Frenkendorf BL — 3\'500 m² Lagerfläche unter Konsolidierungsdruck', areaSqmEstimate: 3500, probability: 0.50, confidenceScore: 0.46, @@ -520,20 +359,219 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-04-07T08:00:00Z', updatedAt: '2025-05-08T09:00:00Z', + aiSummary: 'Der Mutterkonzern hat eine Konsolidierung der Lagerstandorte in der Nordwestschweiz angekündigt. Mitarbeiterzahl Frenkendorf: von 54 auf 44 (–19%) in 8 Monaten. Strukturelle Konsolidierung im Grosshandel trifft Nebenstandorte zuerst — kein Auszugstermin bekannt.', marketIndicators: [ 'Mutterkonzern hat Konsolidierung der Lagerstandorte Nordwestschweiz angekündigt', - 'Mitarbeiterzahl Frenkendorf: von 54 auf 44 (-19%) in 8 Monaten', + 'Mitarbeiterzahl Frenkendorf: von 54 auf 44 (–19%) in 8 Monaten', 'Grosshandel CH: Lagerflächennachfrage 2024 stagniert — Kostendruck durch E-Commerce', ], - strategicInterpretation: 'Strukturelle Konsolidierung im Grosshandel trifft Nebenstandorte wie Frenkendorf zuerst. Kein Auszugstermin bekannt — Signal noch in früher Phase. Eigentümer sollte Kontakt suchen.', + strategicInterpretation: 'Strukturelle Konsolidierung im Grosshandel trifft Nebenstandorte wie Frenkendorf zuerst. Signal noch in früher Phase — Eigentümer sollte Kontakt suchen.', confirmedFacts: ['Konsolidierungsankündigung des Mutterkonzerns publiziert', 'Personalrückgang in Frenkendorf dokumentiert', 'Aktueller Standort Frenkendorf bekannt'], unconfirmedFacts: ['Welche Lagerstandorte konkret betroffen', 'Zeitpunkt eines möglichen Auszugs', 'Ob Fläche ganz oder teilweise aufgegeben'], }, - // --- signal-015: BernTech Innovation AG — Büroexpansion Bern Breitenrain --- + // ── DEMAND signals — company is looking for space → Markt-Leads (Verwaltung) ─ + + // signal-001: DataCloud Systems AG — Büroexpansion Zürich-West + { + id: 'signal-001', + signalType: SignalType.EXPANSION, + signalDirection: 'DEMAND', + companyName: 'DataCloud Systems AG', + locationHint: 'Zürich-West / Technopark', + title: 'DataCloud Systems AG sucht ~600 m² Bürofläche in Zürich-West', + areaSqmEstimate: 600, + probability: 0.72, + confidenceScore: 0.68, + timeHorizonMonths: 10, + source: { + type: 'JOB_POSTING', + url: 'https://example.com/jobs/datacloud', + publishedAt: '2025-04-20', + credibility: 'MEDIUM', + }, + sensitivityLevel: 'INTERNAL', + disclaimer: 'Erkannte Flächennachfrage aus öffentlichen Quellen. Kein bestätigtes Mietverhältnis — potenzielle Mieteranbahnung für Verwaltung.', + riskLevel: RiskLevel.MEDIUM, + marketIndicator: 'Tech-Sektor Stellenwachstum +38% YoY', + relevanceScore: 0.76, + isVerified: false, + expiresAt: '2026-03-01', + organizationId: 'org-wincasa', + createdAt: '2025-05-01T07:00:00Z', + updatedAt: '2025-05-10T07:00:00Z', + aiSummary: 'KI hat in 90 Tagen 14 Stelleninserate von DataCloud Systems AG mit explizitem Standort Zürich-West/Technopark ausgewertet. Das Wachstumsmuster (DevOps, Cloud-Architektur, Sales) deutet auf eine Teamvergrösserung von ~40 Personen hin — entspricht einem Flächenbedarf von ca. 600 m². Potenzieller Mieter für Büroflächen in Zürich-West.', + marketIndicators: [ + '14 Stelleninserate mit Standort Zürich-West in 90 Tagen', + 'Teamwachstum ~40 Personen (DevOps, Cloud-Architektur, Sales)', + 'Tech-Sektor Zürich-West: +38% Stellenwachstum 2024', + ], + strategicInterpretation: 'DataCloud Systems AG befindet sich in einer klaren Wachstumsphase mit Fokus auf Zürich-West. Unternehmen mit diesem Wachstumsmuster sucht typischerweise 500–700 m² Bürofläche mit Ausbauoptionen.', + confirmedFacts: ['Region Zürich-West aus Inseraten bestätigt', 'Flächentyp Büro plausibel', 'Wachstumstrend seit 6 Monaten vorhanden'], + unconfirmedFacts: ['Exakter Flächenbedarf', 'Ob interner Ausbau am aktuellen Standort geplant', 'Zeitplan für die Entscheidung'], + }, + + // signal-004: Novabio Pharma AG — Laborexpansion Basel Allschwil + { + id: 'signal-004', + signalType: SignalType.EXPANSION, + signalDirection: 'DEMAND', + companyName: 'Novabio Pharma AG', + locationHint: 'Basel, Allschwil', + title: 'Novabio Pharma AG sucht ~700 m² Labor-/Bürofläche in Basel Allschwil', + areaSqmEstimate: 700, + probability: 0.63, + confidenceScore: 0.60, + timeHorizonMonths: 14, + source: { + type: 'COMPANY_REPORT', + url: 'https://example.com/annual/novabio-2025', + publishedAt: '2025-03-28', + credibility: 'HIGH', + }, + sensitivityLevel: 'INTERNAL', + disclaimer: 'Erkannte Flächennachfrage aus Geschäftsbericht. Kein bestätigtes Mietverhältnis — potenzielle Mieteranbahnung für Verwaltung.', + riskLevel: RiskLevel.MEDIUM, + marketIndicator: 'Pharmastandort Basel: +22% Beschäftigte Life-Sciences 2024', + relevanceScore: 0.70, + isVerified: false, + expiresAt: '2026-07-01', + organizationId: 'org-wincasa', + createdAt: '2025-04-02T09:00:00Z', + updatedAt: '2025-05-08T10:00:00Z', + aiSummary: 'Novabio Pharma AG kommuniziert im Geschäftsbericht 2024 eine "strategische Kapazitätserweiterung im Forschungsbereich Basel-Allschwil bis 2026". 6 Inserate für Senior Scientists und Lab-Manager mit Standort Allschwil identifiziert. Potenzieller Mieter für Labor-/Büroflächen im Life-Sciences-Korridor.', + marketIndicators: [ + 'Geschäftsbericht 2024: «Kapazitätserweiterung Basel-Allschwil bis 2026» explizit erwähnt', + '6 Inserate für Senior Scientists und Lab-Manager mit Standort Allschwil in 60 Tagen', + 'Life-Sciences-Korridor Basel-Allschwil: höchste CH-weite Laborflächen-Nachfrage 2024', + ], + strategicInterpretation: 'Novabio Pharma AG kommuniziert Expansion öffentlich — Flächensuche sehr wahrscheinlich aktiv. Fokus auf Laborpersonal deutet auf kombinierten Lab-/Bürobedarf von 600–800 m² hin.', + confirmedFacts: ['Expansionspläne im Geschäftsbericht bestätigt', 'Region Basel-Allschwil als Zielstandort genannt', 'Einstellungstrend seit Q1 2025 sichtbar'], + unconfirmedFacts: ['Ob Neubau oder Bestandsfläche gesucht', 'Exakter Flächenbedarf Labor vs. Büro', 'Zeitpunkt des Einzugs'], + }, + + // signal-007: SwissCart E-Commerce GmbH — Logistikexpansion Zug + { + id: 'signal-007', + signalType: SignalType.EXPANSION, + signalDirection: 'DEMAND', + companyName: 'SwissCart E-Commerce GmbH', + locationHint: 'Zug, Industriestrasse', + title: 'SwissCart E-Commerce GmbH sucht ~580 m² Logistikfläche in Zug', + areaSqmEstimate: 580, + probability: 0.66, + confidenceScore: 0.62, + timeHorizonMonths: 9, + source: { + type: 'JOB_POSTING', + url: 'https://example.com/jobs/swisscart-zug', + publishedAt: '2025-04-18', + credibility: 'MEDIUM', + }, + sensitivityLevel: 'INTERNAL', + disclaimer: 'Erkannte Flächennachfrage aus Stelleninseraten. Kein bestätigtes Mietverhältnis — potenzielle Mieteranbahnung für Verwaltung.', + riskLevel: RiskLevel.MEDIUM, + marketIndicator: 'E-Commerce Zug: Stellenwachstum +55% YoY', + relevanceScore: 0.69, + isVerified: false, + expiresAt: '2026-02-01', + organizationId: 'org-wincasa', + createdAt: '2025-04-20T07:00:00Z', + updatedAt: '2025-05-09T08:00:00Z', + aiSummary: 'In 45 Tagen wurden 9 Stelleninserate für Lager- und Logistikpersonal von SwissCart E-Commerce GmbH in Zug identifiziert. E-Commerce-Umsatz CH 2024 +22% — Nachfrage nach Lagerflächen steigt. Potenzieller Mieter für Logistikflächen in der Region Zug.', + marketIndicators: [ + '9 Stelleninserate für Lager- und Logistikpersonal in Zug in 45 Tagen', + 'E-Commerce-Umsatz CH 2024: +22% — Nachfrage nach Lagerflächen steigt', + 'Zug Industriestrasse: aktuelle Leerstandsquote Lager unter 3%', + ], + strategicInterpretation: 'Massiver Personalaufbau im Logistikbereich deutet auf konkreten Flächenbedarf hin. Zug als Steuerkanton bleibt attraktiver Firmensitz — kein Standortwechsel erwartet, nur Erweiterung.', + confirmedFacts: ['Region Zug aus Inseraten bestätigt', 'Flächentyp Logistik/Lager aus Stellenprofilen ableitbar', 'Wachstumstrend seit Q3 2024 sichtbar'], + unconfirmedFacts: ['Ob zusätzliche Bürofläche benötigt', 'Exakter Flächenbedarf', 'Bevorzugte Strassenlage (Anlieferung)'], + }, + + // signal-010: Ostschweiz Digital AG — Büroexpansion St. Gallen + { + id: 'signal-010', + signalType: SignalType.EXPANSION, + signalDirection: 'DEMAND', + companyName: 'Ostschweiz Digital AG', + locationHint: 'St. Gallen, Riethüsli', + title: 'Ostschweiz Digital AG sucht ~480 m² Bürofläche in St. Gallen', + areaSqmEstimate: 480, + probability: 0.60, + confidenceScore: 0.55, + timeHorizonMonths: 10, + source: { + type: 'JOB_POSTING', + url: 'https://example.com/jobs/ostschweiz-digital', + publishedAt: '2025-04-22', + credibility: 'MEDIUM', + }, + sensitivityLevel: 'INTERNAL', + disclaimer: 'Erkannte Flächennachfrage aus Stelleninseraten. Kein bestätigtes Mietverhältnis — potenzielle Mieteranbahnung für Verwaltung.', + riskLevel: RiskLevel.MEDIUM, + marketIndicator: 'Digitalwirtschaft Ostschweiz: +28% Beschäftigte 2024', + relevanceScore: 0.62, + isVerified: false, + expiresAt: '2026-03-01', + organizationId: 'org-wincasa', + createdAt: '2025-04-25T08:00:00Z', + updatedAt: '2025-05-10T07:00:00Z', + aiSummary: '8 Stelleninserate für Software-Entwickler und UX-Designer in St. Gallen in 60 Tagen. Mitarbeiterzahl von 22 auf 31 (+41%) in 9 Monaten. Kontinuierliches Wachstum deutet auf Bedarf nach grösserer Bürofläche hin — potenzieller Mieter für Büroflächen in St. Gallen.', + marketIndicators: [ + '8 Stelleninserate für Software-Entwickler und UX-Designer in St. Gallen in 60 Tagen', + 'Ostschweiz Digital AG: Mitarbeiterzahl von 22 auf 31 (+41%) in 9 Monaten', + 'Digitalwirtschaft Ostschweiz: +28% Beschäftigte 2024 (IHK-Bericht)', + ], + strategicInterpretation: 'Kontinuierliches Teamwachstum mit Fokus auf St. Gallen deutet auf organische Expansion hin. Erweiterungsfläche am bisherigen Standort oder Umzug in grössere Einheit möglich.', + confirmedFacts: ['Region St. Gallen aus Inseraten bestätigt', 'Wachstumstrend seit Q3 2024 nachweisbar', 'Flächentyp Büro aus Stellenprofilen ableitbar'], + unconfirmedFacts: ['Ob aktueller Standort Riethüsli oder neue Lage', 'Exakter Flächenbedarf', 'Zeitpunkt der Entscheidung'], + }, + + // signal-013: Geneva Finance Partners SA — Büroexpansion Genf + { + id: 'signal-013', + signalType: SignalType.EXPANSION, + signalDirection: 'DEMAND', + companyName: 'Geneva Finance Partners SA', + locationHint: 'Genf, La Praille', + title: 'Geneva Finance Partners SA sucht ~520 m² Bürofläche in Genf La Praille', + areaSqmEstimate: 520, + probability: 0.58, + confidenceScore: 0.53, + timeHorizonMonths: 20, + source: { + type: 'COMPANY_REPORT', + url: 'https://example.com/annual/gfp-2025', + publishedAt: '2025-03-05', + credibility: 'MEDIUM', + }, + sensitivityLevel: 'INTERNAL', + disclaimer: 'Erkannte Flächennachfrage aus Jahresbericht. Kein bestätigtes Mietverhältnis — potenzielle Mieteranbahnung für Verwaltung.', + riskLevel: RiskLevel.MEDIUM, + marketIndicator: 'Büroflächennachfrage Genf: +15% 2025', + relevanceScore: 0.60, + isVerified: false, + expiresAt: '2027-01-01', + organizationId: 'org-wincasa', + createdAt: '2025-03-08T11:00:00Z', + updatedAt: '2025-05-07T10:00:00Z', + aiSummary: 'Jahresbericht 2024: «Expansion des Genfer Teams auf 40 FTE bis 2026» angekündigt. 5 neue Inserate für Senior-Portfoliomanager mit Standort Genf in 30 Tagen. Potenzieller Mieter für Büroflächen in Genf La Praille.', + marketIndicators: [ + 'Jahresbericht 2024: «Expansion des Genfer Teams auf 40 FTE bis 2026» angekündigt', + 'Genf Finanzsektor: +15% Büroflächennachfrage 2025 (CBRE-Bericht)', + '5 neue Inserate für Senior-Portfoliomanager mit Standort Genf in 30 Tagen', + ], + strategicInterpretation: 'Öffentlich kommunizierte Expansion mit klarem Zielhorizont 2026. La Praille bietet kostengünstigere Büroflächen als Genf Innenstadt bei guter ÖV-Anbindung. Flächensuche dürfte aktiv beginnen.', + confirmedFacts: ['Expansion im Jahresbericht kommuniziert', 'Teamwachstum auf 40 FTE bis 2026 bestätigt', 'Inserate für Genf aktiv'], + unconfirmedFacts: ['Ob La Praille oder andere Lage bevorzugt', 'Exakter Flächenbedarf', 'Ob Repräsentationsbüros benötigt'], + }, + + // signal-015: BernTech Innovation AG — Büroexpansion Bern Breitenrain { id: 'signal-015', signalType: SignalType.EXPANSION, + signalDirection: 'DEMAND', companyName: 'BernTech Innovation AG', locationHint: 'Bern, Breitenrain', title: 'BernTech Innovation AG sucht ~1\'800 m² Bürofläche in Bern Breitenrain', @@ -548,7 +586,7 @@ export const mockFutureSignals: FutureSignal[] = [ credibility: 'MEDIUM', }, sensitivityLevel: 'INTERNAL', - disclaimer: 'Wachstumssignal aus Stellenanzeigen und Social-Media-Analyse. Kein bestätigtes Objekt.', + disclaimer: 'Erkannte Flächennachfrage aus Stelleninseraten und VC-Finanzierungsdaten. Kein bestätigtes Mietverhältnis — potenzielle Mieteranbahnung für Verwaltung.', riskLevel: RiskLevel.MEDIUM, marketIndicator: 'Bern Tech-Ökosystem: Risikokapital +40% 2024', relevanceScore: 0.66, @@ -557,12 +595,13 @@ export const mockFutureSignals: FutureSignal[] = [ organizationId: 'org-wincasa', createdAt: '2025-04-28T09:00:00Z', updatedAt: '2025-05-10T08:00:00Z', + aiSummary: '18 Stelleninserate in 60 Tagen (Fokus Software-Engineering und Product Management). VC-Finanzierungsrunde CHF 12 Mio. im März 2025 öffentlich bestätigt. Frisch finanziertes Wachstumsunternehmen mit Budget für Flächenexpansion — potenzieller Mieter für Büroflächen in Bern.', marketIndicators: [ '18 Stelleninserate in 60 Tagen — Fokus Software-Engineering und Product Management', 'BernTech Innovation AG: VC-Finanzierungsrunde CHF 12 Mio. im März 2025 bestätigt', 'Bern Tech-Ökosystem: Risikokapital +40% 2024 — stärkstes Wachstum seit 2019', ], - strategicInterpretation: 'Frisch finanziertes Wachstumsunternehmen mit aktivem Stellenaufbau. VC-Finanzierung als starkes Signal für konkreten Flächenbedarf — Budgets vorhanden. Breitenrain als Tech-Standort in Bern etabliert.', + strategicInterpretation: 'Frisch finanziertes Wachstumsunternehmen mit aktivem Stellenaufbau und gesichertem Budget. VC-Finanzierung als starkes Signal für konkreten Flächenbedarf. Breitenrain als Tech-Standort in Bern etabliert.', confirmedFacts: ['VC-Finanzierungsrunde CHF 12 Mio. öffentlich bestätigt', 'Region Bern aus Inseraten bestätigt', 'Wachstumstrend seit Q1 2025 sichtbar'], unconfirmedFacts: ['Exakter Flächenbedarf (Schätzung: 1\'500–2\'000 m²)', 'Ob Breitenrain oder andere Berner Lage bevorzugt', 'Zeitpunkt Einzug'], }, diff --git a/src/pages/supply/MarketLeads.tsx b/src/pages/supply/MarketLeads.tsx new file mode 100644 index 0000000..8663c6b --- /dev/null +++ b/src/pages/supply/MarketLeads.tsx @@ -0,0 +1,296 @@ +import { + Box, + Chip, + CircularProgress, + Divider, + Paper, + Skeleton, + Typography, +} from '@mui/material' +import { + AlertCircle, + BarChart2, + Briefcase, + Building2, + CheckCircle2, + FileText, + Newspaper, + Target, + TrendingUp, + Users, +} from 'lucide-react' +import { useNavigate } from 'react-router' +import { useMarketLeads } from '../../hooks/useMarketLeads' +import { DecisionContextPanel } from '../../components/ui' +import type { MarketLead } from '../../hooks/useMarketLeads' +import type { Property } from '../../domain/property' + +// ── Source meta ────────────────────────────────────────────────────────────── + +const SOURCE_META: Record = { + JOB_POSTING: { label: 'Stelleninserate', icon: }, + PRESS: { label: 'Pressebericht', icon: }, + COMPANY_REPORT: { label: 'Geschäftsbericht',icon: }, + MARKET_DATA: { label: 'Marktdaten', icon: }, +} + +const QUALITY_META: Record = { + HIGH: { label: 'Hohe Signalqualität', color: '#1a7a4a' }, + MEDIUM: { label: 'Mittlere Signalqualität', color: '#d97706' }, + LOW: { label: 'Niedrige Signalqualität', color: '#c0392b' }, +} + +function signalQuality(probability: number): 'HIGH' | 'MEDIUM' | 'LOW' { + return probability >= 0.70 ? 'HIGH' : probability >= 0.50 ? 'MEDIUM' : 'LOW' +} + +// ── Property match chip ─────────────────────────────────────────────────────── + +function PropertyMatchRow({ p }: { p: Property }) { + const navigate = useNavigate() + return ( + navigate('/supply/properties')} + sx={{ + display: 'flex', alignItems: 'center', gap: 1, + px: 1.25, py: 0.75, borderRadius: 1, + bgcolor: '#f0fdf4', border: '1px solid #bbf7d0', + cursor: 'pointer', '&:hover': { bgcolor: '#dcfce7' }, + }} + > + + + {p.title} + + + {p.areaSqm.toLocaleString('de-CH')} m² + + + ) +} + +// ── Lead card ───────────────────────────────────────────────────────────────── + +function LeadCard({ lead }: { lead: MarketLead }) { + const { signal, matchingProperties } = lead + const probPct = Math.round(signal.probability * 100) + const qual = signalQuality(signal.probability) + const qualMeta = QUALITY_META[qual] + const sourceMeta = SOURCE_META[signal.source.type] ?? null + + return ( + + {/* Header */} + + + + + + + + {signal.companyName ?? signal.locationHint} + + + {signal.title} + + + + + + + {/* Key facts strip */} + + {signal.areaSqmEstimate && ( + + Flächenbedarf + ~{signal.areaSqmEstimate.toLocaleString('de-CH')} m² + + )} + + Zeithorizont + ~{signal.timeHorizonMonths} Monate + + + Wahrscheinlichkeit + {probPct}% + + + Standort + {signal.locationHint} + + {sourceMeta && ( + + Quelle + + {sourceMeta.icon} + {sourceMeta.label} + + + )} + + + + + {/* Market indicators */} + {signal.marketIndicators && signal.marketIndicators.length > 0 && ( + + + Erkannte Nachfragesignale + + + {signal.marketIndicators.map((ind, i) => ( + + + {ind} + + ))} + + + )} + + {/* Confirmed / unconfirmed facts */} + {((signal.confirmedFacts?.length ?? 0) > 0 || (signal.unconfirmedFacts?.length ?? 0) > 0) && ( + + + {(signal.confirmedFacts ?? []).map((f, i) => ( + + + {f} + + ))} + {(signal.unconfirmedFacts ?? []).map((f, i) => ( + + + {f} + + ))} + + + )} + + + + {/* Portfolio matches */} + + + Passende Objekte im Portfolio ({matchingProperties.length}) + + {matchingProperties.length === 0 ? ( + + Kein passendes Portfolioobjekt gefunden — manuell prüfen empfohlen + + ) : ( + + {matchingProperties.slice(0, 3).map(p => ( + + ))} + {matchingProperties.length > 3 && ( + + +{matchingProperties.length - 3} weitere Objekte + + )} + + )} + + + {/* Disclaimer */} + + {signal.disclaimer} + + + ) +} + +// ── Loading skeleton ────────────────────────────────────────────────────────── + +function LeadSkeleton() { + return ( + + + + + + + ) +} + +// ── Page ────────────────────────────────────────────────────────────────────── + +export default function MarketLeads() { + const { data: leads, isLoading } = useMarketLeads() + + const leadsWithMatch = leads.filter(l => l.matchingProperties.length > 0) + + return ( + + + {/* Header */} + + + + + Markt-Leads + + Erkannte Unternehmen mit aktivem Flächenbedarf — potenzielle Mieter für Ihr Portfolio + + + {!isLoading && ( + + )} + + + + + + {/* Decision context */} + {!isLoading && leads.length > 0 && ( + 0 + ? [{ label: 'mit passendem Objekt', value: leadsWithMatch.length, severity: 'positive' as const }] + : []), + ]} + risks={leads.length - leadsWithMatch.length > 0 + ? [`${leads.length - leadsWithMatch.length} Leads ohne direkten Portfolio-Match — Leerstandsanalyse empfohlen`] + : [] + } + actions={[]} + /> + )} + + {isLoading ? ( + <> + + + + + ) : leads.length === 0 ? ( + + + Keine aktiven Markt-Leads gefunden. + Signale werden laufend aus öffentlichen Quellen erkannt. + + ) : ( + leads.map(lead => ) + )} + + + ) +}