Aplicación de escritorio para la gestión de relaciones con clientes (CRM), desarrollada como proyecto académico para la materia de Base de Datos y Lenguajes en la Facultad de Ingeniería Mecánica y Eléctrica (FIME) de la Universidad Autónoma de Nuevo León (UANL).
| Tecnología | Versión | Propósito |
|---|---|---|
| Python | 3.x | Lenguaje principal |
| PyQt5 | 5.15.11 | Framework de interfaz gráfica |
| SQLite3 | (incluido en Python) | Motor de base de datos |
| bcrypt | 5.0.0 | Hashing seguro de contraseñas |
| openpyxl | 3.1.5 | Exportación de reportes a Excel (.xlsx) |
| reportlab | 4.4.10 | Exportación de reportes a PDF |
| matplotlib | latest | Gráficas del dashboard (pipeline, oportunidades) |
| pillow | 12.1.1 | Soporte de imágenes en la interfaz |
- MVC (Modelo-Vista-Controlador): separación clara entre la lógica de negocio, la presentación y el control del flujo.
- Patrón Repository: capa de acceso a datos desacoplada de la lógica de negocio.
- Arquitectura por capas: cada capa tiene una responsabilidad única.
- Singleton: conexión a base de datos reutilizable a nivel global.
- Signal-Slot (PyQt5): comunicación desacoplada entre componentes de la interfaz.
Views (Presentación)
|
Controllers (Control de flujo)
|
Services (Lógica de negocio)
|
Repositories (Acceso a datos)
|
Database (SQLite)
CRM-Portable/
├── app/ # Paquete principal de la aplicación
│ ├── assets/ # Iconos SVG para la interfaz
│ ├── config/ # Configuración de la app y catálogos
│ │ ├── settings.py
│ │ └── catalogos.py
│ ├── database/ # Capa de base de datos
│ │ ├── connection.py # Conexión thread-local a SQLite
│ │ └── initializer.py # Creación de esquema, migración y datos iniciales
│ ├── models/ # Modelos de datos
│ │ ├── Usuario.py, Rol.py, Catalogo.py
│ │ ├── Empresa.py, Contacto.py
│ │ ├── NotaContacto.py, NotaEmpresa.py
│ │ ├── Oportunidad.py, Producto.py, Cotizacion.py
│ │ ├── Actividad.py
│ │ ├── Segmento.py, Etiqueta.py
│ │ ├── Plantilla.py, Campana.py
│ │ ├── ConfiguracionCorreo.py
│ │ ├── Notificacion.py # Modelo de notificaciones del sistema
│ │ └── Recordatorio.py # Modelo de recordatorios personales
│ ├── repositories/ # Capa de acceso a datos (CRUD)
│ │ ├── usuario_repository.py, rol_repository.py
│ │ ├── empresa_repository.py, contacto_repository.py
│ │ ├── nota_contacto_repository.py, nota_empresa_repository.py
│ │ ├── catalogo_repository.py, auditoria_repository.py
│ │ ├── oportunidad_repository.py, oportunidad_producto_repository.py
│ │ ├── historial_etapas_repository.py
│ │ ├── producto_repository.py
│ │ ├── cotizacion_repository.py, cotizacion_detalle_repository.py
│ │ ├── actividad_repository.py
│ │ ├── segmento_repository.py, etiqueta_repository.py
│ │ ├── plantilla_repository.py, campana_repository.py
│ │ ├── config_correo_repository.py
│ │ ├── reporte_repository.py # Queries contra 5 vistas precalculadas
│ │ ├── notificacion_repository.py
│ │ ├── recordatorio_repository.py
│ │ └── dashboard_repository.py # KPIs, pipeline, actividades recientes
│ ├── services/ # Capa de lógica de negocio
│ │ ├── auth_service.py, usuario_service.py
│ │ ├── permission_service.py # Matriz de permisos por rol (RBAC)
│ │ ├── empresa_service.py, contacto_service.py
│ │ ├── nota_contacto_service.py, nota_empresa_service.py
│ │ ├── catalogo_service.py
│ │ ├── oportunidad_service.py, producto_service.py
│ │ ├── cotizacion_service.py
│ │ ├── actividad_service.py
│ │ ├── segmento_service.py, etiqueta_service.py
│ │ ├── campana_service.py # Envío SMTP real + sincronización de métricas
│ │ ├── reporte_service.py # Exportación Excel/PDF (openpyxl, reportlab)
│ │ └── notificacion_service.py # CRUD recordatorios + envío email + popup check
│ ├── controllers/ # Controladores MVC
│ │ ├── login_controller.py
│ │ └── main_controller.py
│ ├── utils/ # Utilidades transversales
│ │ ├── validators.py # Validaciones (email, RFC, contraseña, etc.)
│ │ ├── sanitizer.py # Protección XSS en contenido de notas
│ │ ├── catalog_cache.py # Caché en memoria de catálogos (TTL 5 min)
│ │ ├── logger.py # Logger centralizado con rotación 10 MB
│ │ └── db_retry.py # Reintentos con backoff exponencial
│ └── views/ # Vistas e interfaz gráfica
│ ├── ui/ # Archivos .ui (Qt Designer)
│ │ ├── main/ # main_view.ui
│ │ ├── auth/ # login_view.ui, setup_view.ui
│ │ ├── users/ # user_form.ui, user_list.ui
│ │ ├── clientes/ # 6 archivos (empresa, contacto, notas)
│ │ ├── catalogos/ # 14 archivos (ventas, actividades, empresas, sistema)
│ │ ├── actividades/ # 3 archivos
│ │ ├── segmentacion/ # 6 archivos
│ │ ├── comunicacion/ # comunicacion_view.ui
│ │ ├── reportes/ # reportes_view.ui
│ │ ├── notificaciones/ # notificaciones_view.ui, recordatorio_form.ui
│ │ ├── dashboard/ # dashboard_view.ui
│ │ ├── configuracion/ # configuracion_view.ui
│ │ ├── geografia/ # 4 archivos (paises, estados, ciudades)
│ │ └── ventas/ # 10 archivos
│ ├── login_view.py, setup_view.py
│ ├── main_view.py # Barra lateral + QTimer cada 2 min (notificaciones)
│ ├── configuracion_view.py
│ ├── catalogo_list_widget.py, catalogo_form_dialog.py
│ ├── geografia_widget.py
│ ├── clientes_view.py
│ ├── notas_contacto_widget.py, notas_empresa_widget.py
│ ├── ventas_view.py
│ ├── oportunidad_productos_widget.py
│ ├── historial_etapas_widget.py
│ ├── cotizacion_detalle_widget.py
│ ├── actividades_view.py
│ ├── segmentacion_view.py
│ ├── comunicacion_view.py
│ ├── reportes_view.py
│ ├── notificaciones_view.py # Pestañas: Notificaciones + Recordatorios
│ ├── notificacion_popup.py # QDialog popup al iniciar sesión
│ └── dashboard_view.py # KPIs ejecutivos + gráficas matplotlib
├── db/ # Base de datos y esquema SQL
│ ├── database_query.sql # Esquema completo (42+ tablas, vistas, triggers)
│ └── crm.db # Archivo SQLite generado
├── tests/ # Pruebas unitarias
├── docs/ # Documentación del proyecto
├── main.py # Punto de entrada (llama migrate_database())
├── requirements.txt # Dependencias de Python
└── README.md
El esquema SQLite contiene 42 tablas, vistas, triggers e índices. A continuación los módulos principales:
| Módulo | Tablas principales | Descripción |
|---|---|---|
| Usuarios | Usuarios, Roles |
Autenticación y control de acceso |
| Contactos | Empresas, Contactos |
Gestión de cuentas y personas |
| Ventas | Oportunidades, Cotizaciones, Productos |
Pipeline comercial |
| Actividades | Actividades, TiposActividad |
Llamadas, reuniones, tareas |
| Segmentación | Segmentos, SegmentoContactos, Etiquetas |
Agrupación de contactos |
| Comunicación | PlantillasCorreo, Campanas, CampanaDestinatarios |
Campañas de email masivo |
| Notificaciones | Notificaciones, Recordatorios |
Alertas del sistema y recordatorios personales |
| Config. Correo | ConfiguracionCorreo |
Cuentas SMTP/API para envíos |
| Geografía | Paises, Estados, Ciudades |
Jerarquía geográfica |
| Catálogos | Industrias, Monedas, Prioridades, etc. |
Tablas de configuración |
| Auditoría | LogAuditoria |
Trazabilidad de CREATE/UPDATE/DELETE |
| Vista | Propósito |
|---|---|
vw_ResumenEjecutivo |
KPIs del dashboard (contactos, empresas, pipeline, revenue) |
vw_PipelineVentas |
Reporte de pipeline por etapa |
vw_RendimientoVendedores |
Conversión y montos por vendedor |
vw_ConversionEtapas |
Tasa de conversión entre etapas |
vw_MetricasCampanas |
Métricas de campañas de email |
vw_ActividadContactos |
Actividad reciente por contacto |
- Claves foráneas con integridad referencial (
PRAGMA foreign_keys = ON) - Triggers para timestamps automáticos, historial de etapas y auditoría
- Modo WAL para mejor rendimiento concurrente
migrate_database()eninitializer.pycrea tablas faltantes en DBs existentes
# Clonar el repositorio
git clone <url-del-repositorio>
# Instalar dependencias
pip install -r requirements.txt
# Ejecutar la aplicación
python main.pyLa base de datos se crea automáticamente en la primera ejecución con la estructura completa de tablas (roles, catálogos, datos geográficos).
Al iniciar la aplicación por primera vez, se mostrará un asistente de configuración inicial que te permitirá crear tu usuario administrador personalizado:
- La aplicación detecta que no hay usuarios administradores en el sistema
- Se muestra la ventana de "Configuración Inicial"
- Completa el formulario con tu información:
- Nombre
- Apellido Paterno
- Correo Electrónico
- Contraseña (con validación de fortaleza en tiempo real)
- Confirmación de contraseña
- Haz clic en "Crear Usuario Administrador"
- El sistema te redirigirá automáticamente a la pantalla de login
- Inicia sesión con las credenciales que acabas de crear
Nota: No hay credenciales por defecto. El primer usuario siempre debe ser creado manualmente a través del asistente de configuración inicial.
- Autenticación: Login seguro con bcrypt, actualización de último acceso
- Control de acceso por roles (RBAC): Sidebar adaptativo — cada rol ve únicamente los módulos autorizados
- Gestión de usuarios: CRUD completo con validaciones robustas
- Gestión de empresas: CRUD con validación de RFC, email, teléfono
- Gestión de contactos: CRUD con validación de múltiples emails y teléfonos
- Notas de contacto y empresa: CRUD con sanitización XSS y auditoría
- Catálogos genéricos: 13 tipos de catálogo con caché inteligente
- Jerarquía geográfica: Países, Estados, Ciudades con dependencias
- Sistema de logging: Logs rotativos con filtrado de datos sensibles
- Sistema de auditoría: Tracking completo de CREATE/UPDATE/DELETE
- Configuración: Navegación por pestañas con vistas especializadas
- Catálogo de Productos/Servicios: CRUD completo con código, categoría, precio y moneda
- Pipeline de Oportunidades: CRUD con etapas, monto, probabilidad, historial automático de etapas
- Productos en Oportunidades: Líneas de productos vinculadas a cada oportunidad con subtotales
- Cotizaciones: CRUD con número auto-generado (COT-AAAA-NNNN), estados y cálculo de IVA (16%)
- Detalle de Cotizaciones: Líneas de producto con cantidad, precio, descuento y subtotal
- Gestión de actividades: CRUD completo con tipos, prioridades, estados, fechas y asignación
- Segmentación de contactos: Segmentos dinámicos con etiquetas y asignación manual/masiva
- Plantillas de correo: CRUD de plantillas HTML y texto plano por categoría
- Campañas de comunicación: Gestión de campañas de email con destinatarios y métricas
- Envío de correos SMTP: Envío real de campañas vía SMTP con SSL/TLS, manejo de estados y métricas
- Configuración de correo: Cuentas SMTP/API (Gmail, Outlook, SendGrid, Mailgun) para envío masivo
- Reportes: 5 reportes precalculados con filtro de fechas y exportación a Excel y PDF
- Notificaciones: Popup al iniciar sesión con notificaciones no leídas; marcado automático como leídas
- Recordatorios: CRUD de recordatorios personales con envío de email de alerta vía SMTP
- Dashboard ejecutivo: KPIs en tiempo real, gráfica de pipeline por etapa, gráfica de oportunidades y tabla de actividades recientes
El sistema implementa validaciones robustas a través del módulo app/utils/validators.py:
- Correo electrónico con formato válido (regex)
- Teléfono de 10 dígitos
- Código postal de 5 dígitos
- RFC mexicano (12-13 caracteres alfanuméricos)
- URLs con formato válido
- Contraseñas con fortaleza mínima:
- Mínimo 8 caracteres
- Al menos una mayúscula
- Al menos una minúscula
- Al menos un número
- Validación contra contraseñas comunes
- Campos requeridos y restricciones de unicidad
- Protección contra eliminación de registros referenciados
El proyecto incluye las siguientes mejoras de seguridad implementadas:
- Contraseñas hasheadas con bcrypt (factor de costo 12)
- Configuración inicial interactiva para crear primer usuario administrador
- Sin credenciales por defecto ni hardcodeadas en el código fuente
- Validación de fortaleza de contraseña en tiempo real durante el registro
- Cuatro roles definidos: Administrador, Gerente de Ventas, Vendedor, Marketing
- Módulos del sidebar ocultos automáticamente según el rol del usuario autenticado
- Matriz de permisos centralizada en
app/services/permission_service.py
| Módulo | Admin | Gerente | Vendedor | Marketing |
|---|---|---|---|---|
| Dashboard | ✓ | ✓ | ✓ | ✓ |
| Clientes | ✓ | ✓ | ✓ | ✓ |
| Ventas | ✓ | ✓ | ✓ | |
| Actividades | ✓ | ✓ | ✓ | |
| Segmentacion | ✓ | ✓ | ✓ | |
| Comunicacion | ✓ | ✓ | ✓ | |
| Reportes | ✓ | ✓ | ✓ | |
| Notificaciones | ✓ | ✓ | ✓ | ✓ |
| Usuarios | ✓ | |||
| Configuracion | ✓ |
- Queries parametrizadas en todos los repositorios
- Validación de identificadores SQL (tablas y columnas)
- Whitelist de tablas permitidas en CatalogoRepository
- Validación de columnas en filtros dinámicos
- Módulo
validators.pycon funciones reutilizables - Validación de tipos de datos y formatos
- Protección contra entrada maliciosa
- Módulo
sanitizer.pypara prevenir XSS - Escape automático de HTML en contenido de notas
- Validación de longitud con límites configurables
- Truncado automático de texto excedente
- Logger centralizado con rotación automática (10 MB por archivo)
- Filtrado automático de 15+ tipos de datos sensibles (contraseñas, RFC, tokens, etc.)
- Logs separados:
app.log(todos los niveles) yerrors.log(solo errores) - Registro de operaciones CRUD con usuario responsable
- Stack traces completos en logs de error
- Tabla
LogAuditoriacon registro completo de operaciones - Tracking de CREATE, UPDATE, DELETE
- Almacenamiento de valores anteriores y nuevos en JSON
- Asociación de operaciones al usuario que las realiza
- IP de origen registrada
- Sanitización de mensajes de error para usuarios finales
- Reintentos automáticos con backoff exponencial para errores de DB (
db_retry.py) - Validación de foreign keys antes de insertar
- Mensajes amigables sin exponer detalles técnicos
El proyecto implementa optimizaciones clave para mejorar el rendimiento y escalabilidad:
- Sistema de caché en memoria para catálogos frecuentemente consultados
- TTL configurable (5 minutos por defecto)
- Invalidación automática al modificar catálogos
- Reduce consultas repetitivas en carga de formularios
- Implementado en
app/utils/catalog_cache.py
- Soporte de paginación en repositorios de Empresas y Contactos
- Límite de 200 registros por página por defecto
- Métodos
find_all(limit, offset)ycount_all()en repositorios - Reduce uso de memoria con grandes volúmenes de datos
- 6 vistas SQL en la BD calculan agregaciones costosas de forma incremental
- El dashboard y los reportes consultan directamente estas vistas en lugar de hacer JOINs complejos en tiempo real
El proyecto incluye una suite de 46 tests unitarios (100% passing):
tests/
├── test_utils/
│ ├── test_validators.py # Tests de validaciones (15 tests)
│ └── test_catalog_cache.py # Tests de caché (4 tests)
└── test_services/
├── test_auth_service.py # Tests de autenticación (9 tests)
├── test_nota_contacto_service.py # Tests de notas de contacto (9 tests)
└── test_nota_empresa_service.py # Tests de notas de empresa (9 tests)
-
Validadores (15 tests): 100% de cobertura
- Validación de email, teléfono, código postal
- Validación de RFC, URLs
- Validación de fortaleza de contraseña
- Validación de rangos numéricos y longitud de texto
-
Autenticación (9 tests): Tests críticos de seguridad
- Login exitoso con credenciales correctas
- Login con email inexistente
- Login con contraseña incorrecta
- Login con usuario inactivo
- Validación de campos vacíos
- Actualización de último acceso
- Manejo de errores de base de datos
-
Caché de Catálogos (4 tests): Tests de rendimiento
- Verificación de caché en memoria
- Invalidación de caché
- Caché con filtros
- Configuración de TTL
-
Notas de Contacto (9 tests): CRUD completo
- Creación exitosa con validaciones
- Validación de contenido requerido
- Validación de longitud de título y contenido
- Actualización y eliminación
- Manejo de errores
-
Notas de Empresa (9 tests): CRUD completo
- Misma cobertura que notas de contacto
- Validaciones de sanitización
- Integración con auditoría
# Instalar dependencias de testing
pip install pytest pytest-mock
# Ejecutar todos los tests
pytest
# Ejecutar tests con verbose
pytest -v
# Ejecutar tests con coverage
pytest --cov=app --cov-report=html
# Ejecutar tests de un módulo específico
pytest tests/test_utils/test_validators.pyProyecto académico - Equipo #1 Materia: Base de Datos y Lenguajes | FIME | UANL Catedrático: M.C. Jorge Alejandro Lozano González