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>
This commit is contained in:
Benjamin Sutter
2026-05-24 12:32:57 +02:00
parent 0582031930
commit 723f553939
12 changed files with 303 additions and 115 deletions
+10
View File
@@ -0,0 +1,10 @@
import type { PipelineItem, PipelineStage } from '../domain/pipeline'
export interface IPipelineProvider {
getAll(): Promise<PipelineItem[]>
add(item: PipelineItem): Promise<void>
moveStage(id: string, stage: PipelineStage): Promise<void>
updateNotes(id: string, notes: string): Promise<void>
loseItem(id: string): Promise<void>
linkInquiry(id: string, inquiryId: string): Promise<void>
}
+67
View File
@@ -0,0 +1,67 @@
import type { IPipelineProvider } from './IPipelineProvider'
import type { PipelineItem, PipelineStage } from '../domain/pipeline'
import { mockPipelineItems } from '../mock-data/pipelineItems'
const STORAGE_KEY = 'property_match_pipeline_items'
function load(): PipelineItem[] {
try {
const raw = localStorage.getItem(STORAGE_KEY)
if (raw) return JSON.parse(raw) as PipelineItem[]
} catch { /* ignore */ }
return [...mockPipelineItems]
}
function save(items: PipelineItem[]): void {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(items))
} catch { /* ignore */ }
}
export const MockupPipelineProvider: IPipelineProvider = {
async getAll() {
return load()
},
async add(item) {
const items = load()
items.push(item)
save(items)
},
async moveStage(id: string, stage: PipelineStage) {
const items = load()
const idx = items.findIndex(i => i.id === id)
if (idx !== -1) {
items[idx] = { ...items[idx], stage, updatedAt: new Date().toISOString() }
save(items)
}
},
async updateNotes(id: string, notes: string) {
const items = load()
const idx = items.findIndex(i => i.id === id)
if (idx !== -1) {
items[idx] = { ...items[idx], notes }
save(items)
}
},
async loseItem(id: string) {
const items = load()
const idx = items.findIndex(i => i.id === id)
if (idx !== -1) {
items[idx] = { ...items[idx], stage: 'CLOSED_LOST', updatedAt: new Date().toISOString() }
save(items)
}
},
async linkInquiry(id: string, inquiryId: string) {
const items = load()
const idx = items.findIndex(i => i.id === id)
if (idx !== -1) {
items[idx] = { ...items[idx], inquiryId }
save(items)
}
},
}