feat: unified error handling + AI service modularisation
Error handling (Prompt 2): - src/services/errors.ts: AppError class, normalizeError(), throwServiceError() helper - 6 services wrapped with try/catch (property, match, need, shortlist, futureSignal, inquiry) - inquiryService aligned from custom ServiceResult<T> to standard ServiceResponse types - Results, MatchCenter, FutureAvailability pages show <ErrorState onRetry> on query failure AI modularisation (Prompt 3): - src/services/aiService.ts reduced from 755 → 19 lines (barrel re-export) - src/services/ai/IAIService.ts: typed interface + all response types - src/services/ai/mock/: needParser, compareBuilder, decisionBrief, listingParser, MockAIService - src/services/ai/openrouter/OpenRouterAIService.ts: model-agnostic skeleton - src/services/ai/prompts/: 4 prompt template files (needParsing, matchExplanation, compareSummary, decisionBrief) - src/services/ai/index.ts: factory selects Mock or OpenRouter via VITE_USE_REAL_AI flag - All existing import paths unchanged — zero call-site modifications Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
UnifiedResultFeed,
|
||||
} from '../../components/results'
|
||||
import { AddToPipelineDialog } from '../../components/shortlist'
|
||||
import { ErrorState } from '../../components/ui'
|
||||
import { useSessionStore } from '../../stores/sessionStore'
|
||||
import type { UnifiedMatchResult } from '../../domain/unifiedResult'
|
||||
|
||||
@@ -65,7 +66,7 @@ export default function Results() {
|
||||
queryClient.invalidateQueries({ queryKey: ['needs'] })
|
||||
}
|
||||
|
||||
const { data: results = [], isLoading } = useUnifiedResults(effectiveNeedId)
|
||||
const { data: results = [], isLoading, error } = useUnifiedResults(effectiveNeedId)
|
||||
|
||||
const isStaff = currentUser?.role === 'PROPERTY_MANAGER' || currentUser?.role === 'ORGANIZATION_ADMIN'
|
||||
|
||||
@@ -185,6 +186,8 @@ export default function Results() {
|
||||
|
||||
{isLoading ? (
|
||||
<FeedSkeleton />
|
||||
) : error ? (
|
||||
<ErrorState message={(error as Error).message} />
|
||||
) : sorted.length === 0 ? (
|
||||
<FeedEmptyState filtered={filterSource !== 'ALL' || !showFutureAvailability || !showOwnProperties} />
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user