Con qué construimos, y por qué cada cosa.

Esto no es una lista de modas ni de logos bonitos: es el stack exacto con el que están hechos y corriendo nuestros cuatro productos. Al lado de cada tecnología te decimos en qué producto la usamos y por qué la elegimos — porque elegir mal aquí se paga durante años.

01 Stack por producto

Cuatro productos, dos ecosistemas.

No somos una tienda de una sola tecnología. Trabajamos a fondo en .NET y en Node, y elegimos según el problema y según el equipo que va a mantener el sistema después — no según lo que nos resulte más cómodo.

El stack real de cada producto
Producto Backend Frontend Móvil Base de datos
ResiHub NestJS · TypeORM React · Ant Design React Native · Expo PostgreSQL
Billium ASP.NET Core · Clean + CQRS Next.js · Tailwind PostgreSQL
Cliento CRM NestJS · TypeORM React · Ant Design · Vite PostgreSQL
TalentUs ASP.NET Core · EF Core Angular · Material SQL Server

Ecosistema .NET 2 productos

Cuando el cliente ya vive en Microsoft, cuando hay SQL Server de por medio, o cuando el equipo interno que va a heredar el sistema programa en C#.

  • Tipado fuerte y un compilador que atrapa mucho antes de producción.
  • Entity Framework Core con migraciones sólidas.
  • Ecosistema maduro para lo aburrido pero crítico: firma digital X.509, validación XSD, jobs en segundo plano.
  • Es lo que sostiene la conformidad DGII de Billium.
  • ASP.NET Core
  • C#
  • EF Core
  • SQL Server
  • Hangfire

Ecosistema Node 2 productos

Cuando hay app móvil de por medio, cuando se necesita tiempo real, o cuando conviene que backend y frontend compartan tipos y lenguaje.

  • Un solo lenguaje de la base de datos a la app: TypeScript en todo el camino.
  • NestJS impone estructura y sostiene un sistema que cubre 61 áreas de gestión.
  • Tiempo real con Socket.io sin pelear contra el framework.
  • Comparte tipos con React y React Native.
  • NestJS
  • TypeScript
  • TypeORM
  • PostgreSQL
  • Socket.io

02 Backend

Donde vive la lógica de negocio.

Es la parte que nadie ve y la que decide si el sistema aguanta. Aquí no experimentamos: usamos frameworks maduros, con estructura impuesta, que otro equipo pueda retomar.

ASP.NET Core

El compilador atrapa clases enteras de errores antes de que lleguen a producción. Insuperable para lo crítico y aburrido: firma digital X.509, validación contra XSD y criptografía.

Se usa en Billium TalentUs

NestJS

Impone una estructura modular desde el día uno. Es lo que permite que ResiHub tenga 61 áreas de gestión sin convertirse en un plato de espagueti.

Se usa en ResiHub Cliento

TypeScript

Estricto

Todo lo que corre en Node lo escribimos tipado. El tipo que define una factura es el mismo en el backend, en el panel y en la app móvil.

Se usa en ResiHub Cliento Billium

Clean Architecture

Patrón

Las reglas de negocio no dependen de la base de datos ni del framework. Cambiar de proveedor no obliga a reescribir el dominio.

Se usa en Billium TalentUs

CQRS

Patrón

Separar lectura de escritura. En facturación importa: emitir un comprobante y consultarlo tienen requisitos y riesgos completamente distintos.

Se usa en Billium

JWT + Passport

Auth

Access token y refresh token, con revocación real: desactivar un usuario o suspender un tenant corta la sesión en curso, no en la próxima recarga.

Se usa en ResiHub Cliento Billium TalentUs

Socket.io

Mensajes y notificaciones que llegan sin recargar. El chat entre residente y administración corre sobre esto.

Se usa en ResiHub

Hangfire

Jobs

Trabajos en segundo plano con reintentos y panel de control. Verifica el estado de los comprobantes en la DGII y limpia tokens vencidos.

Se usa en Billium

Cron programado

Jobs

17 tareas programadas en ResiHub y 3 diarias en Cliento: marcar facturas vencidas, recordar seguimientos y alertar de oportunidades estancadas.

Se usa en ResiHub Cliento

03 Frontend

Paneles que se usan ocho horas al día.

Un panel administrativo no es una landing: tiene tablas de miles de filas, formularios largos y usuarios que lo conocen de memoria. Se optimiza para velocidad de uso, no para la primera impresión.

React

La base de tres de nuestros cuatro paneles. Ecosistema enorme, y encontrar quien lo mantenga después nunca es un problema.

Se usa en ResiHub Cliento Billium

Next.js

App Router, con rutas públicas y área autenticada separadas. Renderizado en servidor donde importa el SEO y la primera carga.

Se usa en Billium

Angular

Opinionado y estructurado: encaja cuando el sistema tiene más de 30 módulos y muchas manos encima, como TalentUs.

Se usa en TalentUs

Ant Design

Tablas, filtros y formularios de nivel empresarial resueltos de fábrica. Para paneles de gestión ahorra meses.

Se usa en ResiHub Cliento

Tailwind CSS

Cuando el diseño es propio y no queremos pelear contra los estilos de una librería. Consistencia sin hojas de estilo que crecen sin control.

Se usa en Billium Cliento

shadcn/ui + Radix

UI

Componentes accesibles que copias a tu repo y controlas. Sin quedar atado a las decisiones de diseño de un tercero.

Se usa en Billium

TanStack Query

Estado

Caché, revalidación y estados de carga sin escribirlos a mano en cada pantalla. Menos código y menos bugs sutiles.

Se usa en Billium

Zod + React Hook Form

Formularios

Validación declarativa y tipada. El esquema que valida el formulario es la misma fuente que define el tipo.

Se usa en Billium

dnd-kit

Kanban

Arrastrar y soltar accesible, también con teclado. Es lo que mueve el pipeline de Cliento.

Se usa en Cliento

Recharts · ApexCharts

Gráficos

Gráficos de barras, donut, área y apilados para los tableros de gestora, ventas y facturación.

Se usa en ResiHub Cliento TalentUs

ExcelJS · jsPDF

Export

Exportación real: Excel de varias hojas y PDF con tablas y gráficos. Porque el cliente siempre va a pedir «mándamelo en Excel».

Se usa en ResiHub Cliento

Vite

Build

Arranque y recarga casi instantáneos. Suena a detalle, pero multiplicado por cada cambio del día cambia el ritmo del equipo.

Se usa en Cliento

04 Móvil

Dos apps publicadas, una base de código.

ResiHub Mobile y ResiHub Handy comparten backend y arquitectura, pero son proyectos independientes. Todo lo de esta sección está en producción, no en un tutorial.

React Native

iOS y Android desde una sola base de código, con componentes nativos de verdad. Y comparte lenguaje y tipos con el backend.

Se usa en Mobile y Handy

Expo

Resuelve la parte más ingrata: permisos, cámara, notificaciones, certificados y compilación. Handy corre sobre la nueva arquitectura.

Se usa en Mobile y Handy

EAS Build

Publicación

Compilación en la nube y envío a las tiendas. Sin un Mac dedicado ni una tarde peleando con certificados de Apple.

Se usa en Mobile y Handy

Expo Local Authentication

Biometría

Face ID, Touch ID y huella. El residente entra sin teclear contraseña, que es la diferencia entre usar la app y desinstalarla.

Se usa en ResiHub Mobile

Expo Notifications

Push

Notificaciones que sí llegan: visita en la puerta, pago recibido, anuncio de la administración.

Se usa en Mobile y Handy

Expo Camera

QR

Escaneo de códigos QR en la puerta. La seguridad valida la visita sin llamar a nadie.

Se usa en Mobile y Handy

NativeWind

Tailwind dentro de React Native. Un solo lenguaje de estilos entre el panel web y la app.

Se usa en Mobile y Handy

Gluestack UI

UI

Componentes móviles accesibles y consistentes entre plataformas, sin construir cada control desde cero.

Se usa en ResiHub Mobile

Cliente offline propio

A medida

En Handy escribimos nuestro propio cliente fetch: reintentos, timeout, cabeceras multi-tenant y caché de lectura. El personal de campo no siempre tiene señal.

Se usa en ResiHub Handy

05 Datos

Lo único que no se puede rehacer.

El código se reescribe; los datos, no. Por eso el modelo y las migraciones se toman en serio desde el primer día: que ResiHub haya evolucionado años en producción sin perder un dato ni cortar el servicio no es suerte, es método.

PostgreSQL

Nuestra opción por defecto. Sólido, gratis, y con detalles que importan de verdad: los índices únicos parciales son los que permiten el soft delete sin bloquear correos ni números de factura.

Se usa en ResiHub Cliento Billium

SQL Server

Empresarial

Cuando el cliente ya tiene licencia y un DBA que lo conoce. Pelear contra eso es perder el tiempo de todos.

Se usa en TalentUs

TypeORM

Migraciones versionadas y, sobre todo, subscribers: son los que aplican el filtro de tenant solos. Nadie puede olvidarse de filtrar.

Se usa en ResiHub Cliento

Entity Framework Core

Migraciones y filtrado por tenant. En TalentUs, la identidad y los datos de la aplicación viven separados.

Se usa en TalentUs

Base de datos gestionada

AWS · Azure

PostgreSQL gestionado en la nube, con respaldos y alta disponibilidad a cargo del proveedor. Sin servidores de base de datos que parchear a mano.

Se usa en ResiHub Billium

Power BI

BI

Cuando el cliente quiere explorar sus datos por su cuenta, en vez de pedirnos un reporte nuevo cada vez.

Se usa en Servicio

06 Infraestructura

Que desplegar sea rutina, no un evento.

Si publicar da miedo, se publica poco; y si se publica poco, cada entrega acumula más riesgo. La infraestructura existe para romper ese círculo.

Docker

Contenedores

El entorno se define en un archivo y es idéntico en tu máquina y en producción. Se acabó el «en mi computadora sí funciona».

Se usa en ResiHub Cliento

GitHub Actions

CI/CD

Pruebas y despliegue automáticos en cada push. Este mismo sitio se publica así.

Se usa en ResiHub Cliento

AWS · Azure

Nube

Desplegamos sobre nube empresarial, con servicios gestionados para el frontend y el backend. Sin servidores que administrar ni parches de sistema operativo a media noche.

Se usa en ResiHub Cliento

CDN y entrega

AWS · Azure

CDN propio para comprobantes y documentos. El residente abre su recibo rápido, desde donde sea.

Se usa en ResiHub

Almacenamiento intercambiable

Agnóstico

La capa de archivos de ResiHub es agnóstica: AWS S3, Azure Blob y disco local implementan la misma interfaz y se eligen con una variable de entorno. Mover un despliegue de una nube a otra es cambiar esa variable, no reescribir código.

Se usa en ResiHub

AWS S3

Implementado

Provider completo: credenciales IAM, región, buckets público y privado separados y URLs prefirmadas — el archivo se descarga directo desde S3 con un enlace temporal, sin pasar por nuestro servidor.

Se usa en ResiHub

Azure Blob Storage

Implementado

La alternativa cuando el cliente ya está en Microsoft. Mismo contrato que S3 dentro de nuestro código, así que elegir uno u otro no toca la lógica de negocio.

Se usa en ResiHub

Serilog + Seq

Logs

Logging estructurado: los logs se consultan como datos, no se leen a ojo. Cuando algo falla, se encuentra.

Se usa en Billium

Health checks

Monitoreo

El sistema dice si está sano, incluida su base de datos. Enterarse por el cliente no es monitoreo.

Se usa en Billium

Swagger / OpenAPI

Docs

El contrato de la API documentado y navegable. Quien se integre no tiene que adivinar ni escribirnos.

Se usa en ResiHub Cliento Billium TalentUs

reCAPTCHA

v3 · Enterprise

Protección del login contra bots, sin obligar al usuario a identificar semáforos.

Se usa en ResiHub

Analítica

Producto

Medir qué se usa de verdad y qué no. Las decisiones de producto salen de aquí, no de opiniones.

Se usa en ResiHub

07 Seguridad

Controles en el servidor y en la aplicación.

La seguridad no es una casilla que se marca al final: son capas que se aplican solas en cada petición. Estas son las que llevan nuestros sistemas en producción — desde las cabeceras HTTP hasta el cifrado de credenciales en reposo.

Helmet

Cabeceras de seguridad HTTP en cada respuesta: CSP, HSTS, X-Frame-Options y X-Content-Type-Options. Cierra la puerta a clickjacking, sniffing de MIME y buena parte del XSS.

Se usa en ResiHub

Rate limiting

Throttler

Límite de peticiones por origen, aplicado con un guard global. Es lo que impide que alguien pruebe diez mil contraseñas contra el login mientras nadie mira.

Se usa en ResiHub

BCrypt

Hashing

Las contraseñas se guardan como hash con salt, nunca en texto plano ni cifradas de forma reversible. Si la base de datos se filtrara, no hay contraseñas que robar.

Se usa en ResiHub Cliento Billium

Validación estricta de entrada

Whitelist

Cada petición se valida contra un esquema y se descarta todo campo no declarado. Nadie puede colar un role: "admin" en el cuerpo de un formulario y escalar privilegios.

Se usa en ResiHub Cliento

AES-256-GCM

Cifrado

Las credenciales sensibles se guardan cifradas en reposo, con cifrado autenticado: si alguien altera el dato guardado, el descifrado falla en vez de devolver basura.

Se usa en ResiHub

CORS

Origen

Solo los orígenes declarados pueden hablar con la API. Un sitio de terceros no puede llamarla desde el navegador de tu usuario.

Se usa en ResiHub Cliento

Guards por petición

Autorización

El permiso no se comprueba al entrar, sino en cada llamada. En ResiHub, un guard global valida que la gestora siga teniendo asignado ese condominio, o devuelve 403.

Se usa en ResiHub Cliento

Revocación de sesión

JWT

Desactivar un usuario o suspender una organización corta la sesión en curso: se revocan los refresh tokens y la siguiente petición se rechaza. No hay que esperar a que el token expire.

Se usa en ResiHub Cliento

reCAPTCHA

v3 · Enterprise

Filtra bots en el login por puntuación, sin obligar al usuario a identificar semáforos ni escaleras.

Se usa en ResiHub

Protección en el borde

WAF · CDN

El tráfico malicioso se filtra antes de tocar el servidor. Mitigación de DDoS y TLS gestionado sin configurar certificados a mano.

Se usa en ResiHub

Integridad con SHA-256

Votaciones

Cada voto lleva un hash de integridad y control de duplicados. El resultado de una asamblea se puede auditar, no solo creer.

Se usa en ResiHub

Auditoría y borrado suave

Trazabilidad

Bitácora en base de datos y en archivo, y borrado suave en todo el sistema: nada desaparece de verdad, y siempre se puede reconstruir quién hizo qué.

Se usa en ResiHub Cliento TalentUs

08 Inteligencia Artificial

VERA: un asistente que consulta, no que inventa.

Casi todo el mundo dice que «tiene IA». La pregunta correcta es otra: ¿de dónde saca los datos? Un modelo suelto alucina cifras. Uno con herramientas consulta tu base de datos y responde con lo que hay.

Modelos de lenguaje

LLM

El motor detrás de VERA, el asistente de ResiHub. Elegimos el modelo por su fiabilidad usando herramientas y siguiendo instrucciones, y la integración queda aislada para poder cambiar de modelo sin tocar el resto del sistema.

Se usa en ResiHub

Tool use

3 herramientas

VERA tiene herramientas propias —consultar morosidad, resumir pagos, redactar comunicaciones— y lee comprobantes de transferencia por visión. Cada respuesta sale de una consulta real.

Se usa en ResiHub

Asistentes de dominio

Enfoque

Nada de un chatbot genérico pegado en una esquina. VERA vive dentro del sistema, con el contexto y los permisos del usuario que pregunta, y toda acción queda auditada.

Se usa en ResiHub

09 Criterios

Cómo decidimos qué usar.

Elegir tecnología es fácil cuando el criterio es «lo que está de moda» o «lo que sé yo». Nosotros usamos estos cuatro, en este orden.

¿Quién lo va a mantener?

Es la primera pregunta, no la última. Si tu equipo programa en C#, construirte algo en Node te deja atado a nosotros — y eso no es un buen negocio para ti. La tecnología correcta es la que tu gente puede sostener.

¿Existe dentro de cinco años?

Preferimos herramientas aburridas con comunidad grande antes que la novedad del mes. PostgreSQL, React y .NET no van a desaparecer. Un framework con 400 estrellas en GitHub y un solo mantenedor, quizá sí.

¿Resuelve el problema real?

CQRS en Billium tiene sentido porque emitir y consultar comprobantes son mundos distintos. Meter CQRS en un CRUD sencillo es complejidad sin retorno. El patrón se gana su lugar, no viene de regalo.

¿Se puede sacar después?

Nada crítico debe quedar amarrado a un proveedor. El almacenamiento de ResiHub es el ejemplo: AWS S3, Azure Blob y disco local implementan la misma interfaz, y elegir uno u otro es una variable de entorno. Escribimos esos providers antes de necesitarlos, precisamente para no quedar atrapados en una nube.

¿Tu equipo ya trabaja con alguna de estas?

Mejor todavía: podemos construir sobre lo que ya conocen y entregarles algo que puedan mantener sin nosotros. Cuéntanos con qué trabajan.