14 · Arquitectura, estilo de programación y SQL configurable

◀ Volver al índice

Este capítulo resume las reglas técnicas con las que evoluciona Factuzam. Está dirigido a desarrollo, soporte avanzado e implantadores. La referencia completa del repositorio se mantiene en LIBRO_DE_ESTILO_DELPHI.md, LIBRO_DE_ESTILO_BBDD.md, PLAN_SOLID.md y MANUAL_SQL_PERFILES.md.


1. Estilo de programación

Factuzam está escrito en Object Pascal/Delphi VCL y prioriza código legible, predecible y compatible con su base instalada.

Reglas principales:

Los cambios de base de datos se entregan como scripts idempotentes en DESARROLLOS EN CURSO/. El dump factuzam_original.sql no se modifica.


2. SOLID aplicado de forma progresiva

Factuzam está migrando por fascículos desde un núcleo legado hacia una arquitectura SOLID. No se presenta como una reescritura terminada: cada extracción fija primero el comportamiento con pruebas y reduce el acoplamiento sin mezclar cambios funcionales.

Principio Aplicación en Factuzam
SRP — responsabilidad únicaEl formulario coordina la interfaz, el data module persiste y las librerías ejecutan reglas de negocio. Las responsabilidades grandes se extraen a colaboradores TGestor* o servicios específicos.
OCP — abierto/cerradoLas variaciones de compra, venta, impresión o documento se modelan con configuración y estrategias, evitando copiar formularios completos para cada caso.
LSP — sustituciónLas clases base publican contratos y hooks coherentes; se evita ampliar una base cuando sus descendientes tendrían que anular el comportamiento con métodos vacíos.
ISP — interfaces pequeñasCada consumidor recibe solo la capacidad que necesita. Las interfaces propias son pequeñas, tienen GUID y se agrupan únicamente cuando comparten una misma implementación.
DIP — inversión de dependenciasEl dominio depende de contratos inLib*Intf; las implementaciones UniDAC se crean fuera y se inyectan desde la raíz de composición.

La secuencia de un fascículo es: prueba que fija el comportamiento, extracción de una responsabilidad, compilación Win32/Win64, batería DUnitX y comprobación de los trinquetes automáticos de arquitectura.


3. Capas y dirección de dependencias

fzam.dpr / Core (composición)
            |
            v
Forms / Modals (presentación y coordinación)
            |
            v
UniData* (persistencia) ---> inLib* (dominio y colaboradores)
                                  |
                                  v
                            inLib*Intf (contratos)
Capa Responsabilidad
Core / composiciónCrea conexiones, repositorios, servicios y formularios; conecta implementaciones con contratos.
Forms / ModalsMuestra datos, solicita confirmaciones, coordina pestañas y traduce resultados de negocio a acciones visuales.
UniData / DataModulesConsulta y persiste mediante UniDAC, controla datasets y límites transaccionales.
inLibCálculos, validaciones, transformaciones, orquestadores y colaboradores reutilizables.
**inLib*Intf**Interfaces y tipos estables sin dependencias de VCL, formularios o implementaciones de persistencia.

Una librería de dominio no crea un repositorio, no conoce un formulario y no obtiene una conexión global. Recibe por constructor o parámetro el contrato que necesita. Las conexiones, la identidad y las credenciales tienen propietario y ciclo de vida explícitos.

Las escrituras que afectan a varias tablas son atómicas: respetan una transacción existente o realizan Commit/Rollback en el mismo nivel. Los hilos no comparten datasets ni conexiones con la interfaz.


4. Consultas SQL configurables y consultables

El catálogo SQL por perfiles permite corregir determinadas consultas de lectura sin recompilar ni sustituir fzam.exe. El dominio solicita una operación de negocio a un repositorio; la implementación de persistencia elige entre:

  1. El SQL base, incluido y probado con el ejecutable.
  2. Un SQL personalizado activo en fza_usuarios_perfiles.

El dominio no recibe texto SQL y no ofrece un método genérico Ejecutar(SQL). Cada operación mantiene una clave estable con la forma:

KEY_USUPER    = SQL_REPOSITORIOS
SUBKEY_USUPER = SQL__Repositorio__Operacion

Activación por pantalla

La propiedad de perfil oGetSQLFromDB activa el catálogo para cada formulario consumidor. Al abrir la pantalla:

  1. Factuzam carga las definiciones del catálogo compartido.
  2. Publica las operaciones base que todavía falten, sin sobrescribir una personalización existente.
  3. Resuelve cada lectura contra el perfil activo o contra el SQL base.

Desactivar el interruptor en un formulario no cambia los demás consumidores de la misma operación.

El inventario de unidades que leen el interruptor, publican perfiles o aportan definiciones al catálogo, junto con el recorrido histórico de los data modules, está en MANUAL_SQL_PERFILES.md.

Validación y fallback seguro

Antes de ejecutar una personalización se comprueba que:

Si la validación falla, la consulta personalizada se descarta, se registra la causa y se ejecuta el SQL base. Si pasa la validación pero falla al abrir o devuelve una estructura incorrecta, Factuzam reintenta una vez con el SQL base. Si también falla la base, el error se muestra de forma normal.

Las escrituras no usan este reintento automático: cualquier futura personalización de escritura debe estar protegida por transacción y hacer Rollback antes de cambiar de implementación.

Revisión, auditoría y vuelta atrás

El administrador del catálogo permite publicar, revisar y exportar las definiciones base y de perfil. La revisión muestra estado, política, versión, huellas, validación y última causa de fallback. Cada fila guarda además instante y usuario de modificación.

Para volver inmediatamente al comportamiento incluido en el ejecutable se puede:

  1. Desactivar una operación cambiando su estado de S a N.
  2. Eliminar únicamente su fila personalizada.
  3. Establecer oGetSQLFromDB=False para toda la pantalla.

No es necesario desplegar otro ejecutable. Antes de editar una consulta se hace copia del SQL y de sus metadatos; nunca se cambian los parámetros ni los alias exigidos por el contrato.


5. Pruebas y reglas de no regresión

La finalidad es que cada mejora deje una barrera automática que el código posterior no pueda volver a cruzar.


◀ Aplicaciones móviles · Índice · Siguiente ▶ Integración con PrestaShop