Appearance
Una aplicación, varios negocios y verticales
Documento migrado desde
franmc01/ninaku-core-api. Las decisiones de negocio, dominio y base de datos siguen vigentes; las referencias a ASP.NET Core / .NET son históricas: el backend actual es NestJS y su arquitectura se define en ARCHITECTURE.md y NESTJS_STACK_GUIDE.md.
Estado: contrato de la siguiente fase, acordado con el usuario. No describe frontend ni endpoints ya implementados. La entrega actual es el baseline SQL; el backend actual es NestJS (ver ARCHITECTURE.md), y ASP.NET Core 10 es histórico. Se complementa con los contratos API y los límites de administración.
Experiencia que queremos
La persona entra una vez a Ninaku y puede trabajar en sus negocios autorizados sin cerrar sesión. El selector muestra nombres comprensibles, por ejemplo «La Esquina · Centro» y «Tienda Norte». Al cambiar, se actualizan navegación, herramientas y resumen. La sesión continúa mientras sea válida; una expiración o revocación sí puede exigir autenticación.
Se reutilizan la identidad visual y los componentes adecuados de katarion-labs/ninaku-pos: marca, tipografía, colores, formularios, tarjetas, selector, layout y mapa. Registro y acceso tendrán lenguaje neutral. Cocina, mesas, ilustraciones y vocabulario de restaurante pertenecen a esa vertical. El mapa conserva búsqueda, ubicación voluntaria, pin y dirección editable; escribir la dirección debe funcionar si el mapa no carga. Los negocios sin ubicación física no necesitan un mapa para empezar.
La ventaja de producto se comprobará observando si una persona nueva logra su primera tarea y cambia de negocio sin confundirse. La composición de menús, por sí sola, no demuestra esa ventaja.
Modelo de contexto
| Concepto | Responsabilidad |
|---|---|
| Identidad y sesión | La persona autenticada; puede tener acceso a varias organizaciones |
| Organización y membresía | Frontera tenant y pertenencia autorizada |
| Unidad de negocio | Negocio operativo seleccionado, independiente de su vertical |
| Local / outlet | Ubicación operativa cuando la tarea lo necesita |
| Entidad legal / RUC | Titular jurídico de cada operación; no se deduce únicamente de la vertical |
| Vertical y capacidades | Operación disponible y experiencia específica; un negocio puede combinar varias |
Un hotel con restaurante no se convierte en otra empresa al abrir Cocina. Cambiar de negocio y cambiar de área operativa son selecciones distintas. Las relaciones válidas entre organización, unidad, local y entidad legal las resuelve el servidor; no se acepta una combinación de IDs solo porque llegó del navegador.
El contexto efectivo contiene organización, membresía, unidad de negocio, local cuando corresponda, capacidades y permisos efectivos. La operación resuelve su entidad legal y conserva el snapshot vendedor. El perfil vertical seleccionado adapta la experiencia y nunca concede permisos. Los comandos organizacionales tienen su alcance propio: no requieren inventar un local.
Contenedor común y contribuciones de cada vertical
El contenedor común mantiene sesión, selector de negocio/local, cabecera, composición del sidebar, idioma, tema, ayuda y estado de conexión/sincronización. Cada vertical aporta rutas, acciones, tarjetas, vocabulario y pasos de configuración propios mediante un registro tipado en el mismo frontend. No hacen falta microfrontends, plugins remotos ni un motor universal de pantallas para esta fase.
La visibilidad exige a la vez capacidad habilitada, permisos suficientes y contexto compatible. Los planes comerciales aplican donde corresponda. El servidor valida cada consulta y comando incluso si el cliente altera el menú o abre una URL directamente.
Clientes, catálogo, inventario, compras, caja, cuentas y reportes reutilizan componentes y contratos comunes según estén habilitados. Reutilizar una pantalla no comparte automáticamente sus datos. El catálogo compartido respeta asignación y surtido; ventas, saldos y deudas conservan su titular, organización y moneda. Un reporte consolidado necesita autorización y alcance explícitos. Cocina y mesas aparecen para operaciones de restaurante; no se fuerzan en retail.
Cambio de negocio seguro
- Recuperar las opciones autorizadas y paginadas; elegir automáticamente solo si existe una opción válida inequívoca. Revalidar la última selección guardada.
- Solicitar el contexto destino y su versión de permisos. Si se deniega, no mostrar datos del destino ni una mezcla de ambos negocios.
- Aislar claves de caché por contexto, cancelar solicitudes anteriores cuando sea posible y descartar respuestas tardías. Renovar las suscripciones en tiempo real con autorización del destino.
- Cargar navegación y workspace del destino. Los borradores permanecen vinculados al contexto de origen. Si existe trabajo sin guardar, conservarlo o permitir resolverlo antes de salir; nunca trasladar una venta a otro RUC por cambiar el selector.
- Cada pestaña conserva su selección y cada solicitud declara el contexto que el servidor valida. Cambiar en una pestaña no cambia silenciosamente el destino de un cobro abierto en otra. La preferencia del último negocio no es autoridad de seguridad.
La API mantiene la consulta propuesta GET /api/v1/session/context y el presupuesto de dos solicitudes de datos para la carga inicial normal con sesión válida. El catálogo paginado de negocios se obtiene al abrir/buscar en el selector, no dentro de una respuesta ilimitada. La primera entrega del backend debe concretar OpenAPI y errores del bootstrap, selección y workspace antes de conectar el frontend.
Onboarding progresivo
| Momento | Lo mínimo visible | Resultado verificable |
|---|---|---|
| Crear cuenta | Identidad y método de acceso disponible | Cuenta creada sin duplicarse ante un reintento |
| Verificar / acceder | Paso exigido por la política de ese método | El servidor acredita el identificador; el frontend no marca verificación |
| Elegir destino | Entrar a un negocio invitado o crear uno propio | Un invitado no crea accidentalmente otra organización |
| Crear negocio | Nombre y actividad inicial; región cuando determina moneda o reglas operativas | Provisioning idempotente y administración válida |
| Preparar operación | Pocos pasos propios de la vertical | Primera tarea útil; avances guardados y reanudables |
| Ampliar | Más locales, RUC, cajas, equipo y capacidades cuando se necesiten | Configuración avanzada sin repetir el registro |
El método de verificación no está limitado conceptualmente al correo. Teléfono o un proveedor federado requieren su integración y política de confianza; no se muestran como disponibles antes de implementarlos. La ubicación y datos fiscales se piden cuando la operación los exige, evitando bloquear una exploración inicial con información innecesaria. No se promete vender o facturar sin la configuración necesaria.
La fuente de verdad está en el servidor. Estado de identidad, membresía, organización y avance de onboarding son dimensiones diferentes: una persona activa puede tener una invitación pendiente y un negocio suspendido. El onboarding usa pasos requeridos/completados/pendientes/omitidos permitidos, y una siguiente acción calculada. Reanudar no vuelve a provisionar la organización; completar un checklist no activa una organización suspendida. Se reutilizan las estructuras existentes antes de añadir persistencia.
Offline desde la primera fase
Solo puede abrirse para operar offline un contexto previamente preparado en ese dispositivo, con autorización local acotada y vigente para las acciones permitidas. Una sesión conservada no equivale a autorización offline ilimitada. Alta, recuperación, nuevos permisos y admisión de nuevos negocios requieren servidor; sus formularios pueden conservarse como borradores.
La base local y la cola separan organización, negocio, local, dispositivo y actor original. Cada comando conserva identidad, contexto, evidencia y clave idempotente. Cambiar el selector no cambia el destino de operaciones pendientes. Reconectar envía cada una a su contexto original y muestra confirmado, rechazado o requiere conciliación sin perder evidencia. No se interpretan operaciones pendientes como cobros confirmados.
Una revocación no puede conocerse instantáneamente sin red. La política de vigencia, dispositivos revocados y conciliación es el pendiente H08: debe resolverse y probarse antes de habilitar escritura offline en producción. H06 (historia de asignaciones) y H07 (fecha local) siguen siendo gates de los flujos afectados. No se bloquea el diseño del contenedor por ellos, ni se declara resuelto el protocolo porque exista un indicador «sin conexión».
Fases y criterio de salida
- Baseline: fusionar la PR SQL verificada. Esto establece la base y no constituye un despliegue del backend. Mantener las brechas explícitas.
- Identidad, organización y contexto en backend: registro/verificación según método habilitado, sesión, invitación, provisioning reanudable, selección autorizada y permisos/capacidades. Primera entrega vertical de código, con pruebas HTTP y PostgreSQL; no un CRUD por tabla.
- Contenedor y onboarding frontend: reutilizar POS donde corresponda, acceso neutral, selector y sidebar compuesto. Conectar a los contratos reales; las demostraciones con fixtures se identifican como tales.
- Primera operación y contraste: restaurante como primer flujo completo; un escenario retail acotado comprueba reutilización y aislamiento antes de generalizar. Incorporar escritura offline solo al pasar sus pruebas de admisión y recuperación.
La siguiente fase no se considera terminada hasta demostrar: una persona con dos organizaciones; dos locales y tres cajas independientes; negocio con dos verticales; empleado con alcance limitado; usuario invitado; reintento de alta sin duplicación; onboarding reanudado; revocación durante cambio de contexto; respuesta tardía del negocio anterior; dos pestañas en negocios distintos; borrador y cola conservados al cambiar; destino no preparado sin red; rechazo de APIs ajenas aunque se manipule el sidebar. Son criterios pendientes de implementación, no pruebas aprobadas por el baseline SQL.
Protección de main
En esta revisión, listar rulesets devolvió una lista vacía y consultar la protección clásica devolvió HTTP 403, Resource not accessible by integration. La conexión disponible no expone escritura de protección. Por tanto, no se afirma protección activa ni se atribuye este 403 a un plan concreto. La documentación de docs/context/ es histórica y no acredita la configuración actual del repositorio.
Configuración a aplicar por un administrador con acceso: regla activa para main, cambios mediante PR, check obligatorio clean-install, rama actualizada antes de fusionar, conversaciones resueltas y bloqueo de force-push/borrado. No exigir dos aprobaciones en un equipo de una persona. Verificar las restricciones y excepciones efectivas después de guardar. CI verde y una política documentada no sustituyen la protección en GitHub.