Files
property-match/src/services/propertyService.ts
T
Benjamin Sutter 6515acb7f0 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>
2026-05-24 00:32:01 +02:00

74 lines
2.3 KiB
TypeScript

import { MockupPropertyProvider } from '../provider/MockupPropertyProvider'
import type { PropertyFilters } from '../provider/IPropertyProvider'
import type { CreatePropertyInput, UpdatePropertyInput } from '../domain/property'
import type { ListResponse, ItemResponse } from './types'
import type { Property } from '../domain/property'
import { throwServiceError } from './errors'
const provider = MockupPropertyProvider
const ACTIVE_STATUSES: readonly string[] = ['AVAILABLE_NOW', 'AVAILABLE_SOON']
export const propertyService = {
async getAll(filters?: PropertyFilters): Promise<ListResponse<Property>> {
try {
const data = await provider.getAll(filters)
return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
} catch (err) {
throwServiceError(err)
}
},
async getById(id: string): Promise<ItemResponse<Property | null>> {
try {
const data = await provider.getById(id)
return { data }
} catch (err) {
throwServiceError(err)
}
},
async create(input: CreatePropertyInput): Promise<ItemResponse<Property>> {
try {
const data = await provider.create(input)
return { data }
} catch (err) {
throwServiceError(err)
}
},
async update(id: string, input: UpdatePropertyInput): Promise<ItemResponse<Property>> {
try {
const data = await provider.update(id, input)
return { data }
} catch (err) {
throwServiceError(err)
}
},
async remove(id: string): Promise<ItemResponse<void>> {
try {
await provider.remove(id)
return { data: undefined }
} catch (err) {
throwServiceError(err)
}
},
async getDashboardPropertiesSummary(): Promise<{ total: number; active: number }> {
try {
const data = await provider.getAll()
return {
total: data.length,
active: data.filter(p => ACTIVE_STATUSES.includes(p.availabilityStatus)).length,
}
} catch (err) {
throwServiceError(err)
}
},
async getProperties(filters?: PropertyFilters): Promise<ListResponse<Property>> {
try {
const data = await provider.getAll(filters)
return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
} catch (err) {
throwServiceError(err)
}
},
}