La tienda ya puede abrir
Racoonity ya puede conocer a sus clientes, abrir y cerrar una caja, reconstruir su estado después de un reinicio y sobrevivir a dos mapaches intentando cerrarla al mismo tiempo.
Hasta ahora Racoonity ya sabía algunas cosas importantes.
Sabía quién podía entrar.
Sabía qué productos existían.
Sabía dónde estaba la mercancía.
Pero todavía faltaba una pregunta bastante elemental:
¿cómo empieza realmente un día de trabajo?
Una tienda no comienza su operación cuando alguien crea un producto en un catálogo.
Comienza cuando alguien llega, entra al sistema, tiene una caja disponible, puede consultar sus métodos de pago y abre una sesión para empezar a trabajar.
Ese fue el objetivo de nuestra cuarta iteración:
I4 — Preparar la operación diaria
Y terminó siendo bastante más interesante de lo que ese nombre tan inocente sugiere.
Primero: los clientes ya existen
I4 introduce un nuevo dominio en Racoonity:
Customer.
Parece una entidad sencilla.
Nombre.
Teléfono.
Correo.
Notas.
Activo o archivado.
Y precisamente por eso era importante no convertirla prematuramente en un monstruo.
No agregamos crédito.
No agregamos puntos.
No agregamos RFC, CURP ni datos fiscales.
No agregamos ventas.
No agregamos una dirección por cada planeta conocido.
El cliente de este MVP tiene únicamente lo necesario para existir y poder ser utilizado posteriormente por otros dominios.
También tomamos una decisión importante:
los clientes pertenecen a una empresa, no a una sucursal.
Una persona no deja de ser cliente porque hoy compró en otra ubicación.
Así que Customer quedó definido con ownership por compañía y sin branch_id.
También permitimos homónimos.
Racoonity no va a asumir que solamente puede existir un Juan Pérez en todo el negocio porque alguien decidió ponerle un UNIQUE(name) a una tabla un martes por la tarde.
Actualizar no siempre significa escribir
Uno de los detalles que más terminamos cuidando fue customer.update.
La operación utiliza semántica PATCH real.
Eso significa que:
- un campo omitido no cambia;
- un campo opcional enviado vacío puede convertirse en
null; - un nombre vacío es inválido;
- y enviar exactamente los mismos datos que ya existen es un éxito… pero no una escritura.
Esto último nos importa bastante.
Si nada cambió:
- no hacemos
UPDATE; - no modificamos
updated_at; - no producimos un evento nuevo.
El sistema reconoce que hacer nada correctamente también es un resultado válido.
Lo mismo ocurre con archivar un cliente ya archivado o habilitar uno que ya estaba activo.
No necesitamos fingir actividad para sentir que el sistema está trabajando.
Después llegó la caja
Racoonity ya tenía el concepto de Register desde las primeras iteraciones.
Pero hasta ahora una caja era principalmente una pieza de configuración.
I4 introduce lo que realmente le da vida:
RegisterSession.
Una sesión representa el periodo operacional de una caja.
Puede estar:
- abierta;
- cerrada normalmente;
- cerrada forzosamente por un administrador.
Y nada más.
No existe reopen.
No existe una transición secreta.
No existe una sesión zombie regresando de closed a open porque algún handler decidió improvisar.
El flujo es deliberadamente pequeño:
open
├──> closed
└──> force_closed