/**
* useScanStatus Hook
*
* TanStack Query hook for polling scan job status.
* Uses TanStack Query's built-in refetchInterval for automatic polling - NO manual setInterval.
*
* @layer Presentation
*/
import { useQuery } from '@tanstack/react-query';
import { queryKeys } from '@/lib/query-keys';
import { infoCenterApi } from '@/infrastructure/http/api/info-center';
/**
* Scan Job Status from API
*
* Direct mapping from API response
*/
export interface ScanJobStatus {
jobId: string;
tenantId: string;
status: 'QUEUED' | 'DISCOVERING' | 'RUNNING' | 'COMPLETED' | 'FAILED' | 'CANCELLED';
pagesDiscovered: number;
pagesAnalyzed: number;
pagesFailed: number;
priority: 'LOW' | 'NORMAL' | 'HIGH';
progress: number;
createdAt: string;
startedAt: string | null;
completedAt: string | null;
errorMessage: string | null;
message: string;
}
/**
* useScanStatus Hook Options
*/
export interface UseScanStatusOptions {
/**
* Tenant ID for the scan job
*/
tenantId?: string;
/**
* Scan job ID to poll
*/
jobId?: string;
/**
* Enable/disable polling
* @default true (when tenantId and jobId are provided)
*/
enabled?: boolean;
/**
* Polling interval in milliseconds
* @default 30000 (30 seconds)
*/
pollingInterval?: number;
/**
* Callback when scan completes
*/
onComplete?: (status: ScanJobStatus) => void;
/**
* Callback when scan fails/cancels
*/
onError?: (status: ScanJobStatus) => void;
}
/**
* useScanStatus Hook Return Type
*/
export interface UseScanStatusReturn {
/**
* Scan job status
*/
status: ScanJobStatus | undefined;
/**
* Loading state (first fetch)
*/
isLoading: boolean;
/**
* Error state
*/
error: Error | null;
/**
* Refetch function
*/
refetch: () => void;
/**
* Is the scan still active (QUEUED, DISCOVERING, RUNNING)?
*/
isActive: boolean;
/**
* Is the scan complete?
*/
isComplete: boolean;
/**
* Is the scan failed/cancelled?
*/
isFailed: boolean;
}
/**
* Poll scan job status using TanStack Query
*
* Uses TanStack Query's built-in refetchInterval for automatic polling.
* Stops polling when job is complete/failed/cancelled (isActive = false).
*
* Benefits over manual setInterval:
* - Automatic cleanup (no memory leaks)
* - Window focus awareness (pauses when tab not focused)
* - Request deduplication (multiple components = 1 request)
* - Error retry with exponential backoff
* - Respects enabled flag
*
* @param options - Hook options
* @returns Scan status with loading/error states
*
* @example
* ```tsx
* function ScanProgress({ tenantId, jobId }: { tenantId: string; jobId: string }) {
* const { status, isLoading, isActive, isComplete } = useScanStatus({
* tenantId,
* jobId,
* onComplete: () => {
* console.log('Scan finished!');
* },
* });
*
* if (isLoading) return