template-saas/docs/01-modulos/SAAS-020-commissions.md
Adrian Flores Cortes 0b90d87c1f
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
[TASK-021] docs: Sync SAAS-020 documentation with implementation
- Update SAAS-020-COMMISSIONS.md status to Completed
- Add implementation section and mark acceptance criteria
- Create TASK-2026-01-24-SAAS-020-COMMISSIONS documentation
- Update _INDEX.yml with SAAS-020 task
- Fix PROJECT-STATUS.md DDL section (12 -> 14 schemas)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 23:48:02 -06:00

322 lines
9.2 KiB
Markdown

---
id: "SAAS-020"
title: "Commissions"
type: "Module"
status: "Completed"
priority: "P2"
module: "commissions"
version: "1.0.0"
created_date: "2026-01-24"
updated_date: "2026-01-24"
completed_date: "2026-01-24"
estimated_sp: 13
---
# SAAS-020: Commissions
## Metadata
- **Codigo:** SAAS-020
- **Modulo:** Commissions
- **Prioridad:** P2
- **Estado:** Completado
- **Fase:** 6 - Advanced Features
- **Story Points:** 13
## Descripcion
Sistema de comisiones para vendedores y afiliados. Soporta multiples esquemas de comision (porcentaje, fijo, escalonado), periodos de pago configurables, y reportes de earnings. Base para el modulo MLM.
## Objetivos
1. Definir esquemas de comision flexibles
2. Calcular comisiones automaticamente por venta
3. Gestionar periodos de pago
4. Reportes de comisiones por vendedor
5. Integracion con Billing para pagos
## Alcance
### Incluido
- Esquemas de comision configurables
- Tipos: porcentaje, fijo, escalonado
- Calculo automatico por transaccion
- Periodos de pago (semanal, quincenal, mensual)
- Estado de comisiones (pendiente, aprobada, pagada)
- Dashboard de earnings
- Reportes por vendedor/periodo
### Excluido
- Pago automatico (integracion bancaria)
- Estructuras MLM complejas (SAAS-021)
- Impuestos sobre comisiones
## Modelo de Datos
### Schema: commissions
```sql
-- Esquemas de comision
CREATE TABLE commissions.schemes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
name VARCHAR(100) NOT NULL,
description TEXT,
-- Tipo de calculo
type commissions.scheme_type NOT NULL,
-- Configuracion
rate DECIMAL(10,4), -- Porcentaje (ej: 0.10 = 10%)
fixed_amount DECIMAL(15,2), -- Monto fijo
tiers JSONB DEFAULT '[]', -- Para escalonado
-- Aplicabilidad
applies_to commissions.applies_to DEFAULT 'all',
product_ids JSONB DEFAULT '[]', -- Si applies_to = 'products'
category_ids JSONB DEFAULT '[]', -- Si applies_to = 'categories'
-- Limites
min_amount DECIMAL(15,2),
max_amount DECIMAL(15,2),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Asignacion vendedor-esquema
CREATE TABLE commissions.assignments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
user_id UUID NOT NULL REFERENCES users.users(id),
scheme_id UUID NOT NULL REFERENCES commissions.schemes(id),
-- Vigencia
starts_at DATE NOT NULL,
ends_at DATE,
-- Override de rate
custom_rate DECIMAL(10,4),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW(),
CONSTRAINT unique_assignment UNIQUE (user_id, scheme_id, starts_at)
);
-- Comisiones generadas
CREATE TABLE commissions.entries (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
-- Beneficiario
user_id UUID NOT NULL REFERENCES users.users(id),
scheme_id UUID REFERENCES commissions.schemes(id),
-- Transaccion origen
reference_type VARCHAR(50) NOT NULL, -- 'sale', 'subscription', 'referral'
reference_id UUID NOT NULL,
-- Montos
base_amount DECIMAL(15,2) NOT NULL, -- Monto de la venta
rate_applied DECIMAL(10,4) NOT NULL,
commission_amount DECIMAL(15,2) NOT NULL,
currency VARCHAR(3) DEFAULT 'USD',
-- Estado
status commissions.entry_status NOT NULL DEFAULT 'pending',
-- Periodo de pago
period_id UUID REFERENCES commissions.periods(id),
paid_at TIMESTAMPTZ,
-- Metadata
notes TEXT,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Periodos de pago
CREATE TABLE commissions.periods (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
name VARCHAR(100) NOT NULL,
starts_at DATE NOT NULL,
ends_at DATE NOT NULL,
-- Totales
total_entries INTEGER DEFAULT 0,
total_amount DECIMAL(15,2) DEFAULT 0,
currency VARCHAR(3) DEFAULT 'USD',
-- Estado
status commissions.period_status NOT NULL DEFAULT 'open',
closed_at TIMESTAMPTZ,
paid_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Enums
CREATE TYPE commissions.scheme_type AS ENUM (
'percentage', 'fixed', 'tiered'
);
CREATE TYPE commissions.applies_to AS ENUM (
'all', 'products', 'categories'
);
CREATE TYPE commissions.entry_status AS ENUM (
'pending', 'approved', 'rejected', 'paid', 'cancelled'
);
CREATE TYPE commissions.period_status AS ENUM (
'open', 'closed', 'processing', 'paid'
);
```
### Ejemplo Tiers (escalonado)
```json
[
{ "min": 0, "max": 10000, "rate": 0.05 },
{ "min": 10001, "max": 50000, "rate": 0.07 },
{ "min": 50001, "max": null, "rate": 0.10 }
]
```
## Endpoints API
### Schemes
| Metodo | Endpoint | Descripcion |
|--------|----------|-------------|
| GET | /commissions/schemes | Listar esquemas |
| POST | /commissions/schemes | Crear esquema |
| GET | /commissions/schemes/:id | Obtener esquema |
| PATCH | /commissions/schemes/:id | Actualizar esquema |
| DELETE | /commissions/schemes/:id | Eliminar esquema |
### Assignments
| Metodo | Endpoint | Descripcion |
|--------|----------|-------------|
| GET | /commissions/assignments | Listar asignaciones |
| POST | /commissions/assignments | Asignar esquema |
| PATCH | /commissions/assignments/:id | Actualizar asignacion |
| DELETE | /commissions/assignments/:id | Eliminar asignacion |
| GET | /commissions/users/:id/schemes | Esquemas de usuario |
### Entries
| Metodo | Endpoint | Descripcion |
|--------|----------|-------------|
| GET | /commissions/entries | Listar comisiones |
| GET | /commissions/entries/:id | Obtener comision |
| PATCH | /commissions/entries/:id/status | Cambiar estado |
| POST | /commissions/calculate | Calcular comision |
### Periods
| Metodo | Endpoint | Descripcion |
|--------|----------|-------------|
| GET | /commissions/periods | Listar periodos |
| POST | /commissions/periods | Crear periodo |
| GET | /commissions/periods/:id | Obtener periodo |
| POST | /commissions/periods/:id/close | Cerrar periodo |
| POST | /commissions/periods/:id/pay | Marcar como pagado |
### Reports
| Metodo | Endpoint | Descripcion |
|--------|----------|-------------|
| GET | /commissions/reports/summary | Resumen general |
| GET | /commissions/reports/by-user | Por vendedor |
| GET | /commissions/reports/by-period | Por periodo |
## Frontend
### Paginas
- `/commissions` - Dashboard comisiones
- `/commissions/schemes` - Gestion esquemas
- `/commissions/entries` - Lista comisiones
- `/commissions/periods` - Periodos de pago
- `/commissions/my-earnings` - Mis ganancias (vendedor)
### Componentes
- `CommissionsDashboard` - Metricas y graficos
- `SchemesList` - Lista de esquemas
- `SchemeForm` - Formulario esquema
- `TiersEditor` - Editor de niveles
- `EntriesList` - Lista de comisiones
- `PeriodManager` - Gestion periodos
- `EarningsCard` - Resumen ganancias
- `CommissionCalculator` - Simulador
### Hooks
- `useSchemes` - CRUD esquemas
- `useAssignments` - CRUD asignaciones
- `useEntries` - CRUD comisiones
- `usePeriods` - CRUD periodos
- `useMyEarnings` - Ganancias del usuario actual
## Dependencias
### Modulos Requeridos
- SAAS-001 Auth
- SAAS-002 Tenants
- SAAS-003 Users
- SAAS-018 Sales (transacciones origen)
### Modulos Opcionales
- SAAS-004 Billing (pagos automaticos)
- SAAS-021 MLM (estructuras multinivel)
## Criterios de Aceptacion
1. [x] Esquemas porcentaje, fijo y escalonado
2. [x] Asignacion esquema-vendedor funcional
3. [x] Calculo automatico de comisiones
4. [x] Gestion de periodos de pago
5. [x] Dashboard de earnings
6. [x] Reportes por vendedor y periodo
7. [ ] Tests unitarios (>70% coverage) - Pendiente
## Estimacion
| Componente | SP |
|------------|-----|
| DDL + Entities | 2 |
| Backend Services | 4 |
| Controllers + DTOs | 2 |
| Frontend Pages | 3 |
| Frontend Components | 2 |
| Tests | 1 |
| **Total** | **13** |
## Implementacion
### Backend (NestJS)
- **Entities:** CommissionScheme, CommissionAssignment, CommissionEntry, CommissionPeriod
- **Services:** SchemesService, AssignmentsService, EntriesService, PeriodsService, CommissionsDashboardService
- **Controllers:** SchemesController, AssignmentsController, EntriesController, PeriodsController, DashboardController
- **DTOs:** Create/Update DTOs para cada entidad (scheme.dto, assignment.dto, entry.dto, period.dto, dashboard.dto)
- **Tests:** Pendiente - 0 tests unitarios actualmente
### Frontend (React)
- **Pages:** /commissions, /commissions/schemes, /commissions/entries, /commissions/periods, /commissions/my-earnings
- **Components:** CommissionsDashboard, SchemesList, SchemeForm, TiersEditor, EntriesList, PeriodManager, EarningsCard, CommissionCalculator
- **Hooks:** useSchemes, useAssignments, useEntries, usePeriods, useMyEarnings, useCommissionsDashboard (+22 hooks adicionales)
- **Services:** schemes.api, assignments.api, entries.api, periods.api, dashboard.api
### Database (PostgreSQL)
- **Schema:** commissions
- **Tables:** schemes, assignments, entries, periods
- **Enums:** scheme_type, applies_to, entry_status, period_status
- **RLS:** Tenant isolation policies aplicadas a todas las tablas
---
**Ultima actualizacion:** 2026-01-24
**Implementado por:** Claude Opus 4.5