YeboVerify Database Models
YeboVerify uses Prisma ORM with PostgreSQL.
Business
Registered businesses using YeboVerify.
prisma
model Business {
id String @id @default(cuid())
name String
email String @unique
apiKey String @unique
plan String @default("starter")
webhookUrl String?
webhookSecret String?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
verifications Verification[]
}Verification
Core verification record.
prisma
model Verification {
id String @id @default(cuid())
verificationId String @unique // Public ID (vrf_xxx)
// Business reference
businessId String
business Business @relation(fields: [businessId], references: [id])
externalRef String? // Business's reference
// Status
status VerificationStatus @default(PENDING)
// Images (R2 keys - private)
idFrontImage String
idBackImage String?
selfieImage String
// Results
faceScore Float? // 0-100
faceDecision String? // 'approved', 'rejected', 'needs_review'
ocrConfidence Float? // 0-100
extractedData Json? // Parsed document fields
// Decision
decision Decision?
decisionReason String?
confidence String? // 'high', 'medium', 'low'
// Processing
processingMs Int?
// Webhook
webhookSent Boolean @default(false)
webhookSentAt DateTime?
webhookError String?
// Timestamps
createdAt DateTime @default(now())
completedAt DateTime?
}
enum VerificationStatus {
PENDING
PROCESSING
COMPLETED
FAILED
NEEDS_REVIEW
}
enum Decision {
APPROVED
REJECTED
NEEDS_REVIEW
}Extracted Data Schema
The extractedData JSON field contains:
typescript
interface ExtractedData {
surname?: string; // Last name
names?: string; // First + middle names
dateOfBirth?: string; // YYYY-MM-DD
idNumber?: string; // Document number
documentType?: string; // "National ID", "Passport", etc.
nationality?: string; // Country
expiryDate?: string; // Document expiry
gender?: string; // M/F
address?: string; // If present on document
}Indexes
prisma
@@index([businessId])
@@index([verificationId])
@@index([status])
@@index([createdAt])Example Verification Record
json
{
"id": "clx123abc",
"verificationId": "vrf_abc123xyz",
"businessId": "clx456def",
"externalRef": "user_789",
"status": "COMPLETED",
"idFrontImage": "verifications/vrf_abc123xyz/id-front-1705315200000",
"idBackImage": null,
"selfieImage": "verifications/vrf_abc123xyz/selfie-1705315200000",
"faceScore": 92.5,
"faceDecision": "approved",
"ocrConfidence": 85.0,
"extractedData": {
"surname": "Doe",
"names": "John James",
"dateOfBirth": "1990-05-15",
"idNumber": "123456789",
"documentType": "National ID"
},
"decision": "APPROVED",
"decisionReason": "High face match and OCR confidence",
"confidence": "high",
"processingMs": 3250,
"webhookSent": true,
"webhookSentAt": "2024-01-15T10:00:04Z",
"webhookError": null,
"createdAt": "2024-01-15T10:00:00Z",
"completedAt": "2024-01-15T10:00:03Z"
}Relationships
Business 1──────* VerificationData Retention
Images stored in R2:
- Private bucket - Not publicly accessible
- Encrypted at rest
- Retention policy - Configurable per business