A modern, comprehensive business verification and directory platform for Sierra Leone. Built to transform how businesses are verified, discovered, and trusted in the Sierra Leonean economy.
The Sierra Leone Business Directory is a hackathon-winning web application that provides real-time business verification, comprehensive search capabilities, and transparent business information. It serves as the definitive registry for businesses operating in Sierra Leone, enabling consumers, investors, banks, and government agencies to verify business legitimacy instantly.
- π AI-Powered Search - Lightning-fast fuzzy search across 50,000+ registered businesses
- β Real-Time Verification - Instant business status and compliance checking
- π Comprehensive Profiles - Detailed business information including financials, directors, and compliance records
- π― Advanced Filtering - Filter by industry, location, verification status, compliance scores, and more
- π± Mobile Responsive - Beautiful, modern UI with glassmorphism design and smooth animations
- π‘οΈ Complaint System - Public accountability through business complaint tracking
- π¬ WhatsApp Integration - Verify businesses via WhatsApp bot or start chats directly from the web with seamless App/Web choice
- π API-First Design - RESTful API for third-party integrations
- π Business Analytics - ESG scores, risk assessments, and market coverage data
IMPORTANT DATA NOTICE: This project currently uses demo business data that was manually created for testing and evaluation purposes and is stored securely in a PostgreSQL database. We are actively working with the Government of Sierra Leone to onboard and synchronize official registry data in a future release.
- Node.js 20.x or higher
- pnpm (recommended) or npm
- PostgreSQL database (Neon, Supabase, or local)
- Git
-
Clone the repository
git clone https://github.com/Walon-Foundation/business-directory.git cd business-directory -
Install dependencies
pnpm install # or npm install -
Set up environment variables
cp .env.example .env
Edit
.envand add your database URL:DATABASE_URL="postgresql://user:password@host:port/database" NODE_ENV="development"
-
Set up the database
# Generate database migrations pnpm db:generate # Push schema to database pnpm db:push # Seed the database with sample data pnpm db:seed
-
Run the development server
pnpm dev
-
Open your browser
Navigate to http://localhost:3000
business-directory/
βββ app/ # Next.js App Router
β βββ api/ # API Routes
β β βββ explore/ # Business search & details API
β β β βββ route.ts # GET /api/explore - Search businesses
β β β βββ [id]/ # Business details & complaints
β β β βββ route.ts # GET /api/explore/[id] - Business details
β β β βββ complaint/
β β β βββ route.ts # POST/GET complaints
β β βββ webhook/ # Webhook handlers
β βββ explore/ # Business exploration pages
β β βββ page.tsx # Browse all businesses
β β βββ [id]/
β β βββ page.tsx # Individual business profile
β βββ about/ # About page
β βββ api-page/ # API documentation
β βββ layout.tsx # Root layout
β βββ page.tsx # Landing page
β βββ globals.css # Global styles
βββ components/ # React components
β βββ ui/ # shadcn/ui components
β βββ navbar.tsx # Navigation bar
β βββ footer.tsx # Footer component
β βββ complaint.tsx # Complaint form component
βββ db/ # Database layer
β βββ schema.ts # Drizzle ORM schema
β βββ db.ts # Database connection
β βββ drizzle/ # Migrations
βββ lib/ # Utility functions
β βββ utils.ts # Helper utilities
β βββ env.ts # Environment validation
β βββ errorHandler.ts # Error handling
β βββ seed.ts # Database seeding script
βββ public/ # Static assets
βββ types/ # TypeScript type definitions
βββ package.json # Dependencies
βββ tsconfig.json # TypeScript config
βββ drizzle.config.ts # Drizzle ORM config
βββ next.config.ts # Next.js config
βββ biome.json # Biome linter config
βββ README.md # This file
The core business table contains comprehensive business information:
Identification
id- UUID primary keyregistrationNumber- Unique business registration numbertaxId- Tax identification number
Basic Information
name- Official business nametradingName- Trading/brand namedescription- Business descriptionstatus- active | pending | suspended | inactiveverificationLevel- verified | pending | unverifiedindustry- Business industry/sectorbusinessType- Legal structure (private_limited, public_limited, etc.)ownership- local | foreign | joint_venture | government | mixed
Location Data
location,address,city,district,province,countrylatitude,longitude- Geolocation coordinates
Financial Information
foundedYear- Year establishedemployees- Employee count rangerevenue- Revenue rangecapitalInvestment- Capital investment amountrating- Business rating (0-5)complianceScore- Compliance score (0-100)trustScore- Trust score (0-100)
JSON Fields (Rich structured data)
directors[]- Management team and shareholdersservices[]- Products and services offeredcertifications[]- Industry certificationsrecentNews[]- Latest news and updatescomplianceRecords[]- Compliance historyrevenueGrowth[]- Historical revenue datamarketCoverage[]- Regional market presenceesgScores- Environmental, Social, Governance scoresriskAssessment- Risk analysis metricsauditInfo- Audit informationregulatoryFilings[]- Regulatory submissions
id- UUID primary keybusinessId- Reference to businessusername- Complainant name (optional/anonymous)type- Complaint categorydescription- Complaint detailsevidenceUrl- Supporting evidence linkuserPhone- Contact phone (optional)source- web | whatsappstatus- pending | reviewed | resolvedcreatedAt- Submission timestamp
GET /api/exploreQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
search |
string | Search term (name, registration number, description) |
page |
number | Page number (default: 1) |
limit |
number | Results per page (1-100, default: 20) |
status |
enum | Filter by status: active, pending, suspended, inactive |
industry |
enum | Filter by industry sector |
businessType |
enum | Filter by business type |
ownership |
enum | Filter by ownership type |
location |
string | Filter by location |
city |
string | Filter by city |
province |
string | Filter by province |
minRating |
number | Minimum rating (0-5) |
maxRating |
number | Maximum rating (0-5) |
minCompliance |
number | Minimum compliance score (0-100) |
maxCompliance |
number | Maximum compliance score (0-100) |
verificationLevel |
enum | verified, pending, unverified |
sortBy |
enum | Sort field: name, rating, complianceScore, createdAt, foundedYear |
sortOrder |
enum | asc or desc |
tags |
string | Comma-separated tags |
Example Request:
curl "http://localhost:3000/api/explore?search=telecom&industry=telecommunications&minRating=4&sortBy=rating&sortOrder=desc"Response:
{
"success": true,
"data": {
"businesses": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"totalPages": 8,
"hasNextPage": true,
"hasPreviousPage": false
},
"filters": {
"availableStatuses": {...},
"topIndustries": [...]
}
},
"timestamp": "2024-12-04T23:30:00.000Z"
}GET /api/explore/[id]Returns complete business profile including all JSON fields.
POST /api/explore/[id]/complaintRequest Body:
{
"type": "Poor Service",
"description": "Detailed complaint description...",
"username": "John Doe",
"userPhone": "+232 76 123 456",
"evidenceUrl": "https://example.com/evidence.jpg",
"source": "web",
"anonymous": false
}GET /api/explore/[id]/complaintReturns all complaints for a specific business.
The directory can also be queried via WhatsApp, using the hosted Wasender API.
Website Integration:
- Users can start a verification chat directly from the homepage.
- A smart dialog allows users to choose between opening the WhatsApp App (for mobile users) or WhatsApp Web (for desktop users), ensuring a seamless experience across devices.
Bot Capabilities:
- Incoming WhatsApp messages are delivered to the application via the webhook endpoint:
POST /api/webhookβ handled byapp/api/webhook/route.ts
- The webhook extracts the text message and looks up a matching business by:
- Registration number (exact match), or
- Caseβinsensitive partial match on
nameandtradingNamein thebusinesstable.
- The bot replies over WhatsApp with either:
- β A structured summary of the matching company (status, registration, industry, verification level, description)
- β A "not found" message with guidance to try a different name or registration number
- Simple greetings like
hi,hello,good morningtrigger an onboarding message explaining how to use the bot.
For full setup instructions (getting an API key, configuring the webhook URL in Wasender, and securing the integration), see SETUP.md and SECURITY.md.
# Development
pnpm dev # Start development server
pnpm build # Build for production
pnpm start # Start production server
# Code Quality
pnpm lint # Run Biome linter
pnpm format # Format code with Biome
# Database
pnpm db:generate # Generate migrations
pnpm db:push # Push schema to database
pnpm db:migrate # Run migrations
pnpm db:studio # Open Drizzle Studio (database GUI)
pnpm db:seed # Seed database with sample data- Next.js 16 - React framework with App Router
- React 19 - UI library
- TypeScript - Type safety
- Tailwind CSS 4 - Utility-first CSS
- shadcn/ui - Component library
- Radix UI - Headless UI primitives
- Lucide React - Icon library
- Next.js API Routes - Serverless API
- Drizzle ORM - TypeScript ORM
- PostgreSQL - Database (Neon/Supabase)
- Zod - Schema validation
- Biome - Fast linter and formatter
- TypeScript - Static type checking
- Drizzle Kit - Database migrations
- pnpm - Fast package manager
- Push your code to GitHub
- Import project in Vercel
- Add environment variables:
DATABASE_URLNODE_ENV=production
- Deploy!
The application can be deployed to any platform that supports Next.js:
- Netlify
- Railway
- Render
- AWS Amplify
- Self-hosted (Docker, VPS)
The project includes a comprehensive seed script with 50+ sample businesses across various industries:
- Telecommunications (Africell, Orange, QCell)
- Banking & Finance (SLCB, Ecobank, UBA)
- Mining (Sierra Rutile, Koidu Holdings)
- Agriculture (Sierra Palm, Agribusiness ventures)
- Healthcare (Hospitals, clinics)
- Construction (Building companies)
- Technology (IT services)
- And many more...
Run pnpm db:seed to populate your database.
- β Input validation with Zod schemas
- β SQL injection prevention (Drizzle ORM)
- β XSS protection
- β CORS configuration
- β Rate limiting ready
- β Environment variable validation
- β Error handling and logging
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow TypeScript best practices
- Use Biome for linting and formatting
- Write meaningful commit messages
- Add tests for new features
- Update documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
Walon Foundation
- GitHub: @Walon-Foundation
- Built for the Sierra Leone business community
- Inspired by the need for transparent business verification
- Designed to support economic growth and investor confidence
- Created as part of a hackathon initiative
For support, questions, or feedback:
- Open an issue on GitHub
- Contact the Walon Foundation team
To try the live WhatsApp verification bot running on the maintainer's production deployment, send a message to: +23233482361.