# Restoman

**Infraestructura para restaurantes, hecha distinto.**

Restoman es una plataforma B2B que corre el salón de un restaurante — órdenes, mesas, cocina y caja — construida por un equipo de cuatro que dirijo como CEO. Está andando en su primer local, y empezó como un proyecto de colegio que solo servía para un restaurante.

- 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
- Sitio: https://www.restoman.app

## 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.

---

Página: https://eitanf.com/es/work/restoman · English: https://eitanf.com/work/restoman.md · llms.txt: https://eitanf.com/llms.txt
