Appearance
Soporte Técnico del Módulo
Esta sección documenta las funcionalidades de soporte técnico que permiten el funcionamiento óptimo del módulo de membresías, incluyendo enriquecimiento de datos, eventos de dominio, integraciones, caché, validaciones cross-cutting y herramientas de análisis.
Descripción General
Las funcionalidades de soporte técnico incluyen:
- Enriquecimiento y consultas avanzadas: Carga inteligente de datos relacionados con scopes y filtrado complejo
- Eventos de dominio: Sistema de eventos para automatización y desacoplamiento
- Integraciones con módulos: Conexiones con Ventas y CtaCte
- Caché y optimizaciones: Sistema de caché tenant-aware y batch loading
- Validaciones cross-cutting: Reglas de negocio transversales
- Estadísticas de facturación: Reportes agregados de resultados
- Documentación OpenAPI: Especificación automática de la API
Componentes Documentados
Enriquecimiento y Consultas Avanzadas
- Enriquecimiento de Miembros: Carga inteligente de datos
- Sistema de scopes (min/max) para optimizar consultas
- Include tree para categorías, disciplinas, productos, grupos familiares
- Batch loading para evitar N+1 queries
- Lazy loading según scope solicitado
- Filtros avanzados combinados (estado, categoría, disciplina, producto)
- Búsqueda global (nombre, identificación)
- Paginación server-side con metadatos
- Ordenamiento por columnas
Eventos de Dominio
- Eventos de Dominio: Sistema de eventos para automatización
- MiembroBajaEvent: Dispara eliminación automática del grupo familiar
- MiembroReactivacionEvent: Notifica a sistemas externos
- FacturacionLoteProcesadaEvent: Dispara notificaciones y sincronización
- Listeners con orden de ejecución definido
- Desacoplamiento entre componentes
- Extensibilidad sin modificar código existente
Integraciones con Módulos
- Integraciones: Conexiones con otros módulos
- Integración con Ventas: Enriquecimiento de productos con extensión de membresía
- Integración con CtaCte: Validación de cupones contra facturación
- Consultas optimizadas entre módulos
- Mantiene aislamiento multi-tenant
Caché y Optimizaciones
- Caché y Optimizaciones: Performance del sistema
- Caché tenant-aware de categorías y disciplinas
- TTL configurable
- Invalidación automática en operaciones CUD
- Batch loading de datos relacionados
- Reducción de N+1 queries a consultas constantes
- Mapeo eficiente de resultados
Validaciones Cross-Cutting
- Validaciones y Reglas de Negocio: Reglas transversales
- Categoría defecto única (auto-reset)
- Miembro principal único por grupo (con replacement validator)
- Condición de venta fija para facturación (CCC 30 días)
- Baja con grupo familiar (designación de titular)
Estadísticas de Facturación
- Estadísticas de Facturación: Reportes agregados
- Total procesados, exitosos, errores, omitidos
- Monto total facturado
- Cantidad de comprobantes generados
- Errores ARCA agrupados por tipo
- Detalle por socio con estado y razón
Documentación OpenAPI
- Documentación OpenAPI: Especificación automática
- Generación automática OpenAPI 3.0.3
- 7 recursos documentados (miembros, disciplinas, categorías, tipos, grupos, bulk, facturación)
- Schemas de Request/Response
- Ejemplos de uso
- Tipos de error
- Arquitectura modular por recurso
Arquitectura de Enriquecimiento
Sistema de Scopes
Scope 'min'
Carga solo datos básicos del miembro:
- ID, nombre, identificación
- Datos de contacto básicos
- No incluye relaciones
Scope 'max'
Carga completa con todas las relaciones:
- Categoría de membresía
- Disciplinas asignadas (con marca de principal)
- Productos asignados (con ajustes de precio)
- Grupo familiar (si pertenece)
Include Tree
El enriquecimiento funciona con un árbol de inclusiones:
Miembro (scope: max)
├── Categoría
│ └── Producto
├── Disciplinas[]
│ ├── Disciplina
│ └── Producto
├── Productos[]
│ ├── Producto
│ └── Ajuste (signo, tipo, valor)
└── GrupoFamiliar
├── ID del grupo
├── Tipo de relación
└── Es principalBatch Loading
Para evitar N+1 queries, se usa batch loading:
php
// En lugar de:
foreach ($miembros as $miembro) {
$categoria = getCategoriaById($miembro->categoria_id); // N queries
}
// Se hace:
$categoriaIds = array_map(fn($m) => $m->categoria_id, $miembros);
$categorias = getCategoriasByIds($categoriaIds); // 1 query
$miembrosEnriquecidos = mapCategorias($miembros, $categorias);Sistema de Eventos de Dominio
Arquitectura
mermaid
graph LR
A[Acción de Usuario] --> B[Service]
B --> C[Modelo]
C --> D[Base de Datos]
B --> E[Dispatcher]
E --> F[MiembroBajaEvent]
E --> G[MiembroReactivacionEvent]
E --> H[FacturacionLoteProcesadaEvent]
F --> I[RemoveMiembroFromGrupoListener]
G --> J[ActualizarSistemasExternosListener]
H --> K[EnviarNotificacionesListener]
H --> L[ActualizarSistemasExternosListener]Eventos Implementados
1. MiembroBajaEvent
- Cuándo: Al dar de baja un miembro
- Payload: ID del miembro, fecha de baja, motivo
- Listeners:
RemoveMiembroFromGrupoListener: Elimina del grupo familiar
2. MiembroReactivacionEvent
- Cuándo: Al reactivar un miembro
- Payload: ID del miembro
- Listeners:
ActualizarSistemasExternosListener: Notifica a sistemas externos
3. FacturacionLoteProcesadaEvent
- Cuándo: Al completar facturación por lotes
- Payload: Estadísticas, lista de facturas generadas
- Listeners (en orden):
EnviarNotificacionesListener: Envía emails/SMS a sociosActualizarSistemasExternosListener: Sincroniza con ERP externo
Beneficios del Sistema de Eventos
- Desacoplamiento: La baja de miembro no conoce el grupo familiar
- Extensibilidad: Agregar listeners sin modificar código existente
- Auditoría: Los eventos quedan registrados en logs
- Orden garantizado: Los listeners se ejecutan en orden definido
- Transaccionalidad: Los listeners pueden participar en la transacción
Integraciones con Otros Módulos
Ventas: Enriquecimiento de Productos
Cuando Ventas consulta un producto con scope 'max':
mermaid
sequenceDiagram
participant V as Ventas
participant PS as ProductoService
participant MS as MembresiaService
V->>PS: getProducto(id, scope: max)
PS->>PS: Obtener datos base
PS->>MS: getExtensionMembresia(productoId)
MS-->>PS: {signo, tipo, valor}
PS-->>V: Producto + ExtensiónCtaCte: Validación de Cupones
Cuando CtaCte valida un cupón de pago:
mermaid
sequenceDiagram
participant C as CtaCte
participant CV as CuponValidacionService
participant MF as MembresiaFacturacion
C->>CV: validarCupon(codigo)
CV->>CV: Decodificar código
CV->>CV: Verificar DV
CV->>MF: buscarFactura(cliente, periodo)
MF-->>CV: Factura pendiente
CV-->>C: Datos validadosSistema de Caché Tenant-Aware
Estructura de Caché
Cache Key: membresia:categorias:{schema_id}:all
TTL: 3600 segundos (configurable)Invalidación Automática
php
// Al crear/actualizar/eliminar categoría:
1. Ejecutar operación en DB
2. Invalidar caché: cache->delete("membresia:categorias:{schema}:all")
3. Siguiente consulta recargará desde DBAislamiento Multi-Tenant
Cada tenant tiene su propia entrada en caché:
- Schema 'suc0001':
membresia:categorias:suc0001:all - Schema 'suc0002':
membresia:categorias:suc0002:all
Evita contaminación de datos entre tenants.
Validaciones Cross-Cutting
1. Categoría Defecto Única
php
// Al marcar categoría como defecto:
if ($nuevaCategoria->es_defecto) {
// Resetear todas las demás
UPDATE categorias SET es_defecto = false WHERE id != $nuevaCategoria->id;
// Marcar la nueva
UPDATE categorias SET es_defecto = true WHERE id = $nuevaCategoria->id;
}2. Miembro Principal Único
php
// Al agregar miembro a grupo:
if ($tipoRelacion->es_principal) {
$principalExistente = grupoFamiliar->getMiembroPrincipal();
if ($principalExistente) {
throw new ValidationException("Ya existe un miembro principal");
}
}3. Condición de Venta Fija
php
// En facturación por lotes:
const CONDICION_VENTA = 'CCC'; // Hardcoded
const DIAS_PLAZO = 30; // Hardcoded
// No configurable, regla de negocio fija4. Baja con Grupo Familiar
php
// Al dar de baja miembro:
if ($miembro->grupo_familiar_id) {
if ($miembro->es_principal) {
if (!$request->nuevo_titular_id) {
throw new ValidationException("Debe designar nuevo titular");
}
}
}
// Evento elimina del grupo automáticamente
dispatch(new MiembroBajaEvent($miembro->id));Estadísticas de Facturación
Estructura de Estadísticas
typescript
{
stats: {
total: 150, // Total procesados
exitosos: 140, // Facturas OK
errores: 5, // Errores
omitidos: 5, // Deuda cero
monto_total: 450000.00, // Total facturado
comprobantes: 140, // Cantidad de facturas
errores_arca: {
"1001": {
count: 3,
mensaje: "CUIT inválido"
},
"2005": {
count: 2,
mensaje: "CAE expirado"
}
}
}
}Uso
El modal de resultados consume estas estadísticas para:
- Mostrar métricas agregadas con badges de color
- Tabla de errores ARCA agrupados
- Detalle por socio con estado y razón
Documentación OpenAPI
Recursos Documentados
Miembros (
/mod-membresia/miembros)- CRUD completo
- Reactivación
- Disciplinas del miembro
- Productos del miembro
Categorías (
/mod-membresia/categorias)- CRUD completo
- Asignación masiva
Disciplinas (
/mod-membresia/disciplinas)- CRUD completo
Tipos de Relación (
/mod-membresia/tipo-relacion)- CRUD completo
Grupos Familiares (
/mod-membresia/grupo-familiar)- Ver grupo, resumen, por miembro
- Crear, agregar, actualizar, eliminar
Operaciones Bulk (
/mod-membresia/bulk)- Asignación/eliminación masiva de productos
Facturación (
/mod-membresia/comprobantes)- Facturación por lotes
Arquitectura Modular
Cada recurso tiene su propio servicio de documentación:
MiembrosOpenApiServiceCategoriasOpenApiServiceDisciplinasOpenApiService- etc.
El MembresiaOpenApiService orquesta todos los servicios individuales.
Schemas Comunes
yaml
components:
schemas:
MiembroResource:
type: object
properties:
id: integer
nombre: string
identificacion: string
# ...
ErrorResponse:
type: object
properties:
error:
type: string
message:
type: stringDependencias
Funcionalidades que Usan estas Herramientas
Todas las funcionalidades del módulo de membresías dependen de:
- Enriquecimiento (para cargar datos relacionados)
- Eventos (para automatización)
- Integraciones (para interoperar con otros módulos)
- Caché (para performance)
- Validaciones (para integridad de datos)
Tecnologías Utilizadas
- PHP 8.2+: Características modernas del lenguaje
- Doctrine DBAL: Para queries optimizadas
- PSR-14: Estándar de eventos
- PSR-6: Estándar de caché
- OpenAPI 3.0.3: Especificación de API
Consideraciones de Performance
Enriquecimiento
- Use scope 'min' cuando no necesite relaciones
- Use scope 'max' solo cuando sea necesario
- El batch loading optimiza automáticamente las queries
Caché
- Las categorías y disciplinas se cachean automáticamente
- La invalidación es automática en operaciones CUD
- TTL configurable según necesidades
Eventos
- Los listeners se ejecutan síncronamente
- Para operaciones pesadas, considerar listeners asíncronos
- Orden de ejecución garantizado
Estadísticas
- 7 documentos de requisitos de negocio
- 59 criterios de aceptación (todos implementados)
- 19 reglas de negocio
- 17 casos de uso detallados
- Herramientas transversales a todo el módulo
Estado
✅ Implementado - Todas las funcionalidades están en producción
Última actualización: 2026-01-27