CV Unified WebSocket Service
Overview
This document describes the unified WebSocket-based CV processing service that consolidates all CV upload, parsing, and extraction functionality into a single, consistent API.
Architecture
Core Components
useCvProcessorHook - Unified hook for all CV processing needsConnectionStatusComponent - Reusable WebSocket connection indicatorProcessingIndicatorComponent - Reusable progress and status display
Migration from Old Hooks
The following hooks are deprecated but still available:
- ⚠️
useCvUploadAndParse(GraphQL-based) — deprecated, useuseCvProcessorfor new code - ⚠️
useCvManager(GraphQL-based) — deprecated, useuseCvProcessorfor new code - ❌
useCvExtraction(WebSocket-based, limited functionality) - ✅
useCvProcessor(New unified WebSocket-based hook)
Hook API
useCvProcessor
import { useCvProcessor } from "@hooks/useCvProcessor"
const {
// Core function
processFile,
// Status
isConnected,
processing,
result,
// Actions
resetState,
clearError,
} = useCvProcessor()
Core Function
processFile(file: File, options?: CvProcessingOptions): Promise<CvData | null>
Uploads a file and processes it using WebSocket-based CV extraction.
Options:
companyId?: string- Company context for processingpersistent?: boolean- false = temporary extraction, true = stored processing
Status Properties
isConnected: boolean - WebSocket connection status
processing: CvProcessingStatus
{
isUploading: boolean
isProcessing: boolean
uploadProgress: number | null
status: string | null
error: string | null
}
result: CvData | null - Extracted CV data
interface CvData {
firstName?: string
lastName?: string
email?: string
portfolioLink?: string
linkedinLink?: string
description?: string
skills?: Array<{
name: string
proficiency?: string
yearsExperience?: number
}>
experiences?: Array<{
jobTitle?: string
company?: string
startDate?: string
endDate?: string
experience?: string
}>
education?: Array<{
title?: string
institute?: string
startDate?: string
endDate?: string
}>
fileUrl?: string
}
Reusable Components
ConnectionStatus
import { ConnectionStatus } from "@components/cv/ConnectionStatus"
;<ConnectionStatus isConnected={isConnected} className="mb-4" />
Shows real-time WebSocket connection status with appropriate styling.
ProcessingIndicator
import { ProcessingIndicator } from "@components/cv/ProcessingIndicator"
;<ProcessingIndicator
processing={processing}
fileName={file?.name}
className="mt-4"
/>
Displays upload progress, processing status, and loading indicators.
Usage Examples
Basic CV Processing
import { useCvProcessor } from "@hooks/useCvProcessor"
import { ConnectionStatus } from "@components/cv/ConnectionStatus"
import { ProcessingIndicator } from "@components/cv/ProcessingIndicator"
function CVUploadForm() {
const [file, setFile] = useState<File | null>(null)
const { processFile, isConnected, processing, result, clearError } =
useCvProcessor()
const handleUpload = async () => {
if (!file) return
const cvData = await processFile(file, { persistent: false })
if (cvData) {
// Handle extracted data
console.log("CV processed:", cvData)
}
}
return (
<div>
<ConnectionStatus isConnected={isConnected} />
<input
type="file"
accept=".pdf,.doc,.docx"
onChange={(e) => setFile(e.target.files?.[0] || null)}
/>
<Button
onClick={handleUpload}
disabled={
!file ||
!isConnected ||
processing.isUploading ||
processing.isProcessing
}
isLoading={processing.isUploading || processing.isProcessing}
>
Process CV
</Button>
<ProcessingIndicator processing={processing} fileName={file?.name} />
{processing.error && (
<div className="error">
{processing.error}
<Button onClick={clearError}>Dismiss</Button>
</div>
)}
{result && <div>CV processed successfully!</div>}
</div>
)
}
Company Candidate Processing
const handleCandidateCV = async (file: File) => {
const cvData = await processFile(file, {
companyId: user?.selectedCompanyId,
persistent: true, // Store permanently for candidate
})
if (cvData) {
// Auto-fill candidate form
setFormData({
firstName: cvData.firstName,
lastName: cvData.lastName,
email: cvData.email,
// ... other fields
})
}
}
Job Seeker Onboarding
const handleOnboardingCV = async (file: File) => {
const cvData = await processFile(file, {
persistent: false, // Temporary extraction for profile setup
})
if (cvData) {
// Auto-fill onboarding profile
setProfileData(cvData)
proceedToNextStep()
}
}
Migration Guide
From useCvUploadAndParse
Before:
const { uploadAndParse, isUploading, isParsing, error } = useCvUploadAndParse()
const parsedData = await uploadAndParse(file, companyId)
After:
const { processFile, processing, clearError } = useCvProcessor()
const parsedData = await processFile(file, { companyId, persistent: false })
From useCvExtraction
Before:
const { extractFromFile, isUploading, isProcessing, result } = useCvExtraction()
const data = await extractFromFile(file)
After:
const { processFile, processing, result } = useCvProcessor()
const data = await processFile(file, { persistent: false })
File Support
Supported formats:
- PDF (.pdf)
- Microsoft Word (.doc, .docx)
- Plain text (.txt)
Maximum file size: 50MB
Error Handling
The hook provides comprehensive error handling:
- File validation - Type and size checks
- Connection errors - WebSocket connectivity issues
- Upload errors - Network or server issues during upload
- Processing errors - AI extraction failures
Errors are automatically displayed via toast notifications and available in processing.error.
WebSocket Events
The service uses the following WebSocket events:
cv_extraction- Temporary processing (not stored)cv_processing- Persistent processing (stored in system)
Performance
- Upload Progress - Real-time progress tracking
- Processing Status - Live updates during AI extraction
- Connection Management - Automatic reconnection handling
- Error Recovery - Graceful error handling with retry options
Testing
Use the CV demo page for testing:
/app/(shared)/cv-demo/page.tsx
Or the CVExtractor component:
import { CVExtractor } from "@components/cv/CVExtractor"
;<CVExtractor />
Best Practices
- Always check connection status before processing
- Use appropriate persistence setting based on use case
- Handle errors gracefully with user-friendly messages
- Show progress indicators for better UX
- Validate files before processing (type, size)
Configuration
The WebSocket URLs are hardcoded in the application for production readiness:
- Production:
wss://pipeline.aiqlick.com - Development:
ws://localhost:8000
No environment variables are required for pipeline connectivity. The system automatically selects the appropriate URL based on the deployment context.
Note: Make sure your local pipeline service is running on port 8000 for development testing. If the service is unavailable, the system will show appropriate error messages and stop reconnection attempts after 5 tries.