DEV Community

Rents Argentina
Rents Argentina

Posted on

Cómo construimos Rents: gestión de alquileres para el mercado argentino con Expo + Node.js

El mercado de alquileres en Argentina es único: inflación alta, contratos ajustados por índices oficiales (ICL, IPC, CER), operaciones en doble moneda (ARS/USD), y regulación cambiante. Construir una app para propietarios argentinos requirió resolver estos desafíos específicos.

El problema

Los propietarios con 2-10 propiedades en alquiler necesitan:

  • Controlar cuándo vence cada contrato
  • Calcular el próximo ajuste según ICL
  • Registrar cobros en pesos y dólares
  • Enviar recordatorios a inquilinos por WhatsApp

No existía ninguna herramienta diseñada para esta realidad.

La solución: Rents

Construimos Rents — una plataforma cross-platform (iOS, Android, Web) que automatiza la gestión de alquileres con lógica específica para Argentina.

Stack tecnológico

Frontend: Expo (React Native) + TypeScript
Backend:  Node.js + Hono + TypeScript
Database: PostgreSQL + Drizzle ORM
Cache:    Redis
Storage:  Cloudflare R2
Auth:     Lucia Auth + JWT
Deploy:   Kamal (Docker) en VPS
Enter fullscreen mode Exit fullscreen mode

Decisiones técnicas clave

1. Monorepo con Turborepo

Usamos un monorepo con pnpm workspaces para compartir tipos y schemas de validación entre frontend y backend:

// packages/validation/src/schemas/contract.ts
export const createContractSchema = z.object({
  propertyId: z.string().uuid(),
  tenantId: z.string().uuid(),
  startDate: z.string(),
  monthlyRent: z.number().positive(),
  currency: z.enum(['ARS', 'USD']),
  adjustmentIndex: z.enum(['ICL', 'IPC', 'CER', 'NONE']),
});
Enter fullscreen mode Exit fullscreen mode

El mismo schema se usa tanto en el formulario de React Native como en la validación del endpoint de Hono.

2. Lógica de ajuste por índices

El cálculo de ajuste de alquiler según ICL es complejo: cada período tiene una fecha de inicio, un índice base y uno de comparación. Lo modelamos como un scheduler de ajustes:

// Genera todos los períodos de ajuste automáticamente
async function createAdjustmentSchedule(
  contract: Contract,
  indexData: ICLData[]
) {
  const periods = generateAdjustmentPeriods(
    contract.startDate,
    contract.endDate,
    contract.adjustmentFrequency
  );

  return periods.map(period => ({
    contractId: contract.id,
    periodStart: period.start,
    periodEnd: period.end,
    baseIndex: getIndexForDate(indexData, period.start),
    newIndex: getIndexForDate(indexData, period.end),
    adjustmentFactor: null, // se calcula cuando llega la fecha
  }));
}
Enter fullscreen mode Exit fullscreen mode

3. Multi-moneda sin complejidad extra

Los contratos en dólares se registran en USD pero se puede llevar el tracking en ambas monedas. La clave fue no intentar convertir en tiempo real — simplemente guardamos la moneda del pago junto al monto.

4. Expo para cross-platform real

Con Expo Router, el mismo código corre en iOS, Android y Web. La lógica de negocio está completamente separada de la UI, lo que facilita testear la parte crítica (cálculos financieros) sin el overhead de React Native Testing Library.

Desafíos del mercado argentino

Cambios legales frecuentes: La Ley de Alquileres cambió en 2023 y otra vez en 2024. Necesitábamos que los ajustes sean configurables, no hardcodeados.

ICL mensual: El índice se publica el primer día hábil de cada mes. Tuvimos que construir un job que lo consulta y actualiza automáticamente los contratos pendientes.

WhatsApp como canal primario: Los propietarios argentinos no mandan emails — mandan WhatsApp. Integramos envío de recordatorios via API de WhatsApp Business directamente desde la plataforma.

Resultado

Una plataforma que entiende que $ 150.000 y u$s 500 son dos realidades distintas que coexisten en el mismo portfolio.

Pueden probarla en rents.ar.


¿Tenés experiencia construyendo apps financieras para mercados con alta inflación? Me interesa el intercambio.

Top comments (0)