Facundo Cornejo.
Volver a proyectos

Case study

Adoptly — Plataforma de Adopción Animal

Una plataforma fullstack para organizaciones de rescate animal de Paraná, deployada y usada por 4 ONGs reales.

Next.jsNode.jsExpressPrismaPostgreSQLTailwind CSS

Contexto

Adoptly nació como mi Trabajo Final Integrador en la UTN FR Paraná, pero con una premisa clara: que lo usaran organizaciones reales. Hice trabajo de campo con 4 ONGs de rescate animal de la ciudad para entender cómo gestionaban las adopciones.

Problema

Las ONGs gestionaban las adopciones por redes sociales y WhatsApp, sin una plataforma central. Era difícil mostrar a los animales de forma ordenada, recibir y seguir solicitudes, y dar visibilidad a los casos de éxito y las donaciones.

Solución y decisiones técnicas

  • Frontend en React con Clean Architecture (domain, application, infrastructure, presentation, shared). Separé el dominio del framework para que la lógica fuera testeable y la base mantenible más allá del TFI.
  • API REST con Node.js y Express, Prisma como ORM y PostgreSQL (Supabase). Modelos para organizaciones, administradores, animales y casos de éxito.
  • Autenticación con JWT y bcrypt, validación de formularios con React Hook Form + Zod, e imágenes en Cloudinary.
  • Documentación de la API con Swagger.
  • Testing serio: Jest + Supertest, pruebas de carga con k6 y una auditoría de seguridad.

Multi-tenant desde el día uno

La decisión de arquitectura que más condicionó el resto fue no construir una plataforma para una ONG sino para varias. Cada organización tiene sus propios animales, sus propios administradores y sus propias solicitudes, aisladas de las demás, y por encima hay un rol de super administrador para la gestión global. Eso obliga a validar la pertenencia a la organización en cada ruta protegida, no solo el token: tener sesión válida no alcanza, hay que probar que ese usuario pertenece a esa organización. Es más trabajo al principio, y es lo que hizo que sumar la cuarta ONG no fuera un despliegue nuevo.

Seguridad y calidad

  • Autenticación con tokens firmados y expiración acotada; contraseñas con hash y sal, nunca en claro.
  • Validación de entrada en todas las rutas del backend, además de la del cliente. La del cliente es usabilidad; la que cuenta es la del servidor.
  • Consultas parametrizadas por el ORM, que cierra la puerta a la inyección de SQL por construcción.
  • API documentada con Swagger, para que frontend y backend no se pongan de acuerdo por WhatsApp.
  • Tests unitarios y pruebas de carga, para saber cómo se comporta antes de que lo usen personas de verdad.

Mi rol

Trabajé fullstack: relevamiento con las ONGs, frontend con Clean Architecture y la API REST completa. El frente y el back se deployaron por separado (Vercel y Render).

Resultado

La plataforma quedó deployada y en uso por 4 organizaciones de rescate reales de Paraná, con un flujo ordenado para publicar animales y gestionar solicitudes de adopción.

Aprendizajes

  • Aplicar Clean Architecture en un frontend real y ver el pago en mantenibilidad y tests.
  • Construir con usuarios reales obliga a priorizar lo que de verdad importa.
  • Testing de carga y auditoría de seguridad como parte del proceso, no como un extra.

En pantalla

Catálogo de animales en adopción con su estado