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>
348 lines
9.6 KiB
Markdown
348 lines
9.6 KiB
Markdown
---
|
|
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
|