CRM (Prospects & Clients)
Customer Relationship Management module for tracking prospects through the sales pipeline, managing client follow-ups, and coordinating sales team activities.
Overview
The CRM module provides the sales and operations teams with a unified workspace to manage the full lifecycle of potential customers — from initial lead capture through qualification, negotiation, and conversion to active client. It combines three complementary views (Kanban board, data table, and activity calendar) with a detailed side panel for managing contacts, notes, locations, and follow-up data.
The module supports two entity types that share a common interface: prospects (leads without a company account) and clients (companies already registered on the platform). This dual-entity design allows the same pipeline tools to be used regardless of whether a lead has converted.
Key Concepts
| Concept | Description |
|---|---|
| Prospect | A lead without a company account on the platform. Stored in prospection_users with company_id = NULL |
| Client | An existing company on the platform being tracked for follow-up. Linked via prospection_users.company_id |
| Partner Prospect | A special prospect type (type 3) for partner channel leads, with separate follow-up data |
| Follow-up Category | A hierarchical status system organized into groups (e.g., "New", "Contacted", "Qualified"). Drives the Kanban columns |
| Activity | A follow-up note with an associated action type (call, email, WhatsApp, meeting, SMS, other) and optional scheduled date |
| Note | A timestamped comment attached to a prospect or client, recording an interaction or status change |
| Contact | An additional person associated with a prospect or client (beyond the primary contact) |
| Location | A physical address (office, warehouse, branch, headquarters, distribution center) linked to a prospect or client |
Architecture
System Overview
Backend Structure
backend/
├── routes/
│ └── prospects.routes.js # All prospect + client route definitions
├── controllers/
│ └── prospects.controller.js # Request handlers for all CRM operations
├── libraries/
│ ├── prospects.util.js # Prospect processing, filters, notifications
│ └── locationsProspects.util.js # Location CRUD operations
├── constants/
│ ├── prospects.constants.js # Ecommerce filter values
│ └── onboarding.constants.js # Onboarding question IDs
└── jobs/
└── repondio.jobs.js # Respondio integration job processorFrontend Structure
frontend/client/src/
├── views/crm/
│ ├── index.vue # Main view with view switcher
│ ├── components/
│ │ ├── Kamban.vue # Kanban board view
│ │ ├── ListView.vue # Data table view
│ │ ├── CalendarView.vue # Calendar view
│ │ ├── Sidepanel.vue # Detail side panel
│ │ ├── AddProspect.modal.vue # Add prospect modal
│ │ ├── CsvUpload.modal.vue # CSV upload modal
│ │ └── ProcessCsv.offcanvas.vue # CSV processing results
│ └── constants/
│ ├── table.defaults.js # Default column/filter configuration
│ ├── account.constants.js # Account type enum
│ ├── ecommerce.constants.js # Ecommerce filter options
│ ├── prospect.services.js # Service type definitions
│ └── roles.js # Role-based filter definitions
├── services/
│ ├── prospects.service.js # Prospect API client
│ └── clients.service.js # Client API client
└── components/Forms/Follow/
├── Details.form.vue # Follow-up details form
├── Prospect.form.vue # Executive assignment form
├── Contact.form.vue # Contact create/edit form
├── Location.form.vue # Location create/edit form
└── Note.form.vue # Follow-up note formData Flow
Prospect Creation
CSV Bulk Import
Kanban Drag-and-Drop
Follow-up Note Creation
Database
Tables
| Table | Purpose |
|---|---|
prospection_users | Primary prospect/client records with contact info, type, and status |
follow_up_data | Follow-up metadata: channel, account value, shipments, ecommerce, weight, content |
prospect_follow_up_comments | Notes/comments for prospects (linked by prospect_id) |
follow_up_comments | Notes/comments for companies/clients (linked by company_id) |
extra_contacts | Additional contacts beyond the primary, for both prospects and clients |
company_locations | Physical locations (office, warehouse, etc.) for prospects and clients |
partner_follow_up_data | Extended data for partner-type prospects (URL, rating, social network) |
catalog_follow_up_statuses | Follow-up status catalog used for Kanban columns |
Entity Relationship
Key Fields
prospection_users
| Column | Type | Description |
|---|---|---|
id | INT (PK) | Auto-increment |
name | VARCHAR | Contact person name |
company_name | VARCHAR | Company/organization name |
email | VARCHAR | Primary email address |
phone_code | VARCHAR | Country phone code |
phone | VARCHAR | Phone number |
company_id | INT (FK, nullable) | NULL for prospects, set for clients |
follow_up_id | INT (FK) | Current follow-up status |
locale_id | INT (FK) | Country/locale |
monthly_shipment_id | INT | Estimated monthly shipment volume |
type | TINYINT | 1 = prospect, 2 = client, 3 = partner prospect |
status | TINYINT | 0 = removed, 1 = in process, 2 = registered |
created_by | INT (FK) | Admin user who created the record |
created_at | DATETIME | Creation timestamp |
follow_up_data
| Column | Type | Description |
|---|---|---|
company_id | INT (FK, nullable) | Reference to companies (for clients) |
prospect_id | INT (FK, nullable) | Reference to prospection_users (for prospects) |
channel | VARCHAR | Acquisition channel |
account_value | DECIMAL | Estimated account value |
monthly_shipments | INT | Monthly shipment estimate |
ecommerce_type_id | INT (FK) | E-commerce platform type |
weight_id | INT (FK) | Weight range category |
content_id | INT (FK) | Package content type |
account_type | VARCHAR | Account size: individual, startup, sme, enterprise, corporate |
estimated_close_date | DATE | Expected deal close date |
annotations | TEXT | Free-form notes |
prospect_follow_up_comments / follow_up_comments
| Column | Type | Description |
|---|---|---|
prospect_id / company_id | INT (FK) | Parent entity reference |
status_id / follow_up_status_id | INT (FK) | Follow-up status at time of note |
comment | TEXT | Note content |
action | VARCHAR | Action type: call, whatsapp, email, meeting, sms, other |
scheduled_date | DATETIME | Optional scheduled follow-up date |
created_by | INT (FK) | Admin user who created the note |
Role-Based Access
The CRM implements a multi-level permission system that controls both data visibility and available actions.
Permission Matrix
| Permission | Scope | Effect |
|---|---|---|
319 | Base CRM access | Required for all CRM endpoints |
all-prospects | Manager view | See all prospects, date range filter, salesman filter, role filters |
crm-edit-salesman-prospect | Executive reassignment | Allows changing the assigned salesman on a prospect |
crm-partners | Partner management | Access to partner prospect data endpoints |
crm-menu | Location management | Access to location CRUD endpoints |
147 | Manager role | Overrides SDR/MDR restrictions to see all records |
Role-Based Filters
When all-prospects permission is active, additional filters appear for each sales role:
| Role | Permission Key | Description |
|---|---|---|
| KAE | kae | Key Account Executive |
| KAE LTL | kae_ltl | KAE for Less-Than-Truckload |
| CSR | csr | Customer Service Representative |
| CSR LTL | csr_ltl | CSR for LTL |
| Fulfillment | fullfilment | Fulfillment specialist |
| WMS | wms | Warehouse Management |
| Ecartpay | ecartpay | Ecartpay platform specialist |
| Parapaquetes | parapaquetes | Parapaquetes service specialist |
Data Visibility Rules
- SDR users: See only their own prospects (filtered by
created_by) - MDR users: See company-based records
- Managers (permission 147): See all records regardless of assignment
Background Jobs
| Job | Queue | Trigger | Description |
|---|---|---|---|
respondio_add_prospect | respondio | On prospect creation (POST /prospects) | Upserts contact in Respondio, assigns conversation, changes lifecycle to "New Lead", opens conversation |
Key Decisions
| Decision | Reasoning | Alternatives Considered |
|---|---|---|
| Unified route file for prospects and clients | Both entities share most operations (notes, contacts, locations). A single controller reduces duplication. | Separate controllers per entity (more code, harder to maintain shared logic) |
| Separate comment tables for prospects vs companies | Prospects use prospect_follow_up_comments (by prospect_id), clients use follow_up_comments (by company_id). Required because prospects may not have a company_id. | Single table with nullable foreign keys (query complexity, index inefficiency) |
| Provide/inject for cross-component communication | Sidepanel, Kanban, and modals need to communicate without prop drilling. Vue's provide/inject is lightweight and avoids a dedicated store. | Pinia store (overhead for ephemeral UI state), event bus (harder to trace) |
useTablePreferences composable for all views | Standardizes column/filter customization across Kanban, List, and Calendar. Persists to both localStorage and API. | Per-view settings (inconsistent UX), global store (couples unrelated views) |
| Dual validation for CSV import (process then create) | POST /prospects/process validates without writing; POST /prospects performs the actual insert. Gives users a preview before committing. | Single endpoint with rollback (complex transactions), client-side only (misses server duplicate checks) |
Client-side view switching with v-if | Only one view is mounted at a time, keeping memory usage low. Each view fetches its own data on mount. | Vue Router sub-routes (adds URL complexity), keep-alive (memory overhead for three large views) |
Dependencies
- Internal: Auth module (permissions, user context), Catalogs module (follow-up statuses, locales, phone codes, ecommerce types), Tasks module (TodoForm for reminders), Mailing module (email tab in sidepanel)
- External: Respondio (lead conversation automation via Bull queue), FullCalendar (calendar view), vuedraggable (Kanban drag-and-drop), Vuelidate (form validation)
Related Documentation
- API Endpoints — Complete endpoint reference for prospects and clients
- UI Screens & Flows — Frontend screens, components, and user interactions
- User Guide — End-user instructions for CRM operations
- CRM Views Guide — Detailed guide for each view (Kanban, Table, Calendar)
