Lead-module

Detailed documentation and implementation guides.

Lead Module Documentation

Overview

The Lead Module is the core CRM functionality of Mercury CRM, providing comprehensive lead management with clean architecture patterns, third-party integrations, and complete API coverage for frontend applications.

Architecture Overview

Clean Architecture Structure

Lead Module/
├── Controllers/          # HTTP request handlers
├── Services/            # Business logic layer
├── DTOs/                # Data transfer objects
├── Resources/           # API response formatters
├── Models/              # Database entities
└── Exceptions/          # Custom exceptions

Data Flow

HTTP Request → Controller → Service → Domain Logic → Database
                    ↓
            Resource → JSON Response

Core Components

Controllers

  • LeadController - Main CRUD operations and search
  • Handles HTTP requests and returns formatted responses
  • Uses dependency injection for services

Services

  • LeadUpdateService - Lead update orchestration with transactions
  • ChangeTrackingService - Audit trail and change logging
  • LeadParticipantService - Participant management
  • OldBookingApiService - Legacy system integration

DTOs (Data Transfer Objects)

  • UpdateLeadDto - Type-safe data transfer for updates
  • OldBookingRequestDto - Third-party API requests
  • Clean data validation and type safety

API Endpoints

Authentication

All endpoints require JWT authentication:

Authorization: Bearer <jwt-token>
Accept: application/json
Content-Type: application/json

Core Endpoints

List Leads

GET /api/v1/lead

Parameters:

  • page - Page number
  • per_page - Results per page (max 250)
  • search - Search term
  • sourceIds[] - Filter by source IDs
  • price_min / price_max - Price range
  • start_date_from / start_date_to - Date filters

Create Lead

POST /api/v1/lead

Request Body:

{
  "name": "Course Name",
  "website_id": 1,
  "source_id": 2,
  "location_id": 3,
  "start_date": "20-01-2024",
  "end_date": "25-01-2024",
  "price": 2500.00,
  "participants": [
    {
      "first_name": "John",
      "last_name": "Doe",
      "emails": ["john@example.com"],
      "phones": ["+1234567890"],
      "is_responsible": "1"
    }
  ]
}

Update Lead

PUT /api/v1/lead/{id}

Same format as create, all fields optional.

Get Lead for Editing (NEW)

GET /api/v1/lead/{id}/edit

Returns structured data for edit forms with all participants and related entities.

Search Leads

GET /api/v1/lead/search

Advanced search with cross-field capabilities.

Select Endpoints

For dropdown options in forms:

GET /api/v1/lead/select/companies
GET /api/v1/lead/select/currencies
GET /api/v1/lead/select/lead-sources
GET /api/v1/lead/select/lead-statuses
GET /api/v1/lead/select/locations
GET /api/v1/lead/select/websites

Status Management

GET    /api/v1/lead/status           # List statuses
POST   /api/v1/lead/status           # Create status
PUT    /api/v1/lead/status/{id}      # Update status
DELETE /api/v1/lead/status/{id}      # Delete status

User Assignment

POST /api/v1/lead/users/assign/sales
POST /api/v1/lead/users/assign/coordinator
POST /api/v1/lead/users/assign/instructor
POST /api/v1/lead/users/assign/supervisor

Data Structure

Lead Model

Lead {
    id: int
    name: string
    course_code: string
    category: string

    // Dates
    start_date: string  // d-m-Y format
    end_date: string
    number_of_weeks: int

    // Financial
    price: decimal
    discount: decimal
    currency_id: int

    // Location
    location_id: int
    address: string

    // Relations
    website_id: int     // Company website
    source_id: int      // Lead source
    event_id: int
    user_id: int        // Assigned sales person
    coordinator_id: int
    instructor_id: int

    // Status
    current_status_id: int
    old_booking_id: string
    note: text
}

Participant Structure

LeadParticipant {
    id: int
    client_id: int

    // Contact Information (Clean JSON format)
    contact_information: {
        "emails": ["user@example.com"],
        "phones": ["123456789"],
        "mobiles": ["987654321"]
    }

    // Flags
    is_responsible: boolean  // Primary contact
    whatsapp_approval: boolean

    // Financial
    price: decimal
    discount: decimal
}

Client Information

LeadClient {
    id: int
    first_name: string
    last_name: string
    client_title: string  // Mr/Mrs/Dr
    job_title: string
    client_company_name: string
    client_company_id: int
    client_city: string
    client_address: string
    client_country_id: int
    ip: string
    reference: string
}

Key Features

Clean Contact Information Storage

Contact information is now stored in clean JSON format:

Before (Messy):

{
  "phones":["123"],
  "emails":["test@example.com"], 
  "mobiles":["456"],
  "cc":["test@example.com"],
  "fax":"+1 (555) 123-4567"
}

After (Clean):

{
  "emails":["test@example.com"],
  "phones":["123"],
  "mobiles":["456"]
}

Edit Endpoint Features

  • Returns complete lead data for forms
  • Includes both participants and responsible person
  • Related entities for dropdowns
  • Same format as store request for consistency
  • Proper date formatting (d-m-Y)

Change Tracking

  • Comprehensive audit trail
  • Automatic change detection
  • System timeline entries
  • Stakeholder notifications

Third-Party Integrations

OldBooking System

Clean integration with legacy booking system:

  • Modular architecture with separate services
  • ContactExtractor, DateFormatter, RequestBodyBuilder
  • Proper error handling
  • Real API integration (not simulation)

Google Contacts

Lightweight Google API integration:

  • OAuth token management
  • Contact synchronization
  • Error handling with fallbacks

WhatsApp Error Notifications

Global error notification system:

  • Critical error detection
  • Instant team alerts via WhatsApp
  • Clean log management
  • Production-ready monitoring

Development Patterns

SOLID Principles

  • Single Responsibility: Each service handles one concern
  • Dependency Injection: Clean, testable code
  • Interface Segregation: Focused interfaces
  • Open/Closed: Extensible design

Database Transactions

  • ACID compliance for data integrity
  • Proper rollback on failures
  • Transaction boundaries in services

Exception Handling

  • Custom exception types
  • WhatsApp notifications for critical errors
  • Proper error context and logging

Testing

Feature Tests

public function test_can_update_lead_with_participants()
{
    $lead = Lead::factory()->create();

    $response = $this->putJson("/api/v1/lead/{$lead->id}", [
        'name' => 'Updated Course',
        'participants' => [
            [
                'first_name' => 'John',
                'emails' => ['john@example.com']
            ]
        ]
    ]);

    $response->assertStatus(200);
}

Unit Tests

public function test_throws_exception_when_lead_not_found()
{
    $updateDto = new UpdateLeadDto(leadId: 999, name: 'Test');

    $this->expectException(LeadUpdateException::class);
    $this->leadUpdateService->updateLead($updateDto, 1);
}

Usage Examples

Creating a Lead

const response = await fetch('/api/v1/lead', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + token,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "name": "Laravel Training",
    "website_id": 1,
    "source_id": 2,
    "participants": [
      {
        "first_name": "Alice",
        "emails": ["alice@company.com"],
        "is_responsible": "1"
      }
    ]
  })
});

Getting Edit Data

const editData = await fetch(`/api/v1/lead/12345/edit`, {
  headers: { 'Authorization': 'Bearer ' + token }
}).then(r => r.json());

// Populate form fields
document.getElementById('lead-name').value = editData.data.name;
editData.data.participants.forEach(participant => {
  console.log('Participant:', participant.first_name);
});

Advanced Filtering

const leads = await fetch('/api/v1/lead?' + new URLSearchParams({
  'search': 'Laravel',
  'sourceIds[]': [1, 2],
  'price_min': 1000,
  'per_page': 20
}), {
  headers: { 'Authorization': 'Bearer ' + token }
}).then(r => r.json());

Quick Reference

Essential Endpoints

GET    /api/v1/lead              # List leads
POST   /api/v1/lead              # Create lead  
PUT    /api/v1/lead/{id}         # Update lead
GET    /api/v1/lead/{id}/edit    # Get edit data (NEW)
GET    /api/v1/lead/search       # Search leads

Key Services

  • LeadUpdateService - Update orchestration
  • ChangeTrackingService - Audit trail
  • OldBookingApiService - Legacy integration

Key Resources

  • LeadResource - Standard response
  • LeadEditResource - Edit form data (NEW)
  • ParticipantEditResource - Participant data

Security & Performance

Authentication

  • JWT required for all endpoints
  • Bearer token format
  • User context tracking

Database Optimization

  • Eager loading to prevent N+1 queries
  • Selective field loading
  • Proper indexing
  • Pagination for large datasets

Error Handling

  • Custom exception types
  • WhatsApp error notifications
  • Comprehensive logging
  • Production monitoring

This module implements clean architecture principles with comprehensive CRM functionality, third-party integrations, and modern development practices.