# MII-005: Procesamiento IA --- id: MII-005 type: Epic status: Completado priority: P0 phase: 1 story_points: 34 created_date: 2026-01-10 updated_date: 2026-01-13 simco_version: "4.0.0" --- ## Metadata | Campo | Valor | |-------|-------| | **ID** | MII-005 | | **Nombre** | Procesamiento IA | | **Fase** | 1 - MVP Core | | **Prioridad** | P0 | | **Story Points** | 34 | | **Estado** | Completado | --- ## 1. Descripcion Implementar el pipeline de procesamiento de video con IA para deteccion, identificacion y conteo de productos, incluyendo el job asincrono, abstraccion de proveedores, y consolidacion multi-frame. ### Objetivo Procesar videos de anaqueles para identificar y contar productos automaticamente, entregando resultados precisos al usuario. --- ## 2. Requerimientos Relacionados | RF | Descripcion | Prioridad | |----|-------------|-----------| | FR-031 | Job asincrono con estados PENDING/PROCESSING/DONE/FAILED | P0 | | FR-032 | Notificacion push o polling para "resultado listo" | P1 | | FR-033 | Almacenamiento temporal (7-30 dias) y borrado automatico | P1 | | FR-040 | Deteccion con bounding boxes/segmentacion | P0 | | FR-041 | Identificacion SKU (multiclase o 2 etapas) | P0 | | FR-042 | Consolidacion multi-frame (evitar doble conteo) | P0 | | FR-043 | Umbrales de confianza (Duda, Desconocido) | P0 | --- ## 3. Criterios de Aceptacion ### AC-001: Job Asincrono ```gherkin DADO que un video fue subido exitosamente CUANDO el sistema lo recibe ENTONCES se crea un job con status PENDING Y se encola para procesamiento Y el usuario puede ver el status en tiempo real ``` ### AC-002: Deteccion de Productos ```gherkin DADO que el job esta en PROCESSING CUANDO el sistema analiza los frames ENTONCES detecta productos con bounding boxes Y cada deteccion tiene coordenadas y confianza ``` ### AC-003: Identificacion de SKU ```gherkin DADO que hay productos detectados CUANDO el sistema los identifica ENTONCES asocia cada producto a un SKU conocido O lo marca como "Desconocido" si no hay match O lo marca como "Duda" si conf < threshold ``` ### AC-004: Consolidacion Multi-frame ```gherkin DADO que un producto aparece en multiples frames CUANDO el sistema consolida resultados ENTONCES lo cuenta una sola vez Y usa tracking espacial-temporal Y el conteo final es preciso ``` ### AC-005: Notificacion de Resultado ```gherkin DADO que el procesamiento termino CUANDO el status cambia a DONE ENTONCES el usuario recibe notificacion push Y puede ver el reporte inmediatamente ``` ### AC-006: Almacenamiento Temporal ```gherkin DADO que un video fue procesado CUANDO pasan N dias (configurable) ENTONCES el video y artefactos se eliminan automaticamente Y los resultados del inventario se mantienen ``` --- ## 4. Tareas Tecnicas | ID | Tarea | Estimacion | Estado | |----|-------|------------|--------| | T-001 | Crear modulo ia-provider en NestJS | 2 SP | Completado | | T-002 | Implementar abstraccion de proveedores IA | 3 SP | Completado | | T-003 | Crear adapter para proveedor inicial | 2 SP | Completado | | T-004 | Implementar servicio de extraccion de frames | 2 SP | Completado | | T-005 | Crear procesador de queue (Bull) | 3 SP | Completado | | T-006 | Implementar pipeline de deteccion | 4 SP | Completado | | T-007 | Implementar identificacion de SKU | 4 SP | Completado | | T-008 | Crear algoritmo de consolidacion multi-frame | 5 SP | Completado | | T-009 | Implementar tracking espacial-temporal | 3 SP | Completado | | T-010 | Crear logica de umbrales y estados | 2 SP | Completado | | T-011 | Implementar notificaciones push | 2 SP | Completado | | T-012 | Crear job de limpieza automatica | 2 SP | Completado | --- ## 5. Arquitectura del Pipeline ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ PIPELINE DE PROCESAMIENTO IA │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Video │──▶│ Extract │──▶│ Detect │──▶│ Identify │──▶│Consolidate│ │ │ │ Input │ │ Frames │ │ Products │ │ SKU │ │ Results │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ │ │ S3 Key 10-30 frames Bounding Product IDs Final Count │ │ @ 1 fps Boxes + Confidence per SKU │ │ │ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │ │ IA PROVIDER ABSTRACTION │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ │ │ OpenAI │ │ Claude │ │ Google │ │ Custom │ │ │ │ │ │ Vision │ │ Vision │ │ Vision │ │ Model │ │ │ │ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │ │ │ └──────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## 6. Modelo de Datos ### Tabla: inventory_sessions ```sql CREATE TABLE inventory_sessions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), store_id UUID REFERENCES stores(id), user_id UUID REFERENCES users(id), video_id UUID REFERENCES videos(id), status VARCHAR(20) DEFAULT 'PENDING', started_at TIMESTAMP, completed_at TIMESTAMP, total_products INT, total_items INT, confidence_avg DECIMAL(5,2), credits_consumed INT, cogs_amount DECIMAL(10,4), ia_provider VARCHAR(50), processing_metadata JSONB, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Status: PENDING, PROCESSING, DONE, FAILED ``` ### Tabla: inventory_items ```sql CREATE TABLE inventory_items ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), session_id UUID REFERENCES inventory_sessions(id) ON DELETE CASCADE, product_id UUID REFERENCES products(id), quantity INT NOT NULL, confidence DECIMAL(5,2), status VARCHAR(20) DEFAULT 'DETECTED', bounding_boxes JSONB, -- Array de boxes por frame frame_numbers INT[], evidence_urls TEXT[], user_corrected BOOLEAN DEFAULT false, original_product_id UUID, original_quantity INT, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Status: DETECTED, DOUBT, UNKNOWN, CONFIRMED, CORRECTED ``` ### Tabla: products ```sql CREATE TABLE products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(200) NOT NULL, brand VARCHAR(100), category VARCHAR(100), subcategory VARCHAR(100), barcode VARCHAR(50), presentation VARCHAR(100), embedding VECTOR(1536), -- Para busqueda por similitud image_url VARCHAR(500), is_verified BOOLEAN DEFAULT false, created_by UUID REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); ``` ### Tabla: cogs_records ```sql CREATE TABLE cogs_records ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), session_id UUID REFERENCES inventory_sessions(id), provider VARCHAR(50), frames_processed INT, tokens_used INT, cost_usd DECIMAL(10,6), cost_mxn DECIMAL(10,4), exchange_rate DECIMAL(10,4), created_at TIMESTAMP DEFAULT NOW() ); ``` --- ## 7. Endpoints API | Metodo | Endpoint | Descripcion | Auth | |--------|----------|-------------|------| | POST | /inventory/sessions | Crear sesion de inventario | JWT | | GET | /inventory/sessions/:id | Obtener sesion | JWT | | GET | /inventory/sessions/:id/status | Estado del procesamiento | JWT | | GET | /inventory/sessions/:id/items | Items detectados | JWT | | POST | /inventory/sessions/:id/reprocess | Reprocesar sesion | JWT | --- ## 8. Abstraccion de Proveedores ### Interface IAProvider ```typescript interface IAProvider { name: string; detectProducts(frames: Buffer[]): Promise; identifyProduct(detection: Detection): Promise; getCostPerFrame(): number; isAvailable(): Promise; } interface Detection { frameNumber: number; boundingBox: BoundingBox; confidence: number; embedding?: number[]; } interface ProductMatch { productId: string | null; confidence: number; alternatives: Array<{productId: string; confidence: number}>; isKnown: boolean; } ``` --- ## 9. Algoritmo de Consolidacion ``` 1. Para cada frame F[i]: - Obtener detecciones D[i] = detect(F[i]) 2. Para cada deteccion d en D[i]: - Calcular embedding e(d) - Buscar match en detecciones anteriores por: a. Posicion similar (IoU > 0.5) b. Embedding similar (cosine > 0.8) 3. Si hay match: - Actualizar track existente - Promediar confianza 4. Si no hay match: - Crear nuevo track 5. Al final: - Agrupar tracks por producto - Contar instancias unicas - Aplicar umbrales de confianza ``` --- ## 10. Umbrales de Confianza | Rango | Estado | Accion | |-------|--------|--------| | >= 0.85 | DETECTED | Incluir en reporte | | 0.60 - 0.84 | DOUBT | Solicitar confirmacion | | < 0.60 | UNKNOWN | Permitir etiquetado | --- ## 11. Dependencias ### Entrada (Requiere) - MII-001: Infraestructura Base - MII-002: Autenticacion - MII-003: Gestion de Tiendas - MII-004: Captura de Video ### Salida (Bloquea) - MII-006: Reportes de Inventario - MII-007: Retroalimentacion - MII-009: Wallet y Creditos (COGS) --- ## 12. Integraciones | Servicio | Uso | |----------|-----| | Bull/Redis | Job queue | | S3/MinIO | Frames y artefactos | | OpenAI/Claude | Vision API | | Firebase FCM | Push notifications | | PostgreSQL | Resultados | --- ## 13. Riesgos | Riesgo | Probabilidad | Impacto | Mitigacion | |--------|--------------|---------|------------| | IA imprecisa | Alta | Alto | Retroalimentacion, fine-tuning | | Costos altos | Media | Alto | Optimizar frames, cache | | Latencia | Media | Medio | Async, notificaciones | | Proveedor caido | Baja | Alto | Fallback a otro proveedor | --- ## 14. Metricas | Metrica | Objetivo | |---------|----------| | Precision | > 80% en productos conocidos | | Tiempo promedio | < 2 minutos por sesion | | Costo promedio | < $0.50 USD por sesion | | Tasa de "Duda" | < 15% de detecciones | | Tasa de "Desconocido" | < 10% de detecciones | --- ## 15. Referencias - [REQUERIMIENTOS-FUNCIONALES.md](../00-vision-general/REQUERIMIENTOS-FUNCIONALES.md) - Secciones 5.4, 5.5 - [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md) - [ADR-0003](../97-adr/ADR-0003-abstraccion-proveedores-ia.md) - Abstraccion IA - [INT-006](../02-integraciones/INT-006-ia-provider.md) - Integracion IA --- **Ultima Actualizacion:** 2026-01-10