Files
thrilltrack-explorer/src/hooks/useDataCompleteness.ts
gpt-engineer-app[bot] 69db3c7743 Integrate Data Completeness Dashboard
Adds comprehensive data completeness dashboard UI and hooks:
- Introduces data completeness types and hook (useDataCompleteness) to fetch and subscribe to updates
- Builds dashboard components (summary, filters, table) and integrates into Admin Settings
- Wireframes for real-time updates and filtering across parks, rides, companies, and ride models
- Integrates into AdminSettings with a new Data Quality tab and route
- Adds data types and scaffolding for analytics, including completeness analysis structure
2025-11-11 16:38:26 +00:00

107 lines
3.1 KiB
TypeScript

/**
* Data Completeness Hook
*
* React Query hook for fetching and caching data completeness analysis
* with real-time updates via Supabase subscriptions
*/
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { supabase } from '@/integrations/supabase/client';
import { useEffect } from 'react';
import type { CompletenessAnalysis, CompletenessFilters } from '@/types/data-completeness';
import { handleError } from '@/lib/errorHandler';
export function useDataCompleteness(filters: CompletenessFilters = {}) {
const queryClient = useQueryClient();
const query = useQuery({
queryKey: ['data-completeness', filters],
queryFn: async (): Promise<CompletenessAnalysis> => {
try {
const { data, error } = await supabase.rpc('analyze_data_completeness', {
p_entity_type: filters.entityType ?? undefined,
p_min_score: filters.minScore ?? undefined,
p_max_score: filters.maxScore ?? undefined,
p_missing_category: filters.missingCategory ?? undefined,
p_limit: 1000,
p_offset: 0,
});
if (error) throw error;
return data as unknown as CompletenessAnalysis;
} catch (error) {
handleError(error, {
action: 'fetch_data_completeness',
metadata: {
filters,
},
});
throw error;
}
},
staleTime: 5 * 60 * 1000, // Cache for 5 minutes
refetchOnWindowFocus: false,
});
// Real-time subscriptions for data updates
useEffect(() => {
// Subscribe to parks changes
const parksChannel = supabase
.channel('parks-completeness-updates')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'parks' },
() => {
queryClient.invalidateQueries({ queryKey: ['data-completeness'] });
}
)
.subscribe();
// Subscribe to rides changes
const ridesChannel = supabase
.channel('rides-completeness-updates')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'rides' },
() => {
queryClient.invalidateQueries({ queryKey: ['data-completeness'] });
}
)
.subscribe();
// Subscribe to companies changes
const companiesChannel = supabase
.channel('companies-completeness-updates')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'companies' },
() => {
queryClient.invalidateQueries({ queryKey: ['data-completeness'] });
}
)
.subscribe();
// Subscribe to ride_models changes
const modelsChannel = supabase
.channel('ride-models-completeness-updates')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'ride_models' },
() => {
queryClient.invalidateQueries({ queryKey: ['data-completeness'] });
}
)
.subscribe();
return () => {
supabase.removeChannel(parksChannel);
supabase.removeChannel(ridesChannel);
supabase.removeChannel(companiesChannel);
supabase.removeChannel(modelsChannel);
};
}, [queryClient]);
return query;
}