Saltar al contenido

El proyecto del curso de 40 horas

NexoCRM: El CRM sencillo para que un pequeño negocio de servicios no pierda ninguna oportunidad.

Una única aplicación web, rápida y usable desde el móvil, donde el equipo de un pequeño negocio de servicios registra cada contacto, empresa, oportunidad y tarea, ve en qué punto está cada venta y sabe qué seguimiento toca hoy. Está construida con Next.js y Supabase, protegida con RLS por workspace y publicada en Vercel, de forma que quien la crea puede seguir mejorándola durante meses con Claude Code o Codex sin depender de nadie.

Requisitos funcionales
13
Con criterios de aceptación verificables.
Tablas con RLS
9
Aisladas por workspace desde el primer día.
Pantallas
18
Tres públicas y el resto tras la sesión.
Hitos con evidencia
5
Cada uno deja entregables registrados.

El encargo

Qué problema resuelve y para quién

El proyecto no arranca con código: arranca sabiendo qué se rompe hoy en el negocio y quién lo sufre.

Propietario/a (owner)

Dirige el negocio y también vende. Necesita ver el estado real de las oportunidades sin perseguir a nadie y decidir dónde poner el esfuerzo comercial esta semana. Es quien crea el workspace y gestiona al equipo.

  • Ver en menos de un minuto cuántas oportunidades hay abiertas, su valor ponderado y qué tareas están atrasadas.
  • Crear el workspace, dar acceso a su equipo y confiar en que solo ellos ven los datos.
  • Registrar una oportunidad con importe, probabilidad y fecha esperada, y moverla de etapa sin perder el historial.
  • Cerrar una oportunidad como ganada o perdida con motivo y ver cómo cambia el dashboard.

Miembro del equipo (member)

Atiende clientes y hace el seguimiento diario. Necesita saber qué le toca hoy y dejar constancia de cada llamada o nota para que el resto del equipo no repita trabajo ni contradiga lo ya dicho.

  • Encontrar un contacto por nombre, correo o teléfono en segundos y ver su empresa, oportunidades y últimas notas.
  • Completar las tareas de hoy, ver las atrasadas y crear la siguiente acción sin salir de la ficha.
  • Anotar el resultado de una llamada o reunión en el timeline del contacto o de la oportunidad.

Alcance

Qué entra en el proyecto y qué queda fuera

Definir el límite es parte del trabajo: un alcance cerrado es lo que permite terminar y publicar.

Entra en el alcance

13 funciones
  • Registro, inicio y cierre de sesión, recuperación de contraseña y rutas protegidas.
  • Creación automática del workspace inicial con su propietario/a y las etapas de pipeline por defecto.
  • Dashboard con KPIs, pipeline resumido, tareas urgentes y próximos seguimientos.
  • Empresas: listado, búsqueda, alta, edición, detalle y contactos relacionados.
  • Contactos: listado, búsqueda, filtros, alta, edición, detalle y empresa relacionada.
  • Oportunidades: CRUD con empresa y contacto, importe, probabilidad, fecha esperada, etapa, ganada o perdida y actividad registrada.
  • Pipeline por columnas con alternativa de lista accesible y cambios de etapa persistidos.
  • Tareas con prioridad, fecha límite, estado, filtros pendientes / hoy / atrasadas y relación opcional con contacto u oportunidad.
  • Notas y actividades: timeline en contacto y oportunidad con eventos automáticos y notas manuales.
  • Búsqueda global en contactos, empresas y oportunidades.
  • Estados de carga, vacío, error y éxito cuidados en cada flujo relevante.
  • Diseño responsive, usable en móvil y con teclado.
  • Datos demo ficticios para enseñar la aplicación sin información real.

Queda fuera

7 exclusiones
  • Facturación, presupuestos en PDF o cobros.
  • Email marketing, envíos masivos o automatizaciones de correo.
  • Integraciones externas (WhatsApp, Gmail, calendarios, Zapier o similares).
  • Aplicación nativa iOS o Android; la web responsive cubre el uso en móvil.
  • IA predictiva: puntuación automática de leads o previsión de cierre.
  • Multi-idioma; toda la interfaz está en español.
  • Permisos granulares por campo o por registro; solo existen los roles owner y member.

Demo segura

Recorre las pantallas con datos ficticios

Esta maqueta reproduce el panel, el listado de contactos y el pipeline de NexoCRM. Los nombres, empresas e importes están inventados: no hay datos reales de ninguna persona.

Oportunidades abiertas
18
6 en negociación
Valor ponderado
34.150 €
Importe por probabilidad
Ganadas este mes
5
21.900 € cerrados
Tareas atrasadas
3
Revisar hoy

Importe abierto por etapa

  • Nuevo9800 €
    6 oportunidades
  • Cualificado14.200 €
    5 oportunidades
  • Propuesta18.600 €
    4 oportunidades
  • Negociación12.400 €
    3 oportunidades
  • Ganado21.900 €
    5 oportunidades
Importe de las oportunidades por etapa del pipeline. Datos ficticios de la maqueta. Valores: Nuevo 9800 €; Cualificado 14.200 €; Propuesta 18.600 €; Negociación 12.400 €; Ganado 21.900 €.
CategoríaValor
Nuevo9800 €
Cualificado14.200 €
Propuesta18.600 €
Negociación12.400 €
Ganado21.900 €

Tareas que reclaman atención

  • Llamar para confirmar la propuesta

    Estudio Malva

    Prioridad altaVencía ayer
  • Enviar presupuesto revisado

    Clínica Duero

    Prioridad altaHoy
  • Preparar visita de seguimiento

    Talleres Bracamonte

    Prioridad mediaEn 3 días
Las cifras, nombres y empresas de esta maqueta están inventados y no cambian: es una ilustración del producto que construyes.
Abrir NexoCRM en modo demo (se abre en una pestaña nueva)

La demo funciona con datos ficticios cargados en el navegador: puedes crear, editar y borrar sin afectar a nadie.

Requisitos funcionales

13 requisitos repartidos por área

Cada requisito tiene criterios de aceptación verificables: así sabes cuándo está hecho de verdad. Despliega el área que te interese.

Requisitos funcionales
13
De RF-01 a RF-13, todos obligatorios.
Áreas de producto
13
De la autenticación a los datos de demostración.
Criterios de aceptación
60
Cada uno se comprueba usando la aplicación o un comando.

RF-01 Registro, acceso, cierre de sesión, recuperación y rutas protegidas

Cualquier persona puede crear una cuenta con correo y contraseña, entrar, salir y recuperar la contraseña. Todas las rutas de la aplicación exigen sesión; las públicas son solo /login, /register y /forgot-password.

Criterios de aceptación (5)

  • Una persona se registra en /register con correo y contraseña y, tras confirmar el correo, inicia sesión en /login y llega a /dashboard.
  • Al cerrar sesión la sesión queda invalidada y cualquier ruta privada redirige a /login.
  • Desde /forgot-password se envía el correo de recuperación de Supabase y el mensaje de éxito no revela si el correo existe.
  • Sin sesión, acceder a /dashboard, /contacts, /companies, /deals, /pipeline, /tasks o /settings redirige a /login conservando la ruta de destino en ?next=.
  • Los errores de credenciales se muestran en el formulario de forma anunciable (role alert) y sin exponer detalles técnicos.

Modelo de datos

9 tablas con seguridad por filas

Todas las tablas de negocio cuelgan de un workspace y están protegidas con políticas Row Level Security: cada equipo solo ve lo suyo.

Datos del negocio · una fila siempre pertenece a un workspace · Row Level Securityowner_iduser_idworkspace_idworkspace_idcompany_idcompany_idstage_idcontact_iddeal_iddeal_idprofilesPerfil · 3 camposworkspacesWorkspace · 4 camposworkspace_membersMiembro de workspace · 4 camposcompaniesEmpresa · 9 camposcontactsContacto · 13 camposdeal_stagesEtapa de pipeline · 7 camposdealsOportunidad · 12 campostasksTarea · 13 camposactivitiesActividad · 9 campos
El punto morado marca el lado que guarda la clave ajena. El diagrama muestra las relaciones principales; la lista siguiente recoge todas, incluidas las opcionales. En pantallas estrechas el diagrama se desplaza en horizontal dentro de su propio marco.

Relaciones tabla a tabla

profiles

  • profiles.id → auth.users.id (1:1, obligatorio)

workspaces

  • workspaces.owner_id → profiles.id (N:1, obligatorio)

workspace_members

  • workspace_members.workspace_id → workspaces.id (N:1, obligatorio)
  • workspace_members.user_id → profiles.id (N:1, obligatorio)

companies

  • companies.workspace_id → workspaces.id (N:1, obligatorio)

contacts

  • contacts.workspace_id → workspaces.id (N:1, obligatorio)
  • contacts.company_id → companies.id (N:1, opcional)

deal_stages

  • deal_stages.workspace_id → workspaces.id (N:1, obligatorio)

deals

  • deals.workspace_id → workspaces.id (N:1, obligatorio)
  • deals.company_id → companies.id (N:1, opcional)
  • deals.contact_id → contacts.id (N:1, opcional)
  • deals.stage_id → deal_stages.id (N:1, obligatorio)

tasks

  • tasks.workspace_id → workspaces.id (N:1, obligatorio)
  • tasks.assignee_id → profiles.id (N:1, opcional)
  • tasks.contact_id → contacts.id (N:1, opcional)
  • tasks.deal_id → deals.id (N:1, opcional)

activities

  • activities.workspace_id → workspaces.id (N:1, obligatorio)
  • activities.contact_id → contacts.id (N:1, opcional)
  • activities.deal_id → deals.id (N:1, opcional)
  • activities.actor_id → profiles.id (N:1, opcional)

Qué guarda cada tabla

Modelo de datos de NexoCRM: 9 entidades con su tabla y su contenido
EntidadTablaQué guardaCampos
PerfilprofilesDatos públicos de cada usuario registrado. Se crea automáticamente con un trigger sobre auth.users y comparte el mismo id. Cada persona lee su perfil y el de quienes comparten workspace con ella, para poder mostrar autoría y responsables.3
WorkspaceworkspacesEspacio de trabajo de un negocio. Todos los datos comerciales pertenecen a un workspace y el aislamiento entre workspaces lo garantiza RLS. Se crea con la función create_workspace_with_owner, que en la misma transacción inserta también la membresía owner y las seis etapas del pipeline.4
Miembro de workspaceworkspace_membersRelación entre personas y workspaces con su rol. Clave primaria compuesta (workspace_id, user_id). Es la tabla que consulta la función de membresía usada por todas las políticas RLS. Un trigger impide eliminar o degradar a la persona propietaria.4
EmpresacompaniesOrganización cliente o potencial cliente. Agrupa contactos y oportunidades. Índices sobre workspace_id y sobre (workspace_id, lower(name)) para la búsqueda por nombre.9
ContactocontactsPersona con la que el negocio se relaciona. Puede pertenecer a una empresa. Índices sobre workspace_id, company_id, (workspace_id, lower(email)) para la búsqueda por correo y next_follow_up_at para ordenar los seguimientos previstos.13
Etapa de pipelinedeal_stagesEtapas configurables por workspace. create_workspace_with_owner crea seis: Nuevo, Cualificado, Propuesta, Negociación, Ganado (is_closed e is_won) y Perdido (is_closed). Restricción única sobre (workspace_id, position) e índice sobre workspace_id.7
OportunidaddealsVenta potencial con valor esperado y etapa. Índices sobre workspace_id, stage_id, company_id, contact_id y expected_close_date. Constraints: amount >= 0 y probability entre 0 y 100. No existe columna de fecha de cierre: una venta cuenta como ganada del mes cuando su etapa tiene is_won y su updated_at cae en el mes en curso.12
TareatasksAcción de seguimiento con fecha límite, prioridad y responsable. Índices sobre workspace_id, due_date, status, assignee_id, contact_id y deal_id: las columnas por las que filtran las vistas y las relaciones.13
ActividadactivitiesHistorial de eventos de contactos y oportunidades: notas manuales y eventos automáticos. Solo se inserta; nunca se edita. Índices sobre (workspace_id, created_at desc), (contact_id, created_at desc), (deal_id, created_at desc) y actor_id.9

Hitos

El proyecto avanza en cinco entregas

En cada hito registras evidencias concretas (archivos, capturas, enlaces o commits) que quedan guardadas en tu perfil.

  1. Hito 16 entregables

    Cuentas y entorno

    Tienes claro qué vas a construir y para quién, has redactado tu primer prompt profesional y tu ordenador, GitHub, Vercel y Supabase están conectados sin haber expuesto ninguna contraseña ni API key. El repositorio ya contiene la memoria persistente del asistente.

    • Ficha del negocio en docs/product/brief.mdArchivo
    • Prompt de bootstrap en docs/prompts/01-bootstrap.mdArchivo
    • Captura de terminal con versionesCaptura
    • Archivos persistentes del asistenteArchivo
    • Repositorio privado en GitHubEnlace
    • Primer deployment de prueba en VercelEnlace
  2. Hito 26 entregables

    Repositorio y UI

    Has convertido la idea en usuarios, flujos, historias con criterios de aceptación y un mapa de pantallas. El proyecto Next.js arranca en local, tiene sistema visual, shell de navegación y cinco pantallas estáticas con sus estados, y el historial de GitHub cuenta lo que ha pasado con commits semánticos.

    • Usuarios y flujos en docs/product/users-and-flows.mdArchivo
    • Historias de usuario en docs/product/user-stories.mdArchivo
    • Navegación y campos en docs/product/navigation-and-fields.mdArchivo
    • Proyecto Next.js corriendo en localCaptura
    • Cinco pantallas estáticas navegablesCaptura
    • Historial con commits semánticosCommit
  3. Hito 35 entregables

    Datos seguros

    La base de datos existe con sus nueve tablas, claves, índices y constraints; hay datos ficticios; una persona puede registrarse, entrar y salir; y RLS impide que nadie lea o escriba datos de otro workspace. No se avanza al siguiente hito si alguna tabla de negocio está sin RLS.

    • Migraciones en supabase/migrations/0001_init.sql y 0002_rls.sqlArchivo
    • Diagrama y tablas en docs/data-model.mdArchivo
    • Datos ficticios en SupabaseCaptura
    • Flujo de autenticaciónVídeo
    • Prueba de aislamiento RLSTexto
  4. Hito 46 entregables

    CRM funcional

    NexoCRM funciona de punta a punta con Supabase: contactos y empresas con búsqueda, filtros y formularios validados; oportunidades con pipeline y actividad automática; tareas con filtros útiles; timeline con notas; búsqueda global y dashboard con KPIs correctos. Todo con estados de carga, vacío y error cuidados.

    • .env.example completoArchivo
    • CRUD de contactos y empresasCaptura
    • Transición de etapa en el pipelineCaptura
    • Timeline de actividadCaptura
    • Demo de búsqueda globalVídeo
    • Dashboard con datos y sin datosCaptura
  5. Hito 56 entregables

    Publicación

    La aplicación está publicada en Vercel con las variables correctas, los tests pasan, el QA final está documentado con sus correcciones, el README permite que otra persona continúe y existe una hoja de ruta razonada. Es el punto de partida para seguir mejorando el CRM con Claude Code o Codex.

    • Tests en verdeTexto
    • URL pública en VercelEnlace
    • QA final en docs/qa/final-checklist.mdArchivo
    • README revisable por otra personaArchivo
    • Demo de productoVídeo
    • Hoja de ruta en docs/product/roadmap.mdArchivo

Pantallas

Las rutas que construyes

Este es el mapa completo de la aplicación: tres pantallas públicas de acceso y el resto protegidas por sesión y membresía.

Rutas de NexoCRM: 18 pantallas con su propósito
RutaPara qué sirve
/Redirige a /dashboard si hay sesión y a /login si no la hay.
/loginInicio de sesión con correo y contraseña; enlaza a registro y recuperación.
/registerAlta de una cuenta nueva con nombre completo, correo y contraseña.
/forgot-passwordSolicitud del correo de recuperación de contraseña sin revelar si el correo existe.
/dashboardInicio privado: cinco KPIs, pipeline resumido, tareas urgentes y próximos seguimientos con enlace a la acción siguiente.
/contactsListado de contactos con búsqueda por nombre, correo y teléfono y filtros por estado y empresa (?q=, ?status=, ?companyId=).
/contacts/newFormulario de alta de contacto con validación Zod y empresa opcional.
/contacts/[id]Ficha del contacto: datos, empresa, oportunidades, tareas, timeline con notas y edición.
/companiesListado de empresas con búsqueda por nombre y sector (?q=).
/companies/newFormulario de alta de empresa con validación de nombre y web.
/companies/[id]Ficha de la empresa: datos, contactos relacionados, oportunidades abiertas, actividad reciente y edición.
/dealsListado de oportunidades con importe, probabilidad, etapa y valor ponderado, filtrable por estado, etapa y texto (?status=open|won|lost|all, ?stageId=, ?q=).
/deals/newFormulario de alta de oportunidad con empresa, contacto, importe, probabilidad, fecha esperada y etapa.
/deals/[id]Ficha de la oportunidad: datos, cierre como ganada o perdida, cambio de etapa, tareas y timeline.
/pipelineTablero por etapas con recuento e importe por columna, vista de lista accesible y cambio de etapa persistido.
/tasksGestión de tareas con prioridad, responsable y relación con contacto u oportunidad; vistas ?view=pending (por defecto), today, overdue, upcoming, done y all.
/settings/workspaceNombre del workspace; editable solo por owner.
/settings/membersListado de miembros con su rol; alta y baja de miembros solo para owner.

Cómo sabrás que funciona

  • El 100 % de las oportunidades abiertas del negocio están registradas en NexoCRM con importe, etapa y fecha esperada.
  • Crear un contacto completo con empresa asociada cuesta menos de 60 segundos desde el listado.
  • Al cerrar cada semana no queda ninguna tarea atrasada sin responsable; el filtro de atrasadas se revisa a diario.
  • El dashboard responde a las cinco preguntas clave (oportunidades activas, valor ponderado, ganadas del mes, tareas vencidas y próximos seguimientos) sin abrir otra pantalla.
  • Un usuario de otro workspace no puede leer ni escribir datos ajenos: la prueba de aislamiento RLS pasa en cada cambio de esquema.
  • La aplicación publicada en Vercel muestra el dashboard en menos de 3 segundos en una conexión móvil y se maneja completa con teclado.