Files
property-match/src/services/dashboardService.ts
T
Benjamin Sutter 7b7be0b436 feat: F006 supply dashboard — complete spec implementation
- dataQualityService with getPortfolioQualitySummary()
- Service methods: getDashboardPropertiesSummary, getStrongMatches,
  getSignalSummary, getDashboardTasks added to respective services
- dashboardService uses Promise.allSettled for partial error resilience
- KpiCard: onClick + Tooltip support
- KpiGrid: navigate actions and tooltips per card
- StrongMatchMiniCard: Match Center, Prüfung, Vergleichen action buttons
- FutureSignalWidget: time horizon distribution (0–6, 6–12, 12–24 Mo.)
- SupplyDashboard: DashboardHeader, empty state, error state,
  partial widget errors, permission-based rendering per UserRole

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:31:54 +02:00

37 lines
1.5 KiB
TypeScript

import { propertyService } from './propertyService'
import { matchService } from './matchService'
import { futureSignalService } from './futureSignalService'
import { dataQualityService } from './dataQualityService'
import { reviewService } from './reviewService'
import type { DashboardData } from '../domain/dashboard'
export const dashboardService = {
async getDashboardData(): Promise<DashboardData> {
const [propRes, matchRes, signalRes, qualityRes, reviewRes] = await Promise.allSettled([
propertyService.getDashboardPropertiesSummary(),
matchService.getStrongMatches(),
futureSignalService.getSignalSummary(),
dataQualityService.getPortfolioQualitySummary(),
reviewService.getDashboardTasks(),
])
const propSummary = propRes.status === 'fulfilled' ? propRes.value : null
const strongMatches = matchRes.status === 'fulfilled' ? matchRes.value : null
const signals = signalRes.status === 'fulfilled' ? signalRes.value : null
const quality = qualityRes.status === 'fulfilled' ? qualityRes.value : null
const tasks = reviewRes.status === 'fulfilled' ? reviewRes.value : null
return {
totalProperties: propSummary?.total ?? 0,
activeProperties: propSummary?.active ?? 0,
strongMatchCount: strongMatches?.length ?? 0,
avgDataQuality: quality?.avgScore ?? 0,
futureSignals: signals,
dataQuality: quality,
reviewTasks: tasks,
strongMatches,
lastUpdated: new Date().toISOString(),
}
},
}