template-saas/docs/01-modulos/SAAS-021-mlm.md
Adrian Flores Cortes 7d05081b4d
Some checks are pending
CI / Backend CI (push) Waiting to run
CI / Frontend CI (push) Waiting to run
CI / Security Scan (push) Waiting to run
CI / CI Summary (push) Blocked by required conditions
[SAAS-018-022] docs: Add specifications for advanced modules
Add complete specifications for 5 advanced modules:
- SAAS-018 Sales Foundation (21 SP) - Leads, opportunities, pipeline
- SAAS-019 Portfolio (13 SP) - Product/service catalog
- SAAS-020 Commissions (13 SP) - Commission system for salespeople
- SAAS-021 MLM (21 SP) - Multi-level marketing networks
- SAAS-022 Goals (13 SP) - Goals and objectives tracking

Each specification includes:
- Complete DDL with RLS policies
- Full API endpoint documentation
- Frontend pages and components
- Dependencies and integration points
- Story point estimates

Total new SP: 81 (bringing total to 260 SP)
Core modules: 14 (100% complete)
Advanced modules: 5 (specified, ready for implementation)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 20:12:07 -06:00

9.6 KiB

id title type status priority module version created_date updated_date estimated_sp
SAAS-021 MLM (Multi-Level Marketing) Module Specified P3 mlm 1.0.0 2026-01-24 2026-01-24 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

-- 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

-- 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