# Quins Partner Management System - Technical Documentation

## Table of Contents
1. [Architecture Overview](#architecture-overview)
2. [Technology Stack](#technology-stack)
3. [Database Schema](#database-schema)
4. [API Documentation](#api-documentation)
5. [Authentication & Authorization](#authentication--authorization)
6. [Business Logic](#business-logic)
7. [Frontend Architecture](#frontend-architecture)
8. [Code Structure](#code-structure)
9. [Development Guidelines](#development-guidelines)

---

## Architecture Overview

### System Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                        Client Layer                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │   Browser    │  │    Mobile    │  │   Tablet     │      │
│  │  (HTML/CSS)  │  │   (Future)   │  │   (Future)   │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                    Application Layer                         │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              Express.js REST API                      │   │
│  │  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐       │   │
│  │  │ Auth   │ │Partners│ │ Leads  │ │Payments│       │   │
│  │  │ Routes │ │ Routes │ │ Routes │ │ Routes │       │   │
│  │  └────────┘ └────────┘ └────────┘ └────────┘       │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                      Data Layer                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              MongoDB Database                         │   │
│  │  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐       │   │
│  │  │Partners│ │ Leads  │ │Clients │ │Payments│       │   │
│  │  │Collection│Collection│Collection│Collection       │   │
│  │  └────────┘ └────────┘ └────────┘ └────────┘       │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
```

### Request Flow

```
User Request → Express Router → Route Handler → Business Logic → 
Database Query → Response Formatting → JSON Response → Client
```

---

## Technology Stack

### Backend
- **Runtime**: Node.js 20.x
- **Framework**: Express.js 4.18.x
- **Database**: MongoDB 7.0+
- **ODM**: Mongoose 8.0.x
- **Authentication**: JWT (jsonwebtoken)
- **Password Hashing**: bcryptjs
- **Environment**: dotenv

### Frontend
- **HTML5**: Semantic markup
- **CSS3**: Custom styling with CSS variables
- **JavaScript**: ES6+ vanilla JavaScript
- **No Framework**: Pure JavaScript for simplicity

### Development Tools
- **Version Control**: Git
- **Package Manager**: npm
- **Process Manager**: PM2 (production)
- **Development**: nodemon

---

## Database Schema

### User Schema

```javascript
{
  _id: ObjectId,
  username: String (required, unique),
  email: String (required, unique),
  password: String (required, hashed),
  userType: String (enum: ['Admin', 'Partner', 'Manager', 'Staff']),
  partnerId: ObjectId (ref: 'Partner'),
  firstName: String,
  lastName: String,
  phone: String,
  permissions: [String],
  status: String (enum: ['Active', 'Inactive', 'Suspended']),
  lastLogin: Date,
  createdAt: Date,
  updatedAt: Date
}
```

### Partner Schema

```javascript
{
  _id: ObjectId,
  partnerId: String (required, unique),
  partnershipType: String (enum: ['Referral', 'Channel/Reseller', 'Strategic Alliance', 'District/Regional Franchise']),
  companyName: String (required),
  contactPerson: {
    name: String,
    email: String,
    phone: String,
    designation: String
  },
  address: {
    street: String,
    city: String,
    district: String,
    division: String,
    postalCode: String,
    country: String (default: 'Bangladesh')
  },
  registrationNumber: String,
  tinNumber: String,
  tradeLicense: String,
  serviceLines: [String],
  territories: [String],
  commissionTier: String (enum: ['Bronze', 'Silver', 'Gold', 'Platinum']),
  commissionRates: {
    companyFormation: Number,
    technology: Number,
    studentVisa: Number,
    pos: Number,
    workVisa: Number,
    legalRetainer: Number,
    cpdCourses: Number,
    other: Number
  },
  status: String (enum: ['Active', 'Inactive', 'Suspended', 'Pending']),
  totalLeads: Number (default: 0),
  convertedLeads: Number (default: 0),
  totalRevenue: Number (default: 0),
  totalCommission: Number (default: 0),
  bankDetails: {
    bankName: String,
    accountName: String,
    accountNumber: String,
    branchName: String,
    routingNumber: String
  },
  documents: [{
    name: String,
    type: String,
    url: String,
    uploadDate: Date
  }],
  agreementDate: Date,
  agreementExpiryDate: Date,
  createdAt: Date,
  updatedAt: Date,
  lastLoginAt: Date
}
```

### Lead Schema

```javascript
{
  _id: ObjectId,
  leadId: String (required, unique),
  partnerId: ObjectId (ref: 'Partner', required),
  clientName: String (required),
  clientEmail: String,
  clientPhone: String (required),
  clientCompany: String,
  serviceType: String (required),
  serviceDescription: String,
  estimatedValue: Number,
  status: String (enum: ['New', 'Contacted', 'Qualified', 'Proposal Sent', 'Negotiation', 'Won', 'Lost', 'On Hold']),
  source: String (enum: ['Direct', 'Referral', 'Website', 'Social Media', 'Event', 'Cold Call', 'Other']),
  priority: String (enum: ['Low', 'Medium', 'High', 'Urgent']),
  assignedTo: String,
  nextFollowUpDate: Date,
  lastContactDate: Date,
  notes: [{
    note: String,
    createdBy: String,
    createdAt: Date
  }],
  activities: [{
    type: String,
    description: String,
    performedBy: String,
    performedAt: Date
  }],
  convertedToClient: Boolean (default: false),
  conversionDate: Date,
  clientId: ObjectId (ref: 'Client'),
  commissionEligible: Boolean (default: true),
  commissionAmount: Number,
  commissionPaid: Boolean (default: false),
  createdAt: Date,
  updatedAt: Date
}
```

### Client Schema

```javascript
{
  _id: ObjectId,
  clientId: String (required, unique),
  partnerId: ObjectId (ref: 'Partner', required),
  clientType: String (enum: ['Individual', 'Company', 'Institution']),
  name: String (required),
  companyName: String,
  email: String,
  phone: String (required),
  alternatePhone: String,
  address: {
    street: String,
    city: String,
    district: String,
    division: String,
    postalCode: String,
    country: String (default: 'Bangladesh')
  },
  industry: String,
  companySize: String,
  website: String,
  services: [{
    serviceType: String,
    serviceName: String,
    purchaseDate: Date,
    amount: Number,
    status: String (enum: ['Active', 'Completed', 'Cancelled', 'On Hold']),
    commissionAmount: Number,
    commissionPaid: Boolean
  }],
  totalSpent: Number (default: 0),
  outstandingBalance: Number (default: 0),
  creditLimit: Number (default: 0),
  status: String (enum: ['Active', 'Inactive', 'Suspended']),
  accountManager: String,
  acquisitionDate: Date,
  lastPurchaseDate: Date,
  documents: [{
    name: String,
    type: String,
    url: String,
    uploadDate: Date
  }],
  notes: [{
    note: String,
    createdBy: String,
    createdAt: Date
  }],
  createdAt: Date,
  updatedAt: Date
}
```

### Service Schema

```javascript
{
  _id: ObjectId,
  serviceId: String (required, unique),
  serviceName: String (required),
  category: String (required),
  description: String,
  basePrice: Number (required),
  currency: String (default: 'BDT'),
  partnerCommission: {
    referral: Number (default: 15),
    reseller: Number (default: 20),
    strategic: Number (default: 25),
    franchise: Number (default: 30)
  },
  deliveryTime: String,
  requirements: [String],
  features: [String],
  status: String (enum: ['Active', 'Inactive', 'Coming Soon']),
  totalSales: Number (default: 0),
  totalRevenue: Number (default: 0),
  averageRating: Number (default: 0),
  brochure: String,
  sampleContract: String,
  createdAt: Date,
  updatedAt: Date
}
```

### Payment Schema

```javascript
{
  _id: ObjectId,
  paymentId: String (required, unique),
  partnerId: ObjectId (ref: 'Partner', required),
  transactionType: String (enum: ['Commission', 'Bonus', 'Refund', 'Adjustment']),
  clientId: ObjectId (ref: 'Client'),
  leadId: ObjectId (ref: 'Lead'),
  serviceId: ObjectId (ref: 'Service'),
  serviceAmount: Number (required),
  commissionRate: Number (required),
  commissionAmount: Number (required),
  paymentMethod: String (enum: ['Bank Transfer', 'Mobile Banking', 'Cash', 'Cheque', 'Online']),
  paymentStatus: String (enum: ['Pending', 'Processing', 'Completed', 'Failed', 'Cancelled']),
  bankDetails: {
    bankName: String,
    accountNumber: String,
    transactionReference: String
  },
  dueDate: Date,
  paidDate: Date,
  periodStart: Date,
  periodEnd: Date,
  notes: String,
  internalNotes: String,
  approvedBy: String,
  approvedAt: Date,
  createdAt: Date,
  updatedAt: Date
}
```

### CPD Course Schema

```javascript
{
  _id: ObjectId,
  courseId: String (required, unique),
  courseName: String (required),
  category: String (required),
  description: String,
  price: Number (required),
  currency: String (default: 'BDT'),
  resellerCommission: Number (default: 25),
  duration: String,
  cpdPoints: Number,
  level: String (enum: ['Beginner', 'Intermediate', 'Advanced', 'All Levels']),
  modules: [{
    moduleName: String,
    lessons: Number,
    duration: String
  }],
  prerequisites: [String],
  certificationType: String,
  accreditedBy: String (default: 'CPD UK'),
  status: String (enum: ['Active', 'Inactive', 'Coming Soon', 'Archived']),
  totalEnrollments: Number (default: 0),
  totalRevenue: Number (default: 0),
  averageRating: Number (default: 0),
  partnerSales: [{
    partnerId: ObjectId (ref: 'Partner'),
    enrollments: Number (default: 0),
    revenue: Number (default: 0),
    commission: Number (default: 0)
  }],
  createdAt: Date,
  updatedAt: Date
}
```

### Vendor Schema

```javascript
{
  _id: ObjectId,
  vendorId: String (required, unique),
  vendorName: String (required),
  vendorType: String (enum: ['Service Provider', 'Supplier', 'Consultant', 'Contractor', 'Other']),
  contactPerson: {
    name: String,
    email: String,
    phone: String,
    designation: String
  },
  address: {
    street: String,
    city: String,
    district: String,
    division: String,
    postalCode: String,
    country: String (default: 'Bangladesh')
  },
  registrationNumber: String,
  tinNumber: String,
  tradeLicense: String,
  website: String,
  servicesProvided: [String],
  paymentTerms: String,
  creditLimit: Number,
  totalPurchases: Number (default: 0),
  outstandingBalance: Number (default: 0),
  bankDetails: {
    bankName: String,
    accountName: String,
    accountNumber: String,
    branchName: String,
    routingNumber: String
  },
  rating: Number (min: 0, max: 5, default: 0),
  totalOrders: Number (default: 0),
  onTimeDeliveryRate: Number (default: 0),
  status: String (enum: ['Active', 'Inactive', 'Suspended', 'Blacklisted']),
  documents: [{
    name: String,
    type: String,
    url: String,
    uploadDate: Date
  }],
  notes: [{
    note: String,
    createdBy: String,
    createdAt: Date
  }],
  createdAt: Date,
  updatedAt: Date
}
```

---

## API Documentation

### Authentication Endpoints

#### POST /api/auth/login
Login user and receive JWT token.

**Request Body:**
```json
{
  "username": "admin",
  "password": "admin123"
}
```

**Response:**
```json
{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "1",
    "username": "admin",
    "email": "admin@quinsbd.com",
    "userType": "Admin",
    "firstName": "Admin",
    "lastName": "User"
  }
}
```

#### POST /api/auth/register
Register new user.

**Request Body:**
```json
{
  "username": "newuser",
  "email": "user@example.com",
  "password": "password123",
  "firstName": "John",
  "lastName": "Doe",
  "userType": "Partner"
}
```

#### GET /api/auth/me
Get current user information.

**Headers:**
```
Authorization: Bearer <token>
```

**Response:**
```json
{
  "success": true,
  "user": {
    "id": "1",
    "username": "admin",
    "email": "admin@quinsbd.com",
    "userType": "Admin"
  }
}
```

### Partner Endpoints

#### GET /api/partners
Get all partners with optional filters.

**Query Parameters:**
- `status`: Filter by status (Active, Inactive, Pending, Suspended)
- `partnershipType`: Filter by partnership type
- `search`: Search by company name or partner ID

**Response:**
```json
{
  "success": true,
  "data": [...],
  "total": 10
}
```

#### GET /api/partners/:id
Get partner by ID.

#### POST /api/partners
Create new partner.

#### PUT /api/partners/:id
Update partner.

#### DELETE /api/partners/:id
Delete partner.

#### GET /api/partners/:id/stats
Get partner statistics.

### Commission Calculation

#### Formula for Service Commission
```javascript
commissionAmount = serviceAmount × (commissionRate / 100)
```

#### Formula for CPD Commission
```javascript
commissionAmount = coursePrice × 0.25  // 25% fixed
```

---

## Authentication & Authorization

### JWT Token Structure

```javascript
{
  "id": "user_id",
  "username": "username",
  "userType": "Admin|Partner|Manager|Staff",
  "iat": 1234567890,
  "exp": 1234654290
}
```

### Token Expiration
- Default: 24 hours
- Configurable in environment variables

### Password Security
- Hashed using bcryptjs
- Salt rounds: 10
- Never stored in plain text

---

## Business Logic

### Commission Calculation Logic

```javascript
function calculateCommission(serviceAmount, partnershipType, serviceType) {
  const commissionRates = {
    'Referral': {
      'Company Formation': 15,
      'Technology Solutions': 18,
      'Student Visa': 12,
      'POS System': 20,
      'Work Visa': 16,
      'Legal Retainer': 18,
      'CPD Courses': 25
    },
    'Channel/Reseller': {
      'Company Formation': 20,
      'Technology Solutions': 22,
      'Student Visa': 15,
      'POS System': 23,
      'Work Visa': 20,
      'Legal Retainer': 22,
      'CPD Courses': 25
    },
    // ... other partnership types
  };
  
  const rate = commissionRates[partnershipType][serviceType];
  return serviceAmount * (rate / 100);
}
```

### Lead Conversion Logic

```javascript
async function convertLeadToClient(leadId) {
  // 1. Get lead details
  const lead = await Lead.findById(leadId);
  
  // 2. Create client record
  const client = await Client.create({
    clientId: generateClientId(),
    partnerId: lead.partnerId,
    name: lead.clientName,
    email: lead.clientEmail,
    phone: lead.clientPhone,
    // ... other fields
  });
  
  // 3. Update lead status
  lead.status = 'Won';
  lead.convertedToClient = true;
  lead.conversionDate = new Date();
  lead.clientId = client._id;
  await lead.save();
  
  // 4. Calculate and create commission payment
  const payment = await Payment.create({
    paymentId: generatePaymentId(),
    partnerId: lead.partnerId,
    leadId: lead._id,
    clientId: client._id,
    serviceAmount: lead.estimatedValue,
    commissionRate: getCommissionRate(lead.partnerId, lead.serviceType),
    commissionAmount: lead.commissionAmount,
    paymentStatus: 'Pending'
  });
  
  return { client, payment };
}
```

---

## Frontend Architecture

### State Management

```javascript
const state = {
  currentUser: null,
  currentPage: 'dashboard',
  token: localStorage.getItem('token') || null
};
```

### API Communication

```javascript
async function apiCall(endpoint, options = {}) {
  const headers = {
    'Content-Type': 'application/json',
    ...(state.token && { 'Authorization': `Bearer ${state.token}` })
  };

  const response = await fetch(`${API_BASE}${endpoint}`, {
    ...options,
    headers: { ...headers, ...options.headers }
  });

  return await response.json();
}
```

### Navigation System

```javascript
function navigateTo(page) {
  state.currentPage = page;
  updateActiveNavItem(page);
  loadPageContent(page);
}
```

---

## Code Structure

```
quins-partner-management/
├── models/              # Database models
│   ├── User.js
│   ├── Partner.js
│   ├── Lead.js
│   ├── Client.js
│   ├── Service.js
│   ├── Payment.js
│   ├── CPDCourse.js
│   └── Vendor.js
├── routes/              # API routes
│   ├── auth.js
│   ├── partners.js
│   ├── leads.js
│   ├── clients.js
│   ├── services.js
│   ├── payments.js
│   ├── cpd.js
│   ├── vendors.js
│   └── dashboard.js
├── middleware/          # Custom middleware
│   ├── auth.js
│   └── validation.js
├── public/              # Frontend files
│   ├── css/
│   │   └── style.css
│   ├── js/
│   │   └── app.js
│   ├── images/
│   ├── index.html
│   └── dashboard.html
├── .env                 # Environment variables
├── server.js            # Main server file
├── package.json         # Dependencies
└── README.md            # Documentation
```

---

## Development Guidelines

### Code Style
- Use ES6+ features
- Follow camelCase for variables and functions
- Use PascalCase for classes and models
- Add comments for complex logic
- Keep functions small and focused

### Error Handling
```javascript
try {
  // Operation
} catch (error) {
  console.error('Error:', error);
  res.status(500).json({ 
    success: false, 
    message: 'Error message',
    error: error.message 
  });
}
```

### API Response Format
```javascript
// Success
{
  "success": true,
  "data": {...},
  "message": "Optional message"
}

// Error
{
  "success": false,
  "message": "Error description",
  "error": "Detailed error"
}
```

### Testing
- Test all API endpoints
- Verify authentication
- Test commission calculations
- Validate data integrity

---

**Document Version**: 1.0  
**Last Updated**: January 2025  
**Copyright © 2025 Quins International Bangladesh Ltd. All rights reserved.**