Saltar al contenido
Volver a Growork
2024 — presenteParte del ecosistema Growork

Portal de clientes Growork

Diseñé y construí el área privada donde cada cliente puede seguir su búsqueda de empleo en Suiza con datos reales: candidaturas enviadas, respuestas recibidas, documentos, plan contratado, rendimiento y ayuda contextual con IA.

7

módulos privados conectados

5

sistemas sincronizados

0

mocks en la experiencia del cliente

Next.js 16React 19TypeScriptPostgreSQLjose (JWT)bcryptjsStripeTwenty CRMOpenAIn8nTailwind CSS 4

El reto

Growork no vendía solo una página atractiva. Detrás había una operación real: buscar hoteles, enviar candidaturas, gestionar respuestas, actualizar documentos, activar planes, registrar pagos y mantener sincronizados CRM, base de datos, web interna y automatizaciones.

El problema era que gran parte de ese trabajo quedaba invisible. Para el cliente, si no había un mensaje, parecía que no pasaba nada. Y, para el equipo, responder una y otra vez a preguntas de seguimiento no escalaba.

El objetivo del portal fue convertir una operativa compleja en una sensación clara de avance: esto es lo que hemos enviado, esto ha respondido, esto te queda de plan y esto puedes hacer ahora.

Qué construí

Construí una capa privada bajo /portal/* que funciona como un producto SaaS para candidatos. No es una página de estado: es una interfaz conectada a la operativa diaria de Growork, con rutas protegidas, paywall interno, datos por cliente y flujos preparados para usuarios individuales o de pareja.

Dashboard

Vista ejecutiva del caso: candidaturas enviadas, respuestas, actividad reciente, ciudades objetivo, ciudades ya contactadas y días restantes del plan.

Candidaturas

Tabla filtrable de hoteles y empresas contactadas, con estados entendibles para el cliente: enviada, abierta, respondida, entrevista o descartada.

Respuestas

Bandeja privada con respuestas clasificadas, contador de no leídas, hilo de conversación, sugerencia de respuesta y envío directo en hilo.

Estadísticas

Métricas de campaña por periodo con Chart.js: tasa de respuesta, enviados, entrevistas, regiones con más tracción y tipos de respuesta.

Mi plan

Estado del servicio contratado, historial, renovación, upgrades y activación diferida cuando aparece la primera candidatura real.

Perfil

Datos personales, información profesional y subida segura de CV y carta en PDF, también preparada para cuentas de pareja.

Chat IA

Asistente contextual con datos reales del cliente, límites de uso, sanitización de prompts y alcance restringido a Growork.

Antes y después

El portal cambió la percepción del servicio: de una operación que podía sentirse invisible a una experiencia donde el cliente ve progreso, contexto y valor después de comprar.

Antes

Antes: el cliente dependía de mensajes manuales para saber si su búsqueda avanzaba.

Después

Después: entra al portal y ve candidaturas, respuestas, documentos, rendimiento, plan y siguientes pasos con datos reales.

Antes

Antes: la operación estaba repartida entre CRM, web interna, pagos, documentos y automatizaciones.

Después

Después: el portal actúa como una capa clara encima de esas fuentes sin exponer la complejidad técnica.

Antes

Antes: muchas preguntas se repetían porque el progreso no era visible.

Después

Después: el panel reduce la incertidumbre, baja el soporte repetitivo y aumenta la confianza en el servicio.

Arquitectura del portal

El portal actúa como una capa de producto sobre varios sistemas. Cada fuente tiene una responsabilidad distinta y el frontend no habla directamente con los servicios sensibles: el servidor valida la sesión, resuelve el cliente vinculado y consulta lo necesario a través de APIs protegidas.

Lo difícil no era pintar tablas

La complejidad real estaba en que el portal tenía que ser fiel a lo que pasaba fuera de él. No podía inventarse progreso, no podía perder documentos, no podía mezclar clientes y no podía romperse cuando un webhook o una automatización llegaba tarde.

Una operación invisible para el cliente

Growork mueve emails, hoteles, respuestas, documentos, pagos, planes, CRM y automatizaciones. El portal convierte todo eso en una experiencia simple: el cliente entra y entiende qué está pasando.

Fuentes de verdad repartidas

PostgreSQL guarda usuarios, sesiones, servicios, pagos, rate limits y chat. Twenty CRM mantiene el perfil comercial. La web interna aporta candidaturas, respuestas, documentos y métricas. Stripe confirma las compras. El portal orquesta todo sin exponer esa complejidad.

Planes que empiezan cuando tiene sentido

Si alguien paga hoy pero la primera candidatura sale días después, el reloj del plan no debería correr desde el pago. Implementé activación diferida: el servicio se guarda al comprar, pero empieza con el primer envío real.

Modo pareja de verdad

No era duplicar un formulario. Había que soportar dos emails, dos CV, dos perfiles, vinculación en el CRM, precio de pareja, documentos separados, plan compartido y visibilidad correcta dentro del portal.

Sesión preparada para datos asíncronos

El sistema contempla escenarios imperfectos: usuarios creados por Stripe, entidades que Twenty transforma después, identificadores que cambian y cookies que deben refrescarse sin romper la sesión.

Seguridad en todas las entradas

JWT en cookies HTTP-only firmado con jose, bcrypt, bloqueo tras intentos fallidos, rate limits persistidos, tokens de un solo uso, validación real de PDF, proxy server-side con API key y comprobación de pertenencia antes de servir adjuntos.

Seguridad e IA contextual

La parte sensible del portal no era solo autenticar usuarios. Había que proteger documentos personales, adjuntos, pagos, sesiones y un asistente IA que conoce el contexto del cliente sin convertirse en una puerta abierta a los datos internos.

Contexto acotado

El chat recibe solo los datos necesarios del caso y queda restringido a Growork, búsqueda de empleo en Suiza, plan, candidaturas, respuestas y perfil.

Controles de abuso

Rate limits por hora, día y mes, sanitización de prompts, validación de pertenencia antes de servir adjuntos y APIs protegidas server-side.

Contrato de API

Endpoints protegidos del portal

De los 33 endpoints del área del portal, estos resumen cómo se resuelve la sesión, se protegen los documentos y se mantienen los hilos de conversación.

GET/api/portal/me

Resuelve la sesión a partir de la cookie firmada y devuelve el contexto del usuario y su pareja.

auth: JWT en cookie HTTP-only

GET/api/portal/candidaturas/[id]/attachments/[filename]

Sirve un adjunto solo tras comprobar que pertenece al cliente autenticado; proxy server-side hacia la web interna.

auth: JWT + comprobación de propiedad

POST/api/portal/respuestas/send-reply

Responde a un hotel manteniendo el hilo (In-Reply-To, References, threadId de Gmail).

auth: JWT

POST/api/portal/chat

Chat IA con contexto acotado, sanitización de prompts y límites por hora, día y mes.

auth: JWT + rate limit

Decisiones de producto e ingeniería

No hacer un dashboard decorativo

El portal no usa datos falsos para parecer activo. Cada vista se alimenta de datos operativos reales: emails enviados, respuestas, documentos, estado del plan y actividad del caso.

Traducir estados técnicos a lenguaje de cliente

La operativa interna puede tener estados complejos. En el portal se reducen a conceptos claros: enviada, abierta, respondida, entrevista o descartada.

Poner límites al chat IA

El asistente solo recibe el contexto permitido del cliente y solo puede hablar de Growork, búsqueda de empleo en Suiza, plan, candidaturas, respuestas y perfil. Tiene rate limits por hora, día y mes.

Proteger los documentos como datos sensibles

Los CV, cartas y adjuntos pasan por validación de tipo, tamaño y magic bytes. Los nombres se sanitizan y las descargas se validan server-side antes de devolver archivos.

Stack con intención

Cada tecnología aparece porque resolvía una parte concreta del sistema, no para engrosar una lista.

Next.js + React

Portal privado con App Router, Server Components para la carga de datos y Client Components donde había interacción real.

TypeScript

Contratos claros entre APIs, modelos de UI, respuestas del backend interno y datos del CRM.

PostgreSQL

Estado propio del portal: usuarios, servicios, pagos, sesiones auxiliares, tokens, rate limits y mensajes del chat.

jose + bcryptjs

Sesión JWT firmada (HS256) en cookie HTTP-only y contraseñas hasheadas con bcrypt.

Twenty CRM

Perfil comercial, clientes, parejas, estado del plan y sincronización con la operativa de Growork.

Stripe

Pagos, renovaciones, upgrades, checkout invitado y aprovisionamiento posterior mediante webhooks.

Web interna

Fuente operativa de candidaturas enviadas, respuestas recibidas, adjuntos, documentos y métricas de rendimiento.

OpenAI

Chat privado con contexto acotado, sanitización de prompts y controles de abuso.

Impacto

El portal no fue una mejora cosmética. Fue una forma de aumentar la confianza del cliente, reducir el trabajo manual y dar a Growork una experiencia privada a la altura de lo que ya ocurría en operaciones.

Cliente

Gana visibilidad y control: entiende qué se ha hecho, qué respuesta ha llegado, cuánto plan le queda y qué documentos siguen activos.

Empresa

Gana escala operativa: menos seguimiento manual, mejor trazabilidad, menos dudas repetidas y una experiencia premium después del pago.

Producto

Gana coherencia: pagos, CRM, candidaturas, documentos e IA dejan de ser piezas aisladas y se convierten en una experiencia privada.

Lo que demuestra

  • Aprendizaje autodidacta aplicado a un problema real: leer documentación, probar APIs, validar hipótesis y convertir errores de integración en diseño defensivo.
  • Capacidad para pensar en producto después del checkout: no solo vender, sino sostener la confianza durante la prestación del servicio.
  • Criterio para equilibrar experiencia y seguridad cuando hay documentos personales, pagos, sesiones privadas e IA con contexto de usuario.
  • Capacidad para convertir un proceso operativo real en una experiencia de producto clara.
  • Criterio para decidir qué sistema es la fuente de verdad para cada dato.
  • Experiencia conectando pagos, CRM, base de datos propia, backend interno, automatizaciones e IA.
  • Seguridad aplicada desde el diseño, no como una capa al final.
  • Pensamiento de producto: activación diferida, lenguaje entendible, modo pareja y reducción de fricción.
  • Frontend orientado a que el cliente entienda el progreso, no a mostrar la complejidad técnica.