Skip to content

YeboNa Services Deep Dive

The database service (services/database.ts) contains all data access logic.

Database Operations (db object)

db.users

User account management.

typescript
// Create user
await db.users.create({
  id: string;
  phoneNumber: string;
  passwordHash: string;
  name?: string;
  email?: string;
  country?: string;
  countryCode?: string;
}): Promise<User>

// Find by phone
await db.users.findByPhone(phoneNumber: string): Promise<User | null>

// Find by ID
await db.users.findById(id: string): Promise<User | null>

// Find by email
await db.users.findByEmail(email: string): Promise<User | null>

// Update user
await db.users.update(id: string, data: Partial<User>): Promise<User | null>

// Update password
await db.users.updatePassword(id: string, passwordHash: string): Promise<User | null>

// Set verified status
await db.users.setVerified(id: string, verified: boolean): Promise<User | null>

db.providers

Provider profiles.

typescript
// Create provider (upgrades user_type)
await db.providers.create({
  id: string;
  userId: string;
  businessName?: string;
  bio?: string;
  city?: string;
  country?: string;
  languages?: string[];
}): Promise<Provider>

// Find by ID
await db.providers.findById(id: string): Promise<Provider | null>

// Find by user ID
await db.providers.findByUserId(userId: string): Promise<Provider | null>

// Find by category
await db.providers.findByCategory(
  category: ServiceCategory,
  limit?: number,
  offset?: number
): Promise<Provider[]>

// Search providers
await db.providers.search({
  category?: ServiceCategory;
  country?: string;
  minRating?: number;
  limit?: number;
  offset?: number;
}): Promise<Provider[]>

// Update rating (recalculates from reviews)
await db.providers.updateRating(id: string): Promise<void>

// Update profile
await db.providers.update(id: string, data: Partial<Provider>): Promise<Provider | null>

db.providerServices

Services offered by providers.

typescript
// Create service offering
await db.providerServices.create({
  id: string;
  providerId: string;
  category: ServiceCategory;
  description: string;
  startingPrice: number;
  currency?: string;
  priceUnit?: PriceUnit;  // 'fixed' | 'hourly' | 'per_item' | 'percentage'
}): Promise<ProviderService>

// Get services by provider
await db.providerServices.findByProvider(providerId: string): Promise<ProviderService[]>

// Delete service
await db.providerServices.delete(id: string): Promise<boolean>

db.requests

Service requests from users.

typescript
// Create request
await db.requests.create({
  id: string;
  userId: string;
  category: ServiceCategory;
  title: string;
  description: string;
  attachments?: string[];
  budgetMin?: number;
  budgetMax?: number;
  budgetCurrency?: string;
  timeline?: string;
  targetProviders?: string[];  // Specific providers to notify
  expiresAt?: Date;
}): Promise<Request>

// Find by ID
await db.requests.findById(id: string): Promise<Request | null>

// Find user's requests
await db.requests.findByUser(userId: string, limit?: number, offset?: number): Promise<Request[]>

// Find open requests (for providers to see)
await db.requests.findOpen(category?: ServiceCategory, limit?: number, offset?: number): Promise<Request[]>

// Update status
await db.requests.updateStatus(id: string, status: RequestStatus): Promise<Request | null>
// Status: 'open' | 'quoted' | 'accepted' | 'completed' | 'cancelled'

db.quotes

Provider quotes on requests.

typescript
// Create quote
await db.quotes.create({
  id: string;
  requestId: string;
  providerId: string;
  amount: number;
  currency?: string;
  description: string;
  deliverables?: string[];
  timeline?: string;
  validUntil?: Date;
}): Promise<Quote>

// Find by ID
await db.quotes.findById(id: string): Promise<Quote | null>

// Find quotes on a request
await db.quotes.findByRequest(requestId: string): Promise<Quote[]>

// Find provider's quotes
await db.quotes.findByProvider(providerId: string, limit?: number, offset?: number): Promise<Quote[]>

// Update status
await db.quotes.updateStatus(id: string, status: QuoteStatus): Promise<Quote | null>
// Status: 'pending' | 'accepted' | 'declined' | 'expired'

db.transactions

Escrow transactions.

typescript
// Create transaction (when quote is accepted)
await db.transactions.create({
  id: string;
  quoteId: string;
  requestId: string;
  userId: string;
  providerId: string;
  amount: number;
  currency?: string;
  fee?: number;  // Platform fee (default 5%)
}): Promise<Transaction>

// Find by ID
await db.transactions.findById(id: string): Promise<Transaction | null>

// Find user's transactions
await db.transactions.findByUser(userId: string, limit?: number, offset?: number): Promise<Transaction[]>

// Find provider's transactions
await db.transactions.findByProvider(providerId: string, limit?: number, offset?: number): Promise<Transaction[]>

// Update status
await db.transactions.updateStatus(id: string, status: TransactionStatus): Promise<Transaction | null>
// Status: 'pending_payment' | 'payment_received' | 'in_progress' | 'completed' | 'disputed' | 'refunded' | 'released'

db.reviews

Review system.

typescript
// Create review
await db.reviews.create({
  id: string;
  transactionId: string;
  reviewerId: string;
  revieweeId: string;
  reviewType: 'user_to_provider' | 'provider_to_user';
  rating: number;
  ratingCommunication?: number;
  ratingQuality?: number;
  ratingValue?: number;
  ratingTimeliness?: number;
  text: string;
  photos?: string[];
}): Promise<Review>

// Find reviews for a transaction
await db.reviews.findByTransaction(transactionId: string): Promise<Review[]>

// Find reviews for a user/provider
await db.reviews.findByReviewee(revieweeId: string, limit?: number, offset?: number): Promise<Review[]>

db.conversations & db.messages

Messaging system.

typescript
// Find or create conversation
await db.conversations.findOrCreate(
  participant1Id: string,
  participant2Id: string,
  requestId?: string
): Promise<Conversation>

// Get user's conversations
await db.conversations.findByUser(userId: string, limit?: number, offset?: number): Promise<Conversation[]>

// Get conversation by ID
await db.conversations.findById(id: string): Promise<Conversation | null>

// Create message
await db.messages.create({
  id: string;
  conversationId: string;
  senderId: string;
  messageType?: MessageType;  // 'text' | 'image' | 'document' | 'voice' | 'system'
  content: string;
  metadata?: Record<string, any>;
}): Promise<Message>

// Get messages in conversation
await db.messages.findByConversation(conversationId: string, limit?: number, offset?: number): Promise<Message[]>

// Mark messages as read
await db.messages.markRead(conversationId: string, userId: string): Promise<void>

db.otps

OTP management.

typescript
// Create OTP (deletes existing)
await db.otps.create({
  phoneNumber: string;
  code: string;
  type: 'signup' | 'password_reset';
}): Promise<OTPRecord>

// Find OTP
await db.otps.findByPhoneAndType(phoneNumber: string, type: string): Promise<OTPRecord | null>

// Delete OTP
await db.otps.delete(phoneNumber: string, type: string): Promise<void>

// Cleanup expired
await db.otps.deleteExpired(): Promise<number>

db.refreshTokens

Token management.

typescript
// Create token
await db.refreshTokens.create({
  token: string;
  userId: string;
  phoneNumber: string;
  expiresAt: Date;
}): Promise<RefreshToken>

// Find by token
await db.refreshTokens.findByToken(token: string): Promise<RefreshToken | null>

// Delete token
await db.refreshTokens.delete(token: string): Promise<boolean>

// Delete all for user (logout all)
await db.refreshTokens.deleteAllForUser(userId: string): Promise<number>

// Cleanup expired
await db.refreshTokens.deleteExpired(): Promise<number>

db.waitlist

Pre-launch waitlist.

typescript
// Create entry
await db.waitlist.create(data: WaitlistEntry): Promise<WaitlistEntry>

// Check if exists
await db.waitlist.findByPhoneAndProduct(phone: string, product: string): Promise<WaitlistEntry | null>

// List all
await db.waitlist.findAll(filters?: { product?: string; status?: string }): Promise<WaitlistEntry[]>

// Get stats by product
await db.waitlist.getStats(): Promise<Record<string, { total: number; byInterest: Record<string, number> }>>

db.blog

Blog/content system.

typescript
// Initialize blog table
await db.blog.initBlogTable(): Promise<void>

// Create post
await db.blog.createPost({
  title: string;
  slug: string;
  content: string;
  excerpt?: string;
  category?: string;
  tags?: string[];
  status?: string;
  author?: string;
  featured_image?: string;
}): Promise<BlogPost>

// Get published posts
await db.blog.getPublishedPosts(offset?: number, limit?: number, category?: string): Promise<{
  posts: BlogPost[];
  total: number;
}>

// Get post by slug
await db.blog.getPostBySlug(slug: string): Promise<BlogPost | null>

WhatsApp Service

Location: services/whatsappService.ts

Sends messages via YeboLink.

typescript
// Send verification code
await sendVerificationCodeMessage(
  phoneNumber: string,
  code: string,
  template: string,
  channel: 'whatsapp'
): Promise<{ success: boolean }>

// Send password reset code
await sendPasswordResetCode(
  phoneNumber: string,
  code: string,
  channel: 'whatsapp'
): Promise<{ success: boolean }>

HTTP Notification Service

Location: services/http-notification.service.ts

Sends webhook notifications.

typescript
await sendHttpNotification(
  url: string,
  payload: Record<string, unknown>
): Promise<{ success: boolean }>

One chat. Everything done.