Skip to content

YeboJobs Product Requirements Document (PRD)

Product: YeboJobs - African Job Matching Platform
Version: 1.0
Last Updated: 2026-03-19
Generated From: Actual Codebase Analysis


1. Vision & Problem Statement

Problem

Africa faces a massive employment disconnect:

  1. Formal job market: University graduates and professionals struggle to find jobs that match their skills; employers waste time sifting through unqualified applicants
  2. Informal economy: Skilled workers (plumbers, electricians, beauticians) have no way to build verifiable work credentials; customers can't find trustworthy service providers
  3. Word of mouth culture: African hiring relies heavily on trust and reputation, but there's no digital way to capture or transfer this trust
  4. Mobile-first reality: Most job seekers access opportunities via mobile, yet existing platforms are desktop-focused and clunky

Vision

YeboJobs is building Africa's job ecosystem that works for both:

  • Formal employment: TikTok-style job discovery with AI-powered matching and interviewing
  • Informal services: A trust marketplace where workers earn verifiable credentials (YeboScore) based on real work performance

Core Philosophy: In Africa, word of mouth > formal credentials. Repeat customers = real trust. YeboJobs digitizes this reality.


2. Solution Overview

YeboJobs is a dual-marketplace platform consisting of:

2.1 Formal Jobs Platform (Job Seekers & Employers)

  • TikTok-style job discovery: Swipe through jobs with video content
  • AI-powered interviews: Okia Service provides automated candidate screening
  • Smart matching: Personality and culture fit scoring
  • Experience Lab: Micro-credential courses that prove job readiness

2.2 Informal Services Platform (Workers & Clients)

  • Service worker profiles: Video-first portfolios showcasing real work
  • Client requests: Post service needs, get quotes from matched workers
  • YeboScore: Universal work credential based on customer reviews, reliability, repeat business
  • In-app messaging: Communicate and negotiate directly

2.3 Supporting Systems

  • Credits Economy: Monetization via purchasable credits for actions
  • Stripe Subscriptions: Tiered plans for advanced features
  • AI Onboarding: Chat-based profile creation via Okia
  • Admin Dashboard: Full billing, trial, and promotion management

3. Core Features (Based on Actual Code)

3.1 User Management

User Roles (UserRole enum)

RoleDescription
job_seekerFormal job seeker looking for employment
service_workerInformal service provider (plumber, cleaner, etc.)
clientNeeds services done
hybridBoth worker and client

User Profile Fields

  • Basic: name, email, phone (unique), location, bio, profile picture
  • Video: profileVideo (intro video support)
  • Matching: personalityMatch[], culturePreferences[]
  • Privacy: showInterviewScores (boolean)
  • GPS: latitude, longitude (for services)

Authentication

  • Phone-based OTP via WhatsApp (NotificationService)
  • JWT access + refresh tokens
  • Separate auth flows for User vs Employer
  • bcrypt password hashing

3.2 Job Marketplace

Job Listings

  • Full job details: title, company, location, salary, currency
  • Job types: full_time, part_time, contract, internship, remote
  • Experience levels: entry, mid, senior, executive
  • Rich content: requirements[], benefits[], hashtags[]
  • Video: videoContent URL support
  • AI Interview config: aiInterviewEnabled, autoInviteOnApply, interviewQuestions, interviewTimeLimit
  • Engagement: applicationsCount, savesCount, sharesCount, boostLevel

Swipe System

  • TikTok-style discovery: like, dislike, superlike
  • Swipe history tracking (SwipeHistory model)
  • Saved jobs functionality

Applications

StatusDescription
pendingJust applied
reviewedEmployer viewed
shortlistedMade it to next round
rejectedNot selected
hiredGot the job
  • Cover letter support
  • CV upload (cvUrl)
  • AI Interview integration: interviewSessionId, interviewScore, interviewGrade

Placements

  • Tracks successful hires
  • Records: hiredDate, startDate, salary, currency
  • Links User → Job → Employer → Application

3.3 Employer Portal

Employer Profile

  • Company info: companyName, industry, companySize (enum: startup → enterprise)
  • Contact: email, phone, whatsappNumber
  • Branding: logo, website, description
  • Stats: jobsPosted, activeJobs
  • Verification: isVerified boolean

Employer Actions

  • Post jobs with AI interview configuration
  • Review applications
  • Invite candidates to AI interviews
  • Track hiring funnel
  • Access billing/subscription management

3.4 Informal Services Marketplace

Service Categories

  • Hierarchical: parent/child relationships
  • AI-generated categories from user input
  • Examples: plumber, kitchen renovation, electrician
  • Usage tracking for trending categories

Service Worker Profile

  • Headline & Bio: "Experienced Plumber - 10+ years"
  • Skills: Specific abilities like "burst pipe repair", "geyser installation"
  • Pricing (African negotiation style):
    • priceMin / priceMax (ranges, not fixed!)
    • priceNote: "Price depends on job complexity"
    • negotiable: Boolean
    • currency: Default "SZL" (Eswatini Lilangeni)
  • Location & Availability:
    • GPS coordinates (latitude, longitude)
    • serviceRadius (km willing to travel)
    • availableDays[], availableFrom/To (hours)
    • locationName: "Manzini, Eswatini"
  • Portfolio Media (Video-first!):
    • introVideo: Short TikTok-style intro
    • portfolioVideos[], portfolioImages[]
    • certificateUrls[]
  • Trust & Verification:
    • isVerified, idVerified, phoneVerified
  • Performance Stats:
    • jobsCompleted, averageRating, reviewCount
    • responseRate (%), responseTimeMin (avg minutes)
  • AI Profile:
    • onboardingComplete, aiProfileScore (0-100)

Service Listings

  • Worker-created service offerings
  • Category-linked with subcategory option
  • Pricing ranges with notes
  • Duration estimates
  • Includes/excludes lists
  • Requirements (what client provides)
  • Stats: viewCount, inquiryCount, bookingCount

Service Requests (Client Posts)

  • Client describes what they need
  • AI extracts categoryTags from description
  • Location with GPS
  • Timing: preferredDate, preferredTime, isUrgent
  • Budget ranges with notes
  • Status: open, in_progress, completed, cancelled
  • AI matching: aiMatchedWorkers[] (suggested worker IDs)

Quotes System

  • Workers submit quotes on requests
  • Pricing: amount (and optional amountMax range)
  • Personal message to client
  • Availability info: canStartToday, availableDate
  • Status: pending, accepted, rejected, expired, withdrawn

Booking Lifecycle

StatusDescription
pendingRequest awaiting acceptance
acceptedWorker confirmed
declinedWorker declined
in_progressWork started
completedWork finished
cancelledCalled off
disputedIssue raised
  • Full scheduling: date, time, estimated duration
  • Location: GPS + address
  • Agreed pricing
  • Source tracking: isOnPlatform (true = booked via app, false = word-of-mouth)
  • Payment tracking (future-ready): paymentStatus, paymentMethod, transactionId, platformFee

Review System

  • Ratings (1-5 stars):
    • overallRating (required)
    • qualityRating (work quality)
    • punctualityRating (timeliness)
    • communicationRating
    • valueRating (value for money)
  • Title, comment, images (photos of completed work)
  • Worker can respond (workerResponse)
  • Verified only after completed booking

3.5 YeboScore: Universal Work Credential

Philosophy: African context considerations:

  • Word of mouth > formal credentials
  • Repeat customers = real trust
  • Community reputation matters
  • Showing up and doing good work > fancy certificates

Score Components (Weighted for Africa)

ComponentWeightDescription
Customer Reviews35%Word of mouth is king
Reliability25%Do you show up and finish?
Repeat Business20%Do people come back?
Response Time15%Are you available?
Okia Interview5%Optional, for formal roles

Tiers

TierMin ScoreRequirements
Platinum80+20+ jobs, 4.5+ rating, 50%+ repeat customers
Gold60+10+ jobs, 4.0+ rating, 30%+ repeat
Silver40+5+ jobs, 3.5+ rating
Bronze0+New worker

Badges

  • top_rated: 4.8+ stars with 10+ reviews
  • trusted: 50%+ repeat customers
  • fast_responder: <30 min avg response, 90%+ response rate
  • reliable: 95%+ completion rate
  • veteran: 1+ year, 50+ jobs
  • verified: ID verified

3.6 AI Onboarding (Okia Service Integration)

Session Types

  • worker_onboarding: Set up service worker profile via chat
  • service_matching: Find right service for needs
  • request_creation: AI helps write service request
  • general_work_interview: Okia interview for YeboScore

Okia Service (Separate Python FastAPI App)

  • Located in okia-service/
  • Uses Claude AI for conversations
  • Socket.IO for real-time chat
  • Webhook callbacks to YeboJobs backend
  • Extracts structured data from conversations

3.7 AI Interview System

Integration Flow

  1. Employer enables AI interview on job posting
  2. Candidate applies → optionally auto-invited
  3. Okia creates interview session
  4. Candidate completes interview via Okia interface
  5. Okia sends webhook with scores
  6. YeboJobs updates application with:
    • interviewScore (0-100)
    • interviewGrade (A+, A, B+, B, C, D, F)
    • interviewStatus (pending, in_progress, completed, expired)

Score Categories

  • Technical
  • Communication
  • Problem Solving
  • Cultural Fit

Privacy Control

Users can toggle showInterviewScores to hide scores from employers.

3.8 Experience Lab (Gamified Learning)

Tracks

  • Categories: customer_service, data_entry, professional_communication
  • Difficulty: beginner, intermediate, advanced
  • Free or paid tracks
  • Can be employer-created

Tasks

  • Types: multiple_choice, text_response, file_upload, scenario
  • Auto-grading for MCQ and basic text analysis
  • XP rewards on completion
  • Max attempts limit (default 3)
  • Passing score (default 70%)

Progression System

  • XP & Levels:
    • Level 1: 0 XP
    • Level 2: 100 XP
    • Level 10: 4,500 XP
  • Track Completion: Issues verifiable certificate
  • Certificates: Unique verification codes (YJ-XXXXXXXX)
  • Badges: first_task, perfect_score, first_try, track_complete_*, etc.

3.9 Credits System (Monetization)

Credit Costs (Actions)

Job Seeker:

ActionCredits
JOB_APPLY_ENTRY5
JOB_APPLY_MID8
JOB_APPLY_SENIOR12
JOB_APPLY_COVER_LETTER3
JOB_SAVE1
MESSAGE_AFTER_FREE3
INTERVIEW_RETAKE15
INTERVIEW_TRANSCRIPT10

Employer:

ActionCredits
POST_JOB25
POST_JOB_FEATURED50
POST_JOB_URGENT35
VIEW_CV3
SEND_INTERVIEW_INVITE10
ACCESS_CONTACT_INFO8
BULK_MESSAGE_1020
HIRING_SUCCESS50

Service Workers:

ActionCredits
CREATE_WORKER_PROFILE10
ADD_EXTRA_CATEGORY5
SUBMIT_QUOTE2
BOOST_PROFILE_7_DAYS30
PREMIUM_BADGE_MONTHLY50

Clients:

ActionCredits
LIKE_WORKER1
POST_SERVICE_REQUEST8
POST_SERVICE_REQUEST_URGENT20
MESSAGE_WORKER_AFTER_FREE2
BOOK_WORKER_DIRECT5

Credit Rewards

RewardCredits
SIGNUP5
VERIFY_PHONE5
VERIFY_EMAIL3
COMPLETE_PROFILE10
ADD_PROFILE_PHOTO3
CONNECT_WHATSAPP5
FIRST_CV_UPLOAD5
FIRST_INTERVIEW_COMPLETED10
ADD_INTRO_VIDEO10
REFERRAL_SIGNUP15
REFERRAL_FIRST_PURCHASE10
FIVE_STAR_REVIEW2
DAILY_STREAK_75
DAILY_STREAK_3025
YEBOSCORE_SILVER20
YEBOSCORE_GOLD50
YEBOSCORE_PLATINUM100

Multi-Currency Support

  • Currencies table with PPP-adjusted pricing
  • Credit rate per currency
  • Tier system (1-5) for regional pricing
  • Supported: USD, ZAR, SZL, KES, NGN, etc.

Credit Packages

  • Multiple packages: Starter, Popular, Pro, Business
  • Base credits + bonus credits
  • Multi-currency prices

Payment Flow (Manual)

  1. User selects package and currency
  2. Payment request created (48h expiry)
  3. User pays via local method (MTN MoMo, bank transfer, M-Pesa, etc.)
  4. User submits payment reference
  5. Admin confirms → credits added
  6. Full audit trail via CreditTransaction

Worker Cashout

  • Minimum 100 credits
  • Freeze credits during processing
  • Platform fee: 15% on bookings
  • Multiple payout methods

3.10 Stripe Billing System

Subscription Tiers

TierDescription
freeBasic access
proAdvanced features
businessFull platform access
enterpriseCustom pricing

Subscription Status

  • active, trialing, past_due, canceled, unpaid, paused

Admin Controls

  • Free Trials: Admin can grant custom trial periods
  • Vouchers: Create discount codes with:
    • Types: percentage, fixed_amount, free_trial, credits
    • Scope: all_users, new_users_only, specific_users
    • Usage limits, date ranges, stackability rules
  • Promotions: Site-wide banners with voucher links

Billing Features

  • StripeCustomer linking (User or Employer)
  • Multiple payment methods on file
  • Invoice tracking
  • Webhook event idempotency (WebhookEvent model)

3.11 Messaging System

Conversation Types

TypeContext
job_inquiryAbout a job application
booking_inquiryAbout a service booking/quote

Features

  • Multi-participant conversations
  • Message types: text, image, system
  • Status tracking: sent, delivered, read
  • Unread counts per participant
  • Reply-to threading
  • Typing indicators (lastTypingAt)
  • Mute, pin, archive, delete (soft)

3.12 CV Management

AI-Generated CVs

  • Created via Okia chat sessions
  • Structured data extraction:
    • personal_info: full_name, email, phone, location, profile_summary
    • experience: company, position, dates, achievements
    • education: institution, degree, field, graduation
    • skills: technical[], soft[]
    • languages: language, proficiency
    • certifications: name, issuer, year

CV Features

  • Multiple CVs per user
  • Default CV flag
  • Privacy control (isPublic)
  • Source tracking: ai_chat, manual, import

3.13 WhatsApp Alerts

Alert Types

  • new_job_match
  • booking_update
  • new_quote
  • review_received

Integration

  • Uses shared Eneza notification worker
  • HTTP client with retry logic (exponential backoff)
  • Status tracking: pending, sent, failed

3.14 Blog System

  • Full CMS with BlogPost model
  • Slug-based URLs
  • Categories, tags
  • Scheduled publishing
  • AI author support

4. User Journeys

4.1 Job Seeker Journey

1. SIGNUP
   ├── Enter phone number
   ├── Receive OTP via WhatsApp
   ├── Verify and create account
   └── Receive 5 signup credits

2. PROFILE SETUP
   ├── Basic info (name, location)
   ├── Upload profile picture (+3 credits)
   ├── Add education & experience
   ├── Complete AI onboarding (+10 credits)
   └── Upload/generate CV (+5 credits)

3. JOB DISCOVERY
   ├── Browse TikTok-style job feed
   ├── Swipe right (like) / left (dislike) / up (superlike)
   ├── Save interesting jobs
   └── View job details and videos

4. APPLICATION
   ├── Apply with CV (-5 to -12 credits based on level)
   ├── Optional: Add cover letter (-3 credits)
   ├── If AI interview enabled → invited
   └── Track application status

5. AI INTERVIEW
   ├── Receive interview invitation
   ├── Complete via Okia interface
   ├── Get scored (0-100)
   └── Optionally hide scores from employers

6. HIRED
   ├── Employer marks as hired
   ├── Placement record created
   └── Update profile with new experience

4.2 Employer Journey

1. SIGNUP
   ├── Company registration (email-based)
   ├── Set up company profile
   └── Select subscription tier

2. POST JOB
   ├── Job details + requirements
   ├── Set salary and benefits
   ├── Configure AI interview (optional)
   ├── Pay credits (-25 to -50)
   └── Job goes live

3. REVIEW APPLICATIONS
   ├── Browse applicant profiles
   ├── View CVs (-3 credits per view)
   ├── Check AI interview scores
   └── Shortlist candidates

4. HIRE
   ├── Send interview invites (-10 credits)
   ├── Conduct additional interviews
   ├── Mark successful candidate as hired
   └── Complete placement

5. MANAGE BILLING
   ├── View subscription status
   ├── Purchase credit packages
   ├── Apply voucher codes
   └── Download invoices

4.3 Service Worker Journey

1. SIGNUP
   ├── Phone verification
   ├── Choose role: service_worker
   └── Receive signup credits

2. PROFILE SETUP (via AI Onboarding)
   ├── Chat with Okia
   ├── Describe skills & experience
   ├── Set pricing ranges
   ├── Upload intro video
   ├── Add portfolio images/videos
   └── AI generates profile

3. CREATE LISTINGS
   ├── Define services offered
   ├── Set pricing with negotiation notes
   ├── Specify what's included/excluded
   └── Add service images

4. FIND WORK
   ├── Swipe through client requests
   ├── Submit quotes (-2 credits)
   ├── Respond to direct messages
   └── Accept bookings

5. COMPLETE JOBS
   ├── Arrive on time
   ├── Mark job started
   ├── Complete work
   ├── Mark job completed
   └── Receive payment

6. BUILD YEBOSCORE
   ├── Get client reviews
   ├── Build repeat customer base
   ├── Improve response time
   ├── Earn tier upgrades
   └── Unlock badges

7. CASHOUT
   ├── Request cashout (min 100 credits)
   ├── Select payment method
   ├── Admin processes
   └── Receive funds (minus 15% fee)

4.4 Client Journey

1. SIGNUP
   ├── Phone verification
   ├── Choose role: client
   └── Receive signup credits

2. FIND WORKERS
   ├── Browse service worker profiles
   ├── Filter by category, location, rating
   ├── Watch intro videos
   ├── Check YeboScore
   └── Like workers (-1 credit)

3. POST REQUEST
   ├── Describe what you need
   ├── AI extracts category tags
   ├── Set budget range
   ├── Set preferred date/time
   ├── Mark urgent if needed
   ├── Pay credits (-8 or -20)
   └── AI matches relevant workers

4. RECEIVE QUOTES
   ├── Workers submit quotes
   ├── Compare pricing & availability
   ├── Chat with workers
   └── Negotiate if needed

5. BOOK SERVICE
   ├── Accept a quote
   ├── Confirm booking details
   ├── Worker accepts/declines
   └── Job scheduled

6. AFTER SERVICE
   ├── Worker completes job
   ├── Mark as completed
   ├── Submit review (detailed ratings)
   ├── Upload photos of work
   └── Optionally tip/recommend

4.5 Admin Journey

1. BILLING MANAGEMENT
   ├── Review pending payment requests
   ├── Confirm or reject payments
   ├── Process cashout requests
   ├── Manage subscriptions
   └── Issue refunds

2. TRIAL MANAGEMENT
   ├── Grant free trials to users
   ├── Set custom duration
   ├── Send expiry reminders
   ├── Extend or revoke trials
   └── Track conversions

3. VOUCHER MANAGEMENT
   ├── Create voucher codes
   ├── Set discount rules
   ├── Limit to specific users
   ├── Track usage
   └── Deactivate expired vouchers

4. PROMOTIONS
   ├── Create site-wide banners
   ├── Link to vouchers
   ├── Target specific user types
   ├── Schedule start/end dates
   └── A/B test messaging

5. ANALYTICS
   ├── Revenue reports
   ├── Subscription analytics
   ├── Trial conversion rates
   ├── Voucher performance
   └── User breakdowns

5. Data Models (Complete)

5.1 Core User Models

User

prisma
model User {
  id                  String    @id @default(cuid())
  name                String
  email               String?
  password            String
  phone               String    @unique
  location            String
  bio                 String?
  profilePicture      String?
  profileVideo        String?
  personalityMatch    String[]  @default([])
  culturePreferences  String[]  @default([])
  isActive            Boolean   @default(true)
  lastLogin           DateTime?
  refreshToken        String?
  showInterviewScores Boolean   @default(true)
  role                UserRole  @default(job_seeker)
  latitude            Float?
  longitude           Float?
  subscriptionTier    SubscriptionTier @default(free)
  subscriptionStatus  SubscriptionStatus?
  createdAt           DateTime  @default(now())
  updatedAt           DateTime  @updatedAt
}

Employer

prisma
model Employer {
  id             String      @id @default(cuid())
  companyName    String
  email          String      @unique
  password       String
  industry       String
  companySize    CompanySize
  description    String
  phone          String
  whatsappNumber String?
  logo           String?
  website        String?
  location       String
  isVerified     Boolean     @default(false)
  jobsPosted     Int         @default(0)
  activeJobs     Int         @default(0)
  joinedDate     DateTime    @default(now())
  refreshToken   String?
  subscriptionTier   SubscriptionTier @default(free)
  subscriptionStatus SubscriptionStatus?
  createdAt      DateTime    @default(now())
  updatedAt      DateTime    @updatedAt
}

5.2 Job Models

Job (All Fields)

prisma
model Job {
  id                 String          @id @default(cuid())
  title              String
  company            String
  location           String
  salary             Decimal         @db.Decimal(12, 2)
  currency           String          @default("USD")
  description        String
  requirements       String[]        @default([])
  benefits           String[]        @default([])
  jobType            JobType         // full_time, part_time, contract, internship, remote
  experienceLevel    ExperienceLevel // entry, mid, senior, executive
  applicationsCount  Int             @default(0)
  savesCount         Int             @default(0)
  sharesCount        Int             @default(0)
  videoContent       String?
  isActive           Boolean         @default(true)
  postedDate         DateTime        @default(now())
  expiryDate         DateTime
  hashtags           String[]        @default([])
  trending           Boolean         @default(false)
  boostLevel         Int             @default(0) @db.SmallInt
  cultureFit         String[]        @default([])
  personalityMatch   String[]        @default([])
  whatsappContact    String?
  email              String
  employerId         String
  aiInterviewEnabled Boolean         @default(false)
  autoInviteOnApply  Boolean         @default(false)
  interviewQuestions Int             @default(10)
  interviewTimeLimit Int             @default(15)
  createdAt          DateTime        @default(now())
  updatedAt          DateTime        @updatedAt
}

Application

prisma
model Application {
  id                   String            @id @default(cuid())
  userId               String
  jobId                String
  employerId           String
  status               ApplicationStatus @default(pending)
  coverLetter          String?
  cvUrl                String?
  appliedDate          DateTime          @default(now())
  lastUpdated          DateTime          @default(now()) @updatedAt
  interviewSessionId   String?
  interviewStatus      String?   // pending, in_progress, completed, expired
  interviewScore       Int?      // 0-100
  interviewGrade       String?   // A+, A, B+, B, C, D, F
  interviewCompletedAt DateTime?
  createdAt            DateTime          @default(now())
  updatedAt            DateTime          @updatedAt

  @@unique([userId, jobId])
}

5.3 Services Models

ServiceWorkerProfile (All Fields)

prisma
model ServiceWorkerProfile {
  id              String   @id @default(cuid())
  userId          String   @unique
  headline        String
  bio             String?
  skills          String[] @default([])
  yearsExperience Int      @default(0)
  priceMin        Decimal? @db.Decimal(10, 2)
  priceMax        Decimal? @db.Decimal(10, 2)
  priceNote       String?
  currency        String   @default("SZL")
  negotiable      Boolean  @default(true)
  latitude        Float?
  longitude       Float?
  locationName    String
  serviceRadius   Int      @default(25)
  isAvailable     Boolean  @default(true)
  availableDays   String[] @default(["monday","tuesday","wednesday","thursday","friday"])
  availableFrom   String?  @default("08:00")
  availableTo     String?  @default("17:00")
  introVideo      String?
  portfolioVideos String[] @default([])
  portfolioImages String[] @default([])
  certificateUrls String[] @default([])
  isVerified      Boolean  @default(false)
  idVerified      Boolean  @default(false)
  phoneVerified   Boolean  @default(true)
  jobsCompleted   Int      @default(0)
  averageRating   Decimal  @default(0) @db.Decimal(2, 1)
  reviewCount     Int      @default(0)
  responseRate    Int      @default(100)
  responseTimeMin Int      @default(60)
  onboardingComplete Boolean @default(false)
  aiProfileScore  Int?
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}

ServiceBooking (All Fields)

prisma
model ServiceBooking {
  id              String        @id @default(cuid())
  clientId        String
  workerId        String
  listingId       String?
  requestId       String?
  categoryId      String?
  description     String
  categoryTags    String[]      @default([])
  scheduledDate   DateTime
  scheduledTime   String?
  estimatedDuration String?
  latitude        Float
  longitude       Float
  locationName    String
  address         String
  agreedPrice     Decimal       @db.Decimal(10, 2)
  currency        String        @default("SZL")
  priceNotes      String?
  status          BookingStatus @default(pending)
  acceptedAt      DateTime?
  startedAt       DateTime?
  completedAt     DateTime?
  cancelledAt     DateTime?
  clientPhone     String
  workerPhone     String
  notes           String?
  isOnPlatform    Boolean       @default(true)
  sourceNote      String?
  paymentStatus   String        @default("unpaid")
  paymentMethod   String?
  transactionId   String?
  platformFee     Decimal?      @db.Decimal(10, 2)
  createdAt       DateTime      @default(now())
  updatedAt       DateTime      @updatedAt
}

YeboScore (All Fields)

prisma
model YeboScore {
  id               String   @id @default(cuid())
  userId           String   @unique
  generalScore     Int?     // Okia interview (0-100)
  generalGrade     String?  // A+, A, B+, B, C, D, F
  skillScores      Json?    // {"plumbing": 85, "electrical": null}
  lastInterviewAt  DateTime?
  reliabilityScore Int      @default(50)
  responseScore    Int      @default(50)
  customerRating   Decimal  @default(0) @db.Decimal(2, 1)
  reviewCount      Int      @default(0)
  overallScore     Int      @default(0)
  tier             YeboTier @default(bronze)
  badges           String[] @default([])
  lastCalculatedAt DateTime @default(now())
  createdAt        DateTime @default(now())
  updatedAt        DateTime @updatedAt
}

5.4 Billing Models

UserCredits

prisma
model UserCredits {
  id             String   @id @default(cuid())
  userId         String   @unique
  balance        Int      @default(0)
  frozenBalance  Int      @default(0)  // In escrow
  totalPurchased Int      @default(0)
  totalSpent     Int      @default(0)
  totalEarned    Int      @default(0)
  totalBonuses   Int      @default(0)
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt
}

CreditTransaction

prisma
model CreditTransaction {
  id            String   @id @default(cuid())
  userId        String
  type          String   // purchase, spend, earn, refund, freeze, unfreeze, bonus, referral
  amount        Int      // Positive = add, Negative = deduct
  action        String   // job_apply, post_job, booking, signup, etc.
  description   String
  referenceType String?
  referenceId   String?
  balanceBefore Int
  balanceAfter  Int
  createdAt     DateTime @default(now())
}

Subscription

prisma
model Subscription {
  id                   String             @id @default(cuid())
  stripeSubscriptionId String?            @unique
  stripeCustomerId     String
  tier                 SubscriptionTier   @default(free)
  status               SubscriptionStatus @default(active)
  priceId              String?
  currentPeriodStart   DateTime?
  currentPeriodEnd     DateTime?
  billingInterval      BillingInterval?
  trialStart           DateTime?
  trialEnd             DateTime?
  isAdminGrantedTrial  Boolean            @default(false)
  trialGrantedBy       String?
  trialNote            String?
  cancelAtPeriodEnd    Boolean            @default(false)
  canceledAt           DateTime?
  cancelReason         String?
  featuresJson         Json?
  createdAt            DateTime           @default(now())
  updatedAt            DateTime           @updatedAt
}

Voucher (All Fields)

prisma
model Voucher {
  id                  String              @id @default(cuid())
  code                String              @unique
  name                String
  description         String?
  type                VoucherType         // percentage, fixed_amount, free_trial, credits
  discountValue       Decimal?            @db.Decimal(10, 2)
  maxDiscountAmount   Decimal?            @db.Decimal(10, 2)
  bonusCredits        Int                 @default(0)
  trialDays           Int                 @default(0)
  scope               VoucherScope        @default(all_users)
  applicableTiers     SubscriptionTier[]  @default([])
  applicableIntervals BillingInterval[]   @default([])
  subscriberTypes     SubscriberType[]    @default([user, employer])
  maxTotalUses        Int?
  maxUsesPerUser      Int                 @default(1)
  currentUses         Int                 @default(0)
  isActive            Boolean             @default(true)
  startsAt            DateTime            @default(now())
  expiresAt           DateTime?
  isStackable         Boolean             @default(false)
  isExclusive         Boolean             @default(false)
  stripeCouponId      String?
  createdBy           String
  createdAt           DateTime            @default(now())
  updatedAt           DateTime            @updatedAt
}

5.5 Experience Lab Models

ExperienceTrack

prisma
model ExperienceTrack {
  id             String   @id @default(cuid())
  name           String
  slug           String   @unique
  description    String
  category       String   // customer_service, data_entry, etc.
  difficulty     String   // beginner, intermediate, advanced
  estimatedHours Float
  iconUrl        String?
  isActive       Boolean  @default(true)
  isFree         Boolean  @default(true)
  employerId     String?  // null = YeboJobs official
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt
}

ExperienceTask

prisma
model ExperienceTask {
  id               String  @id @default(cuid())
  trackId          String
  orderIndex       Int
  title            String
  description      String
  instructions     String  // markdown
  taskType         String  // multiple_choice, text_response, file_upload, scenario
  taskData         Json    // questions, options, rubric
  estimatedMinutes Int
  passingScore     Int     @default(70)
  maxAttempts      Int     @default(3)
  resources        Json?   // [{title, url}]
  xpReward         Int     @default(50)
  createdAt        DateTime @default(now())
  updatedAt        DateTime @updatedAt
  
  @@unique([trackId, orderIndex])
}

5.6 All Enums

prisma
enum CompanySize { startup, small, medium, large, enterprise }
enum JobType { full_time, part_time, contract, internship, remote }
enum ExperienceLevel { entry, mid, senior, executive }
enum ApplicationStatus { pending, reviewed, shortlisted, rejected, hired }
enum SwipeAction { like, dislike, superlike }
enum UserRole { job_seeker, service_worker, client, hybrid }
enum BookingStatus { pending, accepted, declined, in_progress, completed, cancelled, disputed }
enum YeboTier { bronze, silver, gold, platinum }
enum SubscriptionTier { free, pro, business, enterprise }
enum SubscriptionStatus { active, trialing, past_due, canceled, unpaid, paused }
enum SubscriberType { user, employer }
enum VoucherType { percentage, fixed_amount, free_trial, credits }
enum VoucherScope { all_users, new_users_only, specific_users }
enum PromotionStatus { draft, scheduled, active, ended, paused }
enum TrialStatus { active, expired, converted, revoked }
enum BillingInterval { monthly, yearly }
enum MessageStatus { sent, delivered, read }
enum MessageType { text, image, system }
enum ConversationType { job_inquiry, booking_inquiry }

6. API Reference

6.1 Authentication Routes (/api/auth)

MethodEndpointDescription
POST/registerUser registration with phone OTP
POST/loginUser login (phone + password)
POST/employer/registerEmployer registration
POST/employer/loginEmployer login (email + password)
POST/refreshRefresh access token
POST/logoutInvalidate refresh token
POST/verify-otpVerify phone OTP
POST/resend-otpResend OTP code
POST/forgot-passwordPassword reset request
POST/reset-passwordComplete password reset

6.2 User Routes (/api/user)

MethodEndpointAuthDescription
GET/profileUserGet own profile
PUT/profileUserUpdate profile
GET/profile/:idOptionalGet user public profile
POST/profile/pictureUserUpload profile picture
POST/educationUserAdd education
PUT/education/:idUserUpdate education
DELETE/education/:idUserDelete education
POST/experienceUserAdd work experience
PUT/experience/:idUserUpdate experience
DELETE/experience/:idUserDelete experience
GET/applicationsUserGet user's applications

6.3 Job Routes (/api/jobs)

MethodEndpointAuthDescription
GET/OptionalList jobs (with filters)
GET/feedOptionalTikTok-style job feed
GET/:idOptionalGet job details
POST/EmployerCreate job posting
PUT/:idEmployerUpdate job
DELETE/:idEmployerDelete job
POST/:id/swipeUserSwipe on job
POST/:id/saveUserSave job
DELETE/:id/saveUserUnsave job
GET/savedUserGet saved jobs

6.4 Application Routes (/api/applications)

MethodEndpointAuthDescription
POST/UserApply for job
GET/UserGet user's applications
GET/:idUser/EmployerGet application details
PUT/:id/statusEmployerUpdate application status
DELETE/:idUserWithdraw application

6.5 Employer Routes (/api/employer)

MethodEndpointAuthDescription
GET/profileEmployerGet company profile
PUT/profileEmployerUpdate company profile
GET/jobsEmployerList employer's jobs
GET/applicationsEmployerList all applications
GET/statsEmployerGet hiring stats

6.6 Services Routes (/api/services)

MethodEndpointAuthDescription
GET/categoriesPublicList service categories
GET/categories/:slugPublicGet category by slug
POST/worker/profileUserCreate worker profile
PUT/worker/profileUserUpdate worker profile
GET/worker/profile/:idPublicGet worker profile
GET/workersPublicSearch workers
GET/workers/feedUserTikTok-style worker feed
POST/workers/:id/swipeUserSwipe on worker
POST/listingsWorkerCreate service listing
GET/listings/:idPublicGet listing details
PUT/listings/:idWorkerUpdate listing
DELETE/listings/:idWorkerDelete listing

6.7 Booking Routes (/api/bookings)

MethodEndpointAuthDescription
POST/UserCreate booking
GET/UserList user's bookings
GET/:idUserGet booking details
PUT/:id/statusUser/WorkerUpdate booking status
POST/:id/completeWorkerMark completed
POST/:id/reviewClientSubmit review

6.8 Reviews Routes (/api/reviews)

MethodEndpointAuthDescription
GET/worker/:workerIdPublicGet worker reviews
POST/:bookingIdUserCreate review
PUT/:idUserUpdate review
POST/:id/respondWorkerWorker response

6.9 Credits Routes (/api/credits)

MethodEndpointAuthDescription
GET/balanceUserGet credit balance
GET/transactionsUserGet transaction history
GET/packagesPublicList credit packages
POST/purchaseUserCreate payment request
POST/purchase/:id/referenceUserSubmit payment reference
GET/currenciesPublicList supported currencies
POST/cashoutUserRequest cashout
GET/cashoutUserGet cashout history

6.10 Billing Routes (/api/billing)

MethodEndpointAuthDescription
GET/subscriptionUserGet subscription status
POST/checkoutUserCreate Stripe checkout session
POST/manageUserCreate Stripe portal session
GET/plansPublicList subscription plans
POST/voucher/validateUserValidate voucher code
POST/voucher/applyUserApply voucher
GET/invoicesUserGet invoice history

6.11 Subscription Routes (/api/subscriptions)

MethodEndpointAuthDescription
GET/UserGet active subscription
POST/cancelUserCancel subscription
POST/resumeUserResume cancelled subscription

6.12 Interview Routes (/api/interviews)

MethodEndpointAuthDescription
POST/inviteEmployerInvite to AI interview
GET/status/:applicationIdUser/EmployerGet interview status
GET/pendingUserGet pending interviews
GET/UserGet all interviews
GET/session/:applicationIdUserGet interview session URL
PUT/privacyUserUpdate score visibility
GET/employerEmployerGet applications with interviews
POST/webhook/completedSystemOkia webhook handler

6.13 Experience Routes (/api/experience)

MethodEndpointAuthDescription
GET/tracksPublicList all tracks
GET/tracks/:slugPublicGet track by slug
POST/tracks/:id/enrollUserEnroll in track
GET/enrollmentsUserGet user enrollments
GET/tasks/:idUserGet task with progress
POST/tasks/:id/submitUserSubmit task
GET/certificatesUserGet user certificates
GET/certificates/verify/:codePublicVerify certificate
GET/progressUserGet full progress summary
GET/leaderboardPublicGet XP leaderboard

6.14 AI Onboarding Routes (/api/ai-onboarding)

MethodEndpointAuthDescription
POST/sessionUserStart AI onboarding session
GET/session/:tokenUserGet session status
POST/session/:token/messageUserSend message to AI
POST/session/:token/completeUserComplete session

6.15 Messages Routes (/api/messages)

MethodEndpointAuthDescription
GET/conversationsUserList conversations
POST/conversationsUserCreate conversation
GET/conversations/:idUserGet conversation messages
POST/conversations/:id/messagesUserSend message
PUT/conversations/:id/readUserMark as read
PUT/conversations/:id/archiveUserArchive conversation

6.16 Placement Routes (/api/placements)

MethodEndpointAuthDescription
POST/EmployerCreate placement
GET/employerEmployerGet employer placements
GET/userUserGet user placements
GET/:idAnyGet placement details

6.17 Dashboard Routes (/api/dashboard)

MethodEndpointAuthDescription
GET/metricsDashboardGet dashboard metrics

6.18 Admin Billing Routes (/api/admin/billing)

MethodEndpointAuthDescription
GET/subscriptionsAdminList subscriptions
POST/subscriptions/:id/cancelAdminCancel subscription
POST/subscriptions/:id/refundAdminRefund subscription
GET/trialsAdminList free trials
POST/trialsAdminGrant free trial
PUT/trials/:idAdminExtend trial
DELETE/trials/:id/revokeAdminRevoke trial
GET/vouchersAdminList vouchers
POST/vouchersAdminCreate voucher
PUT/vouchers/:idAdminUpdate voucher
DELETE/vouchers/:idAdminDeactivate voucher
GET/promotionsAdminList promotions
POST/promotionsAdminCreate promotion
GET/analytics/*AdminVarious analytics endpoints

6.19 Webhook Routes (/api/webhooks)

MethodEndpointAuthDescription
POST/stripeStripe SignatureStripe webhook handler

7. Service Architecture

7.1 Backend Structure

yebojobs/backend/
├── prisma/
│   └── schema.prisma          # Database schema
├── src/
│   ├── config/
│   │   ├── prisma.ts          # Prisma client
│   │   └── stripe.ts          # Stripe configuration
│   ├── controllers/           # Request handlers
│   ├── services/              # Business logic
│   ├── routes/                # API routes
│   ├── middleware/
│   │   ├── auth.middleware.ts # JWT auth
│   │   └── validation.middleware.ts
│   ├── utils/
│   │   ├── ApiResponse.ts     # Standardized responses
│   │   └── jwt.ts             # Token utilities
│   └── app.ts                 # Express setup

7.2 External Services

  • Okia Service: AI interviews (Python/FastAPI + Claude)
  • Eneza Notifications: WhatsApp messaging
  • Stripe: Payment processing
  • Cloudflare R2: File storage (implied)
  • GCP Cloud Run: Hosting

7.3 Key Services

YeboScoreService

  • calculateScore(userId): Calculates weighted score
  • updateInterviewScore(): Updates from Okia
  • getScoreWithBreakdown(): Full score details

CreditsService

  • spendCredits(): Deduct credits
  • earnCredits(): Add earned credits
  • freezeCredits(): Escrow for bookings
  • releaseEscrow(): Complete booking payment
  • addBonusCredits(): Reward system

NotificationService

  • sendVerificationCode(): WhatsApp OTP
  • Retry with exponential backoff

ExperienceService

  • Track/task management
  • Auto-grading (MCQ, text analysis)
  • XP/leveling system
  • Certificate generation

8. Authentication & Authorization

8.1 Authentication Methods

  • Users: Phone + OTP + Password
  • Employers: Email + Password

8.2 Token System

  • Access Token: Short-lived JWT
  • Refresh Token: Long-lived, stored in DB
  • Decoded payload: { id, type: 'user' | 'employer' }

8.3 Middleware

MiddlewareDescription
authMiddlewareRequires valid JWT
userAuthRequires type === 'user'
employerAuthRequires type === 'employer'
optionalAuthSets user if token valid, doesn't require
dashboardAuthMiddlewareAdmin dashboard access

8.4 OTP Flow

  1. Request OTP → WhatsApp via Eneza notification service
  2. OTP code hashed with bcrypt, stored in VerificationCode
  3. Max 5 attempts, 10-minute expiry
  4. Verify → Create account / Reset password

9. Payment/Billing

9.1 Dual Payment System

Manual Credits (Africa-focused)

  • Credit packages with multi-currency pricing
  • Local payment methods: MTN MoMo, M-Pesa, bank transfer, Airtel Money
  • Manual confirmation by admin
  • 48-hour payment window

Stripe (International)

  • Subscription management
  • Card payments
  • Webhook-based updates
  • Automatic renewal

9.2 Platform Fee

  • 15% on service bookings
  • Deducted when escrow released to worker

9.3 Escrow System

  1. Client books service → credits frozen
  2. Worker completes job → marked complete
  3. Escrow released: worker gets 85%, platform 15%
  4. If cancelled: full refund to client

10. Matching Algorithm

10.1 Job Matching (Implicit)

  • Location-based filtering
  • Job type and experience level matching
  • Personality/culture fit arrays (for future scoring)
  • Hashtag matching potential

10.2 Service Worker Matching

  • GPS-based radius search (serviceRadius km)
  • Category matching via tags
  • AI extraction of categoryTags from request description
  • Availability filtering (days, hours)
  • Rating/YeboScore sorting

10.3 AI Matching (Service Requests)

  • aiMatchedWorkers[] field on ServiceRequest
  • Populated by AI analysis of request vs worker profiles
  • Considers: skills, location, availability, ratings

11. Notifications

11.1 WhatsApp Alerts

  • Sent via Eneza notification worker
  • Types: new_job_match, booking_update, new_quote, review_received
  • Status tracking: pending → sent/failed

11.2 Notification Triggers

  • New job matching user profile
  • Booking status changes
  • New quotes on requests
  • Review received
  • Interview invitations

12. Technical Stack

12.1 Backend

  • Runtime: Node.js with TypeScript
  • Framework: Express.js
  • ORM: Prisma
  • Database: PostgreSQL (Neon serverless)
  • Auth: JWT (jsonwebtoken)
  • Validation: Joi
  • Payments: Stripe SDK

12.2 Frontend

  • Framework: React 18 with TypeScript
  • Build Tool: Vite
  • Styling: Tailwind CSS
  • UI Components: Headless UI
  • Animation: Framer Motion
  • State: React Context (implied)
  • Real-time: Socket.io client

12.3 Admin Dashboard

  • Separate React app (yebojobs-admin/)
  • Full billing/trial/voucher management
  • Analytics dashboards

12.4 Okia Service (AI Interviews)

  • Language: Python
  • Framework: FastAPI
  • AI: Claude (Anthropic)
  • Real-time: Socket.IO
  • Database: PostgreSQL (SQLAlchemy/Alembic)

12.5 Infrastructure

  • Hosting: GCP Cloud Run
  • Database: Neon (serverless Postgres)
  • Files: Cloudflare R2 (implied)
  • Notifications: Eneza notification service
  • CI/CD: GCP Cloud Build

13. Gaps & What's Missing

13.1 Not Yet Implemented

  1. Real-time chat: Socket.IO for messages (client exists, server implementation unclear)
  2. Push notifications: Mobile app push (only WhatsApp currently)
  3. Video upload processing: No video transcoding pipeline visible
  4. Search: Full-text search enabled in Prisma but implementation unclear
  5. Escrow payment integration: Credits system ready, but no mobile money API integration
  6. Referral tracking: Reward logic exists but referral link generation missing
  7. Analytics events: User behavior tracking for recommendations

13.2 Future Enhancements Indicated in Code

  1. Service matching AI: aiMatchedWorkers field exists, needs implementation
  2. Daily streak tracking: Reward constants exist, tracking logic needed
  3. Payment method storage: Schema ready for saved payment methods
  4. Employer job analytics: View counts, application funnel
  5. Worker calendar/scheduling: Availability exists, calendar view needed

13.3 Admin Features Needed

  1. User/employer management UI
  2. Content moderation (reviews, profiles)
  3. Dispute resolution workflow
  4. Financial reconciliation

13.4 Mobile App

  • Frontend is web-only currently
  • Progressive Web App or native needed for full experience

13.5 Documentation

  • API docs (Swagger/OpenAPI) not found
  • Developer onboarding docs missing

Appendix A: Environment Variables

env
# Database
DATABASE_URL=postgresql://...
DIRECT_URL=postgresql://...

# Auth
JWT_SECRET=...
JWT_REFRESH_SECRET=...

# Stripe
STRIPE_SECRET_KEY=sk_...
STRIPE_PUBLISHABLE_KEY=pk_...
STRIPE_WEBHOOK_SECRET=whsec_...

# Okia Integration
OKIA_SERVICE_URL=https://okia-service-xxx.run.app
OKIA_WEBHOOK_SECRET=...

# Notifications
NOTIFICATION_SERVICE_URL=https://notifications.eneza.app
NOTIFICATION_SERVICE_API_KEY=...

# Environment
NODE_ENV=production
PORT=8080

Appendix B: Database Indexes

Key performance indexes defined in schema:

  • users: phone, location, (latitude, longitude)
  • jobs: location, employerId, isActive+postedDate, expiryDate
  • applications: employerId+status, appliedDate, interviewSessionId
  • service_worker_profiles: (latitude, longitude), isAvailable+averageRating, locationName
  • service_bookings: clientId+status, workerId+status, scheduledDate
  • reviews: workerId+overallRating, workerId+createdAt
  • credit_transactions: userId+createdAt, action, type
  • yebo_scores: tier+overallScore

This PRD represents the actual implemented state of YeboJobs as of the codebase analysis date. Features marked as "exists" are present in the code; gaps are identified based on incomplete implementations or missing integrations.

One chat. Everything done.