Files
property-match/src/services/pipelineService.ts
T
Benjamin Sutter 723f553939 refactor: move PipelineItems from Zustand to Provider→Service→React Query
PipelineItems are domain data and must not live in Zustand. Moves the
full stack to the correct layer: MockupPipelineProvider (localStorage
persistence + seed fallback) → pipelineService → usePipeline hooks
(useQuery for reads, useMutation for writes with cache invalidation).

pipelineStore is now UI-only: dialogOpen, pendingItem, openSavedDialog,
closeSavedDialog. All consumers updated to use the new hooks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 12:32:57 +02:00

86 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { MockupPipelineProvider } from '../provider/MockupPipelineProvider'
import type { PipelineItem, PipelineStage, PendingPipelineItem } from '../domain/pipeline'
import type { ListResponse, ItemResponse } from './types'
import { throwServiceError } from './errors'
const provider = MockupPipelineProvider
export const pipelineService = {
async getAll(): Promise<ListResponse<PipelineItem>> {
try {
const data = await provider.getAll()
return { data, meta: { total: data.length, page: 1, pageSize: data.length, hasMore: false } }
} catch (err) {
throwServiceError(err)
}
},
async confirmSaved(pending: PendingPipelineItem, notes?: string): Promise<ItemResponse<'added' | 'duplicate'>> {
try {
const items = await provider.getAll()
const alreadyExists = items.some(
i => i.id === pending.resultId || (pending.propertyId && i.propertyId === pending.propertyId)
)
if (alreadyExists) return { data: 'duplicate' }
const newItem: PipelineItem = {
id: pending.resultId,
matchId: pending.resultId,
title: pending.title,
location: pending.location ?? '',
matchScore: pending.matchScore,
resultType: pending.resultType,
stage: 'SAVED',
propertyId: pending.propertyId,
unitId: pending.unitId,
propertyAddress: pending.propertyAddress,
areaLabel: pending.areaLabel,
rentLabel: pending.rentLabel,
availabilityLabel: pending.availabilityLabel,
notes: notes || undefined,
addedAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}
await provider.add(newItem)
return { data: 'added' }
} catch (err) {
throwServiceError(err)
}
},
async moveStage(id: string, stage: PipelineStage): Promise<ItemResponse<void>> {
try {
await provider.moveStage(id, stage)
return { data: undefined }
} catch (err) {
throwServiceError(err)
}
},
async updateNotes(id: string, notes: string): Promise<ItemResponse<void>> {
try {
await provider.updateNotes(id, notes)
return { data: undefined }
} catch (err) {
throwServiceError(err)
}
},
async loseItem(id: string): Promise<ItemResponse<void>> {
try {
await provider.loseItem(id)
return { data: undefined }
} catch (err) {
throwServiceError(err)
}
},
async linkInquiry(id: string, inquiryId: string): Promise<ItemResponse<void>> {
try {
await provider.linkInquiry(id, inquiryId)
return { data: undefined }
} catch (err) {
throwServiceError(err)
}
},
}