Skip to content

Zaptam - Product Requirements Document ​

Version: 1.0
Last Updated: March 2026
Status: Built & Documented


Table of Contents ​

  1. Executive Summary
  2. Vision & Mission
  3. Problem Statement
  4. Solution Overview
  5. Target Audience
  6. Core Features
  7. User Journeys
  8. Data Models
  9. API Reference
  10. Service Architecture
  11. Matching Algorithm
  12. Authentication System
  13. Billing & Premium Features
  14. Content Moderation & Trust System
  15. Technical Stack
  16. Gaps & Missing Features

1. Executive Summary ​

Zaptam is a private, verified dating and companionship network targeting the African market with a focus on exclusivity, discretion, and trust. Unlike traditional dating apps, Zaptam implements a rigorous verification system where:

  • Men must verify their financial capacity ("worth verification")
  • Women must verify their identity ("value verification")

The platform operates on a gender-asymmetric business model:

  • Men pay for membership ($49-$499/month)
  • Women join free after passing verification and acceptance review

The system consists of four interconnected applications:

  • zaptam-api: Backend REST API + WebSocket server
  • zaptam-app: User-facing mobile/web app (React)
  • zaptam-admin: Administrative dashboard (React)
  • zaptam-landing: Marketing website (React)

2. Vision & Mission ​

Vision ​

"Not Everyone Deserves Access" — Create the most trusted network for adults seeking genuine connections through rigorous verification and exclusive membership.

Mission ​

  • Build a high-trust dating network where worth and value are verified, not claimed
  • Protect user privacy with industry-leading security measures
  • Maintain quality through selective approval and ongoing behavioral monitoring
  • Create a value balance: men bring financial capacity, women bring authentic presence

Core Principles ​

  1. Verification First: Every member undergoes rigorous screening
  2. Privacy Protected: Screenshot protection, alias mode, encrypted messaging
  3. Quality Over Quantity: 8% acceptance rate (claimed target)
  4. Discretion First: No public profiles, no social sharing
  5. Zero Tolerance: Immediate action on misconduct

3. Problem Statement ​

Industry Problems ​

  1. Fake Profiles: Traditional dating apps are plagued with fake accounts and catfishing
  2. Low Commitment: Free apps attract users who aren't invested
  3. Privacy Concerns: Users fear exposure and lack control over their data
  4. Misaligned Incentives: Apps optimize for time spent swiping, not actual connections
  5. Safety Issues: Inadequate verification leads to harassment, scams, and blackmail

African Market Specific ​

  • Cultural need for discretion in dating
  • Growing affluent population seeking premium services
  • Lack of high-quality, verified dating platforms in the region
  • Trust deficit in online interactions

4. Solution Overview ​

Zaptam addresses these problems through:

ProblemSolution
Fake profilesMulti-tier verification system (ID, Worth, Value)
Low commitmentPaid membership for men ($49-499/month)
Privacy concernsAlias mode, photo blur, screenshot detection, panic delete
Misaligned incentivesMatch-based messaging (must both express interest)
Safety issuesTrust scoring, behavioral monitoring, blackmail hotline

Key Differentiators ​

  • Worth Verification (Men): Financial capacity demonstration
  • Value Verification (Women): Identity verification + selective acceptance
  • Trust Score: Dynamic 0-100 score based on behavior
  • Panic Delete: Instant, permanent data wipe
  • Screenshot Detection: Notify victims + trust penalty for offender

5. Target Audience ​

Male Users ​

  • Demographics: 25-55, professional/business owners
  • Income: Upper-middle to high income
  • Needs: Quality connections, discretion, verified partners
  • Pain Points: Fake profiles, time-wasters, privacy exposure

Female Users ​

  • Demographics: 21-45, various backgrounds
  • Needs: Safe environment, verified partners, earning potential
  • Pain Points: Harassment, fake profiles, unwanted exposure
  • Incentive: Free access + earnings from engagement

Admin Users ​

  • Curators: Review verifications, handle basic reports
  • Admins: User management, payouts, advanced moderation
  • Super Admins: Full system access, analytics, configuration

6. Core Features ​

6.1 User Features ​

Authentication & Onboarding ​

  • Phone number registration with OTP verification
  • Gender-specific application process
  • Multi-step profile completion
  • Password-protected accounts
  • Refresh token rotation

Profile Management ​

  • Alias mode (hide real name)
  • Bio and personal information
  • Photo gallery with blur control
  • Verification badges
  • Trust score display

Discovery & Matching ​

  • Browse opposite gender profiles (default)
  • Filter by verification level
  • Express interest (one-way)
  • Mutual match detection
  • Priority ordering (verified + high trust first)

Messaging ​

  • Real-time WebSocket messaging
  • Conversation list with unread counts
  • Typing indicators
  • Read receipts
  • Disappearing messages (configurable)
  • Media sharing

Privacy Controls ​

  • Alias Mode: Use generated alias instead of real name
  • Photo Blur: Set blur level 0-100% on photos
  • Region Masking: Hide exact location
  • Online Status: Toggle visibility
  • Disappearing Messages: Auto-delete after set hours
  • Panic Delete: Instant account wipe

Wallet & Transactions ​

  • View balance (USD)
  • Purchase credits (men)
  • Request withdrawals (women)
  • Transaction history
  • Membership tier selection

6.2 Admin Features ​

Dashboard ​

  • Total users (by gender, status)
  • Pending verifications count
  • Pending reports count
  • Total matches
  • User growth trends
  • Revenue metrics

User Management ​

  • List all users with filters/search
  • View user details
  • Update user status (suspend/ban)
  • Adjust trust scores
  • Change verification levels

Verification Queue ​

  • List pending verifications
  • Review documents
  • Approve/reject with notes
  • Auto-update user verification level

Report Handling ​

  • List reports by type/status
  • View report details
  • Resolve or dismiss
  • Apply trust penalties
  • Ban offenders

Transaction Management ​

  • View all transactions
  • Process withdrawal requests
  • Approve/reject payouts
  • Revenue analytics

7. User Journeys ​

7.1 Male User Journey ​

1. DISCOVER → Landing page exposure
   ↓
2. APPLY → Submit application (phone, gender, email, occupation, net worth)
   ↓
3. VERIFY PHONE → Receive OTP via WhatsApp/SMS, enter code
   ↓
4. COMPLETE PROFILE → Set password, bio, date of birth
   ↓
5. PENDING APPROVAL → Wait for admin to approve worth verification
   ↓
6. ACTIVATED → Account becomes ACTIVE
   ↓
7. SUBSCRIBE → Choose membership tier ($49/$149/$499)
   ↓
8. PURCHASE CREDITS → Buy credits for messaging/unlocks
   ↓
9. DISCOVER → Browse verified female profiles
   ↓
10. EXPRESS INTEREST → Send interest to profiles
    ↓
11. MATCH → When interest is mutual
    ↓
12. MESSAGE → Start conversation with match
    ↓
13. MEET → Arrange real-world meeting

7.2 Female User Journey ​

1. DISCOVER → Landing page exposure
   ↓
2. APPLY → Submit application (phone, gender, email, intro, photos)
   ↓
3. VERIFY PHONE → Receive OTP, enter code
   ↓
4. COMPLETE PROFILE → Set password, bio, date of birth
   ↓
5. IDENTITY VERIFICATION → Submit ID documents
   ↓
6. ACCEPTANCE REVIEW → Admin reviews (may reject even if verified)
   ↓
7. ACTIVATED → Account becomes ACTIVE (free membership)
   ↓
8. DISCOVER → Browse verified male profiles
   ↓
9. RECEIVE INTERESTS → Get notified of interests
   ↓
10. ACCEPT/DECLINE → Respond to interests
    ↓
11. MATCH → Interest accepted = match created
    ↓
12. MESSAGE → Chat with matches
    ↓
13. EARN → Receive earnings from engagement (to wallet)
    ↓
14. WITHDRAW → Request payout (min $10)

7.3 Admin Journey ​

1. LOGIN → Authenticate with admin credentials
   ↓
2. DASHBOARD → View system overview
   ↓
3. VERIFICATIONS → Review pending verifications
   ├── APPROVE → User level upgraded
   └── REJECT → User notified, can resubmit
   ↓
4. REPORTS → Handle user reports
   ├── INVESTIGATE → Escalate blackmail
   ├── RESOLVE → Apply penalties, ban if needed
   └── DISMISS → Close without action
   ↓
5. USERS → Manage user accounts
   ├── SUSPEND → Temporary restriction
   ├── BAN → Permanent block
   └── RECALCULATE TRUST → Update trust score
   ↓
6. PAYOUTS → Process withdrawal requests
   ├── APPROVE → Release funds
   └── REJECT → Notify user
   ↓
7. ANALYTICS → Review growth and revenue metrics

8. Data Models ​

8.1 User Model ​

typescript
model User {
  id                String            @id @default(uuid()) @db.Uuid
  phoneNumber       String            @unique
  email             String?           @unique
  password          String?           // Hashed, nullable during application
  role              UserRole          @default(USER)
  gender            Gender?           // MALE | FEMALE
  status            UserStatus        @default(PENDING)

  // Profile
  alias             String?           @unique    // System-generated or custom
  name              String?                      // Real name (hidden in alias mode)
  bio               String?                      // User description
  occupation        String?                      // For male users
  intro             String?                      // For female users
  netWorth          String?                      // For male users
  dateOfBirth       DateTime?

  // Trust & Verification
  trustScore        Int               @default(50)  // 0-100
  verificationLevel VerificationLevel @default(NONE)

  // Timestamps
  lastActiveAt      DateTime?
  createdAt         DateTime          @default(now())
  updatedAt         DateTime          @updatedAt
  deletedAt         DateTime?         // Soft delete

  // Relations
  settings          UserSettings?
  photos            Photo[]
  sentMessages      Message[]            @relation("sender")
  receivedMessages  Message[]            @relation("recipient")
  sentInterests     Interest[]           @relation("sender")
  receivedInterests Interest[]           @relation("recipient")
  verifications     Verification[]
  walletTransactions WalletTransaction[]
  reports           Report[]             @relation("reporter")
  reportedBy        Report[]             @relation("reported")
  conversations1    Conversation[]       @relation("participant1")
  conversations2    Conversation[]       @relation("participant2")
  refreshTokens     RefreshToken[]
  otpCodes          OtpCode[]
}

8.2 UserSettings Model ​

typescript
model UserSettings {
  id               String  @id @default(uuid()) @db.Uuid
  userId           String  @unique @db.Uuid
  
  aliasMode        Boolean @default(true)      // Hide real name
  showOnlineStatus Boolean @default(false)     // Show when online
  regionMasking    Boolean @default(true)      // Hide exact location
  photoBlurLevel   Int     @default(100)       // 0-100, default fully blurred
  disappearingMsgs Int?                        // Hours until auto-delete
}

8.3 Photo Model ​

typescript
model Photo {
  id        String   @id @default(uuid()) @db.Uuid
  userId    String   @db.Uuid
  url       String                           // R2/S3 URL
  blurLevel Int      @default(100)           // 0-100
  isPrimary Boolean  @default(false)         // Main profile photo
  order     Int      @default(0)             // Display order
  createdAt DateTime @default(now())
}

8.4 Interest Model ​

typescript
model Interest {
  id          String         @id @default(uuid()) @db.Uuid
  senderId    String         @db.Uuid
  recipientId String         @db.Uuid
  status      InterestStatus @default(PENDING)  // PENDING | ACCEPTED | DECLINED
  createdAt   DateTime       @default(now())

  @@unique([senderId, recipientId])  // Prevent duplicate interests
}

8.5 Conversation Model ​

typescript
model Conversation {
  id             String    @id @default(uuid()) @db.Uuid
  participant1Id String    @db.Uuid
  participant2Id String    @db.Uuid
  messages       Message[]
  createdAt      DateTime  @default(now())
  updatedAt      DateTime  @updatedAt

  @@unique([participant1Id, participant2Id])
}

8.6 Message Model ​

typescript
model Message {
  id             String       @id @default(uuid()) @db.Uuid
  conversationId String       @db.Uuid
  senderId       String       @db.Uuid
  recipientId    String       @db.Uuid
  content        String?                          // Text content
  mediaUrl       String?                          // Media attachment URL
  isRead         Boolean      @default(false)
  expiresAt      DateTime?                        // Disappearing message
  deletedAt      DateTime?                        // Soft delete
  createdAt      DateTime     @default(now())
}

8.7 Verification Model ​

typescript
model Verification {
  id         String             @id @default(uuid()) @db.Uuid
  userId     String             @db.Uuid
  type       VerificationType   // IDENTITY | WORTH | VALUE
  status     VerificationStatus @default(PENDING)
  documents  Json?              // Array of document URLs
  notes      String?            // Admin notes
  reviewedBy String?            @db.Uuid
  reviewedAt DateTime?
  createdAt  DateTime           @default(now())
}

8.8 WalletTransaction Model ​

typescript
model WalletTransaction {
  id        String            @id @default(uuid()) @db.Uuid
  userId    String            @db.Uuid
  type      TransactionType   // MEMBERSHIP | CREDIT_PURCHASE | EARNING | WITHDRAWAL | BOOST
  amount    Decimal           @db.Decimal(10, 2)
  currency  String            @default("USD")
  status    TransactionStatus @default(PENDING)  // PENDING | COMPLETED | FAILED | REFUNDED
  reference String?           // Payment gateway reference
  createdAt DateTime          @default(now())
}

8.9 Report Model ​

typescript
model Report {
  id          String       @id @default(uuid()) @db.Uuid
  reporterId  String       @db.Uuid           // Who filed the report
  reportedId  String       @db.Uuid           // Who is being reported
  type        ReportType   // BLACKMAIL | HARASSMENT | FAKE_PROFILE | INAPPROPRIATE_CONTENT | OTHER
  description String                          // Detailed description
  evidence    Json?                           // Screenshots, links, etc.
  status      ReportStatus @default(PENDING)  // PENDING | INVESTIGATING | RESOLVED | DISMISSED
  resolution  String?                         // Admin's resolution notes
  resolvedBy  String?      @db.Uuid
  resolvedAt  DateTime?
  createdAt   DateTime     @default(now())
}

8.10 MembershipTier Model ​

typescript
model MembershipTier {
  id        String   @id @default(uuid()) @db.Uuid
  name      String                           // Standard, Premium, Elite
  price     Decimal  @db.Decimal(10, 2)      // Monthly price in USD
  currency  String   @default("USD")
  duration  Int                              // Days
  features  Json                             // Array of feature strings
  isActive  Boolean  @default(true)
  createdAt DateTime @default(now())
}

8.11 RefreshToken Model ​

typescript
model RefreshToken {
  id        String   @id @default(uuid()) @db.Uuid
  userId    String   @db.Uuid
  token     String   @unique
  expiresAt DateTime
  createdAt DateTime @default(now())
}

8.12 OtpCode Model ​

typescript
model OtpCode {
  id        String     @id @default(uuid()) @db.Uuid
  userId    String?    @db.Uuid
  phone     String
  code      String                           // 6-digit code
  purpose   OtpPurpose // REGISTRATION | LOGIN | PASSWORD_RESET
  expiresAt DateTime
  usedAt    DateTime?
  createdAt DateTime   @default(now())
}

8.13 Enums ​

typescript
enum UserRole {
  USER
  CURATOR
  ADMIN
  SUPER_ADMIN
}

enum Gender {
  MALE
  FEMALE
}

enum UserStatus {
  PENDING      // Application submitted
  ACTIVE       // Approved and verified
  SUSPENDED    // Temporarily restricted
  BANNED       // Permanently blocked
  DELETED      // Soft deleted
}

enum VerificationLevel {
  NONE         // No verification
  IDENTITY     // ID verified
  FULL         // ID + Worth/Value verified
}

enum VerificationType {
  IDENTITY     // Government ID
  WORTH        // Financial capacity (men)
  VALUE        // Additional verification (women)
}

enum VerificationStatus {
  PENDING
  APPROVED
  REJECTED
}

enum InterestStatus {
  PENDING
  ACCEPTED
  DECLINED
}

enum TransactionType {
  MEMBERSHIP
  CREDIT_PURCHASE
  EARNING
  WITHDRAWAL
  BOOST
}

enum TransactionStatus {
  PENDING
  COMPLETED
  FAILED
  REFUNDED
}

enum ReportType {
  BLACKMAIL
  HARASSMENT
  FAKE_PROFILE
  INAPPROPRIATE_CONTENT
  OTHER
}

enum ReportStatus {
  PENDING
  INVESTIGATING
  RESOLVED
  DISMISSED
}

enum OtpPurpose {
  REGISTRATION
  LOGIN
  PASSWORD_RESET
}

9. API Reference ​

9.1 Base URL & Headers ​

Production: https://api.zaptam.com
Local: http://localhost:3000

Headers:
  Content-Type: application/json
  Authorization: Bearer <access_token>  (for protected routes)

9.2 Authentication Endpoints ​

MethodEndpointDescriptionAuth
POST/api/auth/applySubmit applicationNo
POST/api/auth/verify-phoneSend OTP to phoneNo
POST/api/auth/confirm-phoneVerify OTP codeNo
POST/api/auth/complete-profileComplete registrationNo
POST/api/auth/loginLogin with credentialsNo
POST/api/auth/refreshRefresh access tokenNo
POST/api/auth/logoutInvalidate tokensYes
POST/api/auth/forgot-passwordRequest password resetNo
POST/api/auth/reset-passwordReset password with codeNo

9.3 User Endpoints ​

MethodEndpointDescriptionAuth
GET/api/users/meGet current userYes
PATCH/api/users/meUpdate profileYes
GET/api/users/me/settingsGet settingsYes
PATCH/api/users/me/settingsUpdate settingsYes
POST/api/users/me/photosUpload photoYes
DELETE/api/users/me/photos/:idDelete photoYes
DELETE/api/users/meDelete accountYes
POST/api/users/me/panic-deletePanic delete (hard)Yes

9.4 Discovery & Profile Endpoints ​

MethodEndpointDescriptionAuth
GET/api/discoverBrowse profilesYes
GET/api/profiles/:idView profile detailYes
POST/api/profiles/:id/interestExpress interestYes

9.5 Match Endpoints ​

MethodEndpointDescriptionAuth
GET/api/matchesGet all matchesYes
DELETE/api/matches/:idRemove/decline matchYes

9.6 Message Endpoints ​

MethodEndpointDescriptionAuth
GET/api/messages/conversationsList conversationsYes
GET/api/messages/conversations/:idGet messagesYes
POST/api/messages/conversations/:idSend messageYes
DELETE/api/messages/conversations/:idDelete conversationYes
POST/api/messages/messages/:id/reportReport a messageYes

9.7 Wallet Endpoints ​

MethodEndpointDescriptionAuth
GET/api/walletGet balanceYes
GET/api/wallet/transactionsTransaction historyYes
POST/api/wallet/purchasePurchase creditsYes
POST/api/wallet/withdrawRequest withdrawalYes
GET/api/wallet/membership-tiersGet membership optionsYes

9.8 Verification Endpoints ​

MethodEndpointDescriptionAuth
GET/api/verification/statusGet verification statusYes
POST/api/verification/identitySubmit ID verificationYes
POST/api/verification/worthSubmit worth (men)Yes
POST/api/verification/valueSubmit value (women)Yes

9.9 Report Endpoints ​

MethodEndpointDescriptionAuth
POST/api/reportsSubmit reportYes
POST/api/reports/blackmailEmergency blackmail reportYes
GET/api/reports/my-reportsView submitted reportsYes

9.10 Admin Endpoints ​

MethodEndpointDescriptionRequired Role
GET/api/admin/dashboardDashboard statsCURATOR+
GET/api/admin/usersList usersCURATOR+
GET/api/admin/users/:idUser detailCURATOR+
PATCH/api/admin/users/:idUpdate userADMIN+
POST/api/admin/users/:id/suspendSuspend userADMIN+
POST/api/admin/users/:id/banBan userADMIN+
POST/api/admin/users/:id/recalculate-trustRecalc trustCURATOR+
GET/api/admin/verificationsVerification queueCURATOR+
PATCH/api/admin/verifications/:idReview verificationCURATOR+
GET/api/admin/reportsList reportsCURATOR+
GET/api/admin/reports/:idReport detailCURATOR+
PATCH/api/admin/reports/:idHandle reportCURATOR+
GET/api/admin/transactionsAll transactionsCURATOR+
GET/api/admin/payoutsPayout requestsCURATOR+
PATCH/api/admin/payouts/:idProcess payoutADMIN+
GET/api/admin/analyticsAnalytics dataCURATOR+

9.11 WebSocket Events ​

Connection: ws://api.zaptam.com with auth.token in handshake

Client → Server:

EventPayloadDescription
join:conversationconversationId: stringJoin conversation room
leave:conversationconversationId: stringLeave conversation room
message:send{ conversationId, content, mediaUrl?, expiresIn? }Send message
message:readconversationId: stringMark messages as read
typing:startconversationId: stringStart typing indicator
typing:stopconversationId: stringStop typing indicator
presence:checktargetUserId: stringCheck if user is online
presence:bulk-checkuserIds: string[]Check multiple users
screenshot:detected{ conversationId? }Report screenshot taken

Server → Client:

EventPayloadDescription
message:new{ conversationId, message }New message received
message:read{ conversationId, readBy }Messages were read
typing:start{ conversationId, userId }User started typing
typing:stop{ conversationId, userId }User stopped typing
user:online{ userId }User came online
user:offline{ userId }User went offline
notification:message{ conversationId, senderId, preview }New message notification
screenshot:alert{ conversationId, userId }Screenshot detected

10. Service Architecture ​

10.1 System Overview ​

┌─────────────────────────────────────────────────────────────────┐
│                         CLIENTS                                  │
├─────────────────┬─────────────────┬─────────────────────────────┤
│   zaptam-app    │  zaptam-admin   │      zaptam-landing         │
│   (React SPA)   │   (React SPA)   │        (React SPA)          │
│   Port: 5173    │   Port: 5174    │        Port: 5175           │
└────────┬────────┴────────┬────────┴─────────────────────────────┘
         │                 │
         ├─────────────────┼──────────────────────────────────────┐
         │                 │                                      │
         ▼                 ▼                                      │
┌─────────────────────────────────────────────────────────────────┤
│                      zaptam-api                                  │
│                    (Express + Socket.IO)                         │
│                       Port: 3000                                 │
├─────────────────────────────────────────────────────────────────┤
│  Routes          │  Services       │  Sockets                    │
│  ├─ auth         │  ├─ auth        │  ├─ message.socket          │
│  ├─ users        │  ├─ user        │  └─ presence.socket         │
│  ├─ profiles     │  ├─ match       │                             │
│  ├─ matches      │  ├─ message     │  Middleware                 │
│  ├─ messages     │  ├─ wallet      │  ├─ auth.middleware         │
│  ├─ wallet       │  ├─ verification│  ├─ role.middleware         │
│  ├─ verification │  ├─ report      │  ├─ validation.middleware   │
│  ├─ reports      │  ├─ trust       │  ├─ rateLimit.middleware    │
│  └─ admin/*      │  └─ notification│  └─ error.middleware        │
└────────┬────────────────┬────────────────────────────────────────┘
         │                │
         ▼                ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────────┐
│   PostgreSQL    │ │ Cloudflare R2    │ │ Notification Service    │
│   (via Prisma)  │ │ (Photo Storage)  │ │ (External API)          │
└─────────────────┘ └──────────────────┘ └─────────────────────────┘

10.2 Service Modules ​

AuthService (auth.service.ts) ​

  • applyForAccount() - Handle new applications
  • sendPhoneOtp() - Send verification codes
  • verifyOtp() - Validate OTP codes
  • completeRegistration() - Finalize account setup
  • login() - Authenticate users
  • refreshAccessToken() - Token rotation
  • logout() - Invalidate tokens
  • resetPassword() - Password recovery

UserService (user.service.ts) ​

  • getUserById() - Fetch user profile
  • getUserSettings() - Fetch settings
  • updateProfile() - Update user info
  • updateSettings() - Update privacy settings
  • changePassword() - Password change
  • deleteAccount() - Soft delete
  • panicDelete() - Hard delete (all data)
  • updateLastActive() - Track activity

MatchService (match.service.ts) ​

  • discoverProfiles() - Browse with filters
  • getProfileById() - View detailed profile
  • expressInterest() - Send interest
  • getMatches() - List mutual matches
  • declineMatch() - Remove match

MessageService (message.service.ts) ​

  • getConversations() - List conversations
  • getMessages() - Fetch messages
  • sendMessage() - Send new message
  • deleteConversation() - Remove conversation
  • getOrCreateConversation() - Ensure conversation exists

WalletService (wallet.service.ts) ​

  • getWalletBalance() - Calculate balance
  • getTransactionHistory() - List transactions
  • purchaseCredits() - Buy credits (men)
  • purchaseMembership() - Subscribe to tier
  • requestWithdrawal() - Request payout (women)
  • processWithdrawal() - Admin payout approval
  • getMembershipTiers() - Get pricing

VerificationService (verification.service.ts) ​

  • getVerificationStatus() - Check current level
  • submitVerification() - Submit documents
  • reviewVerification() - Admin review
  • getPendingVerifications() - Admin queue

ReportService (report.service.ts) ​

  • createReport() - Submit report
  • createBlackmailReport() - High-priority report
  • getReports() - Admin list
  • getReportById() - Report detail
  • getUserReports() - User's reports

TrustService (trust.service.ts) ​

  • calculateTrustScore() - Compute score
  • updateTrustScore() - Refresh score
  • applyTrustPenalty() - Deduct points
  • reportScreenshotDetected() - Screenshot penalty

NotificationService (notification.service.ts) ​

  • sendOtpNotification() - Send OTP via WhatsApp/SMS

10.3 Middleware Pipeline ​

Request → RateLimit → Auth → Role → Validation → Controller → Response
              ↓         ↓       ↓        ↓
           429 err   401 err  403 err  400 err

11. Matching Algorithm ​

11.1 Discovery Ordering ​

Profiles are ranked by:

  1. Verification Level (descending): FULL > IDENTITY > NONE
  2. Trust Score (descending): Higher scores first
  3. Last Active (descending): Recently active first

11.2 Interest & Match Flow ​

User A ──[Express Interest]──→ User B
         │
         ├── If B has NOT expressed interest in A:
         │   └── Create Interest (A→B, status: PENDING)
         │
         └── If B has already expressed interest in A:
             └── MUTUAL MATCH!
                 ├── Update B→A Interest to ACCEPTED
                 ├── Create A→B Interest as ACCEPTED
                 └── Create Conversation for A & B

11.3 Photo Blur Logic ​

For non-matched users:

typescript
blurLevel = Math.max(photo.blurLevel, 80) // At least 80% blur

For matched users:

typescript
blurLevel = photo.blurLevel // User's preferred blur level

12. Authentication System ​

12.1 Token Architecture ​

Token TypeExpiryStorageUse
Access Token15 minutesMemoryAPI requests
Refresh Token7 daysDatabase + ClientGet new access token
OTP Code10 minutesDatabasePhone verification

12.2 JWT Payload ​

typescript
{
  userId: string,
  role: UserRole,
  iat: number,
  exp: number
}

12.3 Token Flow ​

1. User logs in
2. Server generates access + refresh tokens
3. Access token sent in Authorization header
4. On 401, client sends refresh token
5. Server validates refresh token, issues new pair
6. Old refresh token invalidated (rotation)

12.4 OTP Flow ​

  1. Request OTP → sendPhoneOtp()
  2. External notification service sends code via WhatsApp/SMS
  3. User enters code
  4. verifyOtp() validates and marks code as used
  5. OTP expires after 10 minutes or single use

13. Billing & Premium Features ​

13.1 Membership Tiers (Men) ​

TierPriceFeatures
Standard$49/monthWorth verification, browse profiles, unlimited interest, messaging, basic privacy
Premium$149/month+ Worth badge, priority discovery, see who viewed, advanced privacy, read receipts
Elite$499/month+ Top placement, personal curator, exclusive events, monthly boost, 24/7 concierge

13.2 Women's Access ​

  • Price: Free
  • Requirement: Identity verification + acceptance review
  • Benefits: Full platform access, earnings from engagement, priority support

13.3 Transaction Types ​

TypeDirectionUser Type
MEMBERSHIPOutMen
CREDIT_PURCHASEIn (wallet credit)Men
EARNINGInWomen
WITHDRAWALOutWomen
BOOSTOutAll

13.4 Withdrawal Process ​

  1. Women request withdrawal (min $10)
  2. Transaction created with status PENDING
  3. Admin reviews in payout queue
  4. Admin approves → status COMPLETED, funds released
  5. Admin rejects → status FAILED, balance restored

14. Content Moderation & Trust System ​

14.1 Trust Score Algorithm ​

Base Score: 50 (starting value) Range: 0-100

Positive Factors:

FactorPointsMax
Verification Level (IDENTITY)+1010
Verification Level (FULL)+2020
Account Age+1/month10
Matches (Interactions)+1 per 2 matches10

Negative Factors:

FactorPoints
Valid Report Against User-5 each
Screenshot Detected-10 each

14.2 Report Types & Handling ​

TypePriorityAuto-Action
BLACKMAILCRITICALImmediate -20 trust, auto-investigate
HARASSMENTHIGHReview within 24h
FAKE_PROFILEMEDIUMReview within 48h
INAPPROPRIATE_CONTENTMEDIUMReview within 48h
OTHERLOWReview within 72h

14.3 Report Status Flow ​

PENDING → INVESTIGATING → RESOLVED
                       → DISMISSED

14.4 Screenshot Detection ​

  1. Client detects screenshot attempt
  2. Sends screenshot:detected socket event
  3. Server applies -10 trust penalty
  4. Server sends screenshot:alert to conversation partner
  5. Logged for review

14.5 Panic Delete ​

Permanently removes ALL user data:

  • Messages (sent and received)
  • Conversations
  • Interests (sent and received)
  • Photos
  • Verifications
  • Wallet transactions
  • Reports (filed and against)
  • Tokens
  • Settings
  • User record

15. Technical Stack ​

15.1 Backend (zaptam-api) ​

CategoryTechnology
RuntimeNode.js
FrameworkExpress.js 4.18
LanguageTypeScript 5.3
ORMPrisma 5.9
DatabasePostgreSQL
Real-timeSocket.IO 4.7
AuthJWT (jsonwebtoken 9.0)
ValidationJoi 17.12
File StorageCloudflare R2 (S3-compatible)
Password Hashingbcryptjs
Rate Limitingexpress-rate-limit
SecurityHelmet

15.2 Frontend Apps (zaptam-app, zaptam-admin) ​

CategoryTechnology
FrameworkReact 18
LanguageTypeScript 5.3
Build ToolVite 5.0
RouterReact Router 6.22
State ManagementZustand 4.5
Data FetchingTanStack Query 5.17
HTTP ClientAxios 1.6
Real-timeSocket.IO Client 4.7
UI ComponentsRadix UI
StylingTailwind CSS 3.4
AnimationFramer Motion 11
FormsReact Hook Form 7.50
Charts (Admin)Recharts 2.15

15.3 Landing Page (zaptam-landing) ​

CategoryTechnology
FrameworkReact 18
LanguageTypeScript 5.3
Build ToolVite 5.0
RouterReact Router 6.22
StylingTailwind CSS 3.4
AnimationFramer Motion 11

15.4 External Services ​

ServicePurpose
Cloudflare R2Photo storage
Notification Service (Eneza)WhatsApp/SMS OTP delivery
PostgreSQLPrimary database

16. Gaps & Missing Features ​

16.1 Not Yet Implemented ​

FeaturePriorityDescription
Payment Gateway IntegrationHIGHStripe/PayPal for actual payments (currently mock)
Push NotificationsHIGHFCM/APNs for mobile notifications
Email NotificationsMEDIUMTransactional emails (welcome, matches, etc.)
Photo ModerationHIGHAI-based nudity/inappropriate content detection
ID Verification IntegrationHIGHJumio/Onfido for automated ID verification
Worth VerificationHIGHPlaid/bank verification for financial capacity
Video CallsMEDIUMIn-app video calling for matches
Voice MessagesLOWAudio message support
Profile BoostMEDIUMPaid boost functionality
Exclusive EventsLOWElite tier event management
Personal CuratorLOWHuman matching assistance for Elite
Crypto PaymentsLOWBitcoin/crypto payment option
2FAMEDIUMTwo-factor authentication option
App Store DeploymentHIGHiOS/Android native apps (currently web only)

16.2 Technical Debt ​

IssueImpactSuggested Fix
No automated testsHIGHAdd Jest/Vitest test suites
No CI/CD pipelineMEDIUMSetup GitHub Actions
No logging infrastructureMEDIUMAdd structured logging (Pino/Winston)
No monitoringMEDIUMAdd APM (DataDog/NewRelic)
Hardcoded notification URLLOWMove to environment config
No database migrationsMEDIUMUse Prisma migrate instead of db push
No API versioningLOWAdd /api/v1/ prefix
No request tracingLOWAdd correlation IDs
Socket.IO not scalableMEDIUMAdd Redis adapter for multi-instance

16.3 Security Improvements Needed ​

IssuePriorityRecommendation
Rate limit bypassHIGHAdd Redis-backed rate limiting
No brute-force protectionHIGHAdd account lockout after failed attempts
JWT in memory onlyMEDIUMConsider HttpOnly cookies
No audit loggingMEDIUMLog all admin actions
Screenshot detection is client-sideLOWInform users this is deterrent only
Panic delete is irreversibleINFOAdd confirmation flow

16.4 UX Improvements ​

FeaturePriorityDescription
Profile completion progressMEDIUMShow % complete
Onboarding tutorialMEDIUMGuide new users
Dark/Light mode toggleLOWTheme switching
Language localizationMEDIUMMulti-language support
Accessibility (a11y)MEDIUMWCAG compliance
Offline supportLOWPWA with service worker
Image compressionMEDIUMClient-side compression before upload

Appendix A: Directory Structure ​

zaptam-api/
├── prisma/
│   ├── schema.prisma          # Database schema
│   └── seed.ts                # Database seeding
├── src/
│   ├── config/                # Configuration
│   │   ├── database.ts        # Prisma client
│   │   ├── jwt.ts             # JWT config
│   │   ├── multer.ts          # File upload config
│   │   ├── r2.ts              # Cloudflare R2 config
│   │   └── socket.ts          # Socket.IO config
│   ├── controllers/           # Route handlers
│   │   ├── admin/             # Admin controllers
│   │   ├── auth.controller.ts
│   │   ├── match.controller.ts
│   │   ├── message.controller.ts
│   │   ├── profile.controller.ts
│   │   ├── report.controller.ts
│   │   ├── user.controller.ts
│   │   ├── verification.controller.ts
│   │   └── wallet.controller.ts
│   ├── middleware/            # Express middleware
│   │   ├── auth.middleware.ts
│   │   ├── error.middleware.ts
│   │   ├── rateLimit.middleware.ts
│   │   ├── role.middleware.ts
│   │   └── validation.middleware.ts
│   ├── routes/                # Route definitions
│   │   ├── admin/
│   │   ├── auth.routes.ts
│   │   ├── match.routes.ts
│   │   ├── message.routes.ts
│   │   ├── profile.routes.ts
│   │   ├── report.routes.ts
│   │   ├── user.routes.ts
│   │   ├── verification.routes.ts
│   │   ├── wallet.routes.ts
│   │   └── index.ts
│   ├── services/              # Business logic
│   │   ├── auth.service.ts
│   │   ├── match.service.ts
│   │   ├── message.service.ts
│   │   ├── notification.service.ts
│   │   ├── report.service.ts
│   │   ├── trust.service.ts
│   │   ├── user.service.ts
│   │   ├── verification.service.ts
│   │   └── wallet.service.ts
│   ├── sockets/               # WebSocket handlers
│   │   ├── index.ts
│   │   ├── message.socket.ts
│   │   └── presence.socket.ts
│   ├── types/                 # TypeScript types
│   │   └── index.ts
│   ├── utils/                 # Utility functions
│   │   ├── crypto.utils.ts
│   │   ├── helpers.ts
│   │   ├── jwt.utils.ts
│   │   └── r2.utils.ts
│   ├── validators/            # Joi schemas
│   │   ├── auth.validator.ts
│   │   ├── message.validator.ts
│   │   └── profile.validator.ts
│   ├── app.ts                 # Express app setup
│   └── server.ts              # Entry point
└── package.json

zaptam-app/
├── src/
│   ├── api/                   # API client modules
│   │   ├── auth.ts
│   │   ├── client.ts
│   │   ├── matches.ts
│   │   ├── messages.ts
│   │   ├── users.ts
│   │   ├── verification.ts
│   │   └── wallet.ts
│   ├── components/            # React components
│   │   ├── auth/
│   │   ├── layout/
│   │   ├── match/
│   │   ├── message/
│   │   ├── profile/
│   │   ├── ui/
│   │   ├── wallet/
│   │   └── AppLayout.tsx
│   ├── hooks/                 # Custom hooks
│   │   └── useAuth.ts
│   ├── lib/                   # Utilities
│   │   ├── constants.ts
│   │   ├── socket.ts
│   │   └── utils.ts
│   ├── pages/                 # Page components
│   │   ├── auth/
│   │   ├── Conversation.tsx
│   │   ├── Discover.tsx
│   │   ├── Matches.tsx
│   │   ├── Messages.tsx
│   │   ├── Profile.tsx
│   │   ├── Settings.tsx
│   │   └── Wallet.tsx
│   ├── services/              # Service layer
│   │   └── api.ts
│   ├── store/                 # Zustand stores
│   │   ├── auth.ts
│   │   └── socketStore.ts
│   ├── types/                 # TypeScript types
│   │   └── index.ts
│   ├── App.tsx                # Root component
│   └── main.tsx               # Entry point
└── package.json

zaptam-admin/
├── src/
│   ├── components/
│   │   ├── dashboard/
│   │   ├── reports/
│   │   ├── ui/
│   │   ├── users/
│   │   ├── verification/
│   │   └── AdminLayout.tsx
│   ├── hooks/
│   ├── pages/
│   │   ├── Dashboard.tsx
│   │   ├── Login.tsx
│   │   ├── Reports.tsx
│   │   ├── Transactions.tsx
│   │   ├── Users.tsx
│   │   └── Verifications.tsx
│   ├── services/
│   │   └── api.ts
│   ├── store/
│   │   └── auth.ts
│   ├── types/
│   │   └── index.ts
│   ├── App.tsx
│   └── main.tsx
└── package.json

zaptam-landing/
├── src/
│   ├── components/
│   │   ├── layout/
│   │   ├── sections/
│   │   └── ui/
│   ├── hooks/
│   ├── pages/
│   │   ├── About.tsx
│   │   ├── Apply.tsx
│   │   ├── Contact.tsx
│   │   ├── Home.tsx
│   │   ├── HowItWorks.tsx
│   │   ├── Membership.tsx
│   │   ├── Privacy.tsx
│   │   └── Terms.tsx
│   ├── App.tsx
│   └── main.tsx
└── package.json

Appendix B: Environment Variables ​

zaptam-api ​

bash
# Database
DATABASE_URL=postgresql://user:pass@host:5432/zaptam

# JWT
JWT_SECRET=your-secret-key
JWT_ACCESS_EXPIRY=15m
JWT_REFRESH_EXPIRY=7d

# Cloudflare R2
R2_ACCOUNT_ID=your-account-id
R2_ACCESS_KEY_ID=your-access-key
R2_SECRET_ACCESS_KEY=your-secret-key
R2_BUCKET_NAME=zaptam-photos
R2_PUBLIC_URL=https://r2.zaptam.com

# Notification Service
NOTIFICATION_SERVICE_URL=https://notifications.eneza.app
NOTIFICATION_SERVICE_API_KEY=your-api-key
DEFAULT_NOTIFICATION_CHANNEL=whatsapp

# Server
PORT=3000
NODE_ENV=production
CORS_ORIGIN=https://app.zaptam.com

zaptam-app / zaptam-admin ​

bash
VITE_API_URL=https://api.zaptam.com
VITE_WS_URL=wss://api.zaptam.com

Document generated from codebase analysis. Last updated: March 2026.

One chat. Everything done.