Preview: README.md
Size: 37.08 KB
/home/byroehnu/easepaybiz.easetack.com/README.md
# 💰 EasePay Backend API# 🔐 EasePay Advanced Authentication System
A comprehensive PERN stack backend for EasePay - a modern business expense and sales tracking application.A comprehensive, enterprise-grade authentication system inspired by OPay, featuring multiple authentication methods, session management, and enhanced security.
## 🚀 **Quick Start**## 🌟 Features
### **Development Setup**### 🔑 Authentication Methods
```bash- **📞 OTP Authentication** - Phone-based verification with SMS
# Clone the repository- **🔢 PIN Authentication** - Quick 4-6 digit PIN login
git clone https://github.com/Emperooid/easepay-backend.git- **👆 Biometric Authentication** - Fingerprint/Face ID support
cd easepay-backend- **🔄 Auto-Login** - Session-based automatic login (30 days)
- **� Secure Logout** - Device-specific session management
# Install dependencies
npm install### 🛡️ Security Features
- **Account Lockout** - 5 failed attempts = 30-minute lockout
# Setup environment variables- **PIN Protection** - Hashed and salted PIN storage
cp .env.production.template .env- **Device Registration** - Multi-device support and management
# Edit .env with your actual values- **Session Tokens** - Long-lived session management
- **Transaction PIN** - Additional security for sensitive operations
# Run database migrations- **Rate Limiting** - API endpoint protection
npm run db:migrate**API Version:** v1
**Authentication:** JWT Bearer Token
# Start development server
npm run dev---
```
## 📋 Table of Contents
### **Production Deployment**
```bash- [Authentication](#authentication)
# Build and start production server- [Business Management](#business-management)
npm start- [Sales Management](#sales-management)
- [Expense Management](#expense-management)
# Database operations- [Dashboard & Analytics](#dashboard--analytics)
npm run db:push # Push schema to database- [Reports](#reports)
npm run db:studio # Open Prisma Studio- [Tax Management](#tax-management)
```- [Credit Score](#credit-score)
- [Subscription Management](#subscription-management)
## 📊 **Project Structure**- [Error Handling](#error-handling)
- [Frontend Integration](#frontend-integration)
```
easepay-backend/---
├── config/ # Database and API configurations
├── controllers/ # Route handlers and business logic## 🔐 Authentication
├── frontend-examples/# Frontend integration examples
├── middleware/ # Express middleware (auth, validation)### Base Route: `/api/auth`
├── prisma/ # Database schema and migrations
├── routes/ # API route definitions#### Public Endpoints
├── scripts/ # Database initialization scripts
├── services/ # External service integrations| Method | Endpoint | Description |
└── utils/ # Utility functions|--------|----------|-------------|
```| `POST` | `/api/auth/register` | Register new user |
| `POST` | `/api/auth/login` | Login user |
## 🔧 **Core Features**| `POST` | `/api/auth/send-otp` | Send OTP to phone number |
| `POST` | `/api/auth/verify-otp` | Verify OTP and get JWT token |
### **🔐 Authentication System**| `POST` | `/api/auth/phone-login` | Send OTP for existing user login |
- **OTP.dev Integration** - Real SMS/WhatsApp verification| `GET` | `/api/auth/staff/invite/:token` | Get staff invitation details |
- **Multiple Login Methods** - Phone OTP, Password, PIN, Biometric
- **Smart Auth Flow** - Automatic user state detection#### Protected Endpoints
- **JWT Tokens** - Secure session management
| Method | Endpoint | Description |
### **💼 Business Management**|--------|----------|-------------|
- **Sales Tracking** - Record and manage sales transactions| `GET` | `/api/auth/me` | Get current user profile |
- **Expense Management** - Track business expenses with categories| `POST` | `/api/auth/staff/accept-invite` | Accept staff invitation |
- **Dashboard Analytics** - Real-time business insights
- **Staff Management** - Multi-user business access### Request Examples
### **📊 Advanced Features**#### Register User
- **Credit Score System** - Business creditworthiness tracking```javascript
- **Tax Reporting** - Quarterly and annual tax calculationsPOST /api/auth/register
- **Invoice Generation** - PDF invoice creationContent-Type: application/json
- **Subscription Management** - Flutterwave payment integration
{
## 🌐 **API Documentation** "phone": "+1234567890",
"role": "OWNER" // Optional: OWNER, STAFF, ADMIN
### **Base URLs**}
- **Development**: `http://localhost:5004````
- **Production**: `https://easepay-backend.onrender.com`
- **API Docs**: `/api-docs` (Swagger UI)#### Login User
```javascript
### **Key Endpoints**POST /api/auth/login
Content-Type: application/json
#### **Authentication**
| Method | Endpoint | Description |{
|--------|----------|-------------| "phone": "+1234567890"
| `POST` | `/api/auth/check-user-status` | Check user authentication state |}
| `POST` | `/api/auth/send-otp` | Send SMS/WhatsApp OTP |```
| `POST` | `/api/auth/verify-otp` | Verify OTP code |
| `POST` | `/api/auth/setup-password` | Setup account password |#### Send OTP
| `POST` | `/api/auth/signin` | Sign in with password |```javascript
POST /api/auth/send-otp
#### **Business Operations**Content-Type: application/json
| Method | Endpoint | Description |
|--------|----------|-------------|{
| `GET/POST` | `/api/sales` | Manage sales records | "phone": "+1234567890"
| `GET/POST` | `/api/expenses` | Manage expense records |}
| `GET` | `/api/dashboard/overview` | Get business analytics |```
| `GET` | `/api/reports/profit-loss` | Generate P&L reports |
#### Verify OTP
## 🔑 **Environment Variables**```javascript
POST /api/auth/verify-otp
### **Required Variables**Content-Type: application/json
```bash
DATABASE_URL=postgresql://... # PostgreSQL connection string{
JWT_SECRET=your_jwt_secret # JWT signing secret (32+ chars) "phone": "+1234567890",
OTP_API_KEY=your_otp_dev_key # OTP.dev API key "otp": "123456"
OTP_SENDER_ID=your_sender_id # OTP.dev sender ID}
OTP_TEMPLATE_ID=your_template_id # OTP.dev message template```
```
#### Phone Login (Existing Users)
### **Optional Variables**```javascript
```bashPOST /api/auth/phone-login
NODE_ENV=development # Environment modeContent-Type: application/json
PORT=5004 # Server port
FRONTEND_URL=http://localhost:8081 # CORS frontend URL{
FLW_SECRET_KEY=flw_secret # Flutterwave secret key "phone": "+1234567890"
EMAIL_USER=your_email@gmail.com # SMTP email settings}
``````
## 🛠 **Available Scripts**#### Response Format
```javascript
```bash// Login/Register Response
npm start # Start production server{
npm run dev # Start development server with nodemon "success": true,
npm run db:migrate # Run database migrations "message": "Login successful",
npm run db:studio # Open Prisma Studio "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
npm run db:generate # Generate Prisma client "user": {
npm run test:otp # Test OTP integration "id": "uuid",
``` "phone": "+1234567890",
"role": "OWNER"
## 📱 **Frontend Integration** }
}
### **React Native Example**
```javascript// Send OTP Response
import { SmartAuthProvider, useSmartAuth } from './AuthContext';{
"success": true,
// Wrap your app "message": "OTP sent successfully",
<SmartAuthProvider> "phone": "+1234567890",
<App /> "otp": "123456" // Only in development mode
</SmartAuthProvider>}
// Use in components// Verify OTP Response
const { handlePhoneInput, currentState } = useSmartAuth();{
``` "success": true,
"message": "Phone verified successfully",
### **Authentication Flow** "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
```javascript "user": {
// 1. Check user status "id": "uuid",
const status = await checkUserStatus(phone); "phone": "+1234567890",
"firstName": "User",
// 2. Route based on status "lastName": "Temp",
switch(status.userStatus) { "email": "1234567890@temp.com",
case 'new': sendOTP(phone); break; "role": "OWNER",
case 'complete': showPasswordLogin(); break; "phoneVerified": true
} }
```}
```
## 🔒 **Security Features**
---
- **Rate Limiting** - 100 requests per 15 minutes
- **CORS Protection** - Configured for your frontend domain## 🏢 Business Management
- **Helmet Security** - HTTP headers protection
- **JWT Authentication** - Secure token-based auth### Base Route: `/api/business`
- **Phone Validation** - International format support**Authentication:** Required
- **Password Hashing** - bcrypt with 12 rounds**Subscription:** Required
## 📚 **Documentation Files**| Method | Endpoint | Description |
|--------|----------|-------------|
- **`FRONTEND_API_ENDPOINTS.md`** - Complete API reference| `GET` | `/api/business/profile` | Get business profile |
- **`OTP_DEV_INTEGRATION_GUIDE.md`** - OTP service setup guide| `POST` | `/api/business/profile` | Create business profile |
- **`frontend-examples/`** - React/React Native integration examples| `PUT` | `/api/business/profile` | Update business profile |
| `DELETE` | `/api/business/profile` | Delete business profile |
## 🚀 **Deployment**| `POST` | `/api/business/staff` | Add staff member |
| `POST` | `/api/business/staff/invite` | Invite staff member |
### **Render Deployment**| `GET` | `/api/business/staff/:businessId` | Get staff list |
1. Connect GitHub repository| `DELETE` | `/api/business/staff` | Remove staff member |
2. Set environment variables from `.env.production.template`
3. Deploy automatically on push to main### Request Examples
### **Database Setup**#### Create Business
```bash```javascript
# Using Neon PostgreSQL (recommended)POST /api/business/profile
# 1. Create database at neon.techAuthorization: Bearer <token>
# 2. Copy connection string to DATABASE_URLContent-Type: application/json
# 3. Run migrations: npm run db:migrate
```{
"name": "My Business",
## 🤝 **Contributing** "type": "RETAIL", // RETAIL, SERVICE, MANUFACTURING, etc.
"vatRegistered": false,
1. Fork the repository "hasStaff": true
2. Create feature branch (`git checkout -b feature/amazing-feature`)}
3. Commit changes (`git commit -m 'Add amazing feature'`)```
4. Push to branch (`git push origin feature/amazing-feature`)
5. Open Pull Request#### Invite Staff
```javascript
## 📄 **License**POST /api/business/staff/invite
Authorization: Bearer <token>
This project is licensed under the ISC License.Content-Type: application/json
## 👨💻 **Author**{
"email": "staff@example.com",
**Emmanuel Awosika** "role": "STAFF",
- GitHub: [@Emperooid](https://github.com/Emperooid) "businessId": "business-uuid"
}
---```
## 🆘 **Support**---
For issues and questions:## 💰 Sales Management
1. Check API documentation at `/api-docs`
2. Review integration examples in `frontend-examples/`### Base Route: `/api/sales`
3. Test OTP service with `npm run test:otp`**Authentication:** Required
4. Open GitHub issue for bugs
| Method | Endpoint | Description |
**Built with ❤️ for modern business management**|--------|----------|-------------|
| `GET` | `/api/sales` | Get all sales (paginated) |
| `POST` | `/api/sales` | Create new sale |
| `GET` | `/api/sales/:id` | Get specific sale |
| `PUT` | `/api/sales/:id` | Update specific sale |
| `DELETE` | `/api/sales/:id` | Delete specific sale |
### Query Parameters for GET `/api/sales`
| Parameter | Type | Description |
|-----------|------|-------------|
| `page` | number | Page number (default: 1) |
| `limit` | number | Items per page (default: 10) |
| `startDate` | string | Filter from date (ISO format) |
| `endDate` | string | Filter to date (ISO format) |
| `category` | string | Filter by category |
### Request Examples
#### Create Sale
```javascript
POST /api/sales
Authorization: Bearer <token>
Content-Type: application/json
{
"amount": "150.00",
"description": "Product sale",
"date": "2026-02-09T10:00:00Z",
"businessId": "business-uuid" // Optional
}
```
#### Get Sales with Filters
```javascript
GET /api/sales?page=1&limit=20&startDate=2026-02-01&endDate=2026-02-09
Authorization: Bearer <token>
```
### Response Format
```javascript
{
"success": true,
"sales": [
{
"id": "sale-uuid",
"amount": "150.00",
"description": "Product sale",
"date": "2026-02-09T10:00:00Z",
"userId": "user-uuid",
"businessId": "business-uuid",
"createdAt": "2026-02-09T10:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 50,
"totalPages": 3
}
}
```
---
## 💸 Expense Management
### Base Route: `/api/expenses`
**Authentication:** Required
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/expenses` | Get all expenses (paginated) |
| `POST` | `/api/expenses` | Create new expense |
| `GET` | `/api/expenses/:id` | Get specific expense |
| `PUT` | `/api/expenses/:id` | Update specific expense |
| `DELETE` | `/api/expenses/:id` | Delete specific expense |
| `GET` | `/api/expenses/analytics` | Get expense analytics |
### Request Examples
#### Create Expense
```javascript
POST /api/expenses
Authorization: Bearer <token>
Content-Type: application/json
{
"amount": "50.00",
"description": "Office supplies",
"category": "office",
"date": "2026-02-09T10:00:00Z",
"businessId": "business-uuid" // Optional
}
```
#### Get Expense Analytics
```javascript
GET /api/expenses/analytics
Authorization: Bearer <token>
```
---
## 📊 Dashboard & Analytics
### Base Route: `/api/dashboard`
**Authentication:** Required
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/dashboard/overview` | Get dashboard overview |
| `GET` | `/api/dashboard/sales-analytics` | Get sales analytics |
| `GET` | `/api/dashboard/expense-analytics` | Get expense analytics |
### Query Parameters
| Parameter | Type | Options | Description |
|-----------|------|---------|-------------|
| `timeframe` | string | week, month, year | For overview endpoint |
| `period` | string | week, month, year | For analytics endpoints |
### Request Examples
#### Get Dashboard Overview
```javascript
GET /api/dashboard/overview?timeframe=month
Authorization: Bearer <token>
```
### Response Format
```javascript
{
"success": true,
"data": {
"revenue": {
"current": 5000.00,
"previous": 4500.00,
"change": 11.11,
"count": 25
},
"expenses": {
"current": 1500.00,
"previous": 1800.00,
"change": -16.67,
"count": 15
},
"profit": {
"current": 3500.00,
"previous": 2700.00,
"change": 29.63
},
"recentTransactions": [...],
"timeframe": "month"
}
}
```
---
## 📈 Reports
### Base Route: `/api/reports`
**Authentication:** Required
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/reports/sales` | Get sales report |
| `GET` | `/api/reports/expenses` | Get expense report |
| `GET` | `/api/reports/profit-loss` | Get profit & loss report |
### Query Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `startDate` | string | Report start date (ISO format) |
| `endDate` | string | Report end date (ISO format) |
| `groupBy` | string | Group by: day, week, month |
| `category` | string | Filter by category |
| `format` | string | Response format: json, csv |
### Request Examples
#### Get Sales Report
```javascript
GET /api/reports/sales?startDate=2026-01-01&endDate=2026-02-09&groupBy=month
Authorization: Bearer <token>
```
---
## 🧮 Tax Management
### Base Route: `/api/tax`
**Authentication:** Required
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/tax/summary` | Get tax summary |
| `GET` | `/api/tax/quarterly/:year/:quarter` | Get quarterly tax report |
| `GET` | `/api/tax/annual/:year` | Get annual tax report |
### Request Examples
#### Get Quarterly Tax Report
```javascript
GET /api/tax/quarterly/2026/1
Authorization: Bearer <token>
```
#### Get Annual Tax Report
```javascript
GET /api/tax/annual/2026
Authorization: Bearer <token>
```
---
## 📊 Credit Score
### Base Route: `/api/credit-score`
**Authentication:** Required
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/credit-score` | Get current credit score |
| `GET` | `/api/credit-score/history` | Get credit score history |
| `POST` | `/api/credit-score/recalculate` | Force recalculate credit score |
| `GET` | `/api/credit-score/factors` | Get credit score factors |
### Query Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| `limit` | number | History items limit (default: 12) |
### Request Examples
#### Get Credit Score History
```javascript
GET /api/credit-score/history?limit=6
Authorization: Bearer <token>
```
### Response Format
```javascript
{
"success": true,
"creditScore": {
"score": 750,
"factors": {...},
"recommendations": [...],
"breakdown": {
"paymentHistory": 85,
"revenueStability": 78,
"businessAge": 65,
"expenseManagement": 82
},
"lastUpdated": "2026-02-09T10:00:00Z"
}
}
```
---
## 💳 Subscription Management
### Base Route: `/api/subscription`
#### Public Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/subscription/plans` | Get available plans |
#### Protected Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/api/subscription/subscribe` | Subscribe to a plan |
| `GET` | `/api/subscription/my-subscription` | Get current subscription |
### Request Examples
#### Subscribe to Plan
```javascript
POST /api/subscription/subscribe
Authorization: Bearer <token>
Content-Type: application/json
{
"planId": "premium-plan",
"paymentMethod": "card"
}
```
---
## ⚠️ Error Handling
### Error Response Format
```javascript
{
"success": false,
"message": "Error description",
"errors": [
{
"field": "email",
"message": "Email is required"
}
]
}
```
### Common HTTP Status Codes
| Code | Meaning |
|------|---------|
| `200` | Success |
| `201` | Created |
| `400` | Bad Request |
| `401` | Unauthorized |
| `403` | Forbidden |
| `404` | Not Found |
| `429` | Too Many Requests |
| `500` | Internal Server Error |
---
## 🛠️ Frontend Integration
### Complete API Service Class
```javascript
class EasePayAPI {
constructor() {
this.baseURL = 'http://localhost:5004/api';
this.token = localStorage.getItem('authToken');
}
// Helper Methods
getHeaders() {
const headers = { 'Content-Type': 'application/json' };
if (this.token) {
headers['Authorization'] = `Bearer ${this.token}`;
}
return headers;
}
setToken(token) {
this.token = token;
localStorage.setItem('authToken', token);
}
// Authentication
async register(userData) {
const response = await fetch(`${this.baseURL}/auth/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
});
return response.json();
}
async login(credentials) {
const response = await fetch(`${this.baseURL}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials)
});
const data = await response.json();
if (data.success && data.token) {
this.setToken(data.token);
}
return data;
}
// OTP Authentication
async sendOTP(phone) {
const response = await fetch(`${this.baseURL}/auth/send-otp`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone })
});
return response.json();
}
async verifyOTP(phone, otp) {
const response = await fetch(`${this.baseURL}/auth/verify-otp`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone, otp })
});
const data = await response.json();
if (data.success && data.token) {
this.setToken(data.token);
}
return data;
}
async phoneLogin(phone) {
const response = await fetch(`${this.baseURL}/auth/phone-login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone })
});
return response.json();
}
async getCurrentUser() {
const response = await fetch(`${this.baseURL}/auth/me`, {
headers: this.getHeaders()
});
return response.json();
}
// Business Management
async getBusinessProfile() {
const response = await fetch(`${this.baseURL}/business/profile`, {
headers: this.getHeaders()
});
return response.json();
}
async createBusiness(businessData) {
const response = await fetch(`${this.baseURL}/business/profile`, {
method: 'POST',
headers: this.getHeaders(),
body: JSON.stringify(businessData)
});
return response.json();
}
// Sales Management
async getSales(params = {}) {
const queryString = new URLSearchParams(params).toString();
const response = await fetch(`${this.baseURL}/sales?${queryString}`, {
headers: this.getHeaders()
});
return response.json();
}
async createSale(saleData) {
const response = await fetch(`${this.baseURL}/sales`, {
method: 'POST',
headers: this.getHeaders(),
body: JSON.stringify(saleData)
});
return response.json();
}
// Expense Management
async getExpenses(params = {}) {
const queryString = new URLSearchParams(params).toString();
const response = await fetch(`${this.baseURL}/expenses?${queryString}`, {
headers: this.getHeaders()
});
return response.json();
}
async createExpense(expenseData) {
const response = await fetch(`${this.baseURL}/expenses`, {
method: 'POST',
headers: this.getHeaders(),
body: JSON.stringify(expenseData)
});
return response.json();
}
// Dashboard
async getDashboardOverview(timeframe = 'month') {
const response = await fetch(`${this.baseURL}/dashboard/overview?timeframe=${timeframe}`, {
headers: this.getHeaders()
});
return response.json();
}
// Reports
async getSalesReport(params = {}) {
const queryString = new URLSearchParams(params).toString();
const response = await fetch(`${this.baseURL}/reports/sales?${queryString}`, {
headers: this.getHeaders()
});
return response.json();
}
// Credit Score
async getCreditScore() {
const response = await fetch(`${this.baseURL}/credit-score`, {
headers: this.getHeaders()
});
return response.json();
}
// Subscription
async getSubscriptionPlans() {
const response = await fetch(`${this.baseURL}/subscription/plans`);
return response.json();
}
async subscribe(planData) {
const response = await fetch(`${this.baseURL}/subscription/subscribe`, {
method: 'POST',
headers: this.getHeaders(),
body: JSON.stringify(planData)
});
return response.json();
}
// Utility
logout() {
this.token = null;
localStorage.removeItem('authToken');
}
isAuthenticated() {
return !!this.token;
}
}
// Export for use
const api = new EasePayAPI();
export default api;
```
### React Hook Example
```javascript
// useAPI.js
import { useState, useEffect } from 'react';
import api from './api';
export function useAuth() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const checkAuth = async () => {
try {
if (api.isAuthenticated()) {
const result = await api.getCurrentUser();
if (result.success) {
setUser(result.user);
}
}
} catch (error) {
console.error('Auth check failed:', error);
} finally {
setLoading(false);
}
};
checkAuth();
}, []);
const login = async (credentials) => {
const result = await api.login(credentials);
if (result.success) {
setUser(result.user);
}
return result;
};
const logout = () => {
api.logout();
setUser(null);
};
return { user, loading, login, logout };
}
export function useDashboard() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const loadDashboard = async () => {
try {
const result = await api.getDashboardOverview();
if (result.success) {
setData(result.data);
}
} catch (error) {
console.error('Dashboard load failed:', error);
} finally {
setLoading(false);
}
};
loadDashboard();
}, []);
return { data, loading, refresh: () => loadDashboard() };
}
```
### Usage Examples
```javascript
// Login
const handleLogin = async (phone) => {
const result = await api.login({ phone });
if (result.success) {
console.log('Logged in:', result.user);
}
};
// OTP Authentication Flow
const handleOTPAuth = async (phone) => {
try {
// Step 1: Send OTP
const otpResult = await api.sendOTP(phone);
if (otpResult.success) {
console.log('OTP sent to:', otpResult.phone);
console.log('OTP (dev mode):', otpResult.otp);
// Step 2: User enters OTP, then verify
const userOTP = prompt('Enter OTP:'); // In real app, get from form
const verifyResult = await api.verifyOTP(phone, userOTP);
if (verifyResult.success) {
console.log('Phone verified! User:', verifyResult.user);
console.log('Token:', verifyResult.token);
// Redirect to dashboard or next step
}
}
} catch (error) {
console.error('OTP authentication failed:', error);
}
};
// Phone Login for Existing Users
const handlePhoneLogin = async (phone) => {
const result = await api.phoneLogin(phone);
if (result.success) {
console.log('Login OTP sent to:', phone);
// Then use verifyOTP to complete login
}
};
// Create Sale
const createSale = async () => {
const result = await api.createSale({
amount: "150.00",
description: "Product sale"
});
if (result.success) {
console.log('Sale created:', result.sale);
}
};
// Get Dashboard
const loadDashboard = async () => {
const result = await api.getDashboardOverview('month');
if (result.success) {
console.log('Dashboard data:', result.data);
}
};
```
---
## 🔒 Security & Authentication
### JWT Token
- Include in `Authorization` header as `Bearer <token>`
- Store securely in localStorage or httpOnly cookies
- Token expires after 7 days
- Refresh by re-logging in
### Rate Limiting
- 100 requests per 15 minutes per IP
- Applies to all `/api/*` routes
### CORS Policy
- Frontend URL: `http://localhost:3000` (configurable)
- Credentials allowed
- Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
---
## 📞 Support
For API questions or issues:
- Check server logs for detailed error messages
- Ensure proper authentication headers
- Verify request body format matches examples
- Check network connectivity to `http://localhost:5004`
---
## 📝 License
This API documentation is part of the EasePay project.
---
**Last Updated:** February 9, 2026
**API Version:** v1.0.0
- **Backend**: Node.js with Express.js
- **Authentication**: JWT (JSON Web Tokens)
- **Security**: Helmet, CORS, Rate Limiting
- **Environment**: dotenv for configuration
- **Password Hashing**: bcryptjs
- **Development**: Nodemon for hot reloading
## Project Structure
```
backend/
├── config/
│ └── db.js # Database configuration
├── controllers/
│ ├── authController.js # Authentication logic
│ ├── businessController.js # Business management
│ ├── saleController.js # Sales management
│ ├── expenseController.js # Expense management
│ ├── dashboardController.js # Dashboard analytics
│ ├── reportController.js # Report generation
│ ├── taxController.js # Tax calculations
│ └── creditScoreController.js # Credit score management
├── models/
│ ├── User.js # User model & schema
│ ├── Business.js # Business model & schema
│ ├── Sale.js # Sales model & schema
│ ├── Expense.js # Expense model & schema
│ └── CreditScore.js # Credit score model & schema
├── routes/
│ ├── authRoutes.js # Authentication routes
│ ├── businessRoutes.js # Business routes
│ ├── saleRoutes.js # Sales routes
│ ├── expenseRoutes.js # Expense routes
│ ├── dashboardRoutes.js # Dashboard routes
│ ├── reportRoutes.js # Report routes
│ ├── taxRoutes.js # Tax routes
│ └── creditScoreRoutes.js # Credit score routes
├── middleware/
│ └── auth.js # Authentication middleware
├── utils/
│ └── creditScoreCalculator.js # Credit score calculation logic
├── scripts/
│ └── initDb.js # Database initialization script
├── .env # Environment variables
├── package.json
├── server.js # Main server file
└── README.md
```
## Quick Start
### Prerequisites
- Node.js (v14 or higher)
- PostgreSQL (v12 or higher)
- npm or yarn
### Installation
1. **Clone and navigate to the project**:
```bash
cd easepayBackend
```
2. **Install dependencies**:
```bash
npm install
```
3. **Set up environment variables**:
Update the `.env` file with your configuration:
```env
# Database Configuration
DB_HOST=localhost
DB_PORT=5432
DB_NAME=easepay_db
DB_USER=your_username
DB_PASSWORD=your_password
# JWT Configuration
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_EXPIRE=7d
# Server Configuration
PORT=5000
NODE_ENV=development
# CORS Configuration
FRONTEND_URL=http://localhost:3000
```
4. **Create PostgreSQL database**:
```sql
CREATE DATABASE easepay_db;
```
5. **Initialize database tables**:
```bash
npm run init-db
```
6. **Start the development server**:
```bash
npm run dev
```
The server will start on `http://localhost:5000`
## API Endpoints
### Authentication
- `POST /api/auth/register` - Register new user
- `POST /api/auth/login` - User login
- `GET /api/auth/me` - Get current user (protected)
### Business Management
- `GET /api/business/profile` - Get business profile
- `POST /api/business/profile` - Create business profile
- `PUT /api/business/profile` - Update business profile
- `DELETE /api/business/profile` - Delete business profile
### Sales Management
- `GET /api/sales` - Get all sales (with pagination & filters)
- `POST /api/sales` - Create new sale
- `GET /api/sales/:id` - Get sale by ID
- `PUT /api/sales/:id` - Update sale
- `DELETE /api/sales/:id` - Delete sale
### Expense Management
- `GET /api/expenses` - Get all expenses (with pagination & filters)
- `POST /api/expenses` - Create new expense
- `GET /api/expenses/:id` - Get expense by ID
- `PUT /api/expenses/:id` - Update expense
- `DELETE /api/expenses/:id` - Delete expense
- `GET /api/expenses/categories` - Get expense categories
### Dashboard
- `GET /api/dashboard/overview` - Get dashboard overview
- `GET /api/dashboard/sales-chart` - Get sales chart data
- `GET /api/dashboard/expense-breakdown` - Get expense breakdown
### Reports
- `GET /api/reports/sales` - Generate sales report
- `GET /api/reports/expenses` - Generate expense report
- `GET /api/reports/profit-loss` - Generate profit/loss report
### Tax Management
- `GET /api/tax/summary` - Get tax summary
- `GET /api/tax/quarterly/:year/:quarter` - Get quarterly tax report
- `GET /api/tax/annual/:year` - Get annual tax report
### Credit Score
- `GET /api/credit-score` - Get current credit score
- `GET /api/credit-score/history` - Get credit score history
- `POST /api/credit-score/recalculate` - Force recalculate score
- `GET /api/credit-score/factors` - Get score factors explanation
## Database Schema
### Users Table
- `id` - Primary key
- `email` - Unique user email
- `password` - Hashed password
- `first_name` - User's first name
- `last_name` - User's last name
- `phone` - Phone number
- `business_name` - Business name
- `is_active` - Account status
- `email_verified` - Email verification status
- `created_at` - Creation timestamp
- `updated_at` - Last update timestamp
### Businesses Table
- `id` - Primary key
- `user_id` - Foreign key to users
- `business_name` - Business name
- `business_type` - Type of business
- `business_address` - Business address
- `tax_id` - Tax identification number
- `phone_number` - Business phone
- `email` - Business email
- `website` - Business website
- `description` - Business description
- Additional metadata fields
### Sales Table
- `id` - Primary key
- `user_id` - Foreign key to users
- `customer_name` - Customer name
- `customer_email` - Customer email
- `customer_phone` - Customer phone
- `items` - JSON array of sale items
- `subtotal` - Subtotal amount
- `tax` - Tax amount
- `total` - Total amount
- `payment_method` - Payment method
- `sale_date` - Sale date
- `notes` - Additional notes
- `category` - Sale category
- Additional metadata fields
### Expenses Table
- `id` - Primary key
- `user_id` - Foreign key to users
- `description` - Expense description
- `amount` - Expense amount
- `category` - Expense category
- `vendor` - Vendor/supplier
- `payment_method` - Payment method
- `expense_date` - Expense date
- `receipt_url` - Receipt image URL
- `notes` - Additional notes
- `is_deductible` - Tax deductible flag
- Additional metadata fields
### Credit Scores Table
- `id` - Primary key
- `user_id` - Foreign key to users
- `score` - Credit score (300-850)
- `factors` - JSON object of score factors
- `recommendations` - JSON array of recommendations
- `payment_history_score` - Payment history component score
- `revenue_stability_score` - Revenue stability component score
- `business_age_score` - Business age component score
- `expense_management_score` - Expense management component score
- Additional metadata fields
## Security Features
- **JWT Authentication** - Secure token-based authentication
- **Password Hashing** - bcrypt with salt rounds
- **Rate Limiting** - Protect against brute force attacks
- **CORS Protection** - Cross-origin resource sharing control
- **Helmet Security** - Various HTTP security headers
- **Input Validation** - Comprehensive data validation
- **SQL Injection Protection** - Parameterized queries
## Development
### Available Scripts
- `npm start` - Start production server
- `npm run dev` - Start development server with nodemon
- `npm run init-db` - Initialize database tables
- `npm test` - Run tests (to be implemented)
### Environment Variables
Make sure to set up all required environment variables in your `.env` file. See `.env.example` for reference.
### Database Setup
1. Install PostgreSQL
2. Create a new database
3. Update connection settings in `.env`
4. Run `npm run init-db` to create tables
## Credit Score Algorithm
The credit score system evaluates businesses based on four key factors:
1. **Payment History (35%)** - Transaction consistency and frequency
2. **Revenue Stability (30%)** - Revenue patterns and growth trends
3. **Business Age (20%)** - Time in business and account history
4. **Expense Management (15%)** - Expense-to-revenue ratio and management
Scores range from 300-850, similar to personal credit scores.
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request
## License
ISC License - see LICENSE file for details
## Support
For support, please open an issue in the repository or contact the development team.
---
**Built with ❤️ using the PERN Stack**
Directory Contents
Dirs: 14 × Files: 19