feat: remove Administration workspace — keep only Verwaltung + Suche
- 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>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import { MockupMatchProvider } from '../provider/MockupMatchProvider'
|
||||
import { MockupPropertyProvider } from '../provider/MockupPropertyProvider'
|
||||
import { MockupNeedProvider } from '../provider/MockupNeedProvider'
|
||||
import type { MatchFilters } from '../provider/IMatchProvider'
|
||||
import type { Match } from '../domain/match'
|
||||
import type { Need } from '../domain/need'
|
||||
import type { Property } from '../domain/property'
|
||||
import type { StrongMatchItem } from '../domain/dashboard'
|
||||
import type { ScoreBreakdown } from '../domain/match'
|
||||
import type { ListResponse, ItemResponse } from './types'
|
||||
import { buildFullMatch, computeRankedMatches } from '../features/matching/rankingEngine'
|
||||
|
||||
const provider = MockupMatchProvider
|
||||
|
||||
export const matchService = {
|
||||
async getAll(filters?: MatchFilters): Promise<ListResponse<Match>> {
|
||||
const data = await provider.getAll(filters)
|
||||
return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
|
||||
},
|
||||
async getById(id: string): Promise<ItemResponse<Match | null>> {
|
||||
const data = await provider.getById(id)
|
||||
return { data }
|
||||
},
|
||||
async getByNeed(needId: string): Promise<ListResponse<Match>> {
|
||||
const data = await provider.getByNeed(needId)
|
||||
return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
|
||||
},
|
||||
async getByProperty(propertyId: string): Promise<ListResponse<Match>> {
|
||||
const data = await provider.getByProperty(propertyId)
|
||||
return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
|
||||
},
|
||||
async approve(id: string, reviewedBy: string): Promise<ItemResponse<Match>> {
|
||||
const data = await provider.approve(id, reviewedBy)
|
||||
return { data }
|
||||
},
|
||||
|
||||
async getMatchesForProperty(propertyId: string): Promise<ListResponse<Match>> {
|
||||
const data = await provider.getByProperty(propertyId)
|
||||
return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
|
||||
},
|
||||
|
||||
async getMatchDetail(id: string): Promise<ItemResponse<Match | null>> {
|
||||
const data = await provider.getById(id)
|
||||
return { data }
|
||||
},
|
||||
|
||||
async getScoreBreakdown(matchId: string): Promise<ItemResponse<ScoreBreakdown | null>> {
|
||||
const match = await provider.getById(matchId)
|
||||
return { data: match?.scoreBreakdown ?? null }
|
||||
},
|
||||
|
||||
// ── Engine-based methods ──────────────────────────────────────────────────
|
||||
|
||||
computeMatch(need: Need, property: Property): Match {
|
||||
return buildFullMatch(need, property)
|
||||
},
|
||||
|
||||
async computeMatchesForNeed(needId: string): Promise<ListResponse<Match>> {
|
||||
const [need, properties] = await Promise.all([
|
||||
MockupNeedProvider.getById(needId),
|
||||
MockupPropertyProvider.getAll(),
|
||||
])
|
||||
if (!need) return { data: [], meta: { total: 0, page: 1, pageSize: 0, hasMore: false } }
|
||||
const data = computeRankedMatches(need, properties)
|
||||
return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
|
||||
},
|
||||
|
||||
async getStrongMatches(minScore = 80): Promise<StrongMatchItem[]> {
|
||||
const [matches, properties] = await Promise.all([
|
||||
provider.getAll(),
|
||||
MockupPropertyProvider.getAll(),
|
||||
])
|
||||
return matches
|
||||
.filter(m => m.matchScore >= minScore)
|
||||
.slice(0, 5)
|
||||
.map(m => {
|
||||
const prop = properties.find(p => p.id === m.propertyId)
|
||||
const topFactor = m.positiveFactors?.[0]
|
||||
const firstAction = m.nextBestActions?.[0]
|
||||
return {
|
||||
matchId: m.id,
|
||||
propertyId: m.propertyId,
|
||||
propertyTitle: prop?.title ?? 'Unbekanntes Objekt',
|
||||
propertyAddress: prop?.address
|
||||
? `${prop.address.street} ${prop.address.houseNumber}, ${prop.address.city}`
|
||||
: '–',
|
||||
needSummary: m.needId,
|
||||
matchScore: m.matchScore,
|
||||
topReason: topFactor?.explanation ?? topFactor?.criterion ?? '–',
|
||||
missingDataCount: m.missingData?.length ?? 0,
|
||||
nextBestAction: firstAction?.label ?? '–',
|
||||
} satisfies StrongMatchItem
|
||||
})
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user