Appearance
Arquitectura General del Sistema Bautista
Esta guía describe la arquitectura general del sistema Bautista, incluyendo decisiones arquitectónicas, patrones de diseño y principios utilizados en todo el proyecto.
Visión General del Sistema
El Sistema Bautista es una aplicación empresarial de gestión administrativa que abarca múltiples módulos de negocio, incluyendo ventas, compras, tesorería, contabilidad, stock y CRM.
Características Principales
- Multi-tenancy: Soporte para múltiples empresas
- Modular: Arquitectura basada en módulos independientes
- Escalable: Diseño preparado para crecimiento
- Seguro: Autenticación, autorización y auditoría completa
- REST API: Backend expone API RESTful para frontend
Arquitectura de Alto Nivel
┌─────────────────────────────────────────────────────┐
│ FRONTEND │
│ (Legacy PHP SSR / Futuro: SPA moderno) │
│ │
│ • Views (PHP Templates) │
│ • JavaScript (Vanilla/jQuery) │
│ • AJAX calls to API │
└────────────────┬────────────────────────────────────┘
│
│ HTTP/REST (JSON)
│
┌────────────────▼────────────────────────────────────┐
│ BACKEND (PHP) │
│ │
│ ┌───────────────────────────────────────────────┐ │
│ │ API Layer (Routes + Controllers) │ │
│ └───────────────────┬───────────────────────────┘ │
│ │ │
│ ┌───────────────────▼───────────────────────────┐ │
│ │ Service Layer (Business Logic) │ │
│ └───────────────────┬───────────────────────────┘ │
│ │ │
│ ┌───────────────────▼───────────────────────────┐ │
│ │ Model Layer (Data Access) │ │
│ └───────────────────┬───────────────────────────┘ │
└─────────────────────┬───────────────────────────────┘
│
│ PDO/SQL
│
┌─────────────────────▼───────────────────────────────┐
│ DATABASE (MySQL/PostgreSQL) │
│ │
│ • Tablas por módulo │
│ • Multi-tenancy schema │
│ • Auditoría │
└─────────────────────────────────────────────────────┘Decisiones Arquitectónicas
1. Arquitectura en Capas (Layered Architecture)
Decisión: Separar el sistema en capas bien definidas (API, Service, Model, Database).
Razones:
- Separación de responsabilidades: Cada capa tiene un propósito claro
- Testeable: Capas pueden testearse independientemente
- Mantenible: Cambios en una capa no afectan otras
- Escalable: Permite escalar capas individualmente
Trade-offs:
- Mayor complejidad inicial
- Más archivos y clases
2. REST API para Backend
Decisión: Backend expone API REST JSON independiente del frontend.
Razones:
- Desacoplamiento: Frontend y backend pueden evolucionar independientemente
- Multi-plataforma: API puede ser consumida por web, mobile, integraciones
- Estándar: REST es ampliamente conocido y soportado
Alternativas consideradas:
- GraphQL: Rechazado por complejidad adicional
- SOAP: Rechazado por ser menos flexible
3. Soft Delete por Defecto
Decisión: Usar soft delete (deleted_at) en lugar de eliminación física.
Razones:
- Auditoría: Mantiene historial completo
- Recuperación: Permite restaurar registros eliminados
- Integridad referencial: Evita problemas con foreign keys
Implementación:
sql
WHERE deleted_at IS NULL -- Solo registros activos4. DTOs (Data Transfer Objects)
Decisión: Usar DTOs para transferir datos entre capas.
Razones:
- Type Safety: Propiedades tipadas en PHP 8+
- Validación: Validación centralizada en DTOs
- Documentación: Estructura de datos clara
- Transformación: Fácil mapeo de base de datos a API
Ejemplo:
php
class BoniretDTO extends FullDto
{
public function __construct(
public ?int $id,
public string $nombre,
public int $cuenta,
public ?float $valor,
public string $tipo,
public bool $impser,
public bool $acumula
) {}
}5. Dependency Injection (DI)
Decisión: Usar inyección de dependencias para gestionar dependencias.
Razones:
- Testeable: Fácil mockar dependencias en tests
- Desacoplamiento: Clases no crean sus propias dependencias
- Configuración centralizada: Container gestiona instancias
Ejemplo:
php
public function __construct(
private BoniretService $service,
private AuditLogger $logger
) {}6. Service Layer Pattern
Decisión: Toda lógica de negocio reside en Services, no en Controllers ni Models.
Razones:
- Reutilización: Lógica puede ser llamada desde múltiples Controllers
- Testing: Lógica de negocio testeable sin HTTP
- Transacciones: Services gestionan transacciones completas
- Separación: Controllers solo manejan HTTP, Services manejan negocio
7. Validación en Múltiples Capas
Decisión: Validar datos en diferentes capas:
- Validator classes (estructura/tipos)
- Service layer (reglas de negocio)
- Database (constraints)
Razones:
- Defensa en profundidad: Múltiples puntos de validación
- Mensajes específicos: Cada capa puede dar feedback apropiado
- Separación de concerns: Validación estructural vs. lógica de negocio
8. Auditoría Integral
Decisión: Registrar todas las operaciones CUD (Create, Update, Delete).
Razones:
- Trazabilidad: Saber quién hizo qué y cuándo
- Cumplimiento: Requisitos regulatorios
- Debugging: Facilita encontrar origen de cambios
Implementación:
php
$this->registrarAuditoria(
"INSERT",
"BONIRET",
"boniret",
$id
);9. Transaction Management
Decisión: Services gestionan transacciones de base de datos explícitamente.
Razones:
- Consistencia: Operaciones múltiples son atómicas
- Rollback: Fácil deshacer cambios en caso de error
- Control: Service decide límites de transacción
Patrón:
php
$this->connections->beginTransaction('oficial');
try {
// Operaciones
$this->connections->commit('oficial');
} catch (Exception $e) {
$this->connections->rollback('oficial');
throw $e;
}10. Organización Modular
Decisión: Organizar código por módulo de negocio, no por tipo técnico.
Estructura:
/controller/modulo-venta/
/models/modulo-venta/
/service/Venta/Razones:
- Cohesión: Todo lo relacionado a un módulo está junto
- Escalabilidad: Módulos pueden crecer independientemente
- Claridad: Fácil encontrar código relacionado
Patrones de Diseño Utilizados
1. MVC (Model-View-Controller)
Aunque modificado para API:
- Model: Acceso a datos
- View: JSON responses (no templates)
- Controller: Maneja requests HTTP
2. Repository Pattern (Implícito)
Models actúan como repositories:
- Encapsulan acceso a datos
- Abstraen queries SQL
- Retornan DTOs
3. Service Layer Pattern
Services contienen lógica de negocio:
- Coordinan múltiples Models
- Aplican reglas de negocio
- Gestionan transacciones
4. Factory Pattern (en Container)
Container DI usa factories para crear instancias:
- Gestiona dependencias
- Permite configuración flexible
- Lazy loading
5. Strategy Pattern
Usado en algunos módulos (ej: facturación electrónica):
- Comportamientos intercambiables
- Fácil agregar proveedores nuevos
Principios de Diseño
SOLID Principles
S - Single Responsibility:
- Controllers: solo HTTP
- Services: solo lógica de negocio
- Models: solo acceso a datos
O - Open/Closed:
- Extendible via herencia
- Configuración via DI
L - Liskov Substitution:
- DTOs intercambiables
- Interfaces respetadas
I - Interface Segregation:
- Interfaces pequeñas y específicas
- No forzar métodos innecesarios
D - Dependency Inversion:
- Dependencias inyectadas
- Programar a interfaces, no implementaciones
DRY (Don't Repeat Yourself)
- Reutilización de código via Services
- Traits para comportamiento compartido
- Helper functions para operaciones comunes
KISS (Keep It Simple, Stupid)
- Soluciones simples preferidas
- Evitar over-engineering
- Código claro y directo
Seguridad
Autenticación
- JWT (JSON Web Tokens)
- Token en header
Authorization: Bearer {token} - Expiración configurable
- Refresh tokens
Autorización
- RBAC (Role-Based Access Control)
- Permisos granulares:
MODULO_RECURSO_ACCION - Verificación en cada endpoint
- Control a nivel de UI y API
Protecciones
- SQL Injection: Prepared statements siempre
- XSS: Sanitización de output
- CSRF: Tokens CSRF en formularios
- Rate Limiting: (pendiente implementación)
- Input Validation: Validación exhaustiva
Multi-Tenancy
Enfoque
- Shared Database, Shared Schema
- Columna
schemaen tablas relevantes - Conexión
oficialcomo principal
Aislamiento
- Queries siempre filtran por empresa
- Middleware verifica empresa del usuario
- Datos completamente aislados
Performance
Database Optimization
- Índices: En columnas frecuentemente consultadas
- Foreign Keys: Para integridad referencial
- Soft Delete Index: En
deleted_at
Caching (Futuro)
Preparado para:
- Synfony cache
- Cache a nivel de Service
- Invalidación automática
Query Optimization
- Evitar N+1 queries
- Usar joins apropiadamente
- Limitar resultados
Escalabilidad
Horizontal Scaling
Sistema preparado para:
- Múltiples instancias de backend
- Load balancer
- Sesiones en base de datos (no en memoria)
Vertical Scaling
- Database indexing
- Connection pooling
- Optimización de queries
Observabilidad
Logging
- Audit Log: Operaciones de negocio
- Error Log: Errores y excepciones
- Access Log: Requests HTTP
Monitoring (Futuro)
Preparado para:
- APM (Application Performance Monitoring)
- Health checks
- Métricas de negocio
Testing Strategy
Levels of Testing
- Unit Tests: Services, Validators, Models
- Integration Tests: Service + Model + Database
- API Tests: End-to-end via HTTP
- Manual QA: Testing de interfaz usuario
Test Coverage Goals
- Services: 100%+ coverage
- Validators: 100% coverage
- Models: 100%+ coverage
Deployment
Environments
- Development: Local development
- Staging: Pre-production testing
- Production: Live environment
CI/CD (Futuro)
Preparado para:
- Automated tests en CI
- Automated deployment
- Database migrations automatizadas
Evolución Futura
Modernización Frontend
Estado actual: ✅ Ya iniciada y en producción
El sistema está en migración activa hacia React SPA:
Completado:
- ✅ Proyecto React independiente
- ✅ Módulo Membresía desarrollado en React completamente (ver rama
feature/modulo-membresia) - ✅ Arquitectura híbrida funcionando (Legacy PHP + React SPA coexistiendo)
- ✅ Comunicación via API REST establecida
- ✅ Autenticación JWT implementada
En progreso:
- Migración incremental de módulos adicionales
- Componentes compartidos y reutilizables
- Gestión de estado centralizada
Próximos pasos:
- Migrar módulos restantes según prioridad de negocio
- Consolidar componentes compartidos
- Eventual deprecación completa de Legacy PHP
Microservices (Consideración)
Si el sistema crece significativamente:
- Separar módulos en servicios independientes
- API Gateway
- Event-driven architecture
GraphQL (Consideración)
Alternativa a REST si:
- Necesidad de queries flexibles
- Reducir over-fetching
- Múltiples clientes con necesidades diferentes
Documentación
Niveles de Documentación
- Arquitectura (este documento)
- Backend (ver backend/index.md)
- Frontend (ver frontend/index.md)
- Features (ver features/index.md)
Mantener Documentación
- Actualizar al hacer cambios arquitectónicos
- Documentar decisiones importantes
- Incluir trade-offs considerados
Decisiones Arquitectónicas por Documento
| Documento | Alcance | Estado |
|---|---|---|
| Consolidación Informes Multi-Schema | Reportes consolidados multi-sucursal | En Uso |
| Operaciones Transaccionales Multi-Schema | Consulta/eliminación/modificación cross-schema | Planificado |
| Integración QZ Tray — Impresión Directa | Impresión silenciosa via QZ Tray | Propuesto |
Referencias
Principio fundamental: Mantener el sistema simple, mantenible y escalable, siguiendo principios SOLID y patrones establecidos.
Última actualización: 2025-12-09