POS + Ecommerce API.
Una REST API lista para producción que unifica las operaciones de punto de venta y ecommerce en un solo backend, diseñada desde el primer día para atender a varias tiendas desde un único despliegue.
Resumen
Una REST API lista para producción que unifica las operaciones de punto de venta y ecommerce en un solo backend, diseñada desde el primer día para atender a varias tiendas desde un único despliegue. El sistema está construido como un monolito modular: un Cargo workspace divide el dominio en crates aislados (identity, inventory, purchasing, sales, core, common) con una capa api-gateway responsable de los aspectos HTTP, la inyección de dependencias, la resolución del tenant y el mapeo de errores. El objetivo era obtener los beneficios de mantenibilidad de los microservicios y las garantías de aislamiento del multi-tenancy sin la carga operativa: límites fuertes, compilación independiente y una sola unidad desplegable.
Pilares clave
Cargo workspace modular
Dominio dividido en crates independientes (identity, inventory, purchasing, sales) con dependencias explícitas que el compilador de Rust hace cumplir.
RBAC con JWT + Argon2
Middleware basado en permisos, roles predefinidos (Admin, Manager, Cashier) y hash de contraseñas con argon2.
Consultas de SQLx verificadas en compilación
Cada sentencia SQL se verifica contra el esquema real en tiempo de compilación, detectando desviaciones antes de llegar a producción.
API Gateway con Axum
Un único punto de entrada HTTP con un contenedor de DI basado en estado compartido, un mapeo unificado de errores a HTTP y extractores tipados como CurrentUser.
Identificadores UUID v7
IDs ordenados por tiempo en todos los agregados para mantener los índices compactos y conservar el orden natural de escritura.
Base multi-tenant
Arquitectura preparada para alojar varias tiendas en un solo despliegue, con el contexto del tenant resuelto en el borde y propagado por el dominio mediante extractores tipados.
Aislamiento de tenants sin una flota de servicios
Ejecutar varias tiendas independientes sobre un solo backend implica que cada consulta, verificación de permisos y clave de caché tiene que tener en cuenta el tenant, y equivocarse filtra los datos de un cliente en el panel de otro.
La solución
La identidad del tenant se saca de los handlers y se lleva al contexto de la solicitud mediante extractores de Axum, de modo que se resuelve una sola vez en el borde y fluye automáticamente por los repositorios. La estructura del workspace mantiene la lógica con alcance de tenant dentro de los crates de dominio, dejando al api-gateway como el único lugar que hace cumplir el límite.
"El multi-tenancy como aspecto transversal resuelto en el borde, no como un flag que se pasa por cada función."
Evitar que un monolito se degrade
Mezclar los flujos de punto de venta y ecommerce en un solo código implicaba el riesgo de la clásica bola de barro: lógica de ventas filtrándose en el inventario, dependencias circulares y una suite de tests que solo corre de punta a punta.
La solución
Estructuré el proyecto como un Cargo workspace donde cada bounded context es su propio crate. El compilador bloquea el acoplamiento accidental, cada módulo expone una API pública acotada y el api-gateway es el único lugar que los conecta mediante un estado de aplicación compartido.
"Límites de dominio aplicados en tiempo de compilación en lugar de en la revisión de código."
Autorización sin código repetitivo
Un sistema de punto de venta tiene decenas de acciones granulares (reembolsar, anular, ajustar inventario, gestionar usuarios). Codificar las verificaciones en cada handler es propenso a errores y dispersa las políticas por todo el código.
La solución
Centralicé la autenticación y la aplicación de permisos en un middleware de Axum y un extractor CurrentUser. Los roles y permisos viven en la base de datos, se cargan en cada solicitud y las rutas declaran el permiso que requieren, de modo que los handlers se mantienen enfocados en la lógica de negocio.
"Las verificaciones de permisos se convirtieron en una anotación de una línea en la ruta."
Evolución de la base de datos segura y repetible
Los cambios de esquema y los datos iniciales (permisos, roles, tienda por defecto) tenían que ser confiables en las máquinas de desarrollo, en CI y en producción, sin desviaciones ni filas duplicadas.
La solución
Adopté migraciones de SQLx para el esquema y un crate de seed idempotente dedicado para los datos de arranque. El seed puede ejecutarse cualquier cantidad de veces sin producir duplicados, y la verificación de consultas en tiempo de compilación garantiza que el código coincida con el esquema actual.
"Esquema, consultas y datos de seed verificados antes de producir el binario."
¿Listo para explorar el código?
POS + Ecommerce API es de código abierto y está disponible para revisión. Conoce las decisiones de arquitectura detrás de este proyecto.