Agrega documentación completa sobre la refactorización realizada: - Estructura de directorios detallada - Detalles por dominio (Products, Customers, Sales, Payments, Admin) - Beneficios y principios aplicados - Ejemplos de uso - Métricas y verificaciones de calidad
10 KiB
Refactorización a Domain-Driven Design - Resumen
✅ Refactorización Completada
Fecha: 29 de Mayo 2026
Commit: 47e87e42048e2394a6461f78d5c8e6a4386aa2f9
Tests: 46 tests pasando ✓
📊 Estadísticas
- Archivos creados: 17
- Archivos eliminados: 2
- Archivos modificados: 1
- Líneas agregadas: +816
- Líneas eliminadas: -621
- Balance neto: +195 líneas (mejor organización, más documentación)
🏗️ Nueva Estructura
don_confiao/
├── models/ # ✅ Ya estaba organizado por dominio
│ ├── products.py
│ ├── customers.py
│ ├── sales.py
│ ├── payments.py
│ └── admin.py
│
├── serializers/ # 🆕 Nuevo - Organizado por dominio
│ ├── __init__.py
│ ├── products.py # ProductSerializer, ListProductSerializer
│ ├── customers.py # CustomerSerializer, ListCustomerSerializer
│ ├── sales.py # Sale, SaleLine, CatalogSale serializers
│ └── payments.py # ReconciliationJar, PaymentMethod serializers
│
├── api/ # 🆕 Nuevo - API Views por dominio
│ ├── __init__.py
│ ├── products.py # ProductView, ProductsFromTrytonView
│ ├── customers.py # CustomerView, CustomersFromTrytonView
│ ├── sales.py # SaleView, CatalogSaleView, Sales*TrytonView
│ ├── payments.py # ReconciliateJarView, PaymentMethodView
│ └── admin.py # AdminCodeValidateView
│
└── services/ # 🆕 Nuevo - Capa de servicios
└── tryton/
├── __init__.py
├── client.py # Factory + TrytonSale/LineSale
├── products.py # ProductTrytonService
├── customers.py # CustomerTrytonService
└── sales.py # SaleTrytonService
📦 Detalles por Dominio
1. Products (Productos)
Serializers (serializers/products.py):
ProductSerializer- Serializer completo de productoListProductSerializer- Versión simplificada para listados
API Views (api/products.py):
ProductView- CRUD de productos con filtrado poractivestatusProductsFromTrytonView- Importación desde Tryton
Services (services/tryton/products.py):
ProductTrytonService- Lógica de sincronización con Trytonimport_from_tryton()- Importa productos_create_product()- Crea nuevo producto_update_product()- Actualiza producto existente_need_update()- Determina si necesita actualización
2. Customers (Clientes)
Serializers (serializers/customers.py):
CustomerSerializer- Serializer completo de clienteListCustomerSerializer- Versión simplificada para listados
API Views (api/customers.py):
CustomerView- CRUD de clientesCustomersFromTrytonView- Importación desde Tryton
Services (services/tryton/customers.py):
CustomerTrytonService- Lógica de sincronización con Trytonimport_from_tryton()- Importa clientes_create_customer()- Crea nuevo cliente_update_customer()- Actualiza cliente existente_need_update()- Determina si necesita actualización
3. Sales (Ventas)
Serializers (serializers/sales.py):
SaleSerializer- Serializer de ventaSaleLineSerializer- Serializer de línea de ventaCatalogSaleSerializer- Serializer de venta por catálogoCatalogSaleLineSerializer- Línea de venta por catálogoSummarySaleLineSerializer- Resumen de línea (con detalles)SaleSummarySerializer- Resumen completo de ventaSaleForRenconciliationSerializer- Ventas para reconciliación
API Views (api/sales.py):
SaleView- CRUD de ventasCatalogSaleView- CRUD de ventas por catálogoSaleSummary- Resumen de venta por IDSalesForTrytonView- Exportar ventas a CSV para TrytonSalesToTrytonView- Enviar ventas a Tryton
Services (services/tryton/sales.py):
SaleTrytonService- Lógica de sincronización con Trytonsend_to_tryton()- Envía ventas a Tryton_to_tryton_params()- Convierte venta a formato Tryton
4. Payments (Pagos y Reconciliación)
Serializers (serializers/payments.py):
ReconciliationJarSerializer- Serializer de arqueo de cajaPaymentMethodSerializer- Serializer de métodos de pago
API Views (api/payments.py):
ReconciliateJarView- Vista de reconciliación (POST/GET)ReconciliateJarModelView- ViewSet para arqueosPaymentMethodView- Listado de métodos de pagoSalesForReconciliationView- Ventas pendientes de reconciliaciónPagination- Paginación personalizada
5. Admin
API Views (api/admin.py):
AdminCodeValidateView- Validación de códigos de administrador
6. Services - Tryton Integration
Client (services/tryton/client.py):
get_tryton_client()- Factory para crear cliente conectadoTrytonSale- Representa venta para exportaciónTrytonLineSale- Representa línea de venta para exportación- Constantes de configuración (HOST, DATABASE, CURRENCY, etc.)
Características:
- ✅ Configuración centralizada
- ✅ Factory pattern para cliente
- ✅ DTOs para transformación de datos
- ✅ Reutilizable desde cualquier vista
🔄 Migración de Código
Archivos Eliminados
❌ serializers.py (170 líneas) → ✅ serializers/ (4 archivos)
❌ api_views.py (526 líneas) → ✅ api/ (5 archivos)
Backwards Compatibility
Todas las importaciones existentes siguen funcionando gracias a __init__.py:
# Antes y Después - Mismas importaciones funcionan
from don_confiao.serializers import ProductSerializer
from don_confiao.api import ProductView
🎯 Beneficios Obtenidos
1. Cohesión
- Cada módulo agrupa código relacionado a un solo dominio
- Fácil encontrar todo lo relacionado a un concepto (ej: productos)
2. Separación de Responsabilidades
- Models: Definición de datos
- Serializers: Transformación API ↔ Modelos
- API Views: Lógica de endpoints
- Services: Lógica de negocio (Tryton)
3. Mantenibilidad
- Archivos más pequeños y enfocados
- Menos de 150 líneas por archivo
- Más fácil de leer y entender
4. Escalabilidad
- Agregar nuevo dominio = crear nuevos archivos en cada capa
- No modifica código existente
- Open/Closed Principle
5. Testabilidad
- Tests pueden organizarse por dominio
- Servicios fáciles de mockear
- Cada componente testeable independientemente
6. Reutilización
- Servicios Tryton usables desde cualquier vista
- Serializers compartibles entre vistas
- DRY (Don't Repeat Yourself)
📝 Próximos Pasos Sugeridos
1. Organizar Tests por Dominio (Opcional)
tests/
├── __init__.py
├── products/
│ ├── test_products_api.py
│ ├── test_products_serializers.py
│ └── test_products_tryton.py
├── customers/
│ └── ...
└── sales/
└── ...
2. Documentación
Crear documentación por dominio:
docs/
├── products.md
├── customers.md
├── sales.md
└── tryton_integration.md
3. Mejorar Services Layer
Agregar más lógica de negocio a services:
- Validaciones complejas
- Cálculos de negocio
- Transformaciones de datos
4. Agregar Type Hints
Mejorar type hints en services para mejor IDE support:
def import_from_tryton(self) -> dict[str, list[int]]:
"""Importa productos desde Tryton
Returns:
Dict con listas de IDs: checked, failed, updated, created, untouched
"""
🧪 Tests
Estado Actual
✅ 46 tests pasando
Cobertura por Dominio
- ✅ Products: 13 tests (incluye filtrado por active status)
- ✅ Sales: 8 tests
- ✅ Customers: Tests de integración Tryton
- ✅ Payments: Tests de reconciliación
- ✅ Admin: Tests de códigos
Ejecución
# Todos los tests
docker compose -f docker-compose.dev.yml run --rm django python manage.py test don_confiao.tests
# Tests específicos
docker compose -f docker-compose.dev.yml run --rm django python manage.py test don_confiao.tests.test_products
📚 Ejemplos de Uso
Importar Serializers
# Forma explícita
from don_confiao.serializers.products import ProductSerializer
# Forma simplificada (recomendada)
from don_confiao.serializers import ProductSerializer
Importar API Views
# Forma explícita
from don_confiao.api.products import ProductView
# Forma simplificada (recomendada)
from don_confiao.api import ProductView
Usar Services
from don_confiao.services import get_tryton_client, ProductTrytonService
# En una vista
def my_view(request):
client = get_tryton_client()
service = ProductTrytonService(client)
result = service.import_from_tryton()
return Response(result)
🔍 Verificación de Calidad
Checks Realizados
- ✅ Todos los tests pasan
- ✅ Sin imports circulares
- ✅ Todas las URLs funcionando
- ✅ Backwards compatibility mantenida
- ✅ Código limpio y documentado
Métricas
- Complejidad ciclomática: Reducida (archivos más pequeños)
- Acoplamiento: Reducido (separación de capas)
- Cohesión: Incrementada (código por dominio)
🎓 Principios Aplicados
- Domain-Driven Design (DDD): Organización por dominios de negocio
- Single Responsibility Principle (SRP): Cada módulo una responsabilidad
- Open/Closed Principle: Abierto a extensión, cerrado a modificación
- Dependency Inversion: Dependencias hacia abstracciones (services)
- DRY: Servicios reutilizables, no repetir lógica
- Separation of Concerns: Capas bien definidas
📞 Soporte
Si tienes preguntas sobre la nueva estructura:
- Serializers: Ver
serializers/__init__.pypara exportaciones - API Views: Ver
api/__init__.pypara exportaciones - Services: Ver
services/tryton/para lógica Tryton - URLs: Ver
urls.pypara rutas disponibles
¡Refactorización completada exitosamente! 🎉
La estructura está lista para escalar y mantener de forma eficiente.