fix: harden pipeline navigation data loading
Some checks failed
Velocity-OS Deployment Pipeline / lint (push) Has been cancelled
Velocity-OS Deployment Pipeline / build-and-push (agents) (push) Has been cancelled
Velocity-OS Deployment Pipeline / build-and-push (core) (push) Has been cancelled
Velocity-OS Deployment Pipeline / build-and-push (media-engine) (push) Has been cancelled
Velocity-OS Deployment Pipeline / build-and-push (webos) (push) Has been cancelled
Velocity-OS Deployment Pipeline / sign-images (agents) (push) Has been cancelled
Velocity-OS Deployment Pipeline / sign-images (core) (push) Has been cancelled
Velocity-OS Deployment Pipeline / sign-images (media-engine) (push) Has been cancelled
Velocity-OS Deployment Pipeline / sign-images (webos) (push) Has been cancelled
Velocity-OS Deployment Pipeline / notify-ingress (push) Has been cancelled
Some checks failed
Velocity-OS Deployment Pipeline / lint (push) Has been cancelled
Velocity-OS Deployment Pipeline / build-and-push (agents) (push) Has been cancelled
Velocity-OS Deployment Pipeline / build-and-push (core) (push) Has been cancelled
Velocity-OS Deployment Pipeline / build-and-push (media-engine) (push) Has been cancelled
Velocity-OS Deployment Pipeline / build-and-push (webos) (push) Has been cancelled
Velocity-OS Deployment Pipeline / sign-images (agents) (push) Has been cancelled
Velocity-OS Deployment Pipeline / sign-images (core) (push) Has been cancelled
Velocity-OS Deployment Pipeline / sign-images (media-engine) (push) Has been cancelled
Velocity-OS Deployment Pipeline / sign-images (webos) (push) Has been cancelled
Velocity-OS Deployment Pipeline / notify-ingress (push) Has been cancelled
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { api } from '@/shared/lib/apiClient';
|
||||
import { stableArray, unwrapObject } from '@/shared/lib/apiShape';
|
||||
|
||||
/**
|
||||
* useClient360 — fetch unified client entity
|
||||
@@ -9,8 +10,8 @@ export function useClient360(personId: string) {
|
||||
const query = useQuery({
|
||||
queryKey: ['client360', personId],
|
||||
queryFn: async () => {
|
||||
const payload = await api.get<Wrapped<Client360Snapshot>>(`/crm/client-360/${personId}`);
|
||||
return mapClient360(payload.data);
|
||||
const payload = await api.get<unknown>(`/crm/client-360/${personId}`);
|
||||
return mapClient360(normalizeSnapshot(payload));
|
||||
},
|
||||
staleTime: 30_000,
|
||||
enabled: !!personId,
|
||||
@@ -26,8 +27,8 @@ export function useConversations(personId: string) {
|
||||
const query = useQuery({
|
||||
queryKey: ['conversations', personId],
|
||||
queryFn: async () => {
|
||||
const payload = await api.get<Wrapped<Client360Snapshot>>(`/crm/client-360/${personId}`);
|
||||
return mapConversationEvents(payload.data);
|
||||
const payload = await api.get<unknown>(`/crm/client-360/${personId}`);
|
||||
return mapConversationEvents(normalizeSnapshot(payload));
|
||||
},
|
||||
staleTime: 10_000,
|
||||
enabled: !!personId,
|
||||
@@ -47,8 +48,8 @@ export function useClientProperties(personId: string) {
|
||||
const query = useQuery({
|
||||
queryKey: ['client-properties', personId],
|
||||
queryFn: async () => {
|
||||
const payload = await api.get<Wrapped<Client360Snapshot>>(`/crm/client-360/${personId}`);
|
||||
return mapPropertyInterests(payload.data);
|
||||
const payload = await api.get<unknown>(`/crm/client-360/${personId}`);
|
||||
return mapPropertyInterests(normalizeSnapshot(payload));
|
||||
},
|
||||
staleTime: 60_000,
|
||||
enabled: !!personId,
|
||||
@@ -64,8 +65,8 @@ export function useClientTasks(personId: string) {
|
||||
const query = useQuery({
|
||||
queryKey: ['client-tasks', personId],
|
||||
queryFn: async () => {
|
||||
const payload = await api.get<Wrapped<Client360Snapshot>>(`/crm/client-360/${personId}`);
|
||||
return mapTasks(payload.data);
|
||||
const payload = await api.get<unknown>(`/crm/client-360/${personId}`);
|
||||
return mapTasks(normalizeSnapshot(payload));
|
||||
},
|
||||
staleTime: 30_000,
|
||||
enabled: !!personId,
|
||||
@@ -144,11 +145,6 @@ interface Task {
|
||||
isAIGenerated?: boolean;
|
||||
}
|
||||
|
||||
interface Wrapped<T> {
|
||||
status: string;
|
||||
data: T;
|
||||
}
|
||||
|
||||
interface Client360Snapshot {
|
||||
client_ref?: string;
|
||||
identity?: {
|
||||
@@ -203,6 +199,22 @@ interface Client360Snapshot {
|
||||
recommended_next_actions?: string[];
|
||||
}
|
||||
|
||||
function normalizeSnapshot(payload: unknown): Client360Snapshot {
|
||||
const snapshot = unwrapObject<Client360Snapshot>(payload);
|
||||
if (!snapshot) return {};
|
||||
return {
|
||||
...snapshot,
|
||||
identity: snapshot.identity ?? {},
|
||||
current_lead: snapshot.current_lead ?? {},
|
||||
active_opportunities: stableArray(snapshot.active_opportunities),
|
||||
recent_interactions: stableArray(snapshot.recent_interactions),
|
||||
property_interests: stableArray(snapshot.property_interests),
|
||||
tasks: stableArray(snapshot.tasks),
|
||||
risk_flags: stableArray(snapshot.risk_flags),
|
||||
recommended_next_actions: stableArray(snapshot.recommended_next_actions),
|
||||
};
|
||||
}
|
||||
|
||||
function scoreToPercent(value: number | null | undefined): number {
|
||||
const safe = Number(value ?? 0);
|
||||
const pct = safe <= 1 ? safe * 100 : safe;
|
||||
|
||||
Reference in New Issue
Block a user