====== Estados de flujo de entrega en MachineDomain ====== ===== Visión general ===== En ''MachineDomain'', el dispositivo máquina ejecuta una máquina de estados (''StateManager'') que controla el flujo completo de cada entrega. Los estados son secuenciales y cada uno es responsable de un aspecto diferente del procesamiento de entregas. Antes de que esa máquina de estados arranque, la app ahora resuelve una **jornada operativa visible** a partir de ''MinutaMenuDue + MachineEnrollmentShift''. Esto deja la experiencia alineada con la Maquina #1: el operador elige una jornada del día y no una asignación técnica cruda. Archivo principal: * ''MachineDomain/src/main/java/co/ada/domain/state/StateManager.kt'' ===== Interfaz ''State'' ===== Cada estado implementa la interfaz ''State'': interface State { val name: String suspend fun run( next: () -> Unit, retry: (String) -> Unit ): Unit } * ''name'': identificador del estado. * ''run()'': ejecuta la lógica del estado. * ''next()'': avanza al siguiente estado. * ''retry()'': retrocede y emite un mensaje de error. ===== Estados de la máquina de entregas ===== Los estados se ejecutan en este orden: ==== 1. ''WaitingForWeight'' ==== * Espera a que se coloque un peso en la balanza. * Verifica que el flujo anterior esté completado. ==== 2. ''CaptureImages'' ==== * Captura imágenes del producto/entrega desde la cámara. * Almacena las fotos localmente en rutas del dispositivo. ==== 3. ''CaptureFace'' ==== * Captura la cara del beneficiario mediante la cámara frontal. * Genera datos biométricos para verificación. ==== 4. ''ComparingWeights'' ==== * Compara el peso capturado con el peso esperado. * Valida que el peso esté dentro de rangos aceptables. * Si hay desviación, puede requerir recaptura. ==== 5. ''GenerateEmbedding'' ==== * Genera un embedding vectorial de 512 dimensiones de la cara del beneficiario. * Usa modelo de IA local para la extracción de características. * Almacena el embedding en la base de datos local. ==== 6. ''VerifyInDatabase'' ==== * Consulta la base de datos local para verificar que el beneficiario existe. * Si hay múltiples coincidencias de embeddingos similares, puede requerir confirmación. * Calcula similitud entre el embedding capturado y los registrados. ==== 7. ''SaveDelivery'' ==== * Guarda la entrega en la base de datos local. * Registra timestamp, fotos, peso, embedding, beneficiario. * Marca la entrega como lista para sincronizar. ==== 8. ''WaitForWeightRemoved'' ==== * Espera a que se retire el peso de la balanza. * Valida que el ciclo esté completo antes de reiniciar. ===== Flujo de control del ''StateManager'' ===== Inicio ↓ [Selección de jornada operativa] ↓ [Estado 1] → [Estado 2] → ... → [Estado 8] ↓ (next) ↓ (next) Avanza Reinicia desde Estado 1 ↓ (retry) Retrocede a Estado 1 + emite error ==== Comportamiento ==== * Cuando un estado llama ''next()'', el ''StateManager'' avanza al siguiente. * Cuando llama ''retry(reason)'', retrocede a ''Estado 1'' y emite mensaje de error. * Si hay excepción no controlada, se registra y se retrocede. * Los estados son síncronos pero se ejecutan en contexto de corrutina. ===== Emisores asociados ===== * ''StateNameEmitter'': emite el nombre del estado actual para la UI. * ''StateMessageEmitter'': emite mensajes de error o información. * ''StateContextEmitter'': almacena contexto compartido entre estados. ===== Reintento y recuperación ===== Si en algún punto hay un error: - Se invoca ''retry(reason)''. - Se resetea ''currentIndex = 0''. - Se retira al usuario a ''WaitingForWeight''. - Se muestra el mensaje de error. - El usuario puede reintentar. ===== Integración con base de datos ===== * ''MachineData/database.db'' almacena entregas, beneficiarios, asignaciones técnicas (''MachineEnrollmentShift'') y jornadas operativas del día (''MinutaMenuDue''). * VectorDB (ORM local) indexa embeddings para búsquedas rápidas. ===== Nota sobre jornadas ===== * ''MachineEnrollmentShift'' sigue siendo la referencia interna para guardar entregas, beneficiarios y actividad. * ''OperationalShift'' es una proyección en memoria usada por la UI. * Si varias asignaciones corresponden a la misma jornada del día, la UI las agrupa y activa un representante para mantener intacto el flujo interno de la Maquina #2.