# RF-REPORT-004: Reportes Programados

## Identificacion

| Campo | Valor |
|-------|-------|
| **ID** | RF-REPORT-004 |
| **Modulo** | MGN-009 Reports |
| **Titulo** | Reportes Programados |
| **Prioridad** | P1 - Alta |
| **Estado** | Draft |
| **Fecha** | 2025-12-05 |

---

## Descripcion

El sistema debe permitir programar la ejecucion automatica de reportes en horarios definidos, con envio automatico por email a destinatarios configurados.

---

## Requisitos Funcionales

### RF-REPORT-004.1: Estructura de Programacion

```typescript
interface ScheduledReport {
  id: UUID;
  tenantId: UUID;
  reportId: UUID;           // Reporte a ejecutar
  name: string;             // Nombre descriptivo
  description?: string;
  parameters: Record<string, any>;  // Parametros fijos
  format: ExportFormat;     // PDF, XLSX, CSV
  schedule: ScheduleConfig;
  recipients: Recipient[];
  options: ScheduleOptions;
  isActive: boolean;
  lastRunAt?: TIMESTAMPTZ;
  nextRunAt?: TIMESTAMPTZ;
  createdBy: UUID;
  createdAt: TIMESTAMPTZ;
  updatedAt: TIMESTAMPTZ;
}

interface ScheduleConfig {
  type: 'cron' | 'interval' | 'once';
  cron?: string;            // "0 8 * * 1" = Lunes 8am
  interval?: number;        // Minutos
  runAt?: TIMESTAMPTZ;      // Para 'once'
  timezone: string;         // "America/Mexico_City"
}

interface Recipient {
  type: 'user' | 'email' | 'role';
  value: string;            // UUID o email
  cc?: boolean;
}

interface ScheduleOptions {
  skipIfEmpty: boolean;     // No enviar si sin datos
  attachFile: boolean;      // Adjuntar o link
  includeLink: boolean;     // Link al reporte online
  emailSubject?: string;    // Subject personalizado
  emailBody?: string;       // Body personalizado
}
```

### RF-REPORT-004.2: Expresiones Cron

Ejemplos de programaciones:

| Cron | Descripcion |
|------|-------------|
| `0 8 * * *` | Diario a las 8:00 |
| `0 8 * * 1` | Lunes a las 8:00 |
| `0 8 1 * *` | Primer dia del mes, 8:00 |
| `0 8 1 1,4,7,10 *` | Trimestral, dia 1, 8:00 |
| `0 8 * * 1-5` | Lunes a Viernes, 8:00 |

### RF-REPORT-004.3: Parametros Dinamicos

Algunos parametros pueden ser relativos:

```typescript
interface DynamicParameter {
  name: string;
  type: 'relative_date' | 'current_user' | 'current_tenant';
  value: string;
}

// Ejemplos de fechas relativas
{
  "fecha_desde": { "type": "relative_date", "value": "start_of_month" },
  "fecha_hasta": { "type": "relative_date", "value": "yesterday" }
}

// Valores relativos soportados
type RelativeDate =
  | 'today' | 'yesterday' | 'tomorrow'
  | 'start_of_week' | 'end_of_week'
  | 'start_of_month' | 'end_of_month'
  | 'start_of_quarter' | 'end_of_quarter'
  | 'start_of_year' | 'end_of_year'
  | '-7d' | '-30d' | '-1m' | '-1y';  // Relativo
```

### RF-REPORT-004.4: Historial de Ejecuciones

```typescript
interface ScheduleExecution {
  id: UUID;
  scheduleId: UUID;
  status: 'success' | 'failed' | 'skipped';
  startedAt: TIMESTAMPTZ;
  completedAt?: TIMESTAMPTZ;
  duration?: number;        // ms
  rowCount?: number;
  fileUrl?: string;
  recipientsSent: number;
  error?: string;
}
```

### RF-REPORT-004.5: Notificaciones

Al ejecutar:

1. Si exito: Email a destinatarios con reporte adjunto
2. Si falla: Email a creador del schedule con error
3. Si vacio y skipIfEmpty: No enviar, registrar skip

---

## Operaciones

### Listar Programaciones

```typescript
GET /api/v1/reports/schedules

Response:
{
  "data": [
    {
      "id": "uuid",
      "name": "Reporte Semanal Ventas",
      "reportName": "Ventas por Cliente",
      "schedule": "Lunes 8:00 AM",
      "format": "xlsx",
      "recipientsCount": 3,
      "isActive": true,
      "lastRunAt": "2025-12-02T08:00:00Z",
      "nextRunAt": "2025-12-09T08:00:00Z"
    }
  ]
}
```

### Crear Programacion

```typescript
POST /api/v1/reports/schedules
{
  "reportId": "uuid-reporte",
  "name": "Ventas Semanales",
  "parameters": {
    "fecha_desde": { "type": "relative_date", "value": "start_of_week" },
    "fecha_hasta": { "type": "relative_date", "value": "end_of_week" }
  },
  "format": "xlsx",
  "schedule": {
    "type": "cron",
    "cron": "0 8 * * 1",
    "timezone": "America/Mexico_City"
  },
  "recipients": [
    { "type": "user", "value": "uuid-user" },
    { "type": "email", "value": "gerencia@example.com" },
    { "type": "role", "value": "sales_manager" }
  ],
  "options": {
    "skipIfEmpty": true,
    "attachFile": true
  }
}
```

### Ejecutar Manualmente

```typescript
POST /api/v1/reports/schedules/:id/run

Response:
{
  "executionId": "uuid",
  "status": "running"
}
```

### Historial de Ejecuciones

```typescript
GET /api/v1/reports/schedules/:id/history

Response:
{
  "data": [
    {
      "id": "uuid",
      "status": "success",
      "startedAt": "2025-12-02T08:00:00Z",
      "duration": 15000,
      "rowCount": 150,
      "recipientsSent": 3
    },
    {
      "id": "uuid2",
      "status": "skipped",
      "startedAt": "2025-11-25T08:00:00Z",
      "reason": "No data for period"
    }
  ]
}
```

### Pausar/Reanudar

```typescript
PUT /api/v1/reports/schedules/:id/status
{
  "isActive": false
}
```

---

## Reglas de Negocio

| ID | Regla | Severidad |
|----|-------|-----------|
| BR-001 | Max 50 schedules por tenant | Resource |
| BR-002 | Minimo intervalo: 1 hora | Resource |
| BR-003 | Max 50 destinatarios por schedule | Email |
| BR-004 | Reintentar 3 veces si falla envio | Reliability |
| BR-005 | Archivos expiran en 7 dias | Storage |

---

## Criterios de Aceptacion

- [ ] CRUD de programaciones
- [ ] Soporte para expresiones cron
- [ ] Parametros con fechas relativas
- [ ] Envio a usuarios, emails y roles
- [ ] Historial de ejecuciones
- [ ] Pausar/reanudar programaciones
- [ ] Ejecucion manual bajo demanda

---

## Historial

| Version | Fecha | Autor | Cambios |
|---------|-------|-------|---------|
| 1.0 | 2025-12-05 | Requirements-Analyst | Creacion inicial |
