miinventario-v2/docs/01-epicas/MII-010-paquetes-recarga.md
rckrdmrd c24f889f70
Some checks failed
Build / Build Backend (push) Has been cancelled
Build / Build Mobile (TypeScript Check) (push) Has been cancelled
Lint / Lint Backend (push) Has been cancelled
Lint / Lint Mobile (push) Has been cancelled
Test / Backend E2E Tests (push) Has been cancelled
Test / Mobile Unit Tests (push) Has been cancelled
Build / Build Docker Image (push) Has been cancelled
[MIINVENTARIO] feat: Add exports, reports, integrations modules and CI/CD pipeline
- Add exports module with PDF/CSV/Excel generation
- Add reports module for inventory analytics
- Add POS integrations module
- Add database migrations for exports, movements and integrations
- Add GitHub Actions CI/CD workflow with Docker support
- Add mobile export and reports screens with tests
- Update epic documentation with traceability
- Add deployment and security guides

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 06:06:34 -06:00

10 KiB

MII-010: Paquetes de Recarga


id: MII-010 type: Epic status: Completado priority: P1 phase: 3 story_points: 8 created_date: 2026-01-10 updated_date: 2026-01-13 simco_version: "4.0.0"

Metadata

Campo Valor
ID MII-010
Nombre Paquetes de Recarga
Fase 3 - Monetizacion
Prioridad P1
Story Points 8
Estado Completado

1. Descripcion

Implementar el catalogo de paquetes de recarga de creditos con precios fijos en MXN y equivalencia dinamica de creditos basada en el motor de costos.

Objetivo

Ofrecer opciones de compra claras y atractivas para los usuarios, con transparencia en la cantidad de creditos que reciben.


2. Requerimientos Relacionados

RF Descripcion Prioridad
FR-090 Paquetes predefinidos: $50, $100, $200, $500 MXN P0
FR-091 Equivalencia dinamica calculada por motor de costos P0
FR-092 Promociones: bonos temporales (+10% creditos) P2

3. Criterios de Aceptacion

AC-001: Ver Paquetes

DADO que quiero comprar creditos
CUANDO veo la lista de paquetes
ENTONCES veo los paquetes disponibles con:
  - Precio en MXN
  - Cantidad de creditos
  - Sesiones aproximadas que puedo hacer
  - Descuento si aplica

AC-002: Equivalencia Dinamica

DADO que los costos de IA cambian
CUANDO el motor recalcula equivalencias
ENTONCES los paquetes muestran creditos actualizados
Y el usuario siempre obtiene valor justo

AC-003: Seleccionar Paquete

DADO que veo los paquetes
CUANDO selecciono uno
ENTONCES paso al flujo de pago
Y veo el resumen antes de confirmar

AC-004: Promociones Activas

DADO que hay una promocion activa
CUANDO veo los paquetes
ENTONCES veo el badge de promocion
Y los creditos adicionales que obtendre
Y la fecha de expiracion de la oferta

AC-005: Paquete Recomendado

DADO que soy usuario frecuente
CUANDO veo los paquetes
ENTONCES el sistema recomienda uno basado en mi uso
Y explica por que es la mejor opcion

4. Tareas Tecnicas

ID Tarea Estimacion Estado
T-001 Crear modulo packages en NestJS 1 SP Completado
T-002 Implementar entidad Package 1 SP Completado
T-003 Crear calculo de equivalencia dinamica 2 SP Completado
T-004 Implementar sistema de promociones 2 SP Completado
T-005 Crear pantalla de paquetes en mobile 1 SP Completado
T-006 Implementar recomendacion de paquete 1 SP Completado

5. Modelo de Datos

Tabla: packages

CREATE TABLE packages (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name VARCHAR(100) NOT NULL,
  slug VARCHAR(50) UNIQUE,
  price_mxn DECIMAL(10,2) NOT NULL,
  base_credits DECIMAL(12,4),
  is_popular BOOLEAN DEFAULT false,
  sort_order INT DEFAULT 0,
  is_active BOOLEAN DEFAULT true,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- base_credits: null = dinamico, valor = fijo

Tabla: promotions

CREATE TABLE promotions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name VARCHAR(100) NOT NULL,
  type VARCHAR(50), -- 'BONUS_PERCENT', 'BONUS_FIXED', 'DISCOUNT_PERCENT'
  value DECIMAL(10,4),
  applies_to VARCHAR(50), -- 'ALL', 'PACKAGE_ID', 'FIRST_PURCHASE'
  package_id UUID REFERENCES packages(id),
  min_purchase DECIMAL(10,2),
  max_uses INT,
  current_uses INT DEFAULT 0,
  valid_from TIMESTAMP,
  valid_until TIMESTAMP,
  is_active BOOLEAN DEFAULT true,
  created_at TIMESTAMP DEFAULT NOW()
);

Tabla: package_history

CREATE TABLE package_history (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  package_id UUID REFERENCES packages(id),
  credits_per_peso DECIMAL(10,6),
  avg_cogs_mxn DECIMAL(10,4),
  calculated_at TIMESTAMP DEFAULT NOW()
);

6. Paquetes Predeterminados

Paquete Precio MXN Creditos* Sesiones** Popular
Basico $50 ~4-6 ~3-5 No
Popular $100 ~8-12 ~6-10 Si
Ahorro $200 ~18-26 ~14-20 No
Pro $500 ~48-70 ~38-55 No

*Creditos varian segun COGS actual **Sesiones estimadas promedio


7. Calculo de Equivalencia

function calculatePackageCredits(priceMXN: number): PackageDetails {
  // Obtener costo promedio por sesion
  const avgCOGS = getAverageCOGS(); // ej: $8 MXN
  const pricePerSession = avgCOGS * 2; // ej: $16 MXN

  // Calcular creditos base
  const creditValue = pricePerSession; // 1 credito = 1 sesion promedio
  const baseCredits = priceMXN / creditValue;

  // Aplicar promociones
  const promos = getActivePromotions(priceMXN);
  let bonusCredits = 0;
  for (const promo of promos) {
    if (promo.type === 'BONUS_PERCENT') {
      bonusCredits += baseCredits * (promo.value / 100);
    }
  }

  return {
    baseCredits,
    bonusCredits,
    totalCredits: baseCredits + bonusCredits,
    estimatedSessions: Math.floor(baseCredits + bonusCredits),
    promotions: promos
  };
}

8. Endpoints API

Metodo Endpoint Descripcion Auth
GET /packages Listar paquetes activos JWT
GET /packages/:id Detalle de paquete JWT
GET /packages/recommended Paquete recomendado JWT
GET /promotions/active Promociones activas JWT

9. Pantallas Mobile

Pantalla Componentes
PackagesScreen Lista cards, promociones, CTA
PackageDetailModal Desglose, comparador
PromosBanner Ofertas activas

10. UI de Paquetes

┌─────────────────────────────────────────┐
│          RECARGAR CREDITOS              │
├─────────────────────────────────────────┤
│                                         │
│  ┌─────────────────────────────────┐   │
│  │ 🔥 OFERTA: +10% CREDITOS        │   │
│  │    Valido hasta 15 Ene          │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │  BASICO                         │   │
│  │  $50 MXN                        │   │
│  │  ─────────                      │   │
│  │  4.5 creditos                   │   │
│  │  ~3-4 inventarios               │   │
│  │                    [Comprar]    │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │  ⭐ POPULAR                      │   │
│  │  $100 MXN                       │   │
│  │  ─────────                      │   │
│  │  9.0 creditos + 0.9 BONUS       │   │
│  │  ~8-10 inventarios              │   │
│  │  Mejor valor                    │   │
│  │                    [Comprar]    │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │  AHORRO                         │   │
│  │  $200 MXN                       │   │
│  │  ─────────                      │   │
│  │  20.0 creditos + 2.0 BONUS      │   │
│  │  ~18-22 inventarios             │   │
│  │                    [Comprar]    │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │  PRO                            │   │
│  │  $500 MXN                       │   │
│  │  ─────────                      │   │
│  │  55.0 creditos + 5.5 BONUS      │   │
│  │  ~50-60 inventarios             │   │
│  │                    [Comprar]    │   │
│  └─────────────────────────────────┘   │
│                                         │
└─────────────────────────────────────────┘

11. Recomendacion Inteligente

function getRecommendedPackage(userId: string): Package {
  const user = getUser(userId);
  const usage = getUserUsageStats(userId);

  // Usuario nuevo: recomendar Popular
  if (usage.totalSessions < 3) {
    return packages.find(p => p.slug === 'popular');
  }

  // Calcular sesiones mensuales promedio
  const avgMonthly = usage.sessionsLast30Days;

  // Recomendar segun uso
  if (avgMonthly < 5) return packages.find(p => p.slug === 'basico');
  if (avgMonthly < 15) return packages.find(p => p.slug === 'popular');
  if (avgMonthly < 30) return packages.find(p => p.slug === 'ahorro');
  return packages.find(p => p.slug === 'pro');
}

12. Dependencias

Entrada (Requiere)

  • MII-009: Wallet y Creditos

Salida (Bloquea)

  • MII-011: Pagos con Tarjeta
  • MII-012: Pagos OXXO
  • MII-013: Pagos 7-Eleven

13. Riesgos

Riesgo Probabilidad Impacto Mitigacion
Confusion precios dinamicos Media Medio UI clara, tooltips
Abuso de promos Baja Bajo Limites, validacion
COGS muy variable Baja Medio Suavizar cambios, minimos

14. Notas de Implementacion

  • Cachear calculos de equivalencia (TTL 1h)
  • No cambiar creditos despues de compra iniciada
  • Guardar historico de equivalencias
  • A/B test de precios y presentacion

15. Referencias


Ultima Actualizacion: 2026-01-10