Navegabilidad - ISPC-WEB-2025/TodoStock-AppMovil GitHub Wiki

🗺️ Diagrama de Navegabilidad y Flujos de Pantalla (#TK102)

Proyecto: TodoStock Mobile — Android Nativo (Java / Material Design 3)
Historia de Usuario: US17 / Sprint 2
Tarea Técnica: #TK102 — Diagrama de navegabilidad y Anexo II con capturas de las pantallas nuevas (#150)
Responsable: Octavio Arnaudo / Equipo CodeLab


📌 1. Resumen de Navegabilidad y Arquitectura de Flujo

La aplicación móvil TodoStock implementa un modelo de navegación explícito basado en Activities de Android, gestionado por Intents, controladores de sesión (SesionManager) y validación de roles de usuario (ADMINISTRADOR vs EMPLEADO/VENDEDOR).

Principios Fundamentales del Flujo:

  1. Punto de Entrada Unificado (SplashActivity): Al iniciar la app, se presenta el Splash durante 3 segundos. Al finalizar el temporizador, se navega hacia LoginActivity ejecutando finish() para evitar el retorno mediante el botón físico/gesto "Atrás".
  2. Ciclo de Autenticación (LoginActivity ↔ RegistroActivity):
    • El usuario inicia sesión autenticándose contra la API REST (POST /api/usuarios/login/). Si la credencial es correcta, se almacena el token JWT de forma segura a través de SesionManager (SharedPreferences) y se redirige a MenuPrincipalActivity.
    • Si el usuario no posee cuenta, accede a RegistroActivity (POST /api/usuarios/registro/). Al completar el registro con éxito, una ventana de diálogo confirma el alta y retorna a LoginActivity.
  3. Hub Central de Operaciones (MenuPrincipalActivity - #TK114):
    • Actúa como panel principal reorganizado con distribución vertical limpia y sin numeración estática. Muestra la sesión activa con encabezado accesible "Bienvenido/a", nombre de usuario y rol.
    • Distribuye la navegación hacia las pantallas operativas directas e intermedias:
      • 🏢 Selección de Sucursal (SeleccionSucursalActivity)
      • 📦 Hub de Gestión de Stock (MenuStockActivity - #TK113) ➔ GestionStockActivity
      • ➕ Carga de Producto (CargaProductoActivity)
      • 🔄 Hub de Movimientos de Stock (MenuMovimientosActivity - #TK113) ➔ MovimientosActivity
      • ✉️ Contacto / Soporte (ContactoActivity)
      • 👤 Perfil de Usuario (PerfilActivity)
  4. Cierre de Sesión: El botón "Cerrar sesión" destruye los tokens JWT en SesionManager, redirige a LoginActivity y limpia el back-stack mediante finish().

📊 2. Diagrama de Navegabilidad (Mermaid)

graph TD
    %% Nodos Principales
    START([Inicio App]) --> Splash[SplashActivity<br/>Splash & Logo]
    Splash -- "Timer 3s<br/>(finish)" --> Login[LoginActivity<br/>Autenticación JWT]

    %% Flujo de Registro
    Login -- "Click 'Registrarme'" --> Registro[RegistroActivity<br/>Formulario de Registro]
    Registro -- "Nav Back / Registro Exitoso<br/>(finish)" --> Login
    Registro -- "Click 'Ver Términos'" --> TyC[Diálogo / Pantalla<br/>Términos y Condiciones]

    %% Flujo de Inicio de Sesión Exitoso
    Login -- "Auth Exitosa 200 OK<br/>(Guarda JWT en SesionManager + finish)" --> Menu[MenuPrincipalActivity<br/>Hub Principal de Navegación - TK114]

    %% Sub-pantallas y Hubs desde el Menú Principal
    Menu -- "Click 'Sucursales'" --> Sucursales[SeleccionSucursalActivity<br/>Lista de Sucursales]
    Menu -- "Click 'Gestión de Stock'" --> StockHub[MenuStockActivity<br/>Hub de Stock - TK113]
    StockHub -- "Ver Inventario" --> Stock[GestionStockActivity<br/>Inventario por Sucursal]
    Menu -- "Click 'Carga Producto'" --> CargaProd[CargaProductoActivity<br/>Alta en Catálogo]
    Menu -- "Click 'Movimientos'" --> MovHub[MenuMovimientosActivity<br/>Hub de Movimientos - TK113]
    MovHub -- "Registrar Traslado" --> Movimientos[MovimientosActivity<br/>Traslado de Stock]
    Menu -- "Click 'Contacto'" --> Contacto[ContactoActivity<br/>Formulario de Soporte]
    Menu -- "Click 'Perfil'" --> Perfil[PerfilActivity<br/>Datos del Usuario]

    %% Navegación Interna entre Sucursal y Stock
    Sucursales -- "Selecciona Sucursal<br/>(Intent: sucursal_id)" --> Stock

    %% Cierre de Sesión
    Menu -- "Click 'Cerrar Sesión'<br/>(Limpia SesionManager + finish)" --> Login

    %% Botones de Retorno (Back Navigation)
    Sucursales -. "Toolbar Back (finish)" .-> Menu
    StockHub -. "Toolbar Back" .-> Menu
    Stock -. "Toolbar Back" .-> StockHub
    CargaProd -. "Toolbar Back" .-> Menu
    MovHub -. "Toolbar Back" .-> Menu
    Movimientos -. "Toolbar Back" .-> MovHub
    Contacto -. "Toolbar Back" .-> Menu
    Perfil -. "Toolbar Back" .-> Menu

    %% Estilos de Nodos
    classDef inicio fill:#1e293b,stroke:#475569,stroke-width:2px,color:#fff;
    classDef auth fill:#1e40af,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef hub fill:#15803d,stroke:#22c55e,stroke-width:2px,color:#fff;
    classDef subpantalla fill:#374151,stroke:#9ca3af,stroke-width:1px,color:#fff;

    class START,Splash inicio;
    class Login,Registro,TyC auth;
    class Menu,StockHub,MovHub hub;
    class Sucursales,Stock,CargaProd,Movimientos,Contacto,Perfil subpantalla;
Loading

📋 3. Matriz de Contratos de Intent y Transferencia de Datos

A continuación se detallan las claves (Extras) transmitidas en los Intents entre pantallas para garantizar la consistencia del estado global:

Activity Origen Activity Destino Extra Key Tipo Descripción / Propósito
SplashActivity LoginActivity (Ninguno) - Transición automática por temporizador (3000 ms). Executa finish().
LoginActivity RegistroActivity (Ninguno) - Navegación hacia formulario de alta. Permite volver con botón atrás.
LoginActivity MenuPrincipalActivity EXTRA_USUARIO String Nombre completo del usuario autenticado devuelto por el backend.
LoginActivity MenuPrincipalActivity rol_usuario String Rol activo ("Administrador" o "Empleado"). Executa finish().
MenuPrincipalActivity SeleccionSucursalActivity rol_usuario String Transmite el rol para restringir o habilitar acciones específicas.
MenuPrincipalActivity GestionStockActivity rol_usuario
sucursal_id
String
int
Transmite el rol y la sucursal activa seleccionada por defecto (default: 1).
SeleccionSucursalActivity GestionStockActivity sucursal_id
sucursal_nombre
int
String
Transmite el ID y Nombre de la sucursal elegida en la lista para filtrar el stock.
MenuPrincipalActivity CargaProductoActivity rol_usuario String Transmite el rol para control de permisos de alta en catálogo.
MenuPrincipalActivity MovimientosActivity rol_usuario String Transmite el rol para la transferencia atómica de existencias.
MenuPrincipalActivity ContactoActivity rol_usuario String Transmite el rol para envío de consultas o feedback de soporte.
MenuPrincipalActivity PerfilActivity EXTRA_USUARIO String Muestra la información del perfil del usuario autenticado.
MenuPrincipalActivity LoginActivity (Ninguno) - Acción "Cerrar sesión": borra la sesión en SesionManager y executa finish().

🔒 4. Matriz de Control de Acceso por Rol (RBAC)

De acuerdo con el modelo de dominio de TodoStock (ADR-0007 / ADR-0008), las pantallas y endpoints de la API adaptan sus funcionalidades según la jerarquía de roles:

Pantalla / Operación SuperAdministrador (is_superuser=True) Administrador Estándar (rol=ADMINISTRADOR) Empleado / Vendedor (es_empleado=True)
Splash & Login ✅ Habilitado ✅ Habilitado ✅ Habilitado
Registro de Usuario ✅ Habilitado ✅ Habilitado ✅ Habilitado (Pendiente)
Menú Principal (Hub) ✅ Control Total ✅ Acceso Administrativo ✅ Acceso Operativo
Selección de Sucursal ✅ Ver todas las sucursales ✅ Ver todas las sucursales ✅ Ver sucursales asignadas
Gestión de Stock ✅ Lectura y Edición de Umbrales ✅ Lectura y Edición de Umbrales ✅ Consulta de existencias
Carga de Producto (Catálogo) ✅ Alta, Edición y Baja Lógica ✅ Alta, Edición y Baja Lógica ⚠️ Solo lectura / Deshabilitado
Movimientos de Stock ✅ Autorización y Traslado ✅ Autorización y Traslado ✅ Registro de traslados
Crear Usuarios Administradores ✅ Habilitado (Control Total) 🚫 Bloqueado (HTTP 403) 🚫 Bloqueado (HTTP 403)
Aprobar Admin Pendientes ✅ Habilitado 🚫 Bloqueado (HTTP 403) 🚫 Bloqueado (HTTP 403)
Aprobar Empleados Pendientes ✅ Habilitado ✅ Habilitado 🚫 Bloqueado (HTTP 403)
Editar Perfiles de Administradores ✅ Habilitado 🚫 Bloqueado (HTTP 403) 🚫 Bloqueado (HTTP 403)
Editar Perfiles de Empleados ✅ Habilitado ✅ Habilitado 🚫 Solo su propio perfil
Contacto / Soporte & Perfil ✅ Habilitado ✅ Habilitado ✅ Habilitado

📑 5. Criterios de Aceptación Cumplidos (#TK102)

  • Publicación en Wiki y Anexo II: El diagrama de navegabilidad está publicado en formato Mermaid interactivo y documentado en el Anexo II.
  • Coincidencia con el Comportamiento Real: El flujo coincide al 100% con la implementación en código Java (AndroidManifest.xml e Intents explícitos de las Activities).
  • Representación de Pantallas Nuevas: Se integraron RegistroActivity, CargaProductoActivity, ContactoActivity y PerfilActivity junto con las pantallas originales del Sprint 1.

🔄 6. Máquina de Estados de Navegación, Contratos de Intent y Seguridad de Rutas

🚀 6.1 Ciclo de Vida del Estado de Navegación en Android (app/src/main/)

  1. Evaluación de Sesión Inicial (SplashActivity): Al lanzar la app, SplashActivity consulta SesionManager.isLoggedIn(). Si el JWT es válido y no ha expirado, redirige directamente a MenuPrincipalActivity suprimiendo la pantalla de Login mediante finish().
  2. Transferencia de Estado entre Activities y Modales: La selección de sucursal en SeleccionSucursalActivity almacena el ID activo en SesionManager.setSucursalActiva(sucursalId) y transmite el parámetro sucursal_id hacia GestionStockActivity y MovimientosActivity. La administración de cuentas en UsuariosActivosFragment (#TK37 - PR #300) despliega un diálogo modal condicional para edición de datos y baja lógica.
  3. Cierre Seguro de Sesión (MenuPrincipalActivity): Al pulsar "Cerrar sesión", SesionManager.clearSession() destruye los tokens JWT e inscribe el flag is_logged_out, limpiando el backstack con Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK.

🔒 6.2 Doble Capa de Validación de Roles (Android UI vs Backend)

  • Capa Cliente (UI Android): MenuPrincipalActivity deshabilita o visibiliza botones como "Carga de Producto" evaluando los flags de perfil is_superuser y es_empleado.
  • Capa Servidor (API REST Django): Si un cliente modificado intenta forzar una petición POST /api/inventario/productos/ o PATCH /api/usuarios/me/ con un token de rol inadecuado, las vistas decoradas con @permission_classes([IsAdminUser]) en Backend/inventario/views.py rechazan la solicitud con HTTP 403 Forbidden.

Volver al Home de la Wiki | Ver Anexo II (IEEE830)

⚠️ **GitHub.com Fallback** ⚠️