feat: Reminder Manager + Schattenmarkt-Freigabe + mock data overhaul

- Add Reminder Manager page (/supply/reminder-manager) with KPI bar,
  filter bar, list/card feed, and detail drawer (7 sections incl.
  activity log, snooze, complete, dismiss actions)
- Add Schattenmarkt-Freigabe toggle on PropertyDetailView: Verwaltung
  can opt-in properties for early market exposure before contract expiry
- Auto-generate FutureSignal cards via useSchattenmarktSignals hook
  when leaseEndDate - leadTimeMonths <= MOCK_TODAY
- Fix useUnifiedResults: use property.resultType as fallback (was
  defaulting everything to VERIFIED_PORTFOLIO)
- Fix demand Results: hide VERIFIED_PORTFOLIO from non-manager users
  even when showOwnProperties toggle was previously enabled
- Fix AppShell: redirect to allowed workspace on user role switch
- Fix 3 wrong match scores (match-002: 93→62, match-009: 86→55,
  match-017: 87→52)
- Add 7 new match records (match-050–056) for need-001, need-002,
  need-011
- Add need-011 (Retail Bern Innenstadt)
- Add prop-031–036 (EXTERNAL_MARKET / MAISON_WORK / FUTURE_AVAILABILITY)
- Fix duplicate image URLs across all properties
- Add signal-011 (Bern Altstadt, Mode Boutique) + propertyId to
  signal-001

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-20 11:52:24 +02:00
parent 0663757cde
commit 9f391d17cb
36 changed files with 3011 additions and 71 deletions
@@ -27,12 +27,13 @@ const RESULT_TYPE_META: Record<string, { label: string; color: string }> = {
}
const SOURCE_META: Record<string, { label: string; icon: React.ReactNode }> = {
JOB_POSTING: { label: 'Stelleninserate', icon: <Briefcase size={11} /> },
PRESS: { label: 'Pressebericht', icon: <Newspaper size={11} /> },
CONSTRUCTION_PERMIT:{ label: 'Baubewilligung', icon: <FileCheck size={11} /> },
COMPANY_REPORT: { label: 'Geschäftsbericht',icon: <FileText size={11} /> },
MARKET_DATA: { label: 'Marktdaten', icon: <BarChart2 size={11} /> },
MANUAL: { label: 'Analyst', icon: <User size={11} /> },
JOB_POSTING: { label: 'Stelleninserate', icon: <Briefcase size={11} /> },
PRESS: { label: 'Pressebericht', icon: <Newspaper size={11} /> },
CONSTRUCTION_PERMIT:{ label: 'Baubewilligung', icon: <FileCheck size={11} /> },
COMPANY_REPORT: { label: 'Geschäftsbericht', icon: <FileText size={11} /> },
MARKET_DATA: { label: 'Marktdaten', icon: <BarChart2 size={11} /> },
MANUAL: { label: 'Analyst', icon: <User size={11} /> },
LEASE_CONTRACT: { label: 'Vertrag verifiziert', icon: <ShieldCheck size={11} /> },
}
const SIGNAL_TYPE_LABELS: Record<string, string> = {
@@ -42,6 +43,7 @@ const SIGNAL_TYPE_LABELS: Record<string, string> = {
RESTRUCTURING: 'Restrukturierung',
PROJECT_DEVELOPMENT: 'Projektentwicklung',
SPACE_CONSOLIDATION: 'Flächenkonsolidierung',
LEASE_EXPIRY: 'Vertragsende',
}
// Human-readable explanation of WHY a signal type is relevant to a space search