d15a13e485
- Delete all ops page components (ReviewQueue, AIMonitoring, Governance, SourceMonitoring, ActivityTimeline, SignalPipeline) - Remove OPERATIONS workspace from AppShell config, nav order, path detection - Remove all /ops/* routes from App.tsx - Remove WorkspaceType.OPERATIONS from allowedWorkspaces in authService, sessionStore, permissions - Keep MarketIntelligence page (already moved to /supply/market-intelligence) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
861 lines
32 KiB
TypeScript
861 lines
32 KiB
TypeScript
import type { PipelineState, GateEvaluation, AuditTrailEntry } from '../domain/signalPipeline'
|
||
import { PipelineStage, GateType, GateStatus } from '../domain/signalPipeline'
|
||
|
||
function gate(
|
||
gateType: GateType,
|
||
status: GateStatus,
|
||
reason: string,
|
||
checks: GateEvaluation['checks'],
|
||
nextAction?: string,
|
||
): GateEvaluation {
|
||
return { gateType, status, reason, checks, nextAction, evaluatedAt: '2026-05-15T06:00:00Z' }
|
||
}
|
||
|
||
// ── sig-001: STAGE_4_REVIEW_CANDIDATE ─────────────────────────────────────────
|
||
const sig001Pipeline: PipelineState = {
|
||
signalId: 'sig-001',
|
||
currentStage: PipelineStage.STAGE_4_REVIEW_CANDIDATE,
|
||
overallEligible: false,
|
||
publishedToFutureAvailability: false,
|
||
gates: {
|
||
EVIDENCE_GATE: gate(
|
||
GateType.EVIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Mindestens ein valides Evidenzstück vorhanden.',
|
||
[
|
||
{ label: 'Evidenz vorhanden', passed: true, value: '1 Stück' },
|
||
{ label: 'Quelle angegeben', passed: true, value: 'Neue Zürcher Zeitung' },
|
||
{ label: 'Inhalt nicht leer', passed: true },
|
||
],
|
||
),
|
||
CONFIDENCE_GATE: gate(
|
||
GateType.CONFIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Konfidenzwert 0.72 liegt über dem Mindestschwellenwert von 0.60.',
|
||
[
|
||
{ label: 'Konfidenz ≥ 0.60', passed: true, value: '0.72' },
|
||
{ label: 'Konfidenz ≥ 0.75 (hoch)', passed: false, value: '0.72', note: 'Mittlere Konfidenz' },
|
||
],
|
||
),
|
||
SENSITIVITY_GATE: gate(
|
||
GateType.SENSITIVITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Sensitivitätsstufe INTERNAL ist für interne Feed-Nutzung zulässig.',
|
||
[
|
||
{ label: 'Nicht CONFIDENTIAL', passed: true, value: 'INTERNAL' },
|
||
{ label: 'Nicht RESTRICTED', passed: true },
|
||
],
|
||
),
|
||
REVIEW_GATE: gate(
|
||
GateType.REVIEW_GATE,
|
||
GateStatus.PENDING,
|
||
'Signal wartet auf manuellen Analyst-Review.',
|
||
[
|
||
{ label: 'Review angefordert', passed: true },
|
||
{ label: 'Review abgeschlossen', passed: false },
|
||
],
|
||
'Analyst-Review durchführen und Signal genehmigen oder ablehnen.',
|
||
),
|
||
MATCHABILITY_GATE: gate(
|
||
GateType.MATCHABILITY_GATE,
|
||
GateStatus.PENDING,
|
||
'Matchbarkeit kann erst nach abgeschlossenem Review bewertet werden.',
|
||
[
|
||
{ label: 'Asset-Typ definiert', passed: true, value: 'OFFICE' },
|
||
{ label: 'Standort definiert', passed: true, value: 'Zürich' },
|
||
{ label: 'Zeithorizont definiert', passed: false },
|
||
{ label: 'Geschäftsrelevanz vorhanden', passed: true },
|
||
],
|
||
'Review abschliessen, dann Matchbarkeit neu bewerten.',
|
||
),
|
||
FEED_ELIGIBILITY_GATE: gate(
|
||
GateType.FEED_ELIGIBILITY_GATE,
|
||
GateStatus.BLOCKED,
|
||
'Feed-Eignung blockiert: Review-Gate noch ausstehend.',
|
||
[
|
||
{ label: 'Review-Gate bestanden', passed: false },
|
||
{ label: 'Matchbarkeits-Gate bestanden', passed: false },
|
||
],
|
||
'Review und Matchbarkeits-Prüfung abschliessen.',
|
||
),
|
||
},
|
||
}
|
||
|
||
// ── sig-002: STAGE_5_APPROVED_FUTURE ─────────────────────────────────────────
|
||
const sig002Pipeline: PipelineState = {
|
||
signalId: 'sig-002',
|
||
currentStage: PipelineStage.STAGE_5_APPROVED_FUTURE,
|
||
overallEligible: true,
|
||
publishedToFutureAvailability: false,
|
||
gates: {
|
||
EVIDENCE_GATE: gate(
|
||
GateType.EVIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Baugesuchdokument als verlässliche Primärquelle vorhanden.',
|
||
[
|
||
{ label: 'Evidenz vorhanden', passed: true, value: '1 Stück' },
|
||
{ label: 'Quelle angegeben', passed: true, value: 'Baugesuchregister BS' },
|
||
{ label: 'Inhalt nicht leer', passed: true },
|
||
],
|
||
),
|
||
CONFIDENCE_GATE: gate(
|
||
GateType.CONFIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Konfidenzwert 0.88 überschreitet den hohen Schwellenwert von 0.75.',
|
||
[
|
||
{ label: 'Konfidenz ≥ 0.60', passed: true, value: '0.88' },
|
||
{ label: 'Konfidenz ≥ 0.75 (hoch)', passed: true, value: '0.88' },
|
||
],
|
||
),
|
||
SENSITIVITY_GATE: gate(
|
||
GateType.SENSITIVITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Öffentliche Quelle – keine Einschränkungen.',
|
||
[
|
||
{ label: 'Nicht CONFIDENTIAL', passed: true, value: 'PUBLIC' },
|
||
{ label: 'Nicht RESTRICTED', passed: true },
|
||
],
|
||
),
|
||
REVIEW_GATE: gate(
|
||
GateType.REVIEW_GATE,
|
||
GateStatus.PASSED,
|
||
'Signal durch Analyst M. Huber am 12.05.2026 genehmigt.',
|
||
[
|
||
{ label: 'Review angefordert', passed: true },
|
||
{ label: 'Review abgeschlossen', passed: true, value: 'M. Huber, 12.05.2026' },
|
||
{ label: 'Genehmigt', passed: true },
|
||
],
|
||
),
|
||
MATCHABILITY_GATE: gate(
|
||
GateType.MATCHABILITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Alle Pflichtfelder für Match-Engine vorhanden.',
|
||
[
|
||
{ label: 'Asset-Typ definiert', passed: true, value: 'OFFICE, LOGISTICS, RETAIL' },
|
||
{ label: 'Standort definiert', passed: true, value: 'Basel' },
|
||
{ label: 'Zeithorizont definiert', passed: true, value: 'Q1 2026' },
|
||
{ label: 'Geschäftsrelevanz vorhanden', passed: true },
|
||
],
|
||
),
|
||
FEED_ELIGIBILITY_GATE: gate(
|
||
GateType.FEED_ELIGIBILITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Alle Gates bestanden – Signal ist feed-fähig.',
|
||
[
|
||
{ label: 'Review-Gate bestanden', passed: true },
|
||
{ label: 'Matchbarkeits-Gate bestanden', passed: true },
|
||
{ label: 'Sensitivität zulässig', passed: true, value: 'PUBLIC' },
|
||
],
|
||
),
|
||
},
|
||
}
|
||
|
||
// ── sig-003: STAGE_3_ENRICHED ─────────────────────────────────────────────────
|
||
const sig003Pipeline: PipelineState = {
|
||
signalId: 'sig-003',
|
||
currentStage: PipelineStage.STAGE_3_ENRICHED,
|
||
overallEligible: false,
|
||
publishedToFutureAvailability: false,
|
||
gates: {
|
||
EVIDENCE_GATE: gate(
|
||
GateType.EVIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'LinkedIn-Datenauszug als Evidenz vorhanden.',
|
||
[
|
||
{ label: 'Evidenz vorhanden', passed: true, value: '1 Stück' },
|
||
{ label: 'Quelle angegeben', passed: true, value: 'LinkedIn Hiring Data' },
|
||
{ label: 'Inhalt nicht leer', passed: true },
|
||
],
|
||
),
|
||
CONFIDENCE_GATE: gate(
|
||
GateType.CONFIDENCE_GATE,
|
||
GateStatus.PENDING,
|
||
'Konfidenzwert 0.61 liegt im Grenzbereich (0.60–0.65). Zusätzliche Validierung empfohlen.',
|
||
[
|
||
{ label: 'Konfidenz ≥ 0.60', passed: true, value: '0.61', note: 'Grenzbereich' },
|
||
{ label: 'Konfidenz ≥ 0.75 (hoch)', passed: false, value: '0.61' },
|
||
],
|
||
'Unternehmensidentität über HR-Netzwerke verifizieren, um Konfidenz zu erhöhen.',
|
||
),
|
||
SENSITIVITY_GATE: gate(
|
||
GateType.SENSITIVITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Öffentliche Quelle – keine Einschränkungen.',
|
||
[
|
||
{ label: 'Nicht CONFIDENTIAL', passed: true, value: 'PUBLIC' },
|
||
{ label: 'Nicht RESTRICTED', passed: true },
|
||
],
|
||
),
|
||
REVIEW_GATE: gate(
|
||
GateType.REVIEW_GATE,
|
||
GateStatus.PENDING,
|
||
'Signal noch nicht für Review eingereicht.',
|
||
[
|
||
{ label: 'Review angefordert', passed: false },
|
||
{ label: 'Review abgeschlossen', passed: false },
|
||
],
|
||
'Signal für Analyst-Review einreichen nach Konfidenz-Verbesserung.',
|
||
),
|
||
MATCHABILITY_GATE: gate(
|
||
GateType.MATCHABILITY_GATE,
|
||
GateStatus.PENDING,
|
||
'Matchbarkeit noch nicht bewertet – Anreicherung läuft.',
|
||
[
|
||
{ label: 'Asset-Typ definiert', passed: true, value: 'OFFICE' },
|
||
{ label: 'Standort definiert', passed: true, value: 'Zug' },
|
||
{ label: 'Zeithorizont definiert', passed: false },
|
||
{ label: 'Geschäftsrelevanz vorhanden', passed: false, note: 'Unternehmensname unbekannt' },
|
||
],
|
||
),
|
||
FEED_ELIGIBILITY_GATE: gate(
|
||
GateType.FEED_ELIGIBILITY_GATE,
|
||
GateStatus.BLOCKED,
|
||
'Feed-Eignung blockiert: Mehrere vorgelagerte Gates ausstehend.',
|
||
[
|
||
{ label: 'Review-Gate bestanden', passed: false },
|
||
{ label: 'Matchbarkeits-Gate bestanden', passed: false },
|
||
],
|
||
),
|
||
},
|
||
}
|
||
|
||
// ── sig-004: STAGE_4_REVIEW_CANDIDATE ─────────────────────────────────────────
|
||
const sig004Pipeline: PipelineState = {
|
||
signalId: 'sig-004',
|
||
currentStage: PipelineStage.STAGE_4_REVIEW_CANDIDATE,
|
||
overallEligible: false,
|
||
publishedToFutureAvailability: false,
|
||
gates: {
|
||
EVIDENCE_GATE: gate(
|
||
GateType.EVIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Mietvertragsdokument als primäre Evidenz vorhanden.',
|
||
[
|
||
{ label: 'Evidenz vorhanden', passed: true, value: '1 Stück' },
|
||
{ label: 'Quelle angegeben', passed: true, value: 'Internes ERP' },
|
||
{ label: 'Inhalt nicht leer', passed: true },
|
||
],
|
||
),
|
||
CONFIDENCE_GATE: gate(
|
||
GateType.CONFIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Konfidenzwert 0.97 – sehr hohe Verlässlichkeit (interne Vertragsdaten).',
|
||
[
|
||
{ label: 'Konfidenz ≥ 0.60', passed: true, value: '0.97' },
|
||
{ label: 'Konfidenz ≥ 0.75 (hoch)', passed: true, value: '0.97' },
|
||
],
|
||
),
|
||
SENSITIVITY_GATE: gate(
|
||
GateType.SENSITIVITY_GATE,
|
||
GateStatus.FAILED,
|
||
'Sensitivitätsstufe CONFIDENTIAL: Signal darf nicht im Demand Feed erscheinen. Mieteridentität ist schützenswert.',
|
||
[
|
||
{ label: 'Nicht CONFIDENTIAL', passed: false, value: 'CONFIDENTIAL', note: 'Interne Vertragsdaten – nur für Property Manager' },
|
||
{ label: 'Nicht RESTRICTED', passed: true },
|
||
],
|
||
'Daten anonymisieren oder auf aggregierter Ebene veröffentlichen.',
|
||
),
|
||
REVIEW_GATE: gate(
|
||
GateType.REVIEW_GATE,
|
||
GateStatus.PENDING,
|
||
'Review angefordert – Sensitivitäts-Gate muss zuerst adressiert werden.',
|
||
[
|
||
{ label: 'Review angefordert', passed: true },
|
||
{ label: 'Review abgeschlossen', passed: false },
|
||
],
|
||
'Sensitivitätsproblem lösen, dann Review abschliessen.',
|
||
),
|
||
MATCHABILITY_GATE: gate(
|
||
GateType.MATCHABILITY_GATE,
|
||
GateStatus.PENDING,
|
||
'Matchbarkeit ausstehend – zuerst Sensitivitätsproblem lösen.',
|
||
[
|
||
{ label: 'Asset-Typ definiert', passed: true, value: 'OFFICE' },
|
||
{ label: 'Standort definiert', passed: true, value: 'Zürich-West' },
|
||
{ label: 'Zeithorizont definiert', passed: true, value: '03/2026' },
|
||
{ label: 'Geschäftsrelevanz vorhanden', passed: true },
|
||
],
|
||
),
|
||
FEED_ELIGIBILITY_GATE: gate(
|
||
GateType.FEED_ELIGIBILITY_GATE,
|
||
GateStatus.BLOCKED,
|
||
'Feed-Eignung blockiert: Sensitivitäts-Gate fehlgeschlagen.',
|
||
[
|
||
{ label: 'Sensitivitäts-Gate bestanden', passed: false, value: 'CONFIDENTIAL' },
|
||
{ label: 'Review-Gate bestanden', passed: false },
|
||
],
|
||
'Anonymisierung der Mieterdaten durchführen.',
|
||
),
|
||
},
|
||
}
|
||
|
||
// ── sig-005: STAGE_2_NORMALIZED ───────────────────────────────────────────────
|
||
const sig005Pipeline: PipelineState = {
|
||
signalId: 'sig-005',
|
||
currentStage: PipelineStage.STAGE_2_NORMALIZED,
|
||
overallEligible: false,
|
||
publishedToFutureAvailability: false,
|
||
gates: {
|
||
EVIDENCE_GATE: gate(
|
||
GateType.EVIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Handelsregistermutation als verlässliche Primärquelle.',
|
||
[
|
||
{ label: 'Evidenz vorhanden', passed: true, value: '1 Stück' },
|
||
{ label: 'Quelle angegeben', passed: true, value: 'Zefix – Handelsregister Schweiz' },
|
||
{ label: 'Inhalt nicht leer', passed: true },
|
||
],
|
||
),
|
||
CONFIDENCE_GATE: gate(
|
||
GateType.CONFIDENCE_GATE,
|
||
GateStatus.PENDING,
|
||
'Konfidenzwert 0.63 – Sitzverlegung bestätigt, aber Flächenbedarf am Zielort noch nicht validiert.',
|
||
[
|
||
{ label: 'Konfidenz ≥ 0.60', passed: true, value: '0.63', note: 'Grenzbereich' },
|
||
{ label: 'Konfidenz ≥ 0.75 (hoch)', passed: false, value: '0.63' },
|
||
],
|
||
'Flächenbedarf in Kloten durch Direktkontakt oder weitere Quellenrecherche bestätigen.',
|
||
),
|
||
SENSITIVITY_GATE: gate(
|
||
GateType.SENSITIVITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Öffentliches Handelsregister – keine Sensitivitätsbedenken.',
|
||
[
|
||
{ label: 'Nicht CONFIDENTIAL', passed: true, value: 'PUBLIC' },
|
||
{ label: 'Nicht RESTRICTED', passed: true },
|
||
],
|
||
),
|
||
REVIEW_GATE: gate(
|
||
GateType.REVIEW_GATE,
|
||
GateStatus.PENDING,
|
||
'Signal noch in Normalisierungsphase – kein Review angefordert.',
|
||
[
|
||
{ label: 'Review angefordert', passed: false },
|
||
{ label: 'Review abgeschlossen', passed: false },
|
||
],
|
||
'Anreicherung abschliessen, dann für Review einreichen.',
|
||
),
|
||
MATCHABILITY_GATE: gate(
|
||
GateType.MATCHABILITY_GATE,
|
||
GateStatus.PENDING,
|
||
'Anreicherung noch nicht abgeschlossen.',
|
||
[
|
||
{ label: 'Asset-Typ definiert', passed: true, value: 'LOGISTICS' },
|
||
{ label: 'Standort definiert', passed: true, value: 'Kloten' },
|
||
{ label: 'Zeithorizont definiert', passed: false },
|
||
{ label: 'Geschäftsrelevanz vorhanden', passed: false },
|
||
],
|
||
),
|
||
FEED_ELIGIBILITY_GATE: gate(
|
||
GateType.FEED_ELIGIBILITY_GATE,
|
||
GateStatus.BLOCKED,
|
||
'Feed-Eignung blockiert: Signal befindet sich noch in der Normalisierungsphase.',
|
||
[
|
||
{ label: 'Review-Gate bestanden', passed: false },
|
||
{ label: 'Matchbarkeits-Gate bestanden', passed: false },
|
||
],
|
||
),
|
||
},
|
||
}
|
||
|
||
// ── sig-006: STAGE_1_RAW_EVIDENCE ────────────────────────────────────────────
|
||
const sig006Pipeline: PipelineState = {
|
||
signalId: 'sig-006',
|
||
currentStage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
overallEligible: false,
|
||
publishedToFutureAvailability: false,
|
||
gates: {
|
||
EVIDENCE_GATE: gate(
|
||
GateType.EVIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Inserat auf Immoscout24 als Primärquelle vorhanden.',
|
||
[
|
||
{ label: 'Evidenz vorhanden', passed: true, value: '1 Stück' },
|
||
{ label: 'Quelle angegeben', passed: true, value: 'Immoscout24' },
|
||
{ label: 'Inhalt nicht leer', passed: true },
|
||
],
|
||
),
|
||
CONFIDENCE_GATE: gate(
|
||
GateType.CONFIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Konfidenzwert 0.83 – direkte Nachfrage-Ausschreibung mit hoher Relevanz.',
|
||
[
|
||
{ label: 'Konfidenz ≥ 0.60', passed: true, value: '0.83' },
|
||
{ label: 'Konfidenz ≥ 0.75 (hoch)', passed: true, value: '0.83' },
|
||
],
|
||
),
|
||
SENSITIVITY_GATE: gate(
|
||
GateType.SENSITIVITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Öffentliche Plattform – keine Einschränkungen.',
|
||
[
|
||
{ label: 'Nicht CONFIDENTIAL', passed: true, value: 'PUBLIC' },
|
||
{ label: 'Nicht RESTRICTED', passed: true },
|
||
],
|
||
),
|
||
REVIEW_GATE: gate(
|
||
GateType.REVIEW_GATE,
|
||
GateStatus.PENDING,
|
||
'Signal soeben erkannt – Normalisierung und Anreicherung noch ausstehend.',
|
||
[
|
||
{ label: 'Review angefordert', passed: false },
|
||
{ label: 'Review abgeschlossen', passed: false },
|
||
],
|
||
'Signal normalisieren und anreichern, dann für Review einreichen.',
|
||
),
|
||
MATCHABILITY_GATE: gate(
|
||
GateType.MATCHABILITY_GATE,
|
||
GateStatus.PENDING,
|
||
'Matchbarkeit noch nicht bewertet – Signal in früher Phase.',
|
||
[
|
||
{ label: 'Asset-Typ definiert', passed: true, value: 'LOGISTICS' },
|
||
{ label: 'Standort definiert', passed: true, value: 'Winterthur' },
|
||
{ label: 'Zeithorizont definiert', passed: true, value: 'September 2025' },
|
||
{ label: 'Geschäftsrelevanz vorhanden', passed: false },
|
||
],
|
||
),
|
||
FEED_ELIGIBILITY_GATE: gate(
|
||
GateType.FEED_ELIGIBILITY_GATE,
|
||
GateStatus.BLOCKED,
|
||
'Feed-Eignung blockiert: Signal in Rohphase – mehrere Stufen offen.',
|
||
[
|
||
{ label: 'Review-Gate bestanden', passed: false },
|
||
{ label: 'Matchbarkeits-Gate bestanden', passed: false },
|
||
],
|
||
),
|
||
},
|
||
}
|
||
|
||
// ── sig-007: STAGE_3_ENRICHED ─────────────────────────────────────────────────
|
||
const sig007Pipeline: PipelineState = {
|
||
signalId: 'sig-007',
|
||
currentStage: PipelineStage.STAGE_3_ENRICHED,
|
||
overallEligible: false,
|
||
publishedToFutureAvailability: false,
|
||
gates: {
|
||
EVIDENCE_GATE: gate(
|
||
GateType.EVIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'SBB-Medienmitteilung als verlässliche behördliche Quelle.',
|
||
[
|
||
{ label: 'Evidenz vorhanden', passed: true, value: '1 Stück' },
|
||
{ label: 'Quelle angegeben', passed: true, value: 'SBB Medienmitteilung' },
|
||
{ label: 'Inhalt nicht leer', passed: true },
|
||
],
|
||
),
|
||
CONFIDENCE_GATE: gate(
|
||
GateType.CONFIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Konfidenzwert 0.79 – behördliche Bestätigung vorhanden.',
|
||
[
|
||
{ label: 'Konfidenz ≥ 0.60', passed: true, value: '0.79' },
|
||
{ label: 'Konfidenz ≥ 0.75 (hoch)', passed: true, value: '0.79' },
|
||
],
|
||
),
|
||
SENSITIVITY_GATE: gate(
|
||
GateType.SENSITIVITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Öffentliche SBB-Mitteilung – keine Sensitivitätsbedenken.',
|
||
[
|
||
{ label: 'Nicht CONFIDENTIAL', passed: true, value: 'PUBLIC' },
|
||
{ label: 'Nicht RESTRICTED', passed: true },
|
||
],
|
||
),
|
||
REVIEW_GATE: gate(
|
||
GateType.REVIEW_GATE,
|
||
GateStatus.PENDING,
|
||
'Matchbarkeits-Problem muss zuerst gelöst werden.',
|
||
[
|
||
{ label: 'Review angefordert', passed: false },
|
||
{ label: 'Review abgeschlossen', passed: false },
|
||
],
|
||
'Matchbarkeits-Frage klären (kein direktes Verfügbarkeitssignal), dann Review starten.',
|
||
),
|
||
MATCHABILITY_GATE: gate(
|
||
GateType.MATCHABILITY_GATE,
|
||
GateStatus.FAILED,
|
||
'Signal Typ PROJECT_DEVELOPMENT ohne direktes Verfügbarkeitssignal – kein konkreter Flächenbedarf erkennbar.',
|
||
[
|
||
{ label: 'Asset-Typ definiert', passed: true, value: 'OFFICE, PRODUCTION' },
|
||
{ label: 'Standort definiert', passed: true, value: 'Schlieren' },
|
||
{ label: 'Zeithorizont definiert', passed: true, value: 'Dezember 2027' },
|
||
{ label: 'Direktes Verfügbarkeitssignal', passed: false, note: 'Infrastrukturverbesserung ohne konkreten Flächenbedarf' },
|
||
],
|
||
'Signal als strategischen Kontext-Input klassifizieren oder konkreten Bedarf nachweisen.',
|
||
),
|
||
FEED_ELIGIBILITY_GATE: gate(
|
||
GateType.FEED_ELIGIBILITY_GATE,
|
||
GateStatus.BLOCKED,
|
||
'Feed-Eignung blockiert: Matchbarkeits-Gate fehlgeschlagen.',
|
||
[
|
||
{ label: 'Matchbarkeits-Gate bestanden', passed: false },
|
||
{ label: 'Review-Gate bestanden', passed: false },
|
||
],
|
||
'Signal als strategischen Input behandeln oder Matchbarkeit nachweisen.',
|
||
),
|
||
},
|
||
}
|
||
|
||
// ── sig-008: STAGE_6_MATCHABLE_RESULT ────────────────────────────────────────
|
||
const sig008Pipeline: PipelineState = {
|
||
signalId: 'sig-008',
|
||
currentStage: PipelineStage.STAGE_6_MATCHABLE_RESULT,
|
||
overallEligible: true,
|
||
publishedToFutureAvailability: true,
|
||
publishedAt: '2026-05-13T11:00:00Z',
|
||
feedDisclaimer: 'Nur in aggregierter Form – Mieteridentität anonymisiert. Kein Rückschluss auf Vertragsparteien möglich.',
|
||
gates: {
|
||
EVIDENCE_GATE: gate(
|
||
GateType.EVIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Eigene Marktbeobachtung mit Vor-Ort-Begehung dokumentiert.',
|
||
[
|
||
{ label: 'Evidenz vorhanden', passed: true, value: '1 Stück' },
|
||
{ label: 'Quelle angegeben', passed: true, value: 'Eigene Beobachtung – Marktanalyse' },
|
||
{ label: 'Inhalt nicht leer', passed: true },
|
||
],
|
||
),
|
||
CONFIDENCE_GATE: gate(
|
||
GateType.CONFIDENCE_GATE,
|
||
GateStatus.PASSED,
|
||
'Konfidenzwert 0.68 – ausreichend für interne Verarbeitung.',
|
||
[
|
||
{ label: 'Konfidenz ≥ 0.60', passed: true, value: '0.68' },
|
||
{ label: 'Konfidenz ≥ 0.75 (hoch)', passed: false, value: '0.68', note: 'Mittlere Konfidenz akzeptiert' },
|
||
],
|
||
),
|
||
SENSITIVITY_GATE: gate(
|
||
GateType.SENSITIVITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Sensitivitätsstufe INTERNAL mit Anonymisierungsauflage zulässig.',
|
||
[
|
||
{ label: 'Nicht CONFIDENTIAL', passed: true, value: 'INTERNAL' },
|
||
{ label: 'Nicht RESTRICTED', passed: true },
|
||
{ label: 'Anonymisierungsauflage gesetzt', passed: true },
|
||
],
|
||
),
|
||
REVIEW_GATE: gate(
|
||
GateType.REVIEW_GATE,
|
||
GateStatus.PASSED,
|
||
'Signal durch Analyst A. Müller am 13.05.2026 genehmigt und zur Publikation freigegeben.',
|
||
[
|
||
{ label: 'Review angefordert', passed: true },
|
||
{ label: 'Review abgeschlossen', passed: true, value: 'A. Müller, 13.05.2026' },
|
||
{ label: 'Genehmigt', passed: true },
|
||
],
|
||
),
|
||
MATCHABILITY_GATE: gate(
|
||
GateType.MATCHABILITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Alle notwendigen Felder für Match-Engine vorhanden.',
|
||
[
|
||
{ label: 'Asset-Typ definiert', passed: true, value: 'OFFICE' },
|
||
{ label: 'Standort definiert', passed: true, value: 'Lausanne' },
|
||
{ label: 'Zeithorizont definiert', passed: true, value: 'Sofort verfügbar (3+ Monate leer)' },
|
||
{ label: 'Geschäftsrelevanz vorhanden', passed: true },
|
||
],
|
||
),
|
||
FEED_ELIGIBILITY_GATE: gate(
|
||
GateType.FEED_ELIGIBILITY_GATE,
|
||
GateStatus.PASSED,
|
||
'Signal im Future Availability Feed publiziert – anonymisiert und aggregiert.',
|
||
[
|
||
{ label: 'Review-Gate bestanden', passed: true },
|
||
{ label: 'Matchbarkeits-Gate bestanden', passed: true },
|
||
{ label: 'Anonymisierungsauflage umgesetzt', passed: true },
|
||
{ label: 'Im Feed publiziert', passed: true, value: '13.05.2026' },
|
||
],
|
||
),
|
||
},
|
||
}
|
||
|
||
export const MOCK_PIPELINE_STATES: PipelineState[] = [
|
||
sig001Pipeline,
|
||
sig002Pipeline,
|
||
sig003Pipeline,
|
||
sig004Pipeline,
|
||
sig005Pipeline,
|
||
sig006Pipeline,
|
||
sig007Pipeline,
|
||
sig008Pipeline,
|
||
]
|
||
|
||
// ── Audit Trails ──────────────────────────────────────────────────────────────
|
||
|
||
export const MOCK_AUDIT_TRAILS: AuditTrailEntry[] = [
|
||
// sig-001
|
||
{
|
||
id: 'audit-001-1',
|
||
signalId: 'sig-001',
|
||
timestamp: '2025-05-10T09:23:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Signal erkannt',
|
||
performedBy: 'System / NZZ-Connector',
|
||
details: 'Signal automatisch aus NZZ-Medienbericht extrahiert. Rohtext gespeichert.',
|
||
},
|
||
{
|
||
id: 'audit-001-2',
|
||
signalId: 'sig-001',
|
||
timestamp: '2025-05-10T10:05:00Z',
|
||
stage: PipelineStage.STAGE_2_NORMALIZED,
|
||
action: 'Normalisierung abgeschlossen',
|
||
performedBy: 'System / NLP-Pipeline',
|
||
details: 'Felder normalisiert: Standort "Zürich ZH", Asset-Typ OFFICE, Signaltyp EXPANSION.',
|
||
},
|
||
{
|
||
id: 'audit-001-3',
|
||
signalId: 'sig-001',
|
||
timestamp: '2025-05-11T08:00:00Z',
|
||
stage: PipelineStage.STAGE_3_ENRICHED,
|
||
action: 'Anreicherung abgeschlossen',
|
||
performedBy: 'System / Enrichment-Engine',
|
||
details: 'Entitäten extrahiert: UBS AG (Konfidenz 0.98), Zürich (0.95), Ende 2025 (0.87). Konfidenzwert: 0.72.',
|
||
},
|
||
{
|
||
id: 'audit-001-4',
|
||
signalId: 'sig-001',
|
||
timestamp: '2025-05-11T08:05:00Z',
|
||
stage: PipelineStage.STAGE_4_REVIEW_CANDIDATE,
|
||
action: 'Zur Prüfung eingereicht',
|
||
performedBy: 'System / Gate-Evaluator',
|
||
details: 'Evidenz-Gate, Konfidenz-Gate und Sensitivitäts-Gate bestanden. Review-Gate offen – wartet auf Analyst.',
|
||
gateType: GateType.REVIEW_GATE,
|
||
},
|
||
|
||
// sig-002
|
||
{
|
||
id: 'audit-002-1',
|
||
signalId: 'sig-002',
|
||
timestamp: '2025-05-08T14:00:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Signal erkannt',
|
||
performedBy: 'System / Baugesuch-Connector',
|
||
details: 'Baugesuch Nr. BS-2025-0312 aus öffentlichem Register extrahiert.',
|
||
},
|
||
{
|
||
id: 'audit-002-2',
|
||
signalId: 'sig-002',
|
||
timestamp: '2025-05-08T15:00:00Z',
|
||
stage: PipelineStage.STAGE_3_ENRICHED,
|
||
action: 'Normalisierung und Anreicherung',
|
||
performedBy: 'System / NLP-Pipeline',
|
||
details: 'Alle Felder normalisiert und angereichert. Standort Basel-Nord, Asset-Typen: OFFICE, LOGISTICS, RETAIL. Konfidenz: 0.88.',
|
||
},
|
||
{
|
||
id: 'audit-002-3',
|
||
signalId: 'sig-002',
|
||
timestamp: '2025-05-12T09:30:00Z',
|
||
stage: PipelineStage.STAGE_4_REVIEW_CANDIDATE,
|
||
action: 'Analyst-Review gestartet',
|
||
performedBy: 'M. Huber',
|
||
details: 'Review-Kandidat angenommen. Öffentliche Quelle mit hoher Verlässlichkeit.',
|
||
},
|
||
{
|
||
id: 'audit-002-4',
|
||
signalId: 'sig-002',
|
||
timestamp: '2025-05-12T09:45:00Z',
|
||
stage: PipelineStage.STAGE_5_APPROVED_FUTURE,
|
||
action: 'Signal genehmigt',
|
||
performedBy: 'M. Huber',
|
||
details: 'Signal als Future Availability genehmigt. Alle Gates bestanden. Bereit zur Feed-Publikation.',
|
||
gateType: GateType.REVIEW_GATE,
|
||
},
|
||
|
||
// sig-003
|
||
{
|
||
id: 'audit-003-1',
|
||
signalId: 'sig-003',
|
||
timestamp: '2025-05-09T11:30:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Signal erkannt',
|
||
performedBy: 'System / LinkedIn-Connector',
|
||
details: 'Stellenwachstumssignal aus LinkedIn-Daten extrahiert. 80 neue Stellenausschreibungen in 6 Monaten.',
|
||
},
|
||
{
|
||
id: 'audit-003-2',
|
||
signalId: 'sig-003',
|
||
timestamp: '2025-05-09T12:00:00Z',
|
||
stage: PipelineStage.STAGE_2_NORMALIZED,
|
||
action: 'Normalisierung abgeschlossen',
|
||
performedBy: 'System / NLP-Pipeline',
|
||
details: 'Standort Zug, Asset-Typ OFFICE, Signaltyp EXPANSION normalisiert. Unternehmensname nicht öffentlich.',
|
||
},
|
||
{
|
||
id: 'audit-003-3',
|
||
signalId: 'sig-003',
|
||
timestamp: '2025-05-11T14:00:00Z',
|
||
stage: PipelineStage.STAGE_3_ENRICHED,
|
||
action: 'Anreicherung abgeschlossen',
|
||
performedBy: 'System / Enrichment-Engine',
|
||
details: 'Konfidenzwert 0.61 – Grenzbereich. Unternehmensverifizierung empfohlen. Weiterer Review nötig.',
|
||
},
|
||
|
||
// sig-004
|
||
{
|
||
id: 'audit-004-1',
|
||
signalId: 'sig-004',
|
||
timestamp: '2025-05-05T08:00:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Signal erkannt',
|
||
performedBy: 'System / ERP-Connector',
|
||
details: 'Vertragslaufdaten aus internem ERP importiert. Vertrag V-2019-0481, Ablauf 31.03.2026.',
|
||
},
|
||
{
|
||
id: 'audit-004-2',
|
||
signalId: 'sig-004',
|
||
timestamp: '2025-05-05T08:30:00Z',
|
||
stage: PipelineStage.STAGE_3_ENRICHED,
|
||
action: 'Normalisierung und Anreicherung',
|
||
performedBy: 'System / NLP-Pipeline',
|
||
details: 'Alle Felder normalisiert. Hohe Konfidenz (0.97) da Primärquelle. Sensitivität CONFIDENTIAL erkannt.',
|
||
},
|
||
{
|
||
id: 'audit-004-3',
|
||
signalId: 'sig-004',
|
||
timestamp: '2025-05-10T10:00:00Z',
|
||
stage: PipelineStage.STAGE_4_REVIEW_CANDIDATE,
|
||
action: 'Sensitivitäts-Warnung gesetzt',
|
||
performedBy: 'System / Gate-Evaluator',
|
||
details: 'Sensitivitäts-Gate fehlgeschlagen: CONFIDENTIAL. Signal zur Review eingereicht mit Anonymisierungsauflage.',
|
||
gateType: GateType.SENSITIVITY_GATE,
|
||
},
|
||
{
|
||
id: 'audit-004-4',
|
||
signalId: 'sig-004',
|
||
timestamp: '2025-05-10T10:05:00Z',
|
||
stage: PipelineStage.STAGE_4_REVIEW_CANDIDATE,
|
||
action: 'Property Manager benachrichtigt',
|
||
performedBy: 'System / Notification-Service',
|
||
details: 'Property Manager über auslaufenden Grossmietvertrag informiert. Verlängerungsgespräch empfohlen.',
|
||
},
|
||
|
||
// sig-005
|
||
{
|
||
id: 'audit-005-1',
|
||
signalId: 'sig-005',
|
||
timestamp: '2025-05-07T16:20:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Signal erkannt',
|
||
performedBy: 'System / Handelsregister-Connector',
|
||
details: 'Sitzverlegung aus Zefix extrahiert: 3014 Bern → 8302 Kloten, eingetragen 07.05.2025.',
|
||
},
|
||
{
|
||
id: 'audit-005-2',
|
||
signalId: 'sig-005',
|
||
timestamp: '2025-05-07T17:00:00Z',
|
||
stage: PipelineStage.STAGE_2_NORMALIZED,
|
||
action: 'Normalisierung abgeschlossen',
|
||
performedBy: 'System / NLP-Pipeline',
|
||
details: 'Standort Kloten (Zielort), Asset-Typ LOGISTICS normalisiert. Flächenbedarf noch nicht validiert.',
|
||
},
|
||
{
|
||
id: 'audit-005-3',
|
||
signalId: 'sig-005',
|
||
timestamp: '2025-05-08T09:00:00Z',
|
||
stage: PipelineStage.STAGE_2_NORMALIZED,
|
||
action: 'Anreicherung gestartet',
|
||
performedBy: 'System / Enrichment-Engine',
|
||
details: 'Konfidenzwert 0.63 – Sitzverlegung bestätigt, konkreter Flächenbedarf am Zielort ausstehend.',
|
||
},
|
||
|
||
// sig-006
|
||
{
|
||
id: 'audit-006-1',
|
||
signalId: 'sig-006',
|
||
timestamp: '2025-05-12T08:15:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Signal erkannt',
|
||
performedBy: 'System / Immoscout-Connector',
|
||
details: 'Neue Suchanzeige auf Immoscout24 erkannt: 800 m² Lagerfläche Winterthur, sofort gesucht.',
|
||
},
|
||
{
|
||
id: 'audit-006-2',
|
||
signalId: 'sig-006',
|
||
timestamp: '2025-05-12T08:30:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Evidenz-Gate bestanden',
|
||
performedBy: 'System / Gate-Evaluator',
|
||
details: 'Evidenz-Gate und Konfidenz-Gate (0.83) bestanden. Signal in Pipeline aufgenommen, Normalisierung startet.',
|
||
gateType: GateType.EVIDENCE_GATE,
|
||
},
|
||
|
||
// sig-007
|
||
{
|
||
id: 'audit-007-1',
|
||
signalId: 'sig-007',
|
||
timestamp: '2025-05-06T10:00:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Signal erkannt',
|
||
performedBy: 'System / SBB-Feed-Connector',
|
||
details: 'SBB-Medienmitteilung zur neuen Haltestelle Schlieren-West 2027 automatisch verarbeitet.',
|
||
},
|
||
{
|
||
id: 'audit-007-2',
|
||
signalId: 'sig-007',
|
||
timestamp: '2025-05-06T11:00:00Z',
|
||
stage: PipelineStage.STAGE_2_NORMALIZED,
|
||
action: 'Normalisierung abgeschlossen',
|
||
performedBy: 'System / NLP-Pipeline',
|
||
details: 'Standort Schlieren, Asset-Typen OFFICE und PRODUCTION, Zeithorizont Dezember 2027 normalisiert.',
|
||
},
|
||
{
|
||
id: 'audit-007-3',
|
||
signalId: 'sig-007',
|
||
timestamp: '2025-05-10T15:00:00Z',
|
||
stage: PipelineStage.STAGE_3_ENRICHED,
|
||
action: 'Matchbarkeits-Problem identifiziert',
|
||
performedBy: 'System / Gate-Evaluator',
|
||
details: 'Matchbarkeits-Gate fehlgeschlagen: PROJECT_DEVELOPMENT ohne direktes Verfügbarkeitssignal. Kein konkreter Flächenbedarf nachweisbar.',
|
||
gateType: GateType.MATCHABILITY_GATE,
|
||
},
|
||
{
|
||
id: 'audit-007-4',
|
||
signalId: 'sig-007',
|
||
timestamp: '2025-05-10T15:05:00Z',
|
||
stage: PipelineStage.STAGE_3_ENRICHED,
|
||
action: 'Analyst-Notiz hinzugefügt',
|
||
performedBy: 'K. Bauer',
|
||
details: 'Infrastrukturverbesserung dokumentiert. Empfehlung: Als strategischen Kontext-Input behandeln, nicht als direktes Matchingobjekt.',
|
||
},
|
||
|
||
// sig-008
|
||
{
|
||
id: 'audit-008-1',
|
||
signalId: 'sig-008',
|
||
timestamp: '2025-05-03T14:30:00Z',
|
||
stage: PipelineStage.STAGE_1_RAW_EVIDENCE,
|
||
action: 'Signal manuell erfasst',
|
||
performedBy: 'A. Müller',
|
||
details: 'Vor-Ort-Begehung Tour de Berne, Lausanne. 4. OG leer stehend, keine Vermarktung erkennbar.',
|
||
},
|
||
{
|
||
id: 'audit-008-2',
|
||
signalId: 'sig-008',
|
||
timestamp: '2025-05-03T15:00:00Z',
|
||
stage: PipelineStage.STAGE_3_ENRICHED,
|
||
action: 'Normalisierung und Anreicherung',
|
||
performedBy: 'System / NLP-Pipeline',
|
||
details: 'Standort Lausanne, Asset-Typ OFFICE, Signaltyp POSSIBLE_MOVE_OUT normalisiert. Konfidenz 0.68.',
|
||
},
|
||
{
|
||
id: 'audit-008-3',
|
||
signalId: 'sig-008',
|
||
timestamp: '2025-05-13T10:30:00Z',
|
||
stage: PipelineStage.STAGE_4_REVIEW_CANDIDATE,
|
||
action: 'Analyst-Review abgeschlossen',
|
||
performedBy: 'A. Müller',
|
||
details: 'Signal geprüft und genehmigt. Anonymisierungsauflage gesetzt: Mieteridentität darf nicht kommuniziert werden.',
|
||
gateType: GateType.REVIEW_GATE,
|
||
},
|
||
{
|
||
id: 'audit-008-4',
|
||
signalId: 'sig-008',
|
||
timestamp: '2025-05-13T11:00:00Z',
|
||
stage: PipelineStage.STAGE_6_MATCHABLE_RESULT,
|
||
action: 'In Future Availability publiziert',
|
||
performedBy: 'A. Müller',
|
||
details: 'Signal als Future Availability "fs-lausanne-001" in den Feed übertragen. Anonymisierter Disclaimer aktiv.',
|
||
gateType: GateType.FEED_ELIGIBILITY_GATE,
|
||
},
|
||
]
|