CRM Pro is a modern, enterprise-grade Sales Pipeline and Customer Relationship Management application. Built on top of Laravel 12, it showcases robust software architecture, design patterns, and performance optimizations tailored for real-world corporate teams.
- Three Corporate Roles:
Super Admin,Manager, andSales Executive. - Dynamic Scoping Boundaries:
Super Admin: Complete administrative access to settings, logs, and global data.Manager: Scoped permissions. Can view, create, edit, and assign leads or customers belonging only to themselves or their direct subordinates.Sales Executive: Strictly restricted to managing their own assigned leads and customers.
- Self-Referential User Tree: Users are linked via a
manager_idforeign key, allowing real-world company reporting structures.
- Least-Busy Representative Assignment: Unassigned leads are automatically assigned to the active Sales Executive with the lowest volume of active leads (excluding
wonorloststatuses). Fosters perfect work-distribution balance. - Fully supports manual reassignment with instant audit logging.
- HubSpot-Style Event Ledger: Merges representative comments (
LeadNote) and automated system events (LeadActivity) into a single, unified, relative-timestamped feed. - Tracks creations, assignments, status changes, notes additions, and customer conversions.
- Automated Event Listeners: Lead assignments instantly dispatch queue jobs.
- Dual Triggers: Sends styled HTML email alerts via SMTP while simultaneously storing dynamic alerts in the Database for instant retrieval via UI/API.
- Role-Scoped Cache Keys: Dynamic keys (
dashboard_stats_global,dashboard_stats_manager_{id},dashboard_stats_executive_{id}) store filtered metrics. - Event-Driven Cache Invalidation: Listeners immediately flush expired keys during creations, updates, or status changes, guaranteeing lightning-fast API responses with 100% data consistency.
- CSV & Excel Streams: Exports filtered lists instantly using memory-efficient PHP stream writers (handles massive datasets without resource exhaustion).
- Print-Optimized PDF Report: Aesthetic print layout with auto-print script hooks.
- Follow-up Reminders: Daily checks scan follow-up notes due today and notify representatives.
- Lost Lead Archival: Nightly cleanups soft-delete leads lost for more than 30 days.
erDiagram
users ||--o{ users : "supervises (manager_id)"
users ||--o{ leads : "assigned_to"
users ||--o{ customers : "assigned_to"
users ||--o{ lead_notes : "writes"
users ||--o{ tasks : "owns"
leads ||--o{ lead_notes : "contains"
leads ||--o{ lead_activities : "audits"
leads ||--o{ tasks : "triggers"
leads ||--o| customers : "converts_to"
users {
bigint id PK
string name
string email UK
string phone
string avatar
bigint manager_id FK
boolean is_active
timestamp email_verified_at
string password
remember_token remember_token
timestamps timestamps
soft_deletes soft_deletes
}
leads {
bigint id PK
string title
string contact_name
string contact_email
string contact_phone
string company
text description
decimal value
string source
string status
string priority
bigint assigned_to FK
bigint created_by FK
bigint customer_id FK
date expected_close_date
timestamp assigned_at
timestamps timestamps
soft_deletes soft_deletes
}
customers {
bigint id PK
string name
string email UK
string phone
string company
string website
text address
string industry
decimal total_revenue
string status
bigint assigned_to FK
bigint created_by FK
timestamps timestamps
soft_deletes soft_deletes
}
lead_notes {
bigint id PK
bigint lead_id FK
bigint user_id FK
text note
date follow_up_date
datetime reminder_at
boolean is_reminder_sent
timestamps timestamps
}
lead_activities {
bigint id PK
bigint lead_id FK
bigint user_id FK
string action
text description
json old_values
json new_values
timestamp created_at
}
tasks {
bigint id PK
bigint user_id FK
bigint lead_id FK
string title
text description
date due_date
string status
timestamps timestamps
}
notifications {
uuid id PK
string type
string notifiable_type
bigint notifiable_id
text data
timestamp read_at
timestamps timestamps
}
Setting up the entire CRM environment, including the PHP 8.2 Application, Nginx, MySQL 8.0, Redis Cache, and Mailhog SMTP server is fully automated.
Just run this single command:
docker-compose up -d --build- The container mounts a self-configuring shell script entrypoint (
docker-entrypoint.sh). - Copies
.env.exampleto.envif missing. - Automatically sets all Docker environment parameters (MySQL hosts, Redis cache stores, SMTP settings).
- Installs all PHP composer packages.
- Generates the application key.
- Waits for the MySQL database container to successfully boot.
- Executes all database migrations and seeds corporate profiles.
- Creates the storage link directory structure.
- Boots up the Nginx server on port
8000.
Open your browser and navigate to:
- Application Portal: http://localhost:8000
- Local Mailhog Portal: http://localhost:8025
All API endpoints are protected using Laravel Sanctum. Ensure you pass the bearer token: Authorization: Bearer <token>.
POST /api/v1/login- Payload:
{ "email": "manager@crmpro.com", "password": "password" } - Response: Returns PlainTextToken and logged-in user profile.
- Payload:
GET /api/v1/dashboard- Response: Returns optimized, cached global statistics for Admins, team-specific statistics for Managers, or representative stats for Executives.
- Header: Cached for 5 minutes (
300seconds).
GET /api/v1/leads- Filters:
?status=proposal&priority=high&search=Acme - Response: Paginated lists of scoped opportunities.
- Filters:
POST /api/v1/leads- Payload:
{ "title": "Acme Renewal", "contact_name": "Wile", "value": 50000 }
- Payload:
GET /api/v1/leads/{lead}- Response: Detail view of a lead with assigned representatives.
POST /api/v1/leads/{lead}/assign- Payload:
{ "assigned_to": 3 }
- Payload:
GET /api/v1/leads/{lead}/notes- Response: List of representative comments and scheduled follow-ups.
POST /api/v1/leads/{lead}/notes- Payload:
{ "note": "Call completed, proposal ready.", "follow_up_date": "2026-06-15", "reminder": true }
- Payload:
The default seeders configure the following hierarchical accounts (password is password for all):
| Role | Supervised Subordinates | |
|---|---|---|
| Super Admin | admin@crmpro.com |
Manages everything, full logs. |
| Manager | manager@crmpro.com |
Manages John and Jane Employee. |
| Sales Executive | employee@crmpro.com |
(John Employee) Reports to Sales Manager. |
| Sales Executive | employee2@crmpro.com |
(Jane Employee) Reports to Sales Manager. |
To verify software integrity, execute the comprehensive PHPUnit test suite:
php artisan testAll feature and unit test suites are fully mock-verified and green!