Saltar al contenido
Caso · 16 / 19← Todos los trabajos

La Trencería

Una web app con la marca de un estudio de trenzas afro en Mar del Plata: reservas online, tienda, cursos pagos y puntos de fidelidad, instalable en el celular.

Rol
Desarrollo completo para una clienta
Stack
Next.js 16, React 19, TypeScript, Prisma + Postgres, Auth.js (NextAuth v5), Mercado Pago, Tailwind CSS 4
Home
HomeUn lock de Postgres por estilista evita turnos dobles
(01) El problema

Katia manejaba el estudio desde Instagram y WhatsApp. Cada turno era un chat, todos los días llegaban las mismas preguntas sobre precios y duración, y las clientas que no venían le dejaban horas que no podía llenar. Quería vender cursos grabados y productos para el pelo, y no tenía dónde. Necesitaba una app con su marca que pudiera manejar sola desde el celular, sin pedirle a un desarrollador que cambie un texto.

Mi rolConstruí el producto entero, del modelo de datos y los pagos a las pantallas de administración que usa todos los días.
(02) ResultadosContados en el código
50pantallas entre el sitio, la cuenta de clienta y el panel
43modelos de Prisma detrás de reservas, tienda, cursos y fidelidad
62textos y fotos del sitio que la dueña edita desde el panel, sin deploy
(03) Arquitectura

Tres decisiones que lo definieron.

  1. 01

    Un lock de Postgres por estilista evita turnos dobles

    Por qué. Chequear un horario y después guardarlo deja un hueco donde dos personas se quedan con la misma hora. La reserva corre en una sola transacción que primero toma un advisory lock sobre la estilista, después busca cualquier solapamiento y recién ahí crea el turno. El segundo pedido espera y recibe un 409 claro. Los canjes de puntos usan el mismo patrón por clienta, así dos toques no gastan los mismos puntos dos veces.

    El costo. Todas las reservas de una estilista pasan de a una. Con un solo estudio no cuesta nada, pero no escalaría a un marketplace. El lock vive en SQL crudo, fuera de lo que modela Prisma, así que hay que acordarse de él en cada camino de escritura nuevo.

  2. 02

    Páginas públicas estáticas, purgadas por tag cuando se guarda en el panel

    Por qué. El sitio corre en un plan gratuito, así que las páginas públicas se generan estáticas y sus lecturas se cachean bajo seis tags: home, servicios, productos, galería, cursos y reseñas. Cada guardado del panel purga sólo su tag, con vencimiento inmediato, así Katia ve el cambio en la carga siguiente. Antes, un guardado invalidaba todo el árbol del layout.

    El costo. Cada ruta del panel tiene que purgar el tag correcto; si falta una llamada, la página queda vieja y nada falla. Hay 41 de esas llamadas en 27 archivos. El vencimiento inmediato también cuesta un render completo por guardado.

  3. 03

    Los textos y los mensajes son configuración, con defaults en el código

    Por qué. Los textos de la home, las fotos, los testimonios y las nueve plantillas de WhatsApp y email viven como filas clave-valor. El código trae un default para cada clave y usa el valor guardado cuando existe. Katia reescribe el mensaje de confirmación o cambia la foto del hero sola, y una base vacía igual muestra un sitio completo.

    El costo. Los valores son strings sin historial, así que una edición mala no se puede deshacer desde el panel. El conjunto de campos sigue fijo en el código: una sección nueva en la home necesita un desarrollador.

(04) GaleríaSeguí scrolleando →
Home
Home · La home pública. Los títulos, los textos y las tres fotos salen del panel.
Reserva en el celular
Reserva en el celular · Paso dos de cuatro. Los horarios tomados y bloqueados aparecen tachados, con las mismas reglas que se cargan en el panel.
Calendario
Calendario · La semana en el panel, con datos de prueba. Los turnos amarillos todavía esperan un pago o una confirmación.
Plantillas de mensajes
Plantillas de mensajes · Los textos de WhatsApp y email para confirmación, recordatorio y cancelación, con variables que la dueña puede mover.
Puntos de fidelidad
Puntos de fidelidad · El saldo y las recompensas de una clienta, con una cuenta de prueba. Las visitas, las reseñas y los referidos suman puntos.
(05) Qué haría después
01Liberar a tiempo los turnos sin pagar. Un turno que espera el pago de Mercado Pago retiene el horario hasta que el webhook avisa una cancelación; un job programado debería liberarlo cuando vence el link de pago.
02Usar una sola regla de solapamiento en el selector de horarios y en la transacción de reserva. El selector sólo mira dónde empieza un turno existente, así que puede ofrecer una hora que después el servidor rechaza con un 409.
03Hacer que el service worker cachee el shell y el próximo turno de la clienta. Hoy sólo maneja las notificaciones push, así que la app instalada no muestra nada sin conexión.
Próximo proyecto · 17 / 19
Noelia Viscelli →Landings que la coach edita sola y una plataforma para su curso
Caso · 16 / 19

La Trencería

Una web app con la marca de un estudio de trenzas afro en Mar del Plata: reservas online, tienda, cursos pagos y puntos de fidelidad, instalable en el celular.

Rol
Desarrollo completo para una clienta
Stack
Next.js 16, React 19, TypeScript, Prisma + Postgres, Auth.js (NextAuth v5), Mercado Pago, Tailwind CSS 4
La Trencería
(01) El problema

Katia manejaba el estudio desde Instagram y WhatsApp. Cada turno era un chat, todos los días llegaban las mismas preguntas sobre precios y duración, y las clientas que no venían le dejaban horas que no podía llenar. Quería vender cursos grabados y productos para el pelo, y no tenía dónde. Necesitaba una app con su marca que pudiera manejar sola desde el celular, sin pedirle a un desarrollador que cambie un texto.

Mi rolConstruí el producto entero, del modelo de datos y los pagos a las pantallas de administración que usa todos los días.
(02) Resultados
50pantallas entre el sitio, la cuenta de clienta y el panel
43modelos de Prisma detrás de reservas, tienda, cursos y fidelidad
62textos y fotos del sitio que la dueña edita desde el panel, sin deploy
(03) Arquitectura

Tres decisiones que lo definieron.

01

Un lock de Postgres por estilista evita turnos dobles

Por qué. Chequear un horario y después guardarlo deja un hueco donde dos personas se quedan con la misma hora. La reserva corre en una sola transacción que primero toma un advisory lock sobre la estilista, después busca cualquier solapamiento y recién ahí crea el turno. El segundo pedido espera y recibe un 409 claro. Los canjes de puntos usan el mismo patrón por clienta, así dos toques no gastan los mismos puntos dos veces.

El costo. Todas las reservas de una estilista pasan de a una. Con un solo estudio no cuesta nada, pero no escalaría a un marketplace. El lock vive en SQL crudo, fuera de lo que modela Prisma, así que hay que acordarse de él en cada camino de escritura nuevo.

02

Páginas públicas estáticas, purgadas por tag cuando se guarda en el panel

Por qué. El sitio corre en un plan gratuito, así que las páginas públicas se generan estáticas y sus lecturas se cachean bajo seis tags: home, servicios, productos, galería, cursos y reseñas. Cada guardado del panel purga sólo su tag, con vencimiento inmediato, así Katia ve el cambio en la carga siguiente. Antes, un guardado invalidaba todo el árbol del layout.

El costo. Cada ruta del panel tiene que purgar el tag correcto; si falta una llamada, la página queda vieja y nada falla. Hay 41 de esas llamadas en 27 archivos. El vencimiento inmediato también cuesta un render completo por guardado.

03

Los textos y los mensajes son configuración, con defaults en el código

Por qué. Los textos de la home, las fotos, los testimonios y las nueve plantillas de WhatsApp y email viven como filas clave-valor. El código trae un default para cada clave y usa el valor guardado cuando existe. Katia reescribe el mensaje de confirmación o cambia la foto del hero sola, y una base vacía igual muestra un sitio completo.

El costo. Los valores son strings sin historial, así que una edición mala no se puede deshacer desde el panel. El conjunto de campos sigue fijo en el código: una sección nueva en la home necesita un desarrollador.

(04) Galería
Home
Home · La home pública. Los títulos, los textos y las tres fotos salen del panel.
Reserva en el celular
Reserva en el celular · Paso dos de cuatro. Los horarios tomados y bloqueados aparecen tachados, con las mismas reglas que se cargan en el panel.
Calendario
Calendario · La semana en el panel, con datos de prueba. Los turnos amarillos todavía esperan un pago o una confirmación.
Plantillas de mensajes
Plantillas de mensajes · Los textos de WhatsApp y email para confirmación, recordatorio y cancelación, con variables que la dueña puede mover.
Puntos de fidelidad
Puntos de fidelidad · El saldo y las recompensas de una clienta, con una cuenta de prueba. Las visitas, las reseñas y los referidos suman puntos.
(05) Qué haría después
01Liberar a tiempo los turnos sin pagar. Un turno que espera el pago de Mercado Pago retiene el horario hasta que el webhook avisa una cancelación; un job programado debería liberarlo cuando vence el link de pago.
02Usar una sola regla de solapamiento en el selector de horarios y en la transacción de reserva. El selector sólo mira dónde empieza un turno existente, así que puede ofrecer una hora que después el servidor rechaza con un 409.
03Hacer que el service worker cachee el shell y el próximo turno de la clienta. Hoy sólo maneja las notificaciones push, así que la app instalada no muestra nada sin conexión.
Próximo proyectoNoelia Viscelli →
Nahuel SantillánES