Ir al contenido
Eitan FeldmanBA, ARGCVenes
All work

Restoman

Infraestructura para restaurantes, hecha distinto.

Rol
CEO. Producto, diseño, y la mayor parte del código.
Período
2025 — hoy
Estado
Activo
Trabajo
Producto · Full-stack · Diseño · Negocio

El problema

Un restaurante funciona sobre información que no se queda quieta. Qué pidió cada mesa. Qué empezó la cocina de verdad. Qué se cobró y qué no. Quién tiene permiso para anular una línea.

La mayoría de los locales tiene todo eso en una mezcla de papel, grito y un sistema de punto de venta diseñado antes de los smartphones. Funciona, en el sentido de que la gente come. Falla de una forma concreta: nadie puede contestar una pregunta sobre la última hora sin caminar a algún lado y preguntarle a una persona.

El software que existe para arreglarlo está hecho para una cadena de doscientos locales y cuesta lo que eso implica, o es un menú en PDF.

De dónde salió la idea

No de un hueco de mercado. De una versión peor de esto mismo.

En tercer año, cuatro armamos Pedilo — Simón Mersich, Oliver Jones, Nicolás Krymkiewicz y yo. Simón había hecho algo parecido para un curso, para reemplazar los PDF que los restaurantes mandaban, y quisimos hacerlo bien y en la web. Anduvo bien y tenía un límite duro: servía para exactamente un restaurante. Podías agregar productos y tomar pedidos. No podías crear un segundo local.

El giro pasó en una cena. Alguien vio el proyecto y me explicó cómo funcionan los centros comerciales en realidad: quién los maneja, quién le alquila a quién, cómo se administra el patio de comidas como una sola cosa. Volviendo a casa me di cuenta de que la versión interesante no era un restaurante: era un patio de comidas, donde una docena de locales comparten piso, comparten clientes, y no comparten nada más. Nadie construye para eso, porque no es el cliente obvio de nadie.

Así que dejamos de teorizar y empezamos a hablar con gente que sí iba a saber. Escribí en nombre del equipo de Pedilo proponiendo una plataforma donde cada restaurante de un centro pudiera tomar y manejar sus propias órdenes, controlar stock y ver sus números, atada a un sitio central por centro y por operador. Ese mail es el primer registro escrito de Pedilo volviéndose Restoman.

Las restricciones

Cuatro personas, ninguna full-time, todas todavía en el secundario. Sin inversión. Y una que marcó cada decisión: el primer cliente tenía que seguir atendiendo mientras lo instalábamos. Nada podía requerir que el personal pare y aprenda un sistema, y nada podía tener un paso que solo funciona si alguien se acuerda de hacerlo.

Qué es, en realidad

No una app. Cuatro, en un monorepo de Turborepo sobre workspaces de Bun:

  • api — todo el dominio. Elysia, tipada de punta a punta, con un documento OpenAPI que los frontends consumen por Eden Treaty, así un cambio en una ruta es un error de tipos en el dashboard y no un bug en producción. Better Auth, Drizzle sobre Postgres, Redis.
  • dashboard — Next 16 y React 19. Lo que usa el negocio: organizaciones, locales, carta, órdenes, cocina, caja, roles, billing.
  • diner — Next 16. Lo que usa el comensal. Entrás escaneando el QR de tu mesa. Anda como invitado anónimo o con cuenta por OTP, porque pedirle a alguien que se cree una cuenta antes de poder pedir una hamburguesa es como se pierde el pedido.
  • landing — el sitio público.

Más paquetes compartidos que existen porque dos apps necesitaban la misma respuesta: permissions (el vocabulario de RBAC y un resolver puro, usado por la API y por el editor de roles, así lo que otorga acceso y lo que dibuja la UI no pueden estar en desacuerdo), ui (el design system — Base UI, CVA, Motion, tokens espejados de Figma), features (feature flags), schemas, i18n, logger.

Qué decidí

Cinco decisiones que tomé y que defiendo.

Escribimos las organizaciones y el RBAC nosotros, en vez de usar el plugin de auth

El plugin modela una empresa plana: miembros, roles, listo. Un grupo gastronómico es una jerarquía — grupo, local, piso, estación — y un permiso tiene que heredar hacia abajo sin escalar nunca hacia arriba ni al costado.

La alternativa era dejar el plugin y modelar la jerarquía al lado, consultándola después de que el plugin contestara. Habría funcionado, y habría significado dos fuentes de verdad para una pregunta. Cada chequeo habría tenido que preguntarle a las dos y reconciliar, y la primera vez que no coincidieran tendríamos un bug de seguridad y no uno de renderizado.

Así que es nuestro schema, con la herencia resuelta por permiso y no por rol: no "un encargado puede hacer X", sino "este permiso hereda hacia abajo desde el scope donde se otorgó". Más código, y es nuestro. Vale la pena, porque los permisos son la única parte de este sistema donde aproximadamente bien y mal son lo mismo.

La posición de un plato es de la relación, no del plato

Un ítem aparece en varios contextos — la carta, una sección, una estación de cocina — y puede estar ordenado distinto en cada uno. Hacer que la posición sea una columna del ítem fuerza un orden global. Hacerla una propiedad del par contexto-ítem significa que no ordenar es simplemente heredar.

Esa está implementada y marcada para rehacer. Funciona, y mover un solo ítem escribe N filas. Prefiero decirlo acá que alguien lo encuentre.

El cache es fail-open, asimétricamente

Un miss de cache degrada a una lectura más lenta. Un error de cache no puede degradar nunca a un permiso equivocado. Y los tokens efímeros viven fuera del cache, porque no son cache: son estado que además expira.

Los overlays del comensal portalean dentro del scope de tema del local

Cada local tematiza su propia app del comensal. Los modales renderizados en la raíz del documento se escapaban de ese scope y salían sin estilos. El arreglo es chico; lo útil es la regla que dejó, y está escrita para que no se redescubra.

La caja es una pantalla para cobrar, no un reporte

Investigada contra Toast, Fudo y Mercado Pago antes de dibujar nada. Lo que las tres aciertan es que la persona en la caja está apurada y todo lo que está en pantalla o es el monto o está estorbando.

El equipo

  • Yo — CEO. Producto, diseño, y la mayor parte del código.
  • Simón Mersich — CTO. Arquitectura y backend.
  • Oliver Jones — COO. Ventas y onboarding B2B.
  • Nicolás Krymkiewicz — CXO. Experiencia.

También es un proyecto académico de ORT, con dos tutores, y son dos cosas distintas a propósito. Alguien más formó parte de la parte académica de Restoman; siempre estuvo hablado y entendido que no iba a formar parte del negocio y que no se usaría nada de su propiedad intelectual en él. Esa línea existía antes de que importara, que es la única vez en que una línea así vale algo.

Dónde está

Andando en su primer local. Todavía no nos paga — estamos probando con ellos, en su servicio, con su personal.

Hay más esperando para entrar, y a propósito todavía no los dejamos. Hacer el onboarding de un local bien significa estar ahí mientras pasa, y cuatro personas no pueden estar en cinco lugares. Ir despacio es la decisión que hace que los primeros funcionen, no la que hace que el número parezca más grande.

Buscando inversión ángel.

La cifra de 500 locales del anteproyecto es capacidad proyectada, no tracción. Prefiero escribir esa frase que un inversor que sabe la diferencia la deduzca solo.

Qué haría distinto

Empezar el design system antes de las pantallas, no después. Volver a mirar el orden por contexto antes de que le creciera una segunda implementación encima. Y escribir qué pasa si alguien se va antes del primer mes de facturación, no después.

Next caseGemm