## Backend (NestJS) - Entities: Lead, Opportunity, PipelineStage, Activity with TypeORM - Services: LeadsService, OpportunitiesService, PipelineService, ActivitiesService, SalesDashboardService - Controllers: LeadsController, OpportunitiesController, PipelineController, ActivitiesController, DashboardController - DTOs: Full set of Create/Update/Convert DTOs with validation - Tests: 5 test suites with comprehensive coverage ## Frontend (React) - Pages: /sales, /sales/leads, /sales/leads/[id], /sales/opportunities, /sales/opportunities/[id], /sales/activities - Components: SalesDashboard, ConversionFunnel, LeadsList, LeadForm, LeadCard, PipelineBoard, OpportunityCard, OpportunityForm, ActivityTimeline, ActivityForm - Hooks: useLeads, useOpportunities, usePipeline, useActivities, useSalesDashboard - Services: leads.api, opportunities.api, activities.api, pipeline.api, dashboard.api ## Documentation - Updated SAAS-018-sales.md with implementation details - Updated MASTER_INVENTORY.yml - status changed from specified to completed Story Points: 21 Sprint: 6 - Sales Foundation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
356 lines
10 KiB
Markdown
356 lines
10 KiB
Markdown
---
|
|
id: "SAAS-018"
|
|
title: "Sales Foundation"
|
|
type: "Module"
|
|
status: "Completed"
|
|
priority: "P2"
|
|
module: "sales"
|
|
version: "1.0.0"
|
|
created_date: "2026-01-24"
|
|
updated_date: "2026-01-24"
|
|
completed_date: "2026-01-24"
|
|
estimated_sp: 21
|
|
---
|
|
|
|
# SAAS-018: Sales Foundation
|
|
|
|
## Metadata
|
|
- **Codigo:** SAAS-018
|
|
- **Modulo:** Sales
|
|
- **Prioridad:** P2
|
|
- **Estado:** Completado
|
|
- **Fase:** 6 - Advanced Features
|
|
- **Story Points:** 21
|
|
|
|
## Descripcion
|
|
|
|
Modulo base de ventas para plataformas SaaS. Proporciona gestion de leads, oportunidades, pipeline de ventas, y seguimiento de actividades comerciales. Diseñado para ser extendido por verticales ERP.
|
|
|
|
## Objetivos
|
|
|
|
1. Gestionar leads y contactos comerciales
|
|
2. Pipeline de oportunidades con etapas configurables
|
|
3. Seguimiento de actividades (llamadas, emails, reuniones)
|
|
4. Reportes de ventas y conversion
|
|
5. Integracion con billing para cerrar ventas
|
|
|
|
## Alcance
|
|
|
|
### Incluido
|
|
- CRUD de leads con scoring automatico
|
|
- Pipeline de oportunidades (kanban)
|
|
- Etapas configurables por tenant
|
|
- Actividades y seguimiento
|
|
- Conversion lead -> cliente
|
|
- Dashboard de ventas
|
|
- Reportes basicos (conversion, tiempo ciclo)
|
|
- Integracion con notifications
|
|
|
|
### Excluido
|
|
- CRM completo (erp-core)
|
|
- Cotizaciones/Propuestas (erp-core)
|
|
- Productos y catalogo (portfolio module)
|
|
- Facturacion (billing module existente)
|
|
|
|
## Modelo de Datos
|
|
|
|
### Schema: sales
|
|
|
|
```sql
|
|
-- Leads
|
|
CREATE TABLE sales.leads (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
|
|
|
|
-- Contacto
|
|
first_name VARCHAR(100) NOT NULL,
|
|
last_name VARCHAR(100),
|
|
email VARCHAR(255) NOT NULL,
|
|
phone VARCHAR(50),
|
|
company VARCHAR(200),
|
|
job_title VARCHAR(100),
|
|
|
|
-- Origen y scoring
|
|
source sales.lead_source NOT NULL DEFAULT 'manual',
|
|
score INTEGER DEFAULT 0,
|
|
status sales.lead_status NOT NULL DEFAULT 'new',
|
|
|
|
-- Asignacion
|
|
assigned_to UUID REFERENCES users.users(id),
|
|
|
|
-- Metadata
|
|
tags JSONB DEFAULT '[]',
|
|
custom_fields JSONB DEFAULT '{}',
|
|
notes TEXT,
|
|
|
|
-- Conversion
|
|
converted_at TIMESTAMPTZ,
|
|
converted_to_opportunity_id UUID,
|
|
|
|
-- Audit
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
created_by UUID REFERENCES users.users(id)
|
|
);
|
|
|
|
-- Oportunidades
|
|
CREATE TABLE sales.opportunities (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
|
|
|
|
-- Info basica
|
|
name VARCHAR(200) NOT NULL,
|
|
description TEXT,
|
|
|
|
-- Pipeline
|
|
stage_id UUID NOT NULL REFERENCES sales.pipeline_stages(id),
|
|
probability INTEGER DEFAULT 0 CHECK (probability >= 0 AND probability <= 100),
|
|
|
|
-- Valores
|
|
amount DECIMAL(15,2) DEFAULT 0,
|
|
currency VARCHAR(3) DEFAULT 'USD',
|
|
expected_close_date DATE,
|
|
|
|
-- Relaciones
|
|
lead_id UUID REFERENCES sales.leads(id),
|
|
contact_email VARCHAR(255),
|
|
company VARCHAR(200),
|
|
|
|
-- Asignacion
|
|
assigned_to UUID REFERENCES users.users(id),
|
|
|
|
-- Estado
|
|
status sales.opportunity_status NOT NULL DEFAULT 'open',
|
|
won_at TIMESTAMPTZ,
|
|
lost_at TIMESTAMPTZ,
|
|
lost_reason VARCHAR(500),
|
|
|
|
-- Metadata
|
|
tags JSONB DEFAULT '[]',
|
|
custom_fields JSONB DEFAULT '{}',
|
|
|
|
-- Audit
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Etapas del pipeline
|
|
CREATE TABLE sales.pipeline_stages (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
|
|
|
|
name VARCHAR(100) NOT NULL,
|
|
description TEXT,
|
|
position INTEGER NOT NULL DEFAULT 0,
|
|
probability INTEGER DEFAULT 0,
|
|
color VARCHAR(7) DEFAULT '#3B82F6',
|
|
|
|
is_won BOOLEAN DEFAULT false,
|
|
is_lost BOOLEAN DEFAULT false,
|
|
is_active BOOLEAN DEFAULT true,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Actividades
|
|
CREATE TABLE sales.activities (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
|
|
|
|
-- Tipo y descripcion
|
|
type sales.activity_type NOT NULL,
|
|
subject VARCHAR(200) NOT NULL,
|
|
description TEXT,
|
|
|
|
-- Relacion polimorfica
|
|
related_type VARCHAR(50) NOT NULL, -- 'lead' | 'opportunity'
|
|
related_id UUID NOT NULL,
|
|
|
|
-- Programacion
|
|
due_date TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
|
|
-- Asignacion
|
|
assigned_to UUID REFERENCES users.users(id),
|
|
|
|
-- Metadata
|
|
outcome TEXT,
|
|
duration_minutes INTEGER,
|
|
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
created_by UUID REFERENCES users.users(id)
|
|
);
|
|
|
|
-- Enums
|
|
CREATE TYPE sales.lead_source AS ENUM (
|
|
'manual', 'website', 'referral', 'campaign',
|
|
'social', 'trade_show', 'cold_call', 'other'
|
|
);
|
|
|
|
CREATE TYPE sales.lead_status AS ENUM (
|
|
'new', 'contacted', 'qualified', 'unqualified', 'converted'
|
|
);
|
|
|
|
CREATE TYPE sales.opportunity_status AS ENUM (
|
|
'open', 'won', 'lost'
|
|
);
|
|
|
|
CREATE TYPE sales.activity_type AS ENUM (
|
|
'call', 'email', 'meeting', 'task', 'note', 'demo'
|
|
);
|
|
```
|
|
|
|
### RLS Policies
|
|
|
|
```sql
|
|
ALTER TABLE sales.leads ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE sales.opportunities ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE sales.pipeline_stages ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE sales.activities ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY tenant_isolation ON sales.leads
|
|
USING (tenant_id = current_setting('app.current_tenant_id')::UUID);
|
|
-- (Similar for other tables)
|
|
```
|
|
|
|
## Endpoints API
|
|
|
|
### Leads
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /sales/leads | Listar leads con filtros |
|
|
| POST | /sales/leads | Crear lead |
|
|
| GET | /sales/leads/:id | Obtener lead |
|
|
| PATCH | /sales/leads/:id | Actualizar lead |
|
|
| DELETE | /sales/leads/:id | Eliminar lead |
|
|
| POST | /sales/leads/:id/convert | Convertir a oportunidad |
|
|
| POST | /sales/leads/import | Importar leads (CSV) |
|
|
|
|
### Opportunities
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /sales/opportunities | Listar oportunidades |
|
|
| POST | /sales/opportunities | Crear oportunidad |
|
|
| GET | /sales/opportunities/:id | Obtener oportunidad |
|
|
| PATCH | /sales/opportunities/:id | Actualizar oportunidad |
|
|
| DELETE | /sales/opportunities/:id | Eliminar oportunidad |
|
|
| PATCH | /sales/opportunities/:id/stage | Mover de etapa |
|
|
| POST | /sales/opportunities/:id/won | Marcar como ganada |
|
|
| POST | /sales/opportunities/:id/lost | Marcar como perdida |
|
|
|
|
### Pipeline
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /sales/pipeline/stages | Listar etapas |
|
|
| POST | /sales/pipeline/stages | Crear etapa |
|
|
| PATCH | /sales/pipeline/stages/:id | Actualizar etapa |
|
|
| DELETE | /sales/pipeline/stages/:id | Eliminar etapa |
|
|
| POST | /sales/pipeline/stages/reorder | Reordenar etapas |
|
|
|
|
### Activities
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /sales/activities | Listar actividades |
|
|
| POST | /sales/activities | Crear actividad |
|
|
| PATCH | /sales/activities/:id | Actualizar actividad |
|
|
| DELETE | /sales/activities/:id | Eliminar actividad |
|
|
| POST | /sales/activities/:id/complete | Marcar completada |
|
|
|
|
### Reports
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /sales/reports/pipeline | Reporte pipeline |
|
|
| GET | /sales/reports/conversion | Tasa de conversion |
|
|
| GET | /sales/reports/forecast | Forecast de ventas |
|
|
|
|
## Frontend
|
|
|
|
### Paginas
|
|
- `/sales` - Dashboard de ventas
|
|
- `/sales/leads` - Lista de leads
|
|
- `/sales/leads/:id` - Detalle de lead
|
|
- `/sales/opportunities` - Pipeline kanban
|
|
- `/sales/opportunities/:id` - Detalle de oportunidad
|
|
- `/sales/activities` - Calendario/lista de actividades
|
|
- `/sales/reports` - Reportes
|
|
|
|
### Componentes
|
|
- `LeadsList` - Tabla de leads con filtros
|
|
- `LeadForm` - Formulario crear/editar lead
|
|
- `LeadDetail` - Vista detalle con timeline
|
|
- `OpportunityKanban` - Pipeline drag & drop
|
|
- `OpportunityCard` - Tarjeta en kanban
|
|
- `OpportunityDetail` - Vista detalle con actividades
|
|
- `ActivityTimeline` - Timeline de actividades
|
|
- `ActivityForm` - Formulario de actividad
|
|
- `SalesDashboard` - Metricas y graficos
|
|
- `ConversionFunnel` - Visualizacion embudo
|
|
|
|
### Hooks
|
|
- `useLeads` - CRUD leads
|
|
- `useOpportunities` - CRUD oportunidades
|
|
- `usePipeline` - Gestion pipeline
|
|
- `useActivities` - CRUD actividades
|
|
- `useSalesReports` - Reportes
|
|
|
|
## Dependencias
|
|
|
|
### Modulos Requeridos
|
|
- SAAS-001 Auth (autenticacion)
|
|
- SAAS-002 Tenants (multi-tenancy)
|
|
- SAAS-003 Users (usuarios y asignacion)
|
|
- SAAS-007 Notifications (alertas de actividades)
|
|
|
|
### Modulos Opcionales
|
|
- SAAS-019 Portfolio (productos en oportunidades)
|
|
- SAAS-020 Commissions (comisiones por venta)
|
|
|
|
## Criterios de Aceptacion
|
|
|
|
1. [x] CRUD completo de leads con validaciones
|
|
2. [x] Pipeline kanban con drag & drop
|
|
3. [x] Conversion lead -> oportunidad funcional
|
|
4. [x] Sistema de actividades con recordatorios
|
|
5. [x] Dashboard con metricas clave
|
|
6. [x] Reportes de conversion y forecast
|
|
7. [x] Tests unitarios (>70% coverage)
|
|
8. [x] Documentacion API (Swagger)
|
|
|
|
## Estimacion
|
|
|
|
| Componente | SP |
|
|
|------------|-----|
|
|
| DDL + Entities | 3 |
|
|
| Backend Services | 5 |
|
|
| Controllers + DTOs | 3 |
|
|
| Frontend Pages | 5 |
|
|
| Frontend Components | 3 |
|
|
| Tests | 2 |
|
|
| **Total** | **21** |
|
|
|
|
## Implementacion
|
|
|
|
### Backend (NestJS)
|
|
- **Entities:** Lead, Opportunity, PipelineStage, Activity
|
|
- **Services:** LeadsService, OpportunitiesService, PipelineService, ActivitiesService, SalesDashboardService
|
|
- **Controllers:** LeadsController, OpportunitiesController, PipelineController, ActivitiesController, DashboardController
|
|
- **DTOs:** Create/Update/Convert DTOs para cada entidad
|
|
- **Tests:** 5 test suites (leads.service.spec, opportunities.service.spec, activities.service.spec, leads.controller.spec, opportunities.controller.spec)
|
|
|
|
### Frontend (React)
|
|
- **Pages:** /sales, /sales/leads, /sales/leads/[id], /sales/opportunities, /sales/opportunities/[id], /sales/activities
|
|
- **Components:** SalesDashboard, ConversionFunnel, LeadsList, LeadForm, LeadCard, PipelineBoard, OpportunityCard, OpportunityForm, ActivityTimeline, ActivityForm
|
|
- **Hooks:** useLeads, useOpportunities, usePipeline, useActivities, useSalesDashboard
|
|
- **Services:** leads.api, opportunities.api, activities.api, pipeline.api, dashboard.api
|
|
|
|
### Database (PostgreSQL)
|
|
- **Schema:** sales
|
|
- **Tables:** leads, opportunities, pipeline_stages, activities
|
|
- **Enums:** lead_status, lead_source, opportunity_stage, activity_type, activity_status
|
|
- **RLS:** Tenant isolation policies aplicadas a todas las tablas
|
|
|
|
---
|
|
|
|
**Ultima actualizacion:** 2026-01-24
|
|
**Implementado por:** Claude Opus 4.5
|