Initial commit

This commit is contained in:
Benjamin Sutter
2026-05-15 00:48:18 +02:00
commit 9e827c50f9
72 changed files with 10477 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
import { SignalType, RiskLevel } from '../domain/enums'
import type { FutureSignal } from '../domain/futureSignal'
export const mockFutureSignals: FutureSignal[] = [
{
id: 'signal-001',
signalType: SignalType.EXPANSION,
companyName: 'DataCloud Systems AG',
locationHint: 'Zürich-West / Technopark',
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',
},
{
id: 'signal-002',
signalType: SignalType.POSSIBLE_MOVE_OUT,
companyName: 'Helvetia Produktion GmbH',
propertyId: 'prop-006',
locationHint: 'Reinach BL, Industriezone Nord',
areaSqmEstimate: 3200,
probability: 0.48,
confidenceScore: 0.44,
timeHorizonMonths: 13,
source: {
type: 'PRESS',
url: 'https://example.com/news/helvetia-restrukturierung',
publishedAt: '2025-03-15',
credibility: 'HIGH',
},
sensitivityLevel: 'CONFIDENTIAL',
disclaimer: 'Dieses Signal basiert auf Pressemeldungen zu Restrukturierungsplänen. Kein bestätigter Auszug. Vertraulich behandeln.',
riskLevel: RiskLevel.HIGH,
marketIndicator: 'Restrukturierungsankündigung Mutterkonzern',
relevanceScore: 0.61,
isVerified: false,
expiresAt: '2026-06-01',
organizationId: 'org-wincasa',
createdAt: '2025-05-03T08:00:00Z',
updatedAt: '2025-05-10T08:00:00Z',
},
{
id: 'signal-003',
signalType: SignalType.CONSTRUCTION_PROJECT,
locationHint: 'Bern, Wankdorf',
areaSqmEstimate: 4500,
probability: 0.85,
confidenceScore: 0.80,
timeHorizonMonths: 24,
source: {
type: 'CONSTRUCTION_PERMIT',
publishedAt: '2025-02-10',
credibility: 'HIGH',
},
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',
relevanceScore: 0.82,
isVerified: true,
verifiedBy: 'admin@ideal-sharing.ch',
verifiedAt: '2025-05-05T09:00:00Z',
expiresAt: '2027-03-01',
organizationId: 'org-wincasa',
createdAt: '2025-02-12T10:00:00Z',
updatedAt: '2025-05-05T09:00:00Z',
},
]
+4
View File
@@ -0,0 +1,4 @@
export { mockProperties } from './properties'
export { mockNeeds } from './needs'
export { mockMatches } from './matches'
export { mockFutureSignals } from './futureSignals'
+141
View File
@@ -0,0 +1,141 @@
import { MatchStrength, RiskLevel } from '../domain/enums'
import type { Match } from '../domain/match'
export const mockMatches: Match[] = [
{
id: 'match-001',
propertyId: 'prop-001',
needId: 'need-001',
matchScore: 88,
matchStrength: MatchStrength.STRONG,
scoreBreakdown: {
hardMatchScore: 92,
softFactorScore: 85,
confidenceModifier: 0.97,
dataQualityModifier: 0.92,
totalScore: 88,
},
positiveFactors: [
{ criterion: 'Fläche', weight: 0.20, score: 95, contribution: 19, explanation: '850m² liegt im Zielkorridor (6001000m²)' },
{ criterion: 'ÖV-Anbindung', weight: 0.20, score: 90, contribution: 18, explanation: '4 Min. zur S-Bahn, Kriterium erfüllt' },
{ criterion: 'Standort', weight: 0.15, score: 88, contribution: 13.2, explanation: 'Zürich-West trifft bevorzugte Lage' },
],
negativeFactors: [
{ criterion: 'Mietpreis', weight: 0.15, score: 76, contribution: 11.4, explanation: 'CHF 38/m² liegt über Wunschbudget von CHF 35/m²' },
],
tradeoffs: [
{ criterion: 'Budget', concern: 'Mietpreis 8% über Budget-Maximum', severity: 'MEDIUM', mitigation: 'Verhandlungspotenzial vorhanden Objekt leer seit 3 Monaten' },
],
explainabilitySummary: 'Starker Match aufgrund idealer Lage und Fläche. Einziger Vorbehalt ist der Mietpreis, der knapp über dem Budget liegt, aber verhandelbar erscheint.',
confidenceLevel: 0.92,
riskLevel: RiskLevel.LOW,
uncertaintyIndicators: [],
alternativeStrategies: [
{ title: 'Kleinere Einheit im gleichen Gebäude', description: '650m² verfügbar ab Q3 2025, CHF 35/m²', expectedScore: 82 },
],
organizationId: 'org-wincasa',
createdAt: '2025-05-10T08:00:00Z',
updatedAt: '2025-05-10T08:00:00Z',
},
{
id: 'match-002',
propertyId: 'prop-004',
needId: 'need-001',
matchScore: 64,
matchStrength: MatchStrength.MODERATE,
scoreBreakdown: {
hardMatchScore: 78,
softFactorScore: 62,
confidenceModifier: 0.68,
dataQualityModifier: 0.55,
totalScore: 64,
},
positiveFactors: [
{ criterion: 'Fläche', weight: 0.20, score: 88, contribution: 17.6, explanation: '1150m² liegt im erweiterten Korridor' },
{ criterion: 'Standort', weight: 0.20, score: 80, contribution: 16, explanation: 'Zürich Kreis 4 nahe bevorzugten Lagen' },
],
negativeFactors: [
{ criterion: 'Datenqualität', weight: 0.10, score: 40, contribution: 4, explanation: 'Mehrere kritische Felder fehlen Verlässlichkeit eingeschränkt' },
{ criterion: 'Mietpreis', weight: 0.15, score: 55, contribution: 8.25, explanation: 'CHF 52/m² deutlich über Budget' },
],
tradeoffs: [
{ criterion: 'Datenqualität', concern: 'Externe Quelle Mietpreis und Verfügbarkeit nicht bestätigt', severity: 'HIGH', mitigation: 'Direkte Anfrage beim Anbieter empfohlen' },
{ criterion: 'Budget', concern: 'Mietpreis 30% über Budget-Maximum', severity: 'HIGH' },
],
explainabilitySummary: 'Moderater Match Fläche und Lage passen, aber Mietpreis und Datenqualität sind kritische Vorbehalte. Nur mit Preisverhandlung und Verifikation sinnvoll.',
confidenceLevel: 0.58,
riskLevel: RiskLevel.MEDIUM,
uncertaintyIndicators: ['Daten aus Drittquelle unvollständig', 'Mietpreis nicht verifiziert'],
organizationId: 'org-wincasa',
createdAt: '2025-05-10T08:05:00Z',
updatedAt: '2025-05-10T08:05:00Z',
},
{
id: 'match-003',
propertyId: 'prop-002',
needId: 'need-002',
matchScore: 91,
matchStrength: MatchStrength.STRONG,
scoreBreakdown: {
hardMatchScore: 94,
softFactorScore: 89,
confidenceModifier: 0.99,
dataQualityModifier: 0.96,
totalScore: 91,
},
positiveFactors: [
{ criterion: 'Fläche', weight: 0.25, score: 96, contribution: 24, explanation: '2400m² im Zielkorridor (15004000m²)' },
{ criterion: 'Autobahnanschluss', weight: 0.20, score: 92, contribution: 18.4, explanation: 'A2-Anschluss ca. 4 Min., Kriterium erfüllt' },
{ criterion: 'Budget', weight: 0.20, score: 88, contribution: 17.6, explanation: 'CHF 14/m² liegt unter Maximum von CHF 18/m²' },
{ criterion: 'Datenqualität', weight: 0.10, score: 96, contribution: 9.6, explanation: 'Verifiziertes Portfolioobjekt, alle Felder vollständig' },
],
negativeFactors: [
{ criterion: 'Erweiterungspotenzial', weight: 0.05, score: 70, contribution: 3.5, explanation: '800m² Erweiterung möglich, aber begrenzt' },
],
tradeoffs: [],
explainabilitySummary: 'Sehr starker Match. Fläche, Anbindung und Budget passen exzellent. Hohe Datenqualität aus internem Portfolio bestätigt Verlässlichkeit.',
confidenceLevel: 0.96,
riskLevel: RiskLevel.LOW,
uncertaintyIndicators: [],
organizationId: 'org-wincasa',
createdAt: '2025-05-10T08:10:00Z',
updatedAt: '2025-05-10T08:10:00Z',
},
{
id: 'match-004',
propertyId: 'prop-006',
needId: 'need-002',
matchScore: 47,
matchStrength: MatchStrength.WEAK,
scoreBreakdown: {
hardMatchScore: 70,
softFactorScore: 40,
confidenceModifier: 0.48,
dataQualityModifier: 0.30,
totalScore: 47,
},
positiveFactors: [
{ criterion: 'Fläche', weight: 0.25, score: 85, contribution: 21.25, explanation: '3200m² im erweiterten Zielkorridor' },
{ criterion: 'Standort', weight: 0.20, score: 72, contribution: 14.4, explanation: 'Reinach BL ist eine bevorzugte Region' },
],
negativeFactors: [
{ criterion: 'Confidence', weight: 0.15, score: 20, contribution: 3, explanation: 'Nur 48% Signalwahrscheinlichkeit kein bestätigtes Objekt' },
{ criterion: 'Datenqualität', weight: 0.10, score: 15, contribution: 1.5, explanation: 'Mehrere kritische Felder fehlen, Schätzwerte' },
{ criterion: 'Timing', weight: 0.15, score: 50, contribution: 7.5, explanation: 'Verfügbarkeit erst Q2 2026, spät für Anforderung' },
],
tradeoffs: [
{ criterion: 'Verfügbarkeit', concern: 'Probabilistisches Future-Signal keine Garantie auf Verfügbarkeit', severity: 'HIGH', mitigation: 'Für Monitoring-Watchlist geeignet' },
{ criterion: 'Daten', concern: 'Mietpreis geschätzt, Andienung nicht bestätigt', severity: 'HIGH' },
],
explainabilitySummary: 'Schwacher Match aufgrund hoher Unsicherheit. Das Signal ist interessant als Frühindikator, aber nicht als aktive Option geeignet. Empfehlung: Watchlist.',
confidenceLevel: 0.38,
riskLevel: RiskLevel.HIGH,
uncertaintyIndicators: ['Probabilistisches Signal ohne Bestätigung', 'Mietpreis geschätzt', 'Verfügbarkeitsdatum unsicher'],
alternativeStrategies: [
{ title: 'Signal beobachten', description: 'Als Future-Availability-Signal auf Watchlist setzen und in 3 Monaten neu evaluieren' },
],
organizationId: 'org-wincasa',
createdAt: '2025-05-10T08:15:00Z',
updatedAt: '2025-05-10T08:15:00Z',
},
]
+76
View File
@@ -0,0 +1,76 @@
import { AssetType } from '../domain/enums'
import type { Need } from '../domain/need'
export const mockNeeds: Need[] = [
{
id: 'need-001',
companyName: 'Innovatech AG',
contactName: 'Sandra Meier',
assetType: AssetType.OFFICE,
requiredArea: { min: 600, max: 1000 },
preferredLocations: ['Zürich', 'Zürich-West', 'Zürich Kreis 5'],
excludedLocations: [],
budgetRange: { maxPerSqm: 45, maxMonthlyTotal: 40000, currency: 'CHF' },
timing: {
earliestMoveIn: '2025-08-01',
latestMoveIn: '2026-01-01',
contractDurationMonths: 60,
flexibleTiming: true,
},
mustCriteriaText: ['ÖV-Anbindung < 5 Min', 'Mindestfläche 600m²', 'Ausbaugrad modern'],
softFactors: {
minPrestige: 70,
minAccessibility: 80,
requireParking: false,
maxPublicTransportMinutes: 6,
},
weightingProfile: {
area: 0.20,
location: 0.20,
budget: 0.15,
timing: 0.15,
prestige: 0.10,
accessibility: 0.10,
expansionPotential: 0.05,
flexibility: 0.05,
},
confidenceInCriteria: 0.88,
extractedFromText: 'Wir suchen moderne Büroflächen in Zürich-West, ca. 700900m², Budget max CHF 42/m², Bezug Herbst 2025.',
organizationId: 'org-wincasa',
createdAt: '2025-04-15T10:00:00Z',
updatedAt: '2025-05-01T09:00:00Z',
},
{
id: 'need-002',
companyName: 'Schweizer Logistik GmbH',
contactName: 'Thomas Brun',
assetType: AssetType.LOGISTICS,
requiredArea: { min: 1500, max: 4000 },
preferredLocations: ['Basel', 'Muttenz', 'Pratteln', 'Reinach BL'],
budgetRange: { maxPerSqm: 18, currency: 'CHF' },
timing: {
earliestMoveIn: '2025-09-01',
latestMoveIn: '2026-06-01',
contractDurationMonths: 36,
flexibleTiming: false,
},
mustCriteriaText: ['Autobahnanschluss < 5 Min', 'Rampe / Andienung', 'Hallenhöhe min 6m'],
softFactors: {
requireParking: true,
},
weightingProfile: {
area: 0.25,
location: 0.20,
budget: 0.20,
timing: 0.15,
prestige: 0.02,
accessibility: 0.10,
expansionPotential: 0.05,
flexibility: 0.03,
},
confidenceInCriteria: 0.94,
organizationId: 'org-wincasa',
createdAt: '2025-03-20T14:00:00Z',
updatedAt: '2025-04-10T11:00:00Z',
},
]
+192
View File
@@ -0,0 +1,192 @@
import { AssetType, ResultType, AvailabilityStatus, DataFreshness, RiskLevel } from '../domain/enums'
import type { Property } from '../domain/property'
export const mockProperties: Property[] = [
// --- VERIFIED_PORTFOLIO ---
{
id: 'prop-001',
title: 'Bürofläche Zollstrasse 12',
assetType: AssetType.OFFICE,
resultType: ResultType.VERIFIED_PORTFOLIO,
location: { city: 'Zürich', district: 'Zürich-West', canton: 'ZH', country: 'CH', coordinates: { lat: 47.3882, lng: 8.5132 } },
address: { street: 'Zollstrasse', houseNumber: '12', postalCode: '8005', city: 'Zürich', country: 'CH' },
areaSqm: 850,
rentPricePerSqm: 38,
totalRentMonthly: 32300,
availabilityDate: '2025-09-01',
availabilityStatus: AvailabilityStatus.AVAILABLE_SOON,
sourceType: 'ERP_IMPORT',
confidenceScore: 0.97,
dataQuality: {
score: 0.92,
missingCriticalFields: [],
missingOptionalFields: ['expansionPotentialSqm'],
lastVerifiedAt: '2025-04-28',
freshness: DataFreshness.FRESH,
warnings: [],
},
softFactors: {
prestige: 78,
accessibility: 90,
visibilityScore: 65,
talentAccess: 85,
parkingSpots: 12,
publicTransportMinutes: 4,
},
floorLevel: 3,
contractDurationMonths: 60,
ancillaryCosts: 5.5,
riskLevel: RiskLevel.LOW,
organizationId: 'org-wincasa',
createdAt: '2025-01-10T08:00:00Z',
updatedAt: '2025-04-28T10:30:00Z',
},
{
id: 'prop-002',
title: 'Lagerfläche Hardstrasse 44',
assetType: AssetType.LOGISTICS,
resultType: ResultType.VERIFIED_PORTFOLIO,
location: { city: 'Basel', district: 'Kleinhüningen', canton: 'BS', country: 'CH', coordinates: { lat: 47.5736, lng: 7.5946 } },
address: { street: 'Hardstrasse', houseNumber: '44', postalCode: '4057', city: 'Basel', country: 'CH' },
areaSqm: 2400,
rentPricePerSqm: 14,
totalRentMonthly: 33600,
availabilityDate: '2025-07-01',
availabilityStatus: AvailabilityStatus.AVAILABLE_NOW,
sourceType: 'ERP_IMPORT',
confidenceScore: 0.99,
dataQuality: {
score: 0.96,
missingCriticalFields: [],
missingOptionalFields: [],
lastVerifiedAt: '2025-05-05',
freshness: DataFreshness.FRESH,
warnings: [],
},
softFactors: {
prestige: 40,
accessibility: 88,
parkingSpots: 30,
publicTransportMinutes: 12,
},
floorLevel: 0,
expansionPotentialSqm: 800,
contractDurationMonths: 36,
ancillaryCosts: 3.0,
riskLevel: RiskLevel.LOW,
organizationId: 'org-wincasa',
createdAt: '2024-11-20T09:00:00Z',
updatedAt: '2025-05-05T11:00:00Z',
},
// --- EXTERNAL_MARKET ---
{
id: 'prop-003',
title: 'Retail-Fläche Bahnhofstrasse 88',
assetType: AssetType.RETAIL,
resultType: ResultType.EXTERNAL_MARKET,
location: { city: 'Bern', district: 'Innenstadt', canton: 'BE', country: 'CH', coordinates: { lat: 46.9483, lng: 7.4474 } },
address: { street: 'Bahnhofstrasse', houseNumber: '88', postalCode: '3011', city: 'Bern', country: 'CH' },
areaSqm: 320,
rentPricePerSqm: 95,
totalRentMonthly: 30400,
availabilityDate: '2025-08-15',
availabilityStatus: AvailabilityStatus.AVAILABLE_SOON,
sourceType: 'MATCHOFFICE_SCRAPE',
sourceUrl: 'https://example.com/listing/prop-003',
confidenceScore: 0.71,
dataQuality: {
score: 0.62,
missingCriticalFields: ['contractDurationMonths'],
missingOptionalFields: ['ancillaryCosts', 'floorLevel'],
lastVerifiedAt: '2025-04-10',
freshness: DataFreshness.STALE,
warnings: ['Mietpreis nicht bestätigt', 'Verfügbarkeit nicht verifiziert'],
},
softFactors: {
prestige: 92,
visibilityScore: 98,
passerbyFrequency: 'VERY_HIGH',
publicTransportMinutes: 2,
},
riskLevel: RiskLevel.MEDIUM,
createdAt: '2025-02-15T14:00:00Z',
updatedAt: '2025-04-10T09:00:00Z',
},
{
id: 'prop-004',
title: 'Gemischte Gewerbeeinheit Europaallee',
assetType: AssetType.MIXED,
resultType: ResultType.EXTERNAL_MARKET,
location: { city: 'Zürich', district: 'Kreis 4', canton: 'ZH', country: 'CH', coordinates: { lat: 47.3775, lng: 8.5398 } },
address: { street: 'Europaallee', houseNumber: '21', postalCode: '8004', city: 'Zürich', country: 'CH' },
areaSqm: 1150,
rentPricePerSqm: 52,
totalRentMonthly: 59800,
availabilityDate: '2025-10-01',
availabilityStatus: AvailabilityStatus.AVAILABLE_SOON,
sourceType: 'IMMOSCOUT_SCRAPE',
confidenceScore: 0.68,
dataQuality: {
score: 0.55,
missingCriticalFields: ['contractDurationMonths', 'ancillaryCosts'],
missingOptionalFields: ['softFactors'],
lastVerifiedAt: '2025-03-20',
freshness: DataFreshness.STALE,
warnings: ['Daten aus Drittquelle nicht verifiziert'],
},
riskLevel: RiskLevel.MEDIUM,
createdAt: '2025-03-01T10:00:00Z',
updatedAt: '2025-03-20T15:00:00Z',
},
// --- FUTURE_AVAILABILITY ---
{
id: 'prop-005',
title: 'Bürofläche Technoparkstrasse (Signal: Expansion)',
assetType: AssetType.OFFICE,
resultType: ResultType.FUTURE_AVAILABILITY,
location: { city: 'Zürich', district: 'Technopark', canton: 'ZH', country: 'CH', coordinates: { lat: 47.3923, lng: 8.5142 } },
address: { street: 'Technoparkstrasse', houseNumber: '1', postalCode: '8005', city: 'Zürich', country: 'CH' },
areaSqm: 600,
rentPricePerSqm: 42,
availabilityDate: '2026-03-01',
availabilityStatus: AvailabilityStatus.FUTURE_SIGNAL,
sourceType: 'AI_SIGNAL',
confidenceScore: 0.55,
dataQuality: {
score: 0.38,
missingCriticalFields: ['totalRentMonthly', 'contractDurationMonths'],
missingOptionalFields: ['ancillaryCosts', 'floorLevel', 'parkingSpots'],
freshness: DataFreshness.FRESH,
warnings: ['Probabilistisches Signal kein bestätigtes Objekt', 'Daten nicht verifiziert'],
},
riskLevel: RiskLevel.HIGH,
createdAt: '2025-05-01T07:00:00Z',
updatedAt: '2025-05-10T07:00:00Z',
},
{
id: 'prop-006',
title: 'Produktionsfläche Reinach (Signal: möglicher Auszug)',
assetType: AssetType.PRODUCTION,
resultType: ResultType.FUTURE_AVAILABILITY,
location: { city: 'Reinach', district: 'Industriezone Nord', canton: 'BL', country: 'CH', coordinates: { lat: 47.4978, lng: 7.5933 } },
address: { street: 'Industriestrasse', houseNumber: '18', postalCode: '4153', city: 'Reinach', country: 'CH' },
areaSqm: 3200,
rentPricePerSqm: 11,
availabilityDate: '2026-06-01',
availabilityStatus: AvailabilityStatus.FUTURE_SIGNAL,
sourceType: 'AI_SIGNAL',
confidenceScore: 0.48,
dataQuality: {
score: 0.30,
missingCriticalFields: ['totalRentMonthly', 'rentPricePerSqm', 'contractDurationMonths'],
missingOptionalFields: ['ancillaryCosts', 'softFactors'],
freshness: DataFreshness.FRESH,
warnings: ['Probabilistisches Signal kein bestätigtes Objekt', 'Mietpreis geschätzt'],
},
riskLevel: RiskLevel.HIGH,
createdAt: '2025-05-03T08:00:00Z',
updatedAt: '2025-05-10T08:00:00Z',
},
]