KYC Service — Testing¶
Running Tests¶
The kyc-service does not currently have a dedicated test suite. Integration testing is done manually or via the Serverpod Auth Center test flows.
For development use npm run dev with a local Redis + PostgreSQL + CompreFace stack.
If a test suite is added in future, place test files in
src/and add atestscript topackage.json.
Manual Testing¶
Submit a KYC job¶
curl -X POST http://localhost:3003/api/v1/process \
-H "Content-Type: application/json" \
-H "X-Service-Token: dev-kyc-secret-change-in-prod" \
-d '{
"userId": 1,
"kycId": 999,
"passportKey": "kyc/999/passport.jpg",
"selfieKey": "kyc/999/selfie.jpg"
}'
Expected response: 202 { "jobId": "kyc-999", "status": "queued" }
Health check¶
Verify CompreFace¶
What Gets Exercised in Integration¶
| Scenario | Expected Outcome |
|---|---|
| Valid passport + matching selfie | kyc_verification.status = 'ocr_complete', encrypted blob in ocrResult |
| All OCR fields null | UnrecoverableError('INVALID_PHOTO:passport:...') → status = 'ocr_failed', no retry |
| No face in selfie | UnrecoverableError('INVALID_PHOTO:selfie:...') → status = 'ocr_failed', no retry |
| Face similarity below 0.75 | UnrecoverableError('FACE_MISMATCH:...') → status = 'ocr_failed', no retry |
Duplicate kycId submission |
Returns 202, BullMQ ignores duplicate (same jobId = "kyc-{kycId}") |
| Gemini 429 rate limit | Retried with exponential backoff (up to 5 attempts) |
Record stuck in in_review for >15 min |
Watchdog marks as ocr_failed with failureCode = 'processing_timeout' |
Local Stack¶
Minimum required for manual testing:
# Redis
docker run -d -p 6379:6379 redis:7-alpine
# CompreFace
docker run -d -v compreface_data:/app/data -p 8000:8000 exadel/compreface:latest
# PostgreSQL (or use Serverpod's dev DB)
Set all required env vars in .env (see DEPLOYMENT.md), then:
Check logs for [KYC] Server listening on port 3003 and [KYC][CompreFace] Health OK.
SIT Considerations¶
- Gemini API has a daily/per-minute quota in the SIT environment. The service handles 429 with automatic retry, but a burst of KYC submissions may exhaust quota quickly.
- CompreFace in SIT must have a verification service created and
COMPREFACE_API_KEYconfigured before the service starts. - PII encryption key (
PII_ENCRYPTION_KEY) must match the ServerpodpiiEncryptionKeyinpasswords.yaml— mismatched keys mean Auth Center cannot decrypt KYC results.