Decisiones vigentes
Las reglas de negocio vigentes viven en producto/decisiones-vigentes.md. Cualquier excepción o ampliación se documenta allí, no en este archivo.
Reglas de negocio
Reglas fundamentales que rigen la operación del sistema. Deben implementarse desde el primer día.
Cómo se identifican las reglas — 2026-06-07
Cada regla enumerada tiene un ID único con formato RN-XXX que se usa para citarla desde otros documentos (SRS, casos de uso, plan de pruebas, mensajes de error de la API, código backend).
Los IDs siguen la convención:
RN-001 a RN-008: origen del usuario
RN-010 a RN-018: asociación de paquetes
RN-020 a RN-029: envío y consolidación
RN-030 a RN-038: almacenamiento
RN-040 a RN-045: KYC
RN-050 a RN-054: servicios adicionales
RN-060 a RN-065: contenido y costos
RN-070 a RN-075: pagos
RN-080 a RN-095: crecimiento y referidos (Fase 2)
RN-100 a RN-104: auditoría y seguridad
RN-105 a RN-109: webhooks e integraciones externas
RN-110 a RN-118: incidencias y reclamos
Regla de origen del usuario (lectura obligatoria)
Regla inquebrantable — origen del usuario que se registra
La app IslaBox está diseñada para que se registren únicamente personas radicadas en Estados Unidos que compran en marketplaces (Amazon, SHEIN, Temu, etc.) y necesitan enviar sus paquetes a destinatarios en Cuba.
- ✅ Puede registrarse cualquier persona con número de teléfono de EE.UU. (+1), dirección en EE.UU. y un documento de identidad válido para KYC (pasaporte, carné de identidad, licencia de conducir).
- ❌ No puede registrarse una persona con número de Cuba (+53), ni con dirección principal en Cuba, ni cuya identificación sea cubana sin equivalente internacional válido. Si intenta registrarse, el sistema debe rechazar el registro y mostrar un mensaje claro: "IslaBox está disponible solo para usuarios en Estados Unidos que envían a Cuba. Si quieres recibir un paquete, pídele a quien te envía que se registre."
- ✅ Puede aparecer como destinatario en Cuba cualquier persona física en Cuba. Los destinatarios no se registran en la app; los crea y los gestiona el usuario registrado desde la sección Destinatarios de su cuenta.
Modelo de las 3 personas
| Persona |
¿Se registra? |
¿Tiene cuenta en la app? |
¿Tiene identificador de casillero? |
¿Aparece en login? |
| Usuario registrado (comprador en EE.UU.) |
Sí |
Sí |
Sí (ej. CP-001042-8) |
Sí |
| Remitente en EE.UU. (persona que entrega el paquete al casillero) |
No |
No |
No |
No |
| Destinatario en Cuba (persona que recibe el paquete) |
No |
No |
No |
No |
¿Por qué esta regla?
- El casillero físico está en Miami, FL. La dirección que se entrega a Amazon/SHEIN/Temu es la dirección del casillero en Miami, no una dirección personal del usuario.
- El identificador de casillero se asigna al usuario en EE.UU. y es el criterio principal para asociar paquetes a un dueño.
- La operación logística requiere un punto de recepción estable en EE.UU. Un usuario en Cuba no puede poner la dirección del casillero como destino de envío.
- El KYC y la verificación de identidad se hacen contra documentos del usuario en EE.UU.
- Los destinatarios en Cuba no necesitan app ni cuenta: solo necesitan que el usuario registrado les guarde sus datos (nombre, CI, dirección, provincia, municipio, teléfono).
Validaciones concretas a nivel de sistema
| Capa |
Validación |
| Registro — pantalla |
El selector de país del teléfono solo debe listar Estados Unidos (+1). No debe haber dropdown. Si el usuario escribe otro código, mostrar error de validación. |
| Registro — API |
El campo phone debe pasar validación E.164 con prefijo +1 y exactamente 10 dígitos nacionales. Si no, devolver INVALID_PHONE_FORMAT o PHONE_COUNTRY_NOT_SUPPORTED. |
| Registro — modelo |
El campo country_code del usuario se fija en US por defecto y no es editable. |
| Login |
No aplica restricción adicional (un usuario ya creado entra con su correo y contraseña sin importar desde dónde se conecte). |
| Destinatarios |
El campo phone de recipients debe aceptar números de Cuba (+53, 8 dígitos) y de EE.UU. (+1, 10 dígitos), porque en la práctica el destinatario puede tener cualquiera de los dos. |
| Remitentes |
El campo phone de senders debe aceptar solo números de EE.UU. (+1), porque el remitente siempre está en EE.UU. (es quien entrega el paquete al casillero en Miami). |
Mensaje de error sugerido (UX)
No podemos registrar tu cuenta
IslaBox está disponible para personas que viven en Estados Unidos y envían paquetes a Cuba.
Si quieres recibir un paquete, no necesitas registrarte. Pídele a quien te envía que use IslaBox y te agregue como destinatario desde su cuenta.
Si vives en EE.UU. y este mensaje aparece por error, escríbenos a soporte@islabox.com.
Reglas de asociación (RN-010 a RN-014)
| ID |
Regla |
| RN-010 |
Ningún paquete debe avanzar sin usuario asociado. |
| RN-011 |
Todo paquete idealmente debe venir pre-reportado por el usuario. |
| RN-012 |
Si llega un paquete sin reporte, debe ir a cola de conciliación. |
| RN-013 |
El identificador del usuario es el primer criterio de búsqueda. |
| RN-014 |
Tracking y nombre son criterios secundarios. |
Ver también las reglas RN-015 a RN-018 (paquetes no identificados) más abajo.
Reglas de envío (RN-020 a RN-022)
| ID |
Regla |
| RN-020 |
El sistema debe permitir consolidar varios paquetes por usuario en un mismo envío. |
| RN-021 |
Todo envío a Cuba debe tener destinatario claramente definido. El destinatario es una persona en Cuba, no un usuario registrado en la app (ver Regla de origen del usuario). |
| RN-022 |
El sistema debe permitir registrar remitente en Estados Unidos cuando aplique. El remitente también es una persona en EE.UU. y nunca se registra en la app. |
Reglas derivadas (no enumeradas en la doc original, agregadas en la normalización 2026-06-07):
| ID |
Regla |
| RN-023 |
No se puede consolidar un paquete con incidencia abierta. |
| RN-024 |
El usuario debe tener KYC aprobado para crear una consolidación. |
| RN-025 |
El usuario debe tener KYC aprobado para confirmar un envío (pagar o despachar). |
| RN-026 |
Una consolidación cancelada libera los paquetes a esperando_instrucciones (no a en_almacen directo). |
Reglas de almacenamiento (RN-030 a RN-032)
| ID |
Regla |
| RN-030 |
El sistema debe mostrar el tiempo en almacén dentro de la pantalla de detalle del paquete, no en el dashboard general. |
| RN-031 |
El sistema debe enviar notificaciones push antes de que venza el período de almacenaje gratis. |
| RN-032 |
El sistema debe poder aplicar cargos automáticos o manuales por almacenamiento prolongado. |
Reglas derivadas de decisiones de negocio resueltas 2026-06-06 (preguntas.md):
| ID |
Regla |
| RN-033 |
El período de almacenaje gratis es de 15 días naturales por defecto. Configurable globalmente por admin. |
| RN-034 |
El costo por día adicional es de $0.50 USD por defecto. Configurable globalmente. |
| RN-035 |
El conteo de días empieza desde la fecha de recepción del paquete (physical_packages.received_at). |
| RN-036 |
Se envía notificación push al usuario 3 días antes de vencer el período gratis. |
| RN-037 |
El plazo y el efecto del abandono de un paquete están pendientes de D-209. |
| RN-038 |
Paquetes con incidencia abierta no acumulan cargos de almacenaje hasta que se resuelva. |
Reglas de servicios adicionales (RN-050 a RN-052)
| ID |
Regla |
| RN-050 |
La inspección o prueba funcional del producto debe registrarse como servicio adicional con costo independiente. |
| RN-051 |
La devolución a tienda o vendedor debe manejarse como servicio adicional con flujo y costo propio. |
| RN-052 |
Los servicios adicionales tienen sus propios estados (ver Estados oficiales). |
Reglas derivadas:
| ID |
Regla |
| RN-053 |
El usuario debe aprobar el costo del servicio antes de que el operador lo ejecute. |
| RN-054 |
El operador carga evidencia (fotos, videos) del servicio ejecutado, visible para el usuario. |
Reglas de paquetes no identificados
- Si llega un paquete sin identificador pero con tracking, el sistema busca una prealerta con ese tracking y sugiere el usuario.
- Si llega un paquete con identificador pero sin prealerta, el sistema crea el paquete y notifica al usuario para que complete los datos.
- Si llega un paquete sin identificador ni prealerta, va a cola de conciliación para resolución manual.
- Si el identificador es inválido (dígito verificador incorrecto, código no existe, usuario bloqueado), el paquete queda retenido por incidencia hasta resolución.
Matriz de acciones por estado
Paquete físico
| Estado |
Qué ve el cliente |
Qué puede hacer |
prealertado |
Paquete reportado, en camino |
Ver datos, actualizar tracking |
en_camino_al_almacen |
En tránsito hacia almacén |
Ver datos |
recibido_sin_identificar |
Paquete recibido, procesando |
esperar |
recibido_identificado |
Paquete identificado |
Ver fotos, solicitar acción |
pendiente_conciliacion |
Tu paquete llegó pero no lo reconocemos |
Completar datos para identificarlo |
en_almacen |
Paquete en almacén, esperando instrucciones |
Enviar, consolidar, inspeccionar, devolver |
esperando_instrucciones |
Sin instrucciones aún |
Enviar, consolidar, solicitar servicio |
en_servicio_adicional |
Servicio en proceso |
Ver estado del servicio |
listo_para_consolidar |
Listo para agrupar |
Agregar a consolidación |
reservado_para_consolidacion |
Incluido en consolidación |
Ver consolidación |
consolidado |
En envío agrupado |
Ver consolidación y tracking |
en_transito |
En camino a Cuba |
Seguir tracking |
entregado |
Entregado |
Ver confirmación |
retenido_por_incidencia |
Paquete retenido |
Ver motivo, resolver |
devuelto_a_tienda |
En devolución |
Ver estado de devolución |
Prealerta (reporte de compra)
| Estado |
Qué ve el cliente |
Qué puede hacer |
borrador |
Reporte incompleto |
Completar datos, eliminar |
reportada |
Compra reportada, esperando llegada |
Editar, agregar tracking, cancelar |
reportada_sin_tracking |
Compra reportada, sin tracking aún |
Agregar tracking cuando esté disponible |
tracking_actualizado |
Tracking agregado |
Ver y editar si cambia |
vinculada_a_paquete |
Vinculada a paquete recibido |
Ver paquete |
cancelada_por_usuario |
Cancelada por ti |
Ninguna (ver historial) |
cancelada_por_operador |
Cancelada por el equipo |
Contactar soporte |
requiere_correccion |
Datos incompletos o incorrectos |
Corregir información |
KYC
| Estado |
Puede prealertar? |
Puede despachar? |
Puede consolidar? |
sin_iniciar |
✅ |
❌ |
❌ |
borrador |
✅ |
❌ |
❌ |
enviado |
✅ |
❌ |
❌ |
en_revision |
✅ |
❌ |
❌ |
aprobado |
✅ |
✅ |
✅ |
rechazado |
✅ |
❌ |
❌ |
requiere_mas_informacion |
✅ |
❌ |
❌ |
vencido |
✅ |
❌ |
❌ |
bloqueado_manual |
❌ |
❌ |
❌ |
Reglas de paquetes no identificados (RN-015 a RN-018)
| ID |
Regla |
| RN-015 |
Si llega un paquete sin identificador pero con tracking, el sistema busca una prealerta con ese tracking y sugiere el usuario. |
| RN-016 |
Si llega un paquete con identificador pero sin prealerta, el sistema crea el paquete y notifica al usuario para que complete los datos. |
| RN-017 |
Si llega un paquete sin identificador ni prealerta, va a cola de conciliación para resolución manual. |
| RN-018 |
Si el identificador es inválido (dígito verificador incorrecto, código no existe, usuario bloqueado), el paquete queda retenido por incidencia hasta resolución. |
Reglas de contenido y costos (RN-060 a RN-061)
| ID |
Regla |
| RN-060 |
La información de aduana no debe quedar fija en texto; debe ser administrable. |
| RN-061 |
Los costos deben distinguir claramente cada concepto: |
| Concepto de costo |
Descripción |
| Servicio de casillero |
Uso del casillero y dirección |
| Envío internacional |
Transporte desde EE.UU. a Cuba |
| Consolidación |
Agrupación de múltiples paquetes |
| Almacenaje adicional |
Días extra después del período gratuito |
| Inspección o prueba |
Revisión visual o funcional del producto |
| Devolución |
Gestión de retorno a tienda o vendedor |
| Gestión |
Costos administrativos o de trámite |
| Aduana |
Pagos aduaneros aplicables |
| Entrega final |
Reparto en Cuba al destinatario |
Transparencia
El usuario siempre debe poder ver un desglose claro de lo que está pagando y por qué. Nunca deben aparecer cargos sorpresa sin explicación.
Reglas derivadas (no enumeradas en la doc original, agregadas 2026-06-07):
| ID |
Regla |
| RN-062 |
El usuario siempre debe poder ver un desglose claro de lo que está pagando. Nunca deben aparecer cargos sorpresa. |
| RN-063 |
La cotización tiene vigencia de 7 días desde su emisión. Pasado ese plazo se marca como vencida y se regenera. |
| RN-064 |
El operador puede aplicar descuentos manuales sobre una cotización, pero cada descuento debe quedar auditado con actor_id, monto, motivo. |
| RN-065 |
La suma de los quote_items debe ser igual al total de la cotización. La API valida esta consistencia antes de aceptar la cotización. |
Reglas de KYC (RN-040 a RN-045)
| ID |
Regla |
| RN-040 |
El KYC bloquea el despacho, no la prealerta. El usuario puede reportar compras aunque no tenga KYC aprobado. |
| RN-041 |
El KYC es válido por 10 años desde la fecha de aprobación (kyc_records.expires_at). Pasado ese plazo, el usuario debe re-verificar. |
| RN-042 |
El usuario solo puede consolidar y despachar con KYC en estado aprobado. Ver RN-024 y RN-025. |
| RN-043 |
El operador puede aprobar, rechazar (con motivo) o requerir más información sobre un KYC. |
| RN-044 |
El usuario puede cargar el KYC antes de necesitarlo, pero no se le exige hasta que intente consolidar o despachar. |
| RN-045 |
El KYC con estado vencido o bloqueado_manual requiere re-verificación o desbloqueo manual. |
Reglas de pago (RN-070 a RN-075)
| ID |
Regla |
| RN-070 |
El MVP acepta pagos manuales registrados por el operador. Stripe entra en Fase 2. |
| RN-071 |
Un pago puede combinar dinero real + crédito + tarjeta vía payment_method_mix. |
| RN-072 |
Solo el webhook de Stripe (Fase 2) puede confirmar pagos online con status = completado. El resto de actores (user, operator) solo pueden crear pagos en estado pendiente. |
| RN-073 |
El sistema debe usar lock distribuido en Redis para evitar doble cobro al confirmar un pago. |
| RN-074 |
El reembolso solo puede ser iniciado por un admin (users.role = admin) y debe quedar registrado en audit_logs. |
| RN-075 |
Si el cargo de Stripe falla, el payment.status debe pasar a fallido y la consolidación sigue en pendiente_pago. |
Reglas de auditoría y seguridad (RN-100 a RN-104)
| ID |
Regla |
| RN-100 |
Todo cambio de estado debe generar un registro en audit_logs con actor_id, resource, old_status, new_status, timestamp, ip. |
| RN-101 |
Las acciones administrativas (PATCH /api/v1/admin/*) requieren scope admin o sysadmin y quedan auditadas. Si es sysadmin, se exige segundo factor (TOTP). |
| RN-102 |
El acceso a documentos KYC ajenos se registra con actor_id, subject_id, ip, timestamp. La visualización por operator se hace con datos enmascarados. |
| RN-103 |
Toda evidencia fotográfica de paquetes y servicios se almacena en MinIO con URLs prefirmadas y tiempo de expiración de 5 minutos. |
| RN-104 |
El sistema no comparte datos del usuario con la agencia aliada sin consentimiento explícito del usuario registrado en T&C. |
Reglas de webhooks e integraciones externas (RN-105 a RN-109)
| ID |
Regla |
| RN-105 |
La firma del webhook de la agencia aliada es obligatoria (HMAC-SHA256). Webhook sin firma válida se rechaza con HTTP 400 y se registra como evento de seguridad. |
| RN-106 |
La idempotencia de webhooks se garantiza por webhook_events.event_id con UNIQUE KEY. Un mismo event_id no se procesa dos veces. |
| RN-107 |
La agencia aliada tiene hasta 24 horas hábiles para reportar la entrega final; pasado ese plazo, el envío se marca como "entrega pendiente de confirmación" y se contacta a la agencia. |
| RN-108 |
Los webhooks de Stripe (cuando estén activos en Fase 2) deben verificar la firma usando STRIPE_WEBHOOK_SECRET antes de procesar cualquier evento. Sin firma válida → HTTP 400. |
| RN-109 |
El handler de webhooks debe responder 2xx en menos de 5 segundos; cualquier procesamiento pesado se delega a workers asíncronos. |
Reglas de incidencias y reclamos (RN-110 a RN-118)
Documento normativo de referencia: flujos/incidencias-reclamos.md.
| ID |
Regla |
| RN-110 |
Toda creación, cambio de estado y cierre de incidencia queda registrado en audit_logs. |
| RN-111 |
El usuario solo puede ver y responder sus propias incidencias. |
| RN-112 |
Un operador solo puede cerrar incidencias que le están asignadas, salvo que sea admin o sysadmin. |
| RN-113 |
Un reembolso solo puede ser iniciado por un operator asignado a la incidencia o por un admin. |
| RN-114 |
Una incidencia cerrada por más de 30 días no se puede reabrir; el usuario debe abrir una nueva. |
| RN-115 |
Toda evidencia fotográfica de una incidencia se almacena con URLs prefirmadas expirables (5 min) y queda auditada al ser visualizada (RN-102, RN-103). |
| RN-116 |
Una incidencia de tipo articulo_prohibido no se cierra sin antes haber escalado al admin y registrado la acción legal. |
| RN-117 |
Una incidencia de tipo pago_duplicado genera automáticamente un reembolso por el monto duplicado una vez confirmada. |
| RN-118 |
El SLA de primera respuesta es 24 horas hábiles (lun-vie 9-18 EST). El SLA de resolución es 5 días hábiles para incidencias 🟠 Alta y 10 días hábiles para 🟡 Media. Las incidencias 🔴 Crítica tienen SLA de primera respuesta de 4 horas hábiles y de resolución de 48 horas hábiles. |
Reglas del programa de crecimiento y referidos (RN-080 a RN-095) — Fase 2
Reglas que gobiernan el sistema de referidos, niveles, crédito y fidelidad. Para la especificación completa ver Modelo de crecimiento.
Generación de beneficios (RN-080 a RN-082)
| ID |
Regla |
| RN-080 |
Solo los envíos pagados con dinero real (no con crédito ni tarjetas) generan crédito para el referidor y cuentan para el nivel. |
| RN-081 |
El pool se calcula por cada libra real enviada, no por el valor monetario del envío. |
| RN-082 |
El crédito se acredita al referidor únicamente cuando el referido completa y paga el envío, no cuando lo reporta. |
Reglas del crédito (RN-083 a RN-086)
| ID |
Regla |
| RN-083 |
El crédito no es dinero, no es retirable y no puede convertirse en efectivo bajo ninguna circunstancia. |
| RN-084 |
El crédito no genera más crédito: pagar un envío total o parcialmente con crédito no activa nuevos bonos. |
| RN-085 |
El crédito tiene vencimiento configurable desde el panel de administración. Crédito no usado en plazo definido se pierde automáticamente. |
| RN-086 |
Al convertir crédito en tarjeta, la tarjeta hereda la fecha de vencimiento original del crédito. No se extiende ni reinicia. |
| RN-087 |
El sistema debe notificar al usuario con anticipación antes de que su crédito expire. |
Reglas de uso del crédito por nivel (RN-088 a RN-091)
| ID |
Regla |
| RN-088 |
Nivel 1: el crédito puede cubrir hasta el 50% del costo del envío. El 50% restante debe pagarse con dinero real. |
| RN-089 |
Nivel 2: el crédito puede cubrir hasta el 75% del costo del envío. El 25% restante debe pagarse con dinero real. |
| RN-090 |
Nivel 3: el crédito puede cubrir hasta el 100% del costo del envío. Se recomienda no abusar de envíos 100% crédito. |
| RN-091 |
El sistema debe bloquear automáticamente cualquier intento de aplicar crédito por encima del porcentaje permitido según el nivel. |
| ID |
Regla |
| RN-092 |
Las tarjetas solo pueden emitirse dentro del tope de la ventana rolling de 30 días según el nivel (3 / 9 / 24 tarjetas totales). |
| RN-093 |
El tope se aplica por denominación y por total. No se puede emitir más de la cantidad máxima de cada denominación. |
| RN-094 |
Las tarjetas solo son aplicables a envíos propios del usuario receptor. |
| RN-095 |
Las tarjetas no se transfieren, no se venden y no tienen valor fuera del sistema. |
Reglas de referidos y ventanas
- Cada persona referida tiene su propia ventana individual de 180 días, contada desde su fecha de registro.
- Un referido solo cuenta para el nivel del referidor si tiene envíos reales dentro de su ventana activa y supera el mínimo de libras requerido para ese nivel.
- Al expirar la ventana de un referido, ese referido deja de contar para el nivel y deja de generar crédito, independientemente de cuántas libras haya acumulado.
- El referidor no puede influir en retrasar o extender la ventana de un referido. La ventana es fija desde el registro.
Reglas de niveles dinámicos
- Los niveles se evalúan de forma continua. El sistema actualiza el nivel de cada usuario en tiempo real o por proceso programado al detectar cambios en la red.
- Subir de nivel es automático al cumplir los requisitos.
- Bajar de nivel es también automático si se dejan de cumplir los requisitos. No hay período de gracia.
- El historial de cambios de nivel debe registrarse con fecha, motivo y estado previo para auditoría.
- Un ajuste manual de nivel por el administrador debe quedar registrado en el log de auditoría con justificación.
Reglas del pool de fidelidad
- El pool de fidelidad solo existe si el pool de referidos no fue consumido en su totalidad para ese usuario ese período.
- El usuario solo puede acceder al 30% del pool libre que él mismo generó con sus propios envíos reales.
- El beneficio de fidelidad nunca se entrega como crédito. Solo como tarjetas o cupones con vencimiento.
- El beneficio de fidelidad no cuenta para subir de nivel y no genera crédito adicional.