YeboMart — Product Requirements Document
Smart Shop Management for Africa
Overview
YeboMart is a comprehensive point-of-sale (POS) and shop management platform designed specifically for African small businesses. It provides inventory tracking, sales processing, staff management, AI-powered business insights, and multi-country support with PPP-adjusted pricing across 15 African nations.
Status: Built and deployed
Stack: Node.js/Express + PostgreSQL + React + Stripe
Markets: Eswatini, South Africa, Kenya, Nigeria, Ghana, Tanzania, Uganda, Rwanda, Ethiopia, Ivory Coast, Senegal, Zambia, Zimbabwe, Botswana, Mozambique
1. Vision & Problem Statement
The Problem
Small shop owners across Africa face critical challenges:
- Paper-based chaos — Handwritten ledgers lead to errors, theft, and no visibility
- No inventory insight — Shops run out of popular items, dead stock ties up cash
- Manual calculations — Errors in pricing, change, and daily totals
- No business intelligence — Owners don't know what's selling, what's not, or how profitable they are
- Expensive software — Western POS systems cost $50-200/month — unaffordable for African tuckshops
- Offline reality — Internet is unreliable; solutions must work offline
The Solution
YeboMart provides:
- Mobile-first POS with offline capability and barcode scanning
- Real-time inventory tracking with low-stock alerts
- AI assistant that answers business questions in plain language
- PPP-adjusted pricing — E99/month in Eswatini (not $99)
- Multi-currency & multi-country support out of the box
- WhatsApp reports delivered daily to the owner's phone
2. Target Users
| User Type | Description | Key Needs |
|---|---|---|
| Shop Owner | Owns a tuckshop, grocery, hardware, or retail shop | Business insights, profit tracking, staff management |
| Cashier | Front-line staff processing sales | Fast POS, PIN login, simple interface |
| Manager | Supervises operations | Stock management, void sales, view reports |
| Admin | YeboMart platform administrator | Monitor shops, manage subscriptions |
3. Features by Tier
Tier Structure
| Tier | Monthly Price (Eswatini) | Products | Users | AI Queries |
|---|---|---|---|---|
| Lite | E99 | 100 | 1 | 100 |
| Starter | E499 | 500 | 3 | 500 |
| Business | E2,499 | 2,500 | 10 | 2,000 |
| Pro | E4,999 | 10,000 | 25 | 10,000 |
| Enterprise | E9,999 | Unlimited | Unlimited | Unlimited |
Feature Matrix
Feature | Lite | Starter | Business | Pro | Enterprise
------------------------|------|---------|----------|-----|------------
Point of Sale | ✓ | ✓ | ✓ | ✓ | ✓
Stock Tracking | ✓ | ✓ | ✓ | ✓ | ✓
Basic Reports | ✓ | ✓ | ✓ | ✓ | ✓
AI Assistant | ✓ | ✓ | ✓ | ✓ | ✓
Barcode Scanning | | ✓ | ✓ | ✓ | ✓
Low Stock Alerts | | ✓ | ✓ | ✓ | ✓
Staff Accounts | | ✓ | ✓ | ✓ | ✓
WhatsApp Reports | | | ✓ | ✓ | ✓
Advanced Analytics | | | ✓ | ✓ | ✓
AI Voice | | | | ✓ | ✓
Multi-Location | | | | ✓ | ✓
API Access | | | | | ✓
Dedicated Support | | | | | ✓4. User Journeys
Journey 1: Shop Owner Onboarding
graph TD
A[Download App] --> B[Select Country]
B --> C[Enter Phone Number]
C --> D[Create PIN]
D --> E[Name Your Shop]
E --> F[Choose Business Type]
F --> G[Name AI Assistant]
G --> H[Start Free Trial]
H --> I[Add First Product]Journey 2: Making a Sale
graph TD
A[Open POS] --> B{Scan or Search}
B -->|Scan| C[Barcode Scanner]
B -->|Search| D[Product Grid]
C --> E[Add to Cart]
D --> E
E --> F{More Items?}
F -->|Yes| B
F -->|No| G[Select Payment]
G --> H[Cash/Card/MoMo/eMali]
H --> I[Print/Email Receipt]
I --> J[Stock Updated]Journey 3: AI Business Insights
graph TD
A[Open Assistant] --> B[Ask Question]
B --> C[AI Analyzes Data]
C --> D[Products + Sales + Stock]
D --> E[Generate Insight]
E --> F[Actionable Response]
F --> G{Take Action?}
G -->|Yes| H[Navigate to Feature]
G -->|No| I[Ask Another Question]5. Data Models
Core Models
Shop
model Shop {
id String @id @default(cuid())
name String
ownerName String
ownerPhone String @unique // E.164 format
ownerEmail String?
password String // Hashed
businessType String @default("general")
assistantName String @default("Yebo")
// Localization
countryCode String @default("SZ")
phoneCountryCode String @default("+268")
currencySymbol String @default("E")
currency String @default("SZL")
timezone String @default("Africa/Mbabane")
// Subscription
tier ShopTier @default(LITE)
status ShopStatus @default(ACTIVE)
licenseKey String? @unique
licenseExpiry DateTime?
// Usage Tracking
monthlyTransactions Int @default(0)
monthlyStockMoves Int @default(0)
monthlyAiQueries Int @default(0)
// Relations
users User[]
products Product[]
sales Sale[]
customers Customer[]
suppliers Supplier[]
// ... more relations
}Product
model Product {
id String @id @default(cuid())
shopId String
barcode String?
name String
category String?
// Pricing
costPrice Float
sellPrice Float
wholesalePrice Float?
packPrice Float?
packSize Int?
// Stock
quantity Int @default(0)
reorderAt Int @default(10)
unit String @default("each")
trackStock Boolean @default(true)
isActive Boolean @default(true)
// Relations
shop Shop @relation(fields: [shopId], references: [id])
saleItems SaleItem[]
stockLogs StockLog[]
}Sale
model Sale {
id String @id @default(cuid())
shopId String
userId String?
customerId String?
// Totals
subtotal Float
discount Float @default(0)
totalAmount Float
// Payment
paymentMethod PaymentMethod
amountPaid Float
change Float @default(0)
status SaleStatus @default(COMPLETED)
receiptNumber String?
// Offline sync
localId String?
offlineAt DateTime?
syncedAt DateTime?
// Relations
items SaleItem[]
}User (Staff)
model User {
id String @id @default(cuid())
shopId String
name String
phone String
pin String? // 4-digit PIN
role UserRole @default(CASHIER)
// Permissions
canDiscount Boolean @default(false)
canVoid Boolean @default(false)
canViewReports Boolean @default(false)
canManageStock Boolean @default(false)
// Relations
shop Shop @relation(fields: [shopId], references: [id])
sales Sale[]
}Supporting Models
- StockLog — Tracks all inventory movements with audit trail
- Customer — Store credit customers with balance tracking
- CustomerCredit — Individual credit transactions
- Supplier — Vendor management with contact info
- PurchaseOrder — Procurement tracking
- Return — Refunds and exchanges
- Expense — Operating expenses by category
- DailyReport — Generated daily summaries
- AIConversation — Chat history with AI assistant
- AuditLog — Security audit trail
- Admin — Platform administrators
6. API Reference
Authentication
| Endpoint | Method | Description |
|---|---|---|
/api/v1/auth/register | POST | Register new shop |
/api/v1/auth/login | POST | Owner login (phone + password) |
/api/v1/auth/login/user | POST | Staff login (phone + PIN) |
/api/v1/auth/refresh | POST | Refresh access token |
/api/v1/auth/me | GET | Get current user/shop |
Products
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api/v1/products | GET | ✓ | List products with pagination |
/api/v1/products | POST | Manager | Create product |
/api/v1/products/:id | GET | ✓ | Get product by ID |
/api/v1/products/:id | PATCH | Manager | Update product |
/api/v1/products/:id | DELETE | Manager | Soft delete product |
/api/v1/products/barcode/:code | GET | ✓ | Lookup by barcode |
/api/v1/products/categories | GET | ✓ | List categories |
/api/v1/products/export | GET | Manager | Export CSV |
/api/v1/products/bulk/import | POST | Manager | Bulk import |
/api/v1/products/bulk/update | POST | Manager | Bulk update |
Sales
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api/v1/sales | GET | ✓ | List sales with filters |
/api/v1/sales | POST | ✓ | Create new sale |
/api/v1/sales/:id | GET | ✓ | Get sale details |
/api/v1/sales/:id/void | POST | Manager | Void a sale |
/api/v1/sales/daily-summary | GET | ✓ | Today's summary |
/api/v1/sales/search/receipt | GET | ✓ | Find by receipt number |
/api/v1/sales/email-receipt | POST | ✓ | Email receipt to customer |
Stock
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api/v1/stock | GET | ✓ | Current stock levels |
/api/v1/stock/alerts | GET | ✓ | Low stock alerts |
/api/v1/stock/movements | GET | ✓ | Movement history |
/api/v1/stock/adjust | POST | Manager | Adjust stock |
/api/v1/stock/receive | POST | Manager | Bulk restock |
AI Assistant
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api/v1/ai/chat | POST | ✓ | Chat with AI assistant |
/api/v1/ai/voice | POST | ✓ | Voice query (transcribed) |
/api/v1/ai/insights | GET | ✓ | Generated insights |
/api/v1/ai/slow-movers | GET | ✓ | Slow-moving products |
/api/v1/ai/summary | GET | ✓ | Business summary |
Reports
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api/v1/reports/summary | GET | Manager | Overview stats |
/api/v1/reports/daily | GET | Manager | Daily report |
/api/v1/reports/weekly | GET | Manager | Weekly report |
/api/v1/reports/products | GET | Manager | Product performance |
/api/v1/reports/staff | GET | Manager | Staff performance |
Billing
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api/v1/billing/plans | GET | Optional | Get pricing plans |
/api/v1/billing/checkout | POST | ✓ | Create Stripe checkout |
/api/v1/billing/webhook | POST | — | Stripe webhook handler |
Additional Endpoints
- Customers — CRUD + credit management
- Returns — Process refunds and exchanges
- Suppliers — Vendor management
- Users/Staff — Staff CRUD with permissions
- Expenses — Operating expense tracking
- License — Subscription management
- Audit — Security audit logs
- Admin — Platform administration
7. Service Architecture
┌─────────────────────────────────────────────────────────────────┐
│ YeboMart App │
│ (React + TypeScript + PWA) │
├─────────────────────────────────────────────────────────────────┤
│ Stores: authStore | inventoryStore | cartStore | subscription │
│ Features: POS | Products | Stock | Sales | Reports | AI Chat │
└───────────────────────────┬─────────────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────────────────────────┐
│ YeboMart API │
│ (Node.js + Express + TypeScript) │
├─────────────────────────────────────────────────────────────────┤
│ Routes: auth | products | sales | stock | ai | billing | admin │
├─────────────────────────────────────────────────────────────────┤
│ Middleware: auth | rateLimit | validation | license | usage │
├─────────────────────────────────────────────────────────────────┤
│ Services: │
│ AuthService - Registration, login, JWT │
│ ProductService - CRUD, bulk import/export │
│ SaleService - Transactions, receipts, voids │
│ StockService - Inventory, adjustments, alerts │
│ AIService - Gemini integration, insights │
│ BillingService - Stripe checkout, subscriptions │
│ ReportService - Daily/weekly/product/staff reports │
│ LicenseService - Tier features, usage tracking │
│ ShopService - Shop management, usage counters │
└───────────────────────────┬─────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Postgres │ │ Gemini │ │ Stripe │
│ (Neon) │ │ API │ │ Billing │
└──────────┘ └──────────┘ └──────────┘8. Authentication & Authorization
Auth Flow
- Shop Registration → Creates shop + generates JWT
- Owner Login → Phone + password → JWT (type: shop, role: OWNER)
- Staff Login → Phone + 4-digit PIN → JWT (type: user, role: CASHIER/MANAGER)
- Token Refresh → Refresh token → New access token
Roles & Permissions
| Permission | CASHIER | MANAGER | OWNER |
|---|---|---|---|
| Make sales | ✓ | ✓ | ✓ |
| View own sales | ✓ | ✓ | ✓ |
| Apply discounts | configurable | ✓ | ✓ |
| Void sales | — | ✓ | ✓ |
| View reports | configurable | ✓ | ✓ |
| Manage stock | configurable | ✓ | ✓ |
| Manage products | — | ✓ | ✓ |
| Manage staff | — | — | ✓ |
| Billing/Settings | — | — | ✓ |
JWT Structure
interface ITokenPayload {
id: string; // User or Shop ID
shopId: string; // Always the shop ID
phone: string;
email?: string;
role: 'OWNER' | 'MANAGER' | 'CASHIER';
type: 'shop' | 'user' | 'admin';
}9. Billing & Pricing
Multi-Country Pricing
YeboMart uses PPP-adjusted pricing across 15 African countries:
| Country | Currency | Lite | Starter | Business | Pro | Enterprise |
|---|---|---|---|---|---|---|
| 🇸🇿 Eswatini | SZL | E99 | E499 | E2,499 | E4,999 | E9,999 |
| 🇿🇦 South Africa | ZAR | R99 | R499 | R3,499 | R6,999 | R13,999 |
| 🇰🇪 Kenya | KES | KSh999 | KSh4,999 | KSh19,999 | KSh39,999 | KSh79,999 |
| 🇳🇬 Nigeria | NGN | ₦9,999 | ₦49,999 | ₦199,999 | ₦399,999 | ₦799,999 |
| 🇬🇭 Ghana | GHS | GH₵99 | GH₵499 | GH₵2,699 | GH₵5,499 | GH₵10,999 |
| 🇹🇿 Tanzania | TZS | TSh9,999 | TSh49,999 | TSh249,999 | TSh499,999 | TSh999,999 |
| 🇺🇬 Uganda | UGX | USh19,999 | USh99,999 | USh499,999 | USh999,999 | USh1,999,999 |
| 🇷🇼 Rwanda | RWF | FRw4,999 | FRw24,999 | FRw124,999 | FRw249,999 | FRw499,999 |
| 🇪🇹 Ethiopia | ETB | Br499 | Br2,499 | Br12,499 | Br24,999 | Br49,999 |
| 🇨🇮 Ivory Coast | XOF | CFA2,999 | CFA14,999 | CFA84,999 | CFA169,999 | CFA339,999 |
| 🇸🇳 Senegal | XOF | CFA2,999 | CFA14,999 | CFA64,999 | CFA129,999 | CFA259,999 |
| 🇿🇲 Zambia | ZMW | ZK99 | ZK499 | ZK2,499 | ZK4,999 | ZK9,999 |
| 🇿🇼 Zimbabwe | USD | $3 | $15 | $79 | $149 | $299 |
| 🇧🇼 Botswana | BWP | P149 | P799 | P4,499 | P8,999 | P17,999 |
| 🇲🇿 Mozambique | MZN | MT99 | MT499 | MT2,499 | MT4,999 | MT9,999 |
Prices shown are Launch Special discounts (75-86% off)
Stripe Integration
- Checkout Flow: One-time payment → License update
- Webhook Events:
checkout.session.completed→ Tier upgrade - Currency Handling: Convert to USD for Stripe-unsupported currencies
10. Technical Stack
Backend
| Component | Technology |
|---|---|
| Runtime | Node.js 20.x |
| Framework | Express 4.x |
| Language | TypeScript 5.x |
| ORM | Prisma 5.x |
| Database | PostgreSQL (Neon) |
| Auth | JWT (jsonwebtoken) |
| Validation | Joi |
| AI | Google Gemini 2.0 Flash |
| Payments | Stripe |
| File Storage | Cloudflare R2 |
| Hosting | Google Cloud Run |
Frontend (App)
| Component | Technology |
|---|---|
| Framework | React 18 |
| Language | TypeScript |
| Routing | React Router 6 |
| State | Zustand |
| Data Fetching | TanStack Query |
| Styling | Tailwind CSS |
| Icons | Heroicons |
| Offline | IndexedDB (Dexie) |
| Build | Vite |
| Hosting | Cloudflare Pages |
Admin Dashboard
| Component | Technology |
|---|---|
| Framework | React 18 |
| Charts | Recharts |
| Icons | Lucide React |
| Styling | Tailwind CSS |
11. Gaps & Future Improvements
Current Gaps
- Offline Sync — Framework exists but not fully implemented
- WhatsApp Reports — Designed but not connected
- Multi-Location — Schema ready, UI not built
- Voice Input — Endpoint exists, mobile mic integration needed
- Receipt Printing — Browser print only, no Bluetooth/thermal
Planned Features
| Feature | Priority | Status |
|---|---|---|
| Full offline mode with sync | High | Partial |
| WhatsApp daily report delivery | High | Designed |
| Supplier auto-reorder suggestions | Medium | Not started |
| Multi-location stock transfers | Medium | Schema ready |
| Accounting module integration | Medium | Not started |
| Customer loyalty/points system | Low | Not started |
| API access for Enterprise tier | Low | Not started |
Technical Debt
- Standardize error handling across all routes
- Add comprehensive test coverage
- Implement proper offline conflict resolution
- Add request logging and observability
- Optimize database queries for large inventories
12. Success Metrics
Business Metrics
- Monthly Active Shops — Target: 1,000 by Q4 2026
- Paid Conversion Rate — Target: 15%
- Monthly Recurring Revenue — Track by country
- Churn Rate — Target: <5% monthly
Product Metrics
- Daily Transactions Processed — Growth indicator
- AI Query Usage — Feature adoption
- Average Session Duration — Engagement
- Feature Adoption by Tier — Upsell opportunities
Technical Metrics
- API Response Time — P95 < 500ms
- Uptime — 99.9% target
- Sync Success Rate — For offline mode
- Error Rate — < 0.1% of requests
Appendix: Business Types
YeboMart supports various shop types with tailored categories:
- Tuckshop — Small convenience store
- Grocery — Food and household items
- Hardware — Construction and tools
- Pharmacy — Medicines and health products
- Salon/Barbershop — Beauty services
- Electronics — Phones, accessories, repairs
- Clothing — Fashion and apparel
- Restaurant/Fast Food — Food service
- General — Multi-category retail
Each type comes with pre-configured product categories and suggested units.