- ET-SAAS-018-sales.md: Sales pipeline/CRM module - ET-SAAS-019-portfolio.md: Product catalog module - ET-SAAS-020-commissions.md: Commissions system - ET-SAAS-021-mlm.md: Multi-Level Marketing module - ET-SAAS-022-goals.md: Goals and objectives system - Update _MAP.md with all 9 specifications All specs document: - Data model (DDL, enums, tables) - Backend architecture (endpoints, services) - Security (RLS, RBAC permissions) - Frontend status and hooks - Module integrations Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
400 lines
11 KiB
Markdown
400 lines
11 KiB
Markdown
---
|
|
id: "ET-SAAS-022"
|
|
title: "Especificacion Tecnica Goals"
|
|
type: "TechnicalSpec"
|
|
status: "Implemented"
|
|
priority: "P1"
|
|
module: "goals"
|
|
version: "1.0.0"
|
|
created_date: "2026-02-03"
|
|
updated_date: "2026-02-03"
|
|
story_points: 8
|
|
---
|
|
|
|
# ET-SAAS-022: Especificacion Tecnica - Sistema de Metas (Goals)
|
|
|
|
## Metadata
|
|
- **Codigo:** ET-SAAS-022
|
|
- **Modulo:** Goals
|
|
- **Version:** 1.0.0
|
|
- **Estado:** Implementado (Backend)
|
|
- **Fecha:** 2026-02-03
|
|
- **Basado en:** SAAS-022
|
|
|
|
---
|
|
|
|
## 1. Resumen Ejecutivo
|
|
|
|
### 1.1 Estado Actual
|
|
|
|
Sistema de metas con backend implementado, UI pendiente.
|
|
|
|
| Capacidad | Estado | Notas |
|
|
|-----------|--------|-------|
|
|
| Definitions | SI | Definiciones de metas |
|
|
| Assignments | SI | Asignaciones usuario/team |
|
|
| Progress | SI | Tracking de progreso |
|
|
| Milestones | SI | Hitos con notificaciones |
|
|
| Auto-tracking | SI | Fuentes automaticas |
|
|
| RLS | SI | Row Level Security |
|
|
| UI | NO | Frontend pendiente |
|
|
|
|
### 1.2 Funcionalidades v1.0
|
|
|
|
Sistema completo con:
|
|
|
|
- **4 Entidades**: Definitions, Assignments, ProgressLog, MilestoneNotifications
|
|
- **3 Tipos de meta**: target, limit, maintain
|
|
- **5 Tipos de metrica**: number, currency, percentage, boolean, count
|
|
- **6 Periodos**: daily, weekly, monthly, quarterly, yearly, custom
|
|
- **Auto-tracking**: Integracion con sales, billing, commissions
|
|
|
|
---
|
|
|
|
## 2. Modelo de Datos
|
|
|
|
### 2.1 Schema: goals
|
|
|
|
#### Tabla: definitions
|
|
| Campo | Tipo | Descripcion |
|
|
|-------|------|-------------|
|
|
| id | UUID | PK |
|
|
| tenant_id | UUID | FK tenants |
|
|
| name | VARCHAR(200) | Nombre de la meta |
|
|
| description | TEXT | Descripcion |
|
|
| category | VARCHAR(100) | Categoria |
|
|
| type | ENUM | target, limit, maintain |
|
|
| metric | ENUM | number, currency, percentage, boolean, count |
|
|
| target_value | DECIMAL(15,2) | Valor objetivo |
|
|
| unit | VARCHAR(50) | USD, units, %, etc. |
|
|
| period | ENUM | daily, weekly, monthly, quarterly, yearly, custom |
|
|
| starts_at | DATE | Fecha inicio |
|
|
| ends_at | DATE | Fecha fin |
|
|
| source | ENUM | manual, sales, billing, commissions, custom |
|
|
| source_config | JSONB | Configuracion de fuente |
|
|
| milestones | JSONB | Hitos de progreso |
|
|
| status | ENUM | draft, active, paused, completed, cancelled |
|
|
| tags | JSONB | Array de tags |
|
|
|
|
**Source Config ejemplo:**
|
|
```json
|
|
{
|
|
"module": "sales",
|
|
"entity": "opportunities",
|
|
"filter": {"stage": "closed_won"},
|
|
"aggregation": "sum",
|
|
"field": "amount"
|
|
}
|
|
```
|
|
|
|
**Milestones ejemplo:**
|
|
```json
|
|
[
|
|
{"percentage": 25, "notify": true},
|
|
{"percentage": 50, "notify": true},
|
|
{"percentage": 75, "notify": true},
|
|
{"percentage": 100, "notify": true}
|
|
]
|
|
```
|
|
|
|
#### Tabla: assignments
|
|
| Campo | Tipo | Descripcion |
|
|
|-------|------|-------------|
|
|
| id | UUID | PK |
|
|
| tenant_id | UUID | FK tenants |
|
|
| definition_id | UUID | FK definitions |
|
|
| assignee_type | ENUM | user, team, tenant |
|
|
| user_id | UUID | FK users (si type=user) |
|
|
| team_id | UUID | Para futuro modulo de equipos |
|
|
| custom_target | DECIMAL(15,2) | Override del target |
|
|
| current_value | DECIMAL(15,2) | Valor actual |
|
|
| progress_percentage | DECIMAL(5,2) | 0-100% |
|
|
| last_updated_at | TIMESTAMPTZ | Ultima actualizacion |
|
|
| status | ENUM | active, achieved, failed, cancelled |
|
|
| achieved_at | TIMESTAMPTZ | Fecha de logro |
|
|
| notes | TEXT | Notas |
|
|
|
|
#### Tabla: progress_log
|
|
| Campo | Tipo | Descripcion |
|
|
|-------|------|-------------|
|
|
| id | UUID | PK |
|
|
| tenant_id | UUID | FK tenants |
|
|
| assignment_id | UUID | FK assignments |
|
|
| previous_value | DECIMAL(15,2) | Valor anterior |
|
|
| new_value | DECIMAL(15,2) | Nuevo valor |
|
|
| change_amount | DECIMAL(15,2) | Diferencia |
|
|
| source | ENUM | manual, automatic, import, api |
|
|
| source_reference | VARCHAR(200) | ID de transaccion origen |
|
|
| notes | TEXT | Notas |
|
|
| logged_at | TIMESTAMPTZ | Fecha del log |
|
|
| logged_by | UUID | FK users |
|
|
|
|
#### Tabla: milestone_notifications
|
|
| Campo | Tipo | Descripcion |
|
|
|-------|------|-------------|
|
|
| id | UUID | PK |
|
|
| tenant_id | UUID | FK tenants |
|
|
| assignment_id | UUID | FK assignments |
|
|
| milestone_percentage | INT | % del hito alcanzado |
|
|
| achieved_value | DECIMAL(15,2) | Valor al alcanzar |
|
|
| notified_at | TIMESTAMPTZ | Fecha de notificacion |
|
|
|
|
### 2.2 Enums
|
|
|
|
```sql
|
|
goals.goal_type: target, limit, maintain
|
|
goals.metric_type: number, currency, percentage, boolean, count
|
|
goals.period_type: daily, weekly, monthly, quarterly, yearly, custom
|
|
goals.data_source: manual, sales, billing, commissions, custom
|
|
goals.goal_status: draft, active, paused, completed, cancelled
|
|
goals.assignee_type: user, team, tenant
|
|
goals.assignment_status: active, achieved, failed, cancelled
|
|
goals.progress_source: manual, automatic, import, api
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Tipos de Meta
|
|
|
|
### 3.1 Target (Alcanzar objetivo)
|
|
- **Descripcion**: Alcanzar un valor especifico
|
|
- **Ejemplo**: "Vender $50,000 este mes"
|
|
- **Logro**: current_value >= target_value
|
|
|
|
### 3.2 Limit (No exceder)
|
|
- **Descripcion**: No superar un limite
|
|
- **Ejemplo**: "Mantener gastos bajo $10,000"
|
|
- **Logro**: current_value <= target_value durante todo el periodo
|
|
|
|
### 3.3 Maintain (Mantener valor)
|
|
- **Descripcion**: Mantener un valor constante
|
|
- **Ejemplo**: "Mantener NPS >= 8.5"
|
|
- **Logro**: current_value dentro de rango durante todo el periodo
|
|
|
|
---
|
|
|
|
## 4. Arquitectura Backend
|
|
|
|
### 4.1 Estructura de Archivos
|
|
|
|
```
|
|
backend/src/modules/goals/
|
|
├── goals.module.ts
|
|
├── controllers/
|
|
│ ├── definitions.controller.ts
|
|
│ ├── assignments.controller.ts
|
|
│ ├── progress.controller.ts
|
|
│ └── dashboard.controller.ts
|
|
├── services/
|
|
│ ├── definitions.service.ts
|
|
│ ├── assignments.service.ts
|
|
│ ├── progress.service.ts
|
|
│ ├── tracking.service.ts
|
|
│ └── dashboard.service.ts
|
|
├── entities/
|
|
│ ├── definition.entity.ts
|
|
│ ├── assignment.entity.ts
|
|
│ ├── progress-log.entity.ts
|
|
│ └── milestone-notification.entity.ts
|
|
└── dto/
|
|
```
|
|
|
|
### 4.2 Endpoints API
|
|
|
|
#### Definitions
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /goals/definitions | Listar |
|
|
| GET | /goals/definitions/:id | Obtener |
|
|
| POST | /goals/definitions | Crear |
|
|
| PUT | /goals/definitions/:id | Actualizar |
|
|
| PATCH | /goals/definitions/:id/status | Cambiar status |
|
|
| DELETE | /goals/definitions/:id | Eliminar |
|
|
| POST | /goals/definitions/:id/duplicate | Duplicar |
|
|
|
|
#### Assignments
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /goals/assignments | Listar |
|
|
| GET | /goals/assignments/:id | Obtener |
|
|
| GET | /goals/assignments/user/:userId | Por usuario |
|
|
| GET | /goals/assignments/definition/:defId | Por definicion |
|
|
| POST | /goals/assignments | Crear |
|
|
| PUT | /goals/assignments/:id | Actualizar |
|
|
| DELETE | /goals/assignments/:id | Eliminar |
|
|
|
|
#### Progress
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /goals/progress/:assignmentId | Historial |
|
|
| POST | /goals/progress | Registrar progreso |
|
|
| POST | /goals/progress/bulk | Registrar multiples |
|
|
|
|
#### Dashboard
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /goals/dashboard | Resumen general |
|
|
| GET | /goals/dashboard/my | Mis metas |
|
|
| GET | /goals/dashboard/team/:teamId | Metas del equipo |
|
|
| GET | /goals/dashboard/user/:userId | Metas de usuario |
|
|
| GET | /goals/dashboard/achieved | Metas logradas |
|
|
| GET | /goals/dashboard/at-risk | Metas en riesgo |
|
|
|
|
---
|
|
|
|
## 5. Auto-Tracking
|
|
|
|
### 5.1 Configuracion de Fuentes
|
|
|
|
```typescript
|
|
interface SourceConfig {
|
|
module: 'sales' | 'billing' | 'commissions';
|
|
entity: string; // 'opportunities', 'invoices', etc.
|
|
filter?: Record<string, any>; // Filtros adicionales
|
|
aggregation: 'sum' | 'count' | 'avg' | 'min' | 'max';
|
|
field?: string; // Campo para sum/avg
|
|
}
|
|
```
|
|
|
|
### 5.2 Ejemplo: Meta de Ventas
|
|
|
|
```json
|
|
{
|
|
"name": "Ventas Q1 2026",
|
|
"type": "target",
|
|
"metric": "currency",
|
|
"target_value": 100000,
|
|
"unit": "USD",
|
|
"source": "sales",
|
|
"source_config": {
|
|
"module": "sales",
|
|
"entity": "opportunities",
|
|
"filter": {"stage": "closed_won"},
|
|
"aggregation": "sum",
|
|
"field": "amount"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 5.3 Flujo de Actualizacion
|
|
|
|
```typescript
|
|
// Listener para eventos de ventas
|
|
@OnEvent('opportunity.won')
|
|
async handleOpportunityWon(event: OpportunityWonEvent) {
|
|
// 1. Buscar metas con source_config que matchee
|
|
const goals = await this.findMatchingGoals({
|
|
module: 'sales',
|
|
entity: 'opportunities',
|
|
userId: event.opportunity.assignedTo
|
|
});
|
|
|
|
// 2. Para cada meta, actualizar progreso
|
|
for (const assignment of goals) {
|
|
await this.updateProgress(assignment.id, {
|
|
changeAmount: event.opportunity.amount,
|
|
source: 'automatic',
|
|
sourceReference: event.opportunity.id
|
|
});
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Frontend (Pendiente)
|
|
|
|
### 6.1 Paginas Propuestas
|
|
|
|
| Ruta | Componente | Estado |
|
|
|------|------------|--------|
|
|
| /dashboard/goals | GoalsDashboard | Pendiente |
|
|
| /dashboard/goals/my | MyGoalsPage | Pendiente |
|
|
| /dashboard/goals/definitions | DefinitionsPage | Pendiente |
|
|
| /dashboard/goals/new | GoalFormPage | Pendiente |
|
|
| /dashboard/goals/:id | GoalDetailPage | Pendiente |
|
|
|
|
### 6.2 Hooks Existentes
|
|
|
|
```typescript
|
|
// frontend/src/hooks/useGoals.ts
|
|
useDefinitions, useDefinition, useCreateDefinition, useUpdateDefinition
|
|
useAssignments, useMyAssignments, useUserAssignments
|
|
useAssignmentProgress, useUpdateProgress
|
|
useGoalsDashboard, useAchievedGoals, useAtRiskGoals
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Seguridad
|
|
|
|
### 7.1 RLS
|
|
|
|
```sql
|
|
CREATE POLICY definitions_tenant_isolation ON goals.definitions
|
|
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
|
|
CREATE POLICY assignments_tenant_isolation ON goals.assignments
|
|
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
```
|
|
|
|
### 7.2 Permisos RBAC
|
|
|
|
| Permiso | Descripcion |
|
|
|---------|-------------|
|
|
| goals:read | Ver metas |
|
|
| goals:write | Crear/editar metas |
|
|
| goals:assign | Asignar metas |
|
|
| goals:progress | Actualizar progreso |
|
|
| goals:manage | Administrar |
|
|
|
|
---
|
|
|
|
## 8. Notificaciones
|
|
|
|
### 8.1 Eventos de Notificacion
|
|
|
|
| Evento | Trigger | Destinatario |
|
|
|--------|---------|--------------|
|
|
| goal.milestone_reached | Alcanzar % | Usuario asignado |
|
|
| goal.achieved | 100% completado | Usuario + Manager |
|
|
| goal.at_risk | <50% y queda poco tiempo | Manager |
|
|
| goal.failed | Periodo terminado sin lograr | Manager |
|
|
|
|
### 8.2 Ejemplo de Notificacion
|
|
|
|
```typescript
|
|
interface MilestoneNotification {
|
|
type: 'goal.milestone_reached';
|
|
userId: string;
|
|
data: {
|
|
goalName: string;
|
|
milestone: 50; // percentage
|
|
currentValue: 25000;
|
|
targetValue: 50000;
|
|
remainingDays: 15;
|
|
};
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Integraciones
|
|
|
|
| Modulo | Integracion |
|
|
|--------|-------------|
|
|
| sales | Tracking automatico |
|
|
| billing | Tracking de ingresos |
|
|
| commissions | Metas de comision |
|
|
| notifications | Alertas de hitos |
|
|
| audit | Log de cambios |
|
|
|
|
---
|
|
|
|
## 10. Referencias
|
|
|
|
- DDL: `database/ddl/schemas/goals/`
|
|
- Backend: `backend/src/modules/goals/`
|
|
- Frontend Services: `frontend/src/services/goals/`
|
|
- Frontend Hooks: `frontend/src/hooks/useGoals.ts`
|