--- id: "SAAS-021" title: "MLM (Multi-Level Marketing)" type: "Module" status: "Specified" priority: "P3" module: "mlm" version: "1.0.0" created_date: "2026-01-24" updated_date: "2026-01-24" estimated_sp: 21 --- # SAAS-021: MLM (Multi-Level Marketing) ## Metadata - **Codigo:** SAAS-021 - **Modulo:** MLM - **Prioridad:** P3 - **Estado:** Especificado - **Fase:** 7 - Enterprise Features - **Story Points:** 21 ## Descripcion Sistema de marketing multinivel para redes de distribuidores/afiliados. Soporta estructuras jerarquicas (binario, unilevel, matriz), comisiones por niveles, bonos por objetivos, y visualizacion de red. Extiende el modulo de Commissions. ## Objetivos 1. Estructuras de red configurables 2. Comisiones por niveles (downline) 3. Bonos por rangos y objetivos 4. Visualizacion de arbol de red 5. Reportes de estructura y earnings ## Alcance ### Incluido - Estructuras: Unilevel, Binario, Matriz - Comisiones multinivel (N niveles) - Sistema de rangos/calificaciones - Bonos por rango y periodo - Visualizacion de red (arbol) - Dashboard de distribuidor - Reportes de red y earnings ### Excluido - Planes de compensacion predefinidos - Integracion con pagos automaticos - Compliance regulatorio automatico ## Modelo de Datos ### Schema: mlm ```sql -- Configuracion de estructura CREATE TABLE mlm.structures ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants.tenants(id), name VARCHAR(100) NOT NULL, type mlm.structure_type NOT NULL, -- Configuracion por tipo config JSONB NOT NULL DEFAULT '{}', -- Unilevel: { max_width: null, max_depth: 10 } -- Binary: { spillover: 'left_first' | 'weak_leg' } -- Matrix: { width: 3, depth: 7 } -- Comisiones por nivel level_rates JSONB NOT NULL DEFAULT '[]', -- [{ level: 1, rate: 0.10 }, { level: 2, rate: 0.05 }, ...] is_active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT NOW() ); -- Nodos de la red (distribuidores) CREATE TABLE mlm.nodes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants.tenants(id), structure_id UUID NOT NULL REFERENCES mlm.structures(id), user_id UUID NOT NULL REFERENCES users.users(id), -- Jerarquia parent_id UUID REFERENCES mlm.nodes(id), sponsor_id UUID REFERENCES mlm.nodes(id), -- Quien lo refirio position INTEGER, -- Para binario: 1=left, 2=right -- Path materializado para consultas eficientes path LTREE, depth INTEGER DEFAULT 0, -- Rango actual rank_id UUID REFERENCES mlm.ranks(id), highest_rank_id UUID REFERENCES mlm.ranks(id), -- Metricas personal_volume DECIMAL(15,2) DEFAULT 0, group_volume DECIMAL(15,2) DEFAULT 0, direct_referrals INTEGER DEFAULT 0, total_downline INTEGER DEFAULT 0, -- Estado status mlm.node_status NOT NULL DEFAULT 'active', joined_at TIMESTAMPTZ DEFAULT NOW(), created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW(), CONSTRAINT unique_user_structure UNIQUE (structure_id, user_id) ); -- Rangos/Calificaciones CREATE TABLE mlm.ranks ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants.tenants(id), structure_id UUID NOT NULL REFERENCES mlm.structures(id), name VARCHAR(100) NOT NULL, level INTEGER NOT NULL, -- 1=Bronze, 2=Silver, etc. badge_url VARCHAR(500), -- Requisitos para alcanzar requirements JSONB NOT NULL DEFAULT '{}', -- { -- personal_volume: 1000, -- group_volume: 10000, -- direct_referrals: 3, -- active_legs: 2, -- rank_in_legs: { rank_level: 2, count: 1 } -- } -- Beneficios bonus_rate DECIMAL(10,4), -- Bono adicional por rango benefits JSONB DEFAULT '{}', is_active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT NOW() ); -- Comisiones MLM (extiende commissions.entries) CREATE TABLE mlm.commissions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants.tenants(id), node_id UUID NOT NULL REFERENCES mlm.nodes(id), source_node_id UUID NOT NULL REFERENCES mlm.nodes(id), -- Quien genero -- Tipo de comision type mlm.commission_type NOT NULL, -- Nivel de diferencia level INTEGER NOT NULL, -- 1 = directo, 2 = segundo nivel, etc. -- Montos source_amount DECIMAL(15,2) NOT NULL, rate_applied DECIMAL(10,4) NOT NULL, commission_amount DECIMAL(15,2) NOT NULL, currency VARCHAR(3) DEFAULT 'USD', -- Periodo period_id UUID REFERENCES commissions.periods(id), status mlm.commission_status NOT NULL DEFAULT 'pending', created_at TIMESTAMPTZ DEFAULT NOW() ); -- Bonos por rango CREATE TABLE mlm.bonuses ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants.tenants(id), node_id UUID NOT NULL REFERENCES mlm.nodes(id), rank_id UUID NOT NULL REFERENCES mlm.ranks(id), type mlm.bonus_type NOT NULL, amount DECIMAL(15,2) NOT NULL, currency VARCHAR(3) DEFAULT 'USD', period_id UUID REFERENCES commissions.periods(id), status mlm.commission_status NOT NULL DEFAULT 'pending', achieved_at TIMESTAMPTZ DEFAULT NOW(), created_at TIMESTAMPTZ DEFAULT NOW() ); -- Historial de rangos CREATE TABLE mlm.rank_history ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), node_id UUID NOT NULL REFERENCES mlm.nodes(id), rank_id UUID NOT NULL REFERENCES mlm.ranks(id), achieved_at TIMESTAMPTZ DEFAULT NOW() ); -- Enums CREATE TYPE mlm.structure_type AS ENUM ( 'unilevel', 'binary', 'matrix', 'hybrid' ); CREATE TYPE mlm.node_status AS ENUM ( 'pending', 'active', 'inactive', 'suspended' ); CREATE TYPE mlm.commission_type AS ENUM ( 'level', 'matching', 'infinity', 'leadership', 'pool' ); CREATE TYPE mlm.commission_status AS ENUM ( 'pending', 'approved', 'paid', 'cancelled' ); CREATE TYPE mlm.bonus_type AS ENUM ( 'rank_achievement', 'rank_maintenance', 'fast_start', 'pool_share' ); ``` ### Indices especiales ```sql -- Indice para LTREE (path materializado) CREATE INDEX idx_nodes_path ON mlm.nodes USING GIST (path); -- Para buscar downline CREATE INDEX idx_nodes_parent ON mlm.nodes (parent_id); CREATE INDEX idx_nodes_sponsor ON mlm.nodes (sponsor_id); ``` ## Endpoints API ### Structures | Metodo | Endpoint | Descripcion | |--------|----------|-------------| | GET | /mlm/structures | Listar estructuras | | POST | /mlm/structures | Crear estructura | | GET | /mlm/structures/:id | Obtener estructura | | PATCH | /mlm/structures/:id | Actualizar estructura | ### Nodes | Metodo | Endpoint | Descripcion | |--------|----------|-------------| | GET | /mlm/nodes | Listar nodos | | POST | /mlm/nodes | Crear nodo (registrar) | | GET | /mlm/nodes/:id | Obtener nodo | | GET | /mlm/nodes/:id/downline | Obtener downline | | GET | /mlm/nodes/:id/upline | Obtener upline | | GET | /mlm/nodes/:id/tree | Arbol visual | | PATCH | /mlm/nodes/:id/status | Cambiar estado | ### Ranks | Metodo | Endpoint | Descripcion | |--------|----------|-------------| | GET | /mlm/ranks | Listar rangos | | POST | /mlm/ranks | Crear rango | | GET | /mlm/ranks/:id | Obtener rango | | PATCH | /mlm/ranks/:id | Actualizar rango | | POST | /mlm/ranks/evaluate | Evaluar calificaciones | ### Commissions | Metodo | Endpoint | Descripcion | |--------|----------|-------------| | GET | /mlm/commissions | Listar comisiones MLM | | POST | /mlm/commissions/calculate | Calcular comisiones | | GET | /mlm/commissions/by-level | Por nivel | ### My Network (Distribuidor) | Metodo | Endpoint | Descripcion | |--------|----------|-------------| | GET | /mlm/my/dashboard | Dashboard personal | | GET | /mlm/my/network | Mi red | | GET | /mlm/my/earnings | Mis ganancias | | GET | /mlm/my/rank | Mi rango y progreso | | POST | /mlm/my/invite | Generar link de invitacion | ## Frontend ### Paginas - `/mlm` - Dashboard MLM - `/mlm/network` - Visualizacion de red - `/mlm/structures` - Configuracion estructuras - `/mlm/ranks` - Gestion de rangos - `/mlm/commissions` - Comisiones MLM - `/mlm/my` - Portal distribuidor ### Componentes - `NetworkTree` - Arbol de red interactivo - `BinaryTree` - Visualizacion binaria - `UnivelTree` - Visualizacion unilevel - `NodeCard` - Tarjeta de nodo - `RankBadge` - Badge de rango - `RankProgress` - Progreso hacia siguiente rango - `DownlineList` - Lista de downline - `EarningsBreakdown` - Desglose de ganancias - `InviteLink` - Generador de link - `StructureConfig` - Configuracion de estructura - `LevelRatesEditor` - Editor de comisiones por nivel ### Hooks - `useStructures` - CRUD estructuras - `useNodes` - CRUD nodos - `useRanks` - CRUD rangos - `useMyNetwork` - Red del usuario actual - `useNetworkTree` - Datos del arbol - `useMLMCommissions` - Comisiones MLM ## Dependencias ### Modulos Requeridos - SAAS-001 Auth - SAAS-002 Tenants - SAAS-003 Users - SAAS-020 Commissions (base) ### Modulos Opcionales - SAAS-018 Sales (ventas como fuente) - SAAS-019 Portfolio (productos) - SAAS-022 Goals (objetivos por rango) ## Criterios de Aceptacion 1. [ ] Estructuras unilevel y binario funcionales 2. [ ] Registro de nodos con sponsor 3. [ ] Calculo de comisiones por niveles 4. [ ] Sistema de rangos con requisitos 5. [ ] Visualizacion de arbol interactivo 6. [ ] Dashboard de distribuidor completo 7. [ ] Reportes de red y earnings 8. [ ] Tests unitarios (>70% coverage) ## Estimacion | Componente | SP | |------------|-----| | DDL + Entities | 4 | | Backend Services | 6 | | Controllers + DTOs | 3 | | Frontend Pages | 4 | | Frontend Components (Tree) | 3 | | Tests | 1 | | **Total** | **21** | --- **Ultima actualizacion:** 2026-01-24 **Autor:** Claude Opus 4.5