Skip to content

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 activos

4. 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 schema en tablas relevantes
  • Conexión oficial como 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

  1. Unit Tests: Services, Validators, Models
  2. Integration Tests: Service + Model + Database
  3. API Tests: End-to-end via HTTP
  4. 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

  1. Arquitectura (este documento)
  2. Backend (ver backend/index.md)
  3. Frontend (ver frontend/index.md)
  4. 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

DocumentoAlcanceEstado
Consolidación Informes Multi-SchemaReportes consolidados multi-sucursalEn Uso
Operaciones Transaccionales Multi-SchemaConsulta/eliminación/modificación cross-schemaPlanificado
Integración QZ Tray — Impresión DirectaImpresión silenciosa via QZ TrayPropuesto

Referencias


Principio fundamental: Mantener el sistema simple, mantenible y escalable, siguiendo principios SOLID y patrones establecidos.


Última actualización: 2025-12-09