JP Consultoría

Transformación digital y cultural a la medida

  • En muchos proyectos te encuentras retos inesperados tras hacer la toma de requisitos. Parte de lo bonito de nuestra profesión es afrontarlos y superarlos, pero claro, esto aumenta el trabajo a realizar.

    En nuestro mayor proyecto hasta la fecha, la Reingeniería del Sistema interno de Grupo Kineret SA, se buscaba actualizar el sistema sustituyendo módulos desarrollados varias tecnologías (Coldfusion, VisualFox, ASP.NET, vb.net) cada uno con su bases de datos, por un sistema integrado con una sola tecnología (vb.net) y una única base datos.

    El primer paso consistía en la integración y rediseño de bases de datos.

    Estado previo:

    • Diferentes módulos accediendo cada uno a una base de datos propia (4 bases de datos).
    • Algunas de las tablas de las bases de datos propias con pequeñas sincronizaciones.
    • Varios cientos de tablas, la mayoría con decenas de columnas.
    • Desarrollo largo (finalmente, tras varios aumentos en el alcance) unos dos años y medio.
    • Requisito de liberación paulatina de cada desarrollo (ir liberando módulos dejando todos los demás perfectamente operativos).

    Requisitos integración y sincronización de las bases de datos:

    • Algunos cambios en el diseño de las tablas (varias normalizaciones e integraciones de información).
    • Todos los nombres de tabla diferentes (estandarización).
    • Todos los nombres de las columnas diferentes (estandarización).
    • Algunas claves primarias se modificarían (integraciones de información y mejoras).
    • Mantener la sincronización ACID.
    • Modificaciones masivas.

    De la mano con el departamento de TI de Kineret (área con bastante músculo), tras analizar las opciones de sincronización que nos ofrecía el motor utilizado (SQL Server 2008 R2), se decidió que la única opción era hacer la sincronización a través de disparadores de tabla a tabla. Evidentemente esta solución nos aumentaba el nivel de carga en el servidor durante el periodo de desarrollo, pero era la única forma de cumplir los requisitos.

    Esta solución implicaba realizar 6 disparadores por tabla, uno para inserciones, uno para modificaciones y otro para borrados, a ambos extremos de la sincronización:

    • Cada disparador debe insertar, actualizar o borrar la información equivalente en el otro extremo a partir de los datos en las tablas «inserted» y «deleted».
    • En los casos de modificación de tabla primaria necesitamos generar tablas intermedias.
    • Hay que evitar revotes en estos disparadores (controlar al principio su nivel de anidamiento para que no se ejecuten más que una vez).
    • Modificaciones masivas: la mejor forma para realizar las modificaciones fue generado los insert, update y delete haciendo inner joins entre la tabla origen, la tabla inserted o deleted, apuntando la acción a la tabla destino. De esta forma se ejecuta bien tanto las modificaciones sobre una fila, como sobre varias.
    • Deshabilitar todos estos disparadores fácilmente (estandarizamos los nombres con un prefijo que nos permitía simplemente deshabilitarlos haciendo un recorrido automático).

    Formato SQL inserción:

    INSERT INTO rutaCompletaTabla (col1,col2,….)
    select col1,col2,… from inserted

    Formato SQL actualización:

    UPDATE destino
    SET  destino.ch_col1 = i.col1,  destino.col2 = i.col2, …
    FROM INSERTED i
    INNER JOIN rutaCompletaTabla destino ON  destino.col1PK = i.col1PK …

    Formato SQL borrado:

    DELETE destino FROM DELETED d
    INNER JOIN rutaCompletaTabla destino ON destino.col1PK = d.col1PK …

    Generador de código

    Escribir manualmente todos estos disparadores sin errores nos hubiese llevado una barbaridad de tiempo, por lo que decidimos desarrollar un generador de código, el cual requería una tabla con la ruta completa de cada tabla y columna de ambos extremos de la sincronización, y tenía las siguientes funciones:

    • Carga de datos.
    • Generación de disparadores.

    En este tipo de tareas siempre me acuerdo de esta imagen:

    Original de Bruno Oliveira
    Original de Bruno Oliveira

    El generador bien alimentado nos automatizó la generación de toda la sincronización entre las tablas sin cambios entre claves primarias, y su carga de datos. Y su código generado nos servía como base para modificar las que necesitasen una tabla intermedia para la sincronización, o una carga diferente por la integración de información o modificaciones en el diseño.

    De no ser por el desarrollo de este generador, el tiempo de desarrollo se hubiese disparado por culpa de algo invisible para los usuarios (siempre es más complicado de justificar).

  • Además de proyectos directos para clientes, también dedicamos tiempo a desarrollo propios. En este caso un Sistema de Administración de Propiedades Inmobiliarias con las siguientes características:

    • Administración de propiedades:
      • Terrenos
      • Edificios
      • Locales comerciales
      • Viviendas
      • Almacenes
      • Etc.
    • Administración de entidades:
      • Arrendatarios
      • Compradores
      • Operadores
      • Propietarios
      • Proveedores
    • Administración de mantenimientos
    • Control de gastos e ingresos

    Nos hemos planteado el desarrollo de una aplicación Web (para disponible de acceso multidispositivo y multiplataforma) y un entorno de desarrollo flexible, rápido y moderno. Se decidió realizar el desarrollo sobre Grails, un metaframework de código libre para el desarrollo rápido de aplicaciones Web basado en la convención sobre la configuración, que corre sobre la JVM, y sustentando en solventes tecnologías como:

    Para la maquetación general y la definición de estilos visuales estamos utilizando el framework Twitter Bootstrap. Como gestor de control de versiones de código utilizamos Git (GitFlow como flujo de trabajo), y tenemos el repositorio principal alojado en Bitbucket.

  • Según la Wikipedia, un código QR es:

    …(quick response code, «código de respuesta rápida») es un módulo útil para almacenar información en una matriz de puntos o un código de barras bidimensional…

    Un código QR puede contener una dirección Web, un texto, un teléfono, o incluso un Vcard (nombre, empresa, dirección, teléfono, email y web).

    Hace años que se inventaron (1994), y hace ya bastante tiempo que se pueden utilizar desde dispositivos móviles (accesibles para el público en general), pero nunca ha conseguido un uso real. La mayoría de usuarios desconocen lo que son, o como escanearlos. La mejor forma de que su uso se generalice sería que la aplicación nativa de los celulares los interprete.

    Como ejemplo, hemos creado el siguiente código QR que contiene un Vcard con la información de contacto de JPicado y Asociados:

    qr_contacto
    Contacto JPicado y Asociados

    Utilizando la cámara de nuestro celular, a través de una aplicación que lea códigos QR, podemos guardar automáticamente la información en nuestra agenda, o realizar una acción con la información (realizar una llamada, enviar un email, visitar una Web, etc.).

    Aplicaciones para leer códigos QR

    Basta con acceder a la tienda de aplicaciones de cualquier de plataforma y buscar «qr code» para encontrar bastantes aplicaciones con esta funcionalidad (muchas de ellas gratuitas).