Caso de estudio · Full stack

Un taller de muebles a medida, ahora en la web

Sistema de catálogo y consultas para una carpintería: el cliente encuentra el mueble que busca y consulta en un minuto; el taller administra su catálogo y responde desde un solo panel.

5entidades de dominio
6módulos funcionales
2tipos de consulta
8fases de rediseño visual
01

Relevamiento

Situación de partida

MDZ Muebles es una carpintería que fabrica muebles a medida: cocinas, placares, racks, camas, escritorios. Mostraba su trabajo en redes sociales y recibía consultas por mensaje, sin un lugar propio donde ordenar el catálogo ni las consultas.

◎

Dolores detectados

  • Los trabajos quedaban dispersos entre publicaciones y no se podían buscar por tipo.
  • Las consultas llegaban por varios canales y algunas quedaban sin respuesta.
  • No había registro de quién consultó por qué mueble.
◆

Objetivo

Un sitio propio con catálogo por categorías, ficha de cada mueble y un formulario de consulta que llegue al taller y se pueda responder y seguir desde un panel.

◐

Usuarios

  • Visitante: quiere ver trabajos parecidos al que necesita y consultar sin registrarse.
  • Taller: carga los muebles con sus fotos y responde las consultas.

Resultado del relevamiento: el valor no está en vender online, sino en convertir una visita en una consulta bien registrada y respondida.

02

Análisis

Requisitos

Funcionales y no funcionales, con prioridad. Filtrá por tipo.

IDRequisitoTipoPrioridad
RF-01Mostrar el catálogo paginado, completo o por categoría.FuncionalAlta
RF-02Buscar muebles por nombre o color.FuncionalAlta
RF-03Ver la ficha de un mueble con su galería de fotos.FuncionalAlta
RF-04Enviar una consulta sobre un mueble o una consulta general, sin registrarse.FuncionalAlta
RF-05Avisar al taller por mail cada vez que llega una consulta.FuncionalMedia
RF-06Responder una consulta por mail desde el panel y dejarla registrada.FuncionalAlta
RF-07Alta, edición y baja lógica de categorías y muebles.FuncionalAlta
RF-08Gestionar las fotos de un mueble y elegir su portada.FuncionalAlta
RF-09Publicar muebles nuevos en una sección de Novedades.FuncionalMedia
RF-10Guardar links a la publicación del mueble en Instagram y Facebook.FuncionalMedia
RNF-01Uso cómodo en celular desde 360 px de ancho.UsabilidadAlta
RNF-02Fotos livianas: compresión automática de las que superan 1 MB.RendimientoAlta
RNF-03El panel del taller solo es accesible para el administrador.SeguridadAlta
RNF-04Esquema de base versionado y reproducible.MantenibilidadMedia
RNF-05Cada cambio a producción pasa por un build automático.CalidadMedia
RNF-06Identidad visual única en todo el sitio.UsabilidadMedia

Alcance

Qué entra, qué queda afuera a propósito y hacia dónde puede crecer.

Dentro

  • Catálogo, búsqueda y ficha de producto.
  • Consultas puntuales y generales.
  • Respuesta por mail y seguimiento.
  • Panel de catálogo y de consultas.
  • Novedades.

Fuera

  • Precios y venta online: cada mueble es a medida y se cotiza.
  • Registro de clientes: consultar no debe tener fricción.
  • Gestión de producción y stock.

Casos de uso

Cada caso indica desde dónde se accede: el sitio público o el panel del taller.

CU-01

Explorar el catálogo

Filtra por categoría, busca por nombre o color y pagina los resultados.

Sitio público
CU-02

Ver la ficha de un mueble

Galería con miniaturas y pantalla completa, datos del mueble y categorías relacionadas.

Sitio público
CU-03

Consultar por un mueble

Completa nombre, contacto y mensaje desde la ficha; la consulta queda asociada a ese mueble.

Sitio público
CU-04

Hacer una consulta general

Desde la Home, sin mueble asociado.

Sitio público
CU-05

Ver Novedades

Muestra los últimos trabajos publicados, del más nuevo al más viejo.

Sitio público
CU-06

Administrar categorías

Alta, edición y baja lógica, con listado de las dadas de baja.

Panel del taller
CU-07

Administrar muebles

Alta con fotos y portada, edición, links a redes, baja lógica y opción de publicar en Novedades.

Panel del taller
CU-08

Gestionar fotos

Agregar, quitar y cambiar la portada de un mueble existente.

Panel del taller
CU-09

Responder consultas

Ver el mueble consultado, escribir la respuesta y enviarla por mail. El estado pasa a Respondida.

Panel del taller
03

Diseño

Arquitectura

SPA en React que consume una API REST en Spring Boot organizada en capas. Pasá el mouse o tocá un bloque.

USUARIOSCLIENTEAPIDATOS Y SERVICIOS Visitantecatálogo y consultas Administradorpanel del taller SPA ReactTypeScript · Vite ControllersREST · DTOs Servicesreglas de negocio RepositoriesSpring Data JPA Servicio de mailavisos y respuestas PostgreSQL 16esquema con Flyway Spring Boot 3 · Java 17 · contenedor Docker
Tocá un bloque para ver qué hace.

Modelo de dominio

Las cinco clases del negocio. Todas heredan un identificador de una entidad base. Tocá una clase para resaltar sus relaciones.

*1pertenece a 11..*galería *1realiza *0..1sobre CategorianombreCategoriaStringfechaAltaDatefechaModificacionDatefechaBajaDate MueblenombreMuebleStringcolorMuebleStringdescripcionStringlinkInstagramString?linkFacebookString?publicarbooleanfechaAlta / fechaBajaString MuebleImagenesesPortadabooleanimagenbyte[] ClientenombreClienteStringapellidoClienteStringtelefonoClienteStringmailClienteStringfechaHoraAltaLocalDateTime ConsultamensajeConsultaStringrespuestaString?fechaHoraAltaLocalDateTime
CatálogoProductoClienteConsultas◆ composición
La clave del modelo: Consulta → Mueble es opcional. Una sola entidad cubre la consulta sobre un producto y la consulta general.

Modelo de datos

Tablas del dominio en PostgreSQL (se omiten algunas fechas de auditoría). PK clave primaria, FK clave foránea.

N1 N1 N1 N0..1 categoriaPKidbigintnombre_categoriavarcharfecha_alta_categoriatimestampfecha_baja_categoriatimestamp mueblePKidbigintnombreMueblevarcharcolorMueblevarchardescripcionvarcharlink_instagramvarcharlink_facebookvarcharpublicarbooleanfecha_alta / fecha_bajavarcharFKcategoria_idbigint mueble_imagenesPKidbigintes_portadabooleanimagen_imagenesbyteaFKmueble_idbigint clientePKidbigintnombre_clientevarcharapellido_clientevarchartelefono_clientevarchar(30)mail_clientevarchar consultaPKidbigintmensaje_consultavarcharrespuestatextfecha_hora_alta_consultatimestampFKcliente_idNOT NULLFKmueble_idNULL
Tocá una tabla para ver un detalle.

Procesos

Los dos flujos que generan valor: la consulta de un cliente y la carga de un mueble.

Consulta y respuesta

ClienteSitio webAPITallerválidoasyncsínoVe un muebleo la HomeCompleta elformularioValida campos(Formik + Yup)Crea Cliente+ ConsultaRecibe avisopor mailEscribe larespuesta¿Mailenviado?Guarda larespuestaRecibe larespuestaVe el error;no se guarda

Alta de un mueble

TallerSitio webAPIVisitantesíCarga datosy fotosComprime fotosde más de 1 MBElige portaday validaGuarda mueble+ imágenes¿Publicar enNovedades?Lo ve enNovedadesLo ve enel catálogo

Estructura de código

Dos repositorios: API y frontend. Vista simplificada.

backend/
Controller/
MuebleController…REST
DTO/
entrada y salida de la API
Entity/
Mueble · Categoria · Consulta…dominio
Service/
BaseService + impl. por entidadreglas
Repositories/
Spring Data JPA
resources/db/migration/
V1__esquema_inicial.sqlFlyway
frontend/src/
pages/
Home · Catalogo · Novedades…
components/
ViewMueble · modales · tablas
services/
clientes HTTP por recurso
styles/
mdz-theme.css · mdz-site.csstema
utils/
comprimirImagen.ts

Principios

  • Capas claras: controlador → servicio → repositorio; la regla de negocio vive en el servicio.
  • Reutilizar antes de duplicar: servicio base genérico en la API y componentes mdz-* compartidos en el front.
  • El esquema se versiona: ningún cambio de tabla sin su migración.

Decisiones de diseño

Formato ADR: contexto, decisión y lo que cuesta.

Contexto
Hay consultas sobre un mueble puntual y consultas generales desde la Home. Antes existía una entidad distinta ("solicitar visita").
Decisión
Consulta.mueble admite nulo. Si es nulo, es una consulta general.
Consecuencias
Un solo flujo, una sola pantalla de gestión (con dos pestañas). Se resigna validar a nivel de base que cierto tipo de consulta tenga mueble: eso queda en la lógica.
Contexto
Si se guarda la respuesta y el mail falla, el panel la muestra como respondida pero el cliente nunca la recibió.
Decisión
Primero se envía el mail; solo si sale bien se persiste la respuesta.
Consecuencias
No hay respuestas "fantasma". A cambio, si el mail falla el administrador tiene que reintentar y el texto no queda guardado.
Contexto
Con generación automática del esquema, la base de cada entorno podía quedar distinta. Además se migró de MySQL a PostgreSQL.
Decisión
Flyway maneja las tablas; Hibernate arranca en modo validate.
Consecuencias
Mismo esquema en local, CI y producción. Cuesta disciplina: cualquier cambio de entidad necesita su migración o la app no arranca.
Contexto
Había un diseño de referencia hecho con Tailwind y shadcn, pero el frontend usa React-Bootstrap.
Decisión
Extraer la paleta y la tipografía a variables CSS y reescribir los estilos con clases prefijadas mdz-, en 8 fases.
Consecuencias
Sin dependencias nuevas ni choques con el CSS existente, y migración pantalla por pantalla. Se resigna la velocidad de usar componentes ya hechos.
Contexto
Cada mueble tiene varias fotos y el proyecto corre en infraestructura sencilla.
Decisión
Guardar la imagen como bytea junto al mueble, y comprimirla en el navegador antes de subirla.
Consecuencias
Un solo lugar para respaldar y nada que sincronizar. Se resigna el rendimiento de un almacenamiento de objetos con CDN; el listado devuelve solo la portada para compensar.
Contexto
Novedades debe mostrar trabajos recientes, no muebles viejos que se editan.
Decisión
La marca se define en el alta y la columna no se actualiza en ediciones.
Consecuencias
El feed se mantiene honesto sin reglas extra. Si el taller se equivoca al crear, no lo puede corregir editando.
04

Implementación

Tecnologías

Frontend

ReactTypeScriptViteReact RouterReact-BootstrapFormik + YupCSS propio

Backend

Java 17Spring Boot 3Spring Data JPAHibernateSpring MailLombok

Datos

PostgreSQL 16Flyway

Entrega

DockerGitHub ActionsnginxRamas master / develop

Módulos

Las fotos son trabajos reales del taller que usa el sitio.

Taller de MDZ Muebles

Home

Hero con carrusel, destacados con un mueble por categoría y formulario de contacto general.

Público
Placar a medida

Catálogo

Filtro por categoría, búsqueda con debounce y paginado. En celular, el filtro pasa a un desplegable.

Público
Rack de TV a medida

Ficha de producto

Galería con miniaturas y pantalla completa, y formulario de consulta atado al mueble.

Público
Cocina a medida

Novedades

Feed de los trabajos publicados, del más nuevo al más viejo.

Público

Evolución

  1. Primera versiónCatálogo y una entidad "solicitar visita".
  2. Refactor a ConsultaModelo unificado de consultas con respuesta por mail.
  3. Octubre 2026 · Rediseño visualNueva identidad en 8 fases, de la Home a los modales.
  4. Noviembre 2026 · ProductoNovedades, aviso de consultas por mail, optimización de imágenes y auditoría mobile.
  5. Noviembre 2026 · PlataformaPostgreSQL + Flyway, CI con GitHub Actions, rama de producción protegida y despliegue.

¿Hablamos?

Si te interesa cómo trabajo, con gusto te cuento más del proyecto.