# Manual Técnico - Tresipunt Manager

Este manual está dirigido a desarrolladores que necesitan instalar, ejecutar, entender la arquitectura y consumir la API del sistema de gestión de licencias.

## Índice

1. [Instalación y Puesta en Marcha](#1-instalación-y-puesta-en-marcha)
2. [Arquitectura y Componentes](#2-arquitectura-y-componentes)
3. [API - Endpoints y Contratos](#3-api---endpoints-y-contratos)
4. [Despliegue](#4-despliegue)

---

## 1. Instalación y Puesta en Marcha

### 1.1. Entorno de Desarrollo

**Se asume el uso de Laragon** como entorno de desarrollo local en Windows. Laragon proporciona Apache/Nginx, MySQL/MariaDB, PHP y herramientas necesarias de forma integrada.

**Alternativas**: Si no usas Laragon, puedes usar XAMPP, WAMP, o configurar manualmente Apache/Nginx + PHP + MySQL.

### 1.2. Requisitos del Sistema

- **PHP**: >= 8.2 (incluido en Laragon)
- **Composer**: Última versión ([descargar](https://getcomposer.org/))
- **Node.js**: >= 18.x y npm ([descargar](https://nodejs.org/))
- **MySQL/MariaDB**: Incluido en Laragon
- **Git**: Para clonar el repositorio

**Extensiones PHP requeridas** (normalmente ya incluidas en Laragon):
- BCMath
- Ctype
- cURL
- DOM
- Fileinfo
- JSON
- Mbstring
- OpenSSL
- PCRE
- PDO
- Tokenizer
- XML

**Verificar extensiones PHP**:
```bash
php -m
```

### 1.3. Instalación con Laragon

#### Paso 1: Clonar Repositorio

```bash
cd C:\laragon\www
git clone git@bitbucket.org:tresipunt/tresipunt-manager.git tresipunt-manager
cd tresipunt-manager
```

#### Paso 2: Asegurar que Laragon esté Ejecutándose

1. Abrir Laragon
2. Verificar que **Apache/Nginx** esté activo (botón verde)
3. Verificar que **MySQL** esté activo (botón verde)

#### Paso 3: Instalar Dependencias de PHP

```bash
composer install
```

#### Paso 4: Configurar Variables de Entorno

Crear archivo `.env` basándote en `.env.example` (si existe) o crear uno nuevo:

```bash
# Si existe .env.example
copy .env.example .env

# O crear manualmente
notepad .env
```

**Configuración mínima para Laragon**:

```env
APP_NAME="Tresipunt Manager"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_TIMEZONE=UTC
APP_URL=http://tresipunt-manager.test
APP_LOCALE=es
APP_FALLBACK_LOCALE=es
APP_FAKER_LOCALE=es_ES

LOG_CHANNEL=stack
LOG_LEVEL=debug

# Base de datos - Valores por defecto de Laragon
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tresipunt_manager
DB_USERNAME=root
DB_PASSWORD=

# Sesiones y Cache
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
SESSION_DRIVER=database
SESSION_LIFETIME=120
CACHE_STORE=database

# Mail (para desarrollo, usar log)
MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="noreply@tresipunt.com"
MAIL_FROM_NAME="${APP_NAME}"

# Vite
VITE_APP_NAME="${APP_NAME}"
```

#### Paso 5: Generar Clave de Aplicación

```bash
php artisan key:generate
```

Esto generará automáticamente `APP_KEY` en el archivo `.env`.

#### Paso 6: Crear Base de Datos

**Opción A: Desde HeidiSQL (incluido en Laragon)**
1. Abrir HeidiSQL
2. Conectar a MySQL (usuario: root, sin contraseña)
3. Crear nueva base de datos:
   ```sql
   CREATE DATABASE tresipunt_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
   ```

**Opción B: Desde Terminal**
```bash
mysql -u root -e "CREATE DATABASE tresipunt_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
```

#### Paso 7: Ejecutar Migraciones y Seeders

```bash
php artisan migrate --force
php artisan db:seed
```

**Qué hace el seeder**:
- Crea roles (Admin, Manager, Developer, Support, System, WebService)
- Crea permisos y los asigna a roles
- Crea usuarios por defecto:
  - `amanzano@tresipunt.com` / `Pruebas@123` (rol Admin)
  - `sergio@tresipunt.com` / `12345678` (rol Admin)
  - `manager@tresipunt.com` / `Pruebas@123` (rol WebService)
- Crea tipos de entornos
- Crea configuraciones iniciales

#### Paso 8: Crear Enlace Simbólico de Storage

```bash
php artisan storage:link
```

Esto crea un enlace simbólico desde `public/storage` a `storage/app/public` para que los archivos subidos sean accesibles públicamente.

#### Paso 9: Instalar Dependencias de Node.js

```bash
npm install
```

#### Paso 10: Compilar Assets

**Para desarrollo**:
```bash
npm run dev
```

**Para producción**:
```bash
npm run build
```

#### Paso 11: Acceder a la Aplicación

Laragon crea automáticamente dominios virtuales basados en el nombre de la carpeta. Accede a:

```
http://tresipunt-manager.test
```

**Si el dominio no funciona**:
1. Configurar manualmente en Laragon: Menú → Tools → Quick add → Agregar dominio
2. O usar: `http://localhost:8000` con `php artisan serve`

#### Paso 12: Login Inicial

Usar las credenciales del seeder:
- **Email**: `amanzano@tresipunt.com`
- **Contraseña**: `Pruebas@123`

O cualquiera de los otros usuarios creados por el seeder.

### 1.4. Variables de Entorno Importantes

Explicación de las variables más importantes del `.env`:

| Variable | Descripción | Valor Laragon |
|----------|-------------|---------------|
| `APP_KEY` | Clave de cifrado de Laravel | Generada automáticamente |
| `APP_DEBUG` | Modo debug (muestra errores) | `true` (desarrollo) |
| `APP_URL` | URL base de la aplicación | `http://tresipunt-manager.test` |
| `DB_HOST` | Host de la base de datos | `127.0.0.1` |
| `DB_DATABASE` | Nombre de la base de datos | `tresipunt_manager` |
| `DB_USERNAME` | Usuario de MySQL | `root` |
| `DB_PASSWORD` | Contraseña de MySQL | `` (vacío) |
| `QUEUE_CONNECTION` | Driver de colas | `database` (usa BD) |
| `SESSION_DRIVER` | Driver de sesiones | `database` (usa BD) |
| `CACHE_STORE` | Driver de caché | `database` (usa BD) |
| `MAIL_MAILER` | Driver de correo | `log` (desarrollo, guarda en logs) |

**Para producción**, cambiar:
- `APP_DEBUG=false`
- `APP_ENV=production`
- `MAIL_MAILER=smtp` (y configurar SMTP real)
- `QUEUE_CONNECTION=redis` o `database` (según infraestructura)

### 1.5. Arranque del Proyecto

#### Opción 1: Comando Todo-en-Uno (Recomendado)

```bash
composer run dev
```

Este comando inicia simultáneamente:
- Servidor Laravel (`php artisan serve` en puerto 8000)
- Queue worker (`php artisan queue:listen`)
- Pail (logs en tiempo real) (`php artisan pail`)
- Vite dev server (`npm run dev`)

**Nota**: Si usas Laragon para servir la aplicación, no necesitas `php artisan serve`. Solo ejecuta:

```bash
php artisan queue:listen
npm run dev
```

#### Opción 2: Comandos Separados

**Terminal 1 - Servidor Laravel** (si no usas Laragon):
```bash
php artisan serve
```

**Terminal 2 - Queue Worker**:
```bash
php artisan queue:listen
```

**Terminal 3 - Vite Dev Server**:
```bash
npm run dev
```

**Terminal 4 - Logs** (opcional):
```bash
php artisan pail
```

### 1.6. Problemas Frecuentes

#### Cache

Si ves cambios que no se reflejan, limpiar caché:

```bash
php artisan config:clear
php artisan cache:clear
php artisan view:clear
php artisan route:clear
```

#### Permisos Storage

En Windows/Laragon generalmente no hay problemas, pero si aparecen errores de permisos:

1. Verificar que las carpetas `storage` y `bootstrap/cache` existan
2. Verificar permisos de escritura (clic derecho → Propiedades → Seguridad)

En Linux:
```bash
chmod -R 775 storage bootstrap/cache
```

#### Keys

Si aparece error de "APP_KEY not set":

```bash
php artisan key:generate
```

#### Colas

Si las colas no procesan:

```bash
# Verificar que el worker esté corriendo
php artisan queue:work

# O en modo listen (recomendado para desarrollo)
php artisan queue:listen
```

**Nota**: Con `composer run dev` se inicia automáticamente.

#### Dominio Virtual No Funciona

1. **Verificar hosts de Windows**:
   - Abrir `C:\Windows\System32\drivers\etc\hosts` como administrador
   - Agregar: `127.0.0.1 tresipunt-manager.test`

2. **Configurar en Laragon**:
   - Menú → Tools → Quick add
   - Agregar dominio: `tresipunt-manager.test`

3. **Alternativa**: Usar `http://localhost:8000` con `php artisan serve`

#### Error "Class not found" o "Service Provider not found"

```bash
composer dump-autoload
php artisan config:clear
```

#### Base de Datos No Conecta

1. Verificar que MySQL esté corriendo en Laragon
2. Verificar credenciales en `.env`:
   - `DB_HOST=127.0.0.1`
   - `DB_USERNAME=root`
   - `DB_PASSWORD=` (vacío por defecto)
3. Probar conexión:
   ```bash
   php artisan tinker
   DB::connection()->getPdo();
   ```

---

## 2. Arquitectura y Componentes

### 2.1. Estructura de Módulos

```
app/
├── Http/
│   ├── Controllers/          # Controladores de la API y web
│   │   └── Api/V1/          # Controlador principal de la API
│   ├── Middleware/           # Middleware personalizado
│   │   └── ProductToken.php # Validación de tokens API
│   └── Requests/            # Form Requests (validación)
├── Livewire/                # Componentes Livewire (interfaz web)
│   ├── Clients/            # Gestión de clientes
│   ├── Dashboard/          # Panel principal
│   ├── Environments/       # Gestión de entornos
│   ├── Features/           # Gestión de features
│   ├── LicenseTokens/      # Gestión de tokens
│   ├── Products/           # Gestión de productos
│   ├── Resources/          # Gestión de recursos
│   ├── Scss/               # Gestión de archivos SCSS
│   ├── ScssCdn/            # Gestión de bundles SCSS CDN
│   ├── Setups/             # Gestión de configuraciones
│   ├── Tutorials/           # Gestión de tutoriales
│   └── Users/              # Gestión de usuarios
├── Models/                  # Modelos Eloquent organizados por dominio
│   ├── Auth/               # User
│   ├── Clients/            # Client
│   ├── Environments/       # Environment, Type
│   ├── Features/           # Feature, FeatureVersion
│   ├── Products/           # Product, LicenseToken, LicenseTokenProduct
│   ├── Resources/          # Resource, ResourceVersion
│   ├── Scss/               # ScssFile, ScssVersion
│   ├── ScssCdn/            # ScssCdnBundle, ScssCdnFile
│   ├── Setups/             # Setup
│   └── Tutorials/          # Tutorial, TutorialVersion
└── Services/                # Lógica de negocio
    ├── Api/                # Servicios de la API
    │   └── Actions/        # Acciones de la API (SyncAction, LicenceAction, etc.)
    ├── ScssCdn/            # Servicios de SCSS CDN
    └── Tutorials/          # Servicios de tutoriales
```

### 2.2. Storage (Almacenamiento de Archivos)

El sistema usa Laravel Filesystem para gestionar archivos:

**Discos configurados** (`config/filesystems.php`):

| Disco | Ruta Física | URL Pública | Uso |
|-------|-------------|-------------|-----|
| `local` | `storage/app/private` | No accesible | Archivos privados |
| `public` | `storage/app/public` | `/storage/...` | Archivos públicos (imágenes, etc.) |

**Estructura de almacenamiento**:

```
storage/
├── app/
│   ├── private/            # Archivos privados (disco 'local')
│   ├── public/            # Archivos públicos (disco 'public')
│   │   ├── products/      # Imágenes de productos
│   │   └── features/     # Imágenes de features
│   ├── SCSS_CDN/          # Bundles SCSS CDN
│   │   └── {product_slug}/
│   │       └── {version}/
│   │           └── {archivos}
│   └── setups/            # Archivos YAML de setups (si se usan archivos)
└── logs/                  # Logs de la aplicación
```

**Acceso público**:
- Los archivos en `storage/app/public` son accesibles vía URL después de ejecutar `php artisan storage:link`
- Ejemplo: `storage/app/public/products/image.png` → `http://tresipunt-manager.test/storage/products/image.png`

### 2.3. Jobs / Queues / Cron

**Sistema de colas**:
- **Driver por defecto**: `database` (usa tabla `jobs` en BD)
- **Configuración**: `config/queue.php`
- **Tablas**: `jobs`, `job_batches`, `failed_jobs`

**No hay jobs específicos implementados** actualmente, pero el sistema está preparado para usarlos.

**Queue Worker**:
En desarrollo, ejecutar:
```bash
php artisan queue:listen
```

O usar `composer run dev` que lo inicia automáticamente.

**Cron Jobs**:
No hay tareas programadas (cron) configuradas actualmente. Si se necesitan, agregar en `routes/console.php` o usar Laravel Scheduler.

### 2.4. Policies / Middleware

#### Middleware Personalizado

**ProductToken** (`app/Http/Middleware/ProductToken.php`):
- Valida tokens de licencia en peticiones API
- Verifica: existencia, activo, fechas válidas, rate limiting, host vinculado
- Se aplica automáticamente a todas las rutas `/api/v1/*`

#### Middleware de Spatie Permission

Configurado en `bootstrap/app.php`:
- `permission:` - Verifica permiso específico
- `role:` - Verifica rol específico
- `role_or_permission:` - Verifica rol O permiso

**Uso en rutas**:
```php
Route::middleware(['permission:admin.users.index'])->group(function () {
    // Rutas protegidas
});
```

#### Policies

No hay Policies explícitas. La autorización se hace vía:
- Middleware de permisos en rutas
- `authorize()` en componentes Livewire

### 2.5. API / Endpoints

#### Endpoint Principal

**POST** `/api/v1/`

Endpoint único que maneja todas las acciones mediante el parámetro `action` en el payload.

**Middleware**: `product_token` (validación de Bearer Token)

#### Otros Endpoints

**GET** `/api/cdn/scss/{token}/{filename}`
- Sirve archivos SCSS CDN vía URL firmada
- Middleware: `signed` (URL firmada con expiración)
- Headers: `Cache-Control: public, max-age=31536000`

**POST** `/api/features/upload-image`
- Sube imágenes para features
- Middleware: `auth`, `permission:admin.features.create`
- Requiere autenticación web

### 2.6. Flujo de una Petición API

```mermaid
sequenceDiagram
    participant Client as Cliente (Moodle)
    participant Middleware as ProductToken Middleware
    participant Controller as MoodleApiController
    participant Resolver as ActionResolver
    participant Action as Action (ej: SetupAction)
    participant Model as Model (ej: Setup)

    Client->>Middleware: POST /api/v1/ + Bearer Token
    Middleware->>Middleware: Validar token (activo, fechas, host)
    Middleware->>Middleware: Validar producto y licencia
    Middleware->>Controller: Request validado
    Controller->>Resolver: Resolver acción
    Resolver->>Action: Ejecutar acción
    Action->>Model: Buscar datos
    Model->>Action: Datos
    Action->>Controller: Response
    Controller->>Client: JSON Response
```

---

## 3. API - Endpoints y Contratos

### 3.1. Lista Completa de Endpoints

| Método | Ruta | Descripción | Auth |
|--------|------|-------------|------|
| POST | `/api/v1/` | Endpoint principal (todas las acciones) | Bearer Token |
| GET | `/api/cdn/scss/{token}/{filename}` | Servir archivo SCSS CDN | Signed URL |
| POST | `/api/features/upload-image` | Subir imagen para feature | Web Auth |

### 3.2. Autenticación

**Tipo**: Bearer Token

**Header requerido**:
```
Authorization: Bearer {token}
```

**Ejemplo**:
```bash
curl -X POST https://manager.tresipunt.com/api/v1/ \
  -H "Authorization: Bearer 3IP-A1B2-C3D4-E5F6-G7H8" \
  -H "Content-Type: application/json" \
  -d '{"action": "licence", ...}'
```

### 3.3. Acciones Disponibles

Todas las acciones se envían al mismo endpoint (`POST /api/v1/`) con el campo `action` en el payload.

#### 3.3.1. Sync

**Acción**: `sync`

**Descripción**: Actualiza información de un entorno existente. **NO crea nuevos entornos**.

**Request**:
```json
{
  "action": "sync",
  "plugin": "local_tresipunt",
  "host": "https://moodle.ejemplo.com",
  "version": "2025110401",
  "environment": {
    "version": "2025081101",
    "release": "4.5.1",
    "lastversion": "4.5",
    "lastminor": "4.5.3",
    "token": "token_moodle_opcional",
    "type": "moodle",
    "env": "pro"
  },
  "projectid": "S3-3434"
}
```

**Response** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "sync",
  "data": {
    "id": 1,
    "name": "moodle.ejemplo.com",
    "domain": "https://moodle.ejemplo.com",
    "version": "2025081101",
    "env": "pro"
  }
}
```

#### 3.3.2. Licence

**Acción**: `licence`

**Descripción**: Verifica si un plugin tiene licencia válida para el entorno.

**Request**:
```json
{
  "action": "licence",
  "plugin": "theme_fresk",
  "host": "https://moodle.ejemplo.com",
  "version": "2025110401",
  "environment": {...}
}
```

**Response exitosa** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "licence",
  "data": {
    "valid": true,
    "plugin": "theme_fresk",
    "version": "2025110401"
  }
}
```

**Response error** (401):
```json
{
  "success": false,
  "error": "Licence does not include this plugin",
  "code": 2001,
  "action": "licence",
  "data": {}
}
```

#### 3.3.3. Products

**Acción**: `products`

**Descripción**: Obtiene todos los productos activos disponibles para el entorno.

**Request**:
```json
{
  "action": "products",
  "host": "https://moodle.ejemplo.com",
  "environment": {...}
}
```

**Response** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "products",
  "data": [
    {
      "slug": "theme_fresk",
      "name": "Tema Fresk",
      "version": "2025110401"
    }
  ]
}
```

#### 3.3.4. Setup

**Acción**: `setup`

**Descripción**: Obtiene configuración YAML del producto.

**Request**:
```json
{
  "action": "setup",
  "plugin": "theme_fresk",
  "version": "2025110401",
  "host": "https://moodle.ejemplo.com",
  "environment": {...}
}
```

**Response** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "setup",
  "data": {
    "version": "2025110401",
    "yaml": {
      "theme": {
        "colors": {
          "primary": "#007bff"
        }
      }
    }
  }
}
```

#### 3.3.5. SCSS

**Acción**: `scss`

**Descripción**: Obtiene archivos SCSS del producto.

**Request**:
```json
{
  "action": "scss",
  "plugin": "theme_fresk",
  "version": "2025110401",
  "host": "https://moodle.ejemplo.com",
  "environment": {...},
  "data": {
    "files": ["variables", "custom"]
  }
}
```

**Response** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "scss",
  "data": {
    "files": [
      {
        "filename": "variables.scss",
        "content": "$primary: #007bff;",
        "found": true
      },
      {
        "filename": "custom.scss",
        "content": ".custom { color: $primary; }",
        "found": true
      }
    ]
  }
}
```

#### 3.3.6. SCSS CDN

**Acción**: `scss-cdn`

**Descripción**: Obtiene URLs firmadas de archivos SCSS CDN.

**Request**:
```json
{
  "action": "scss-cdn",
  "plugin": "theme_fresk",
  "version": "2025110401",
  "host": "https://moodle.ejemplo.com",
  "environment": {...}
}
```

**Response** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "scss-cdn",
  "data": {
    "files": [
      {
        "filename": "main.css",
        "url": "https://manager.tresipunt.com/api/cdn/scss/abc123/main.css?signature=...",
        "expires_at": "2026-01-15T10:30:00Z"
      }
    ]
  }
}
```

#### 3.3.7. JS

**Acción**: `js`

**Descripción**: Obtiene archivos JavaScript del producto.

**Request**: Similar a `scss`

**Response**: Similar a `scss`, pero con archivos `.js`

#### 3.3.8. Features

**Acción**: `features`

**Descripción**: Obtiene features publicadas del producto.

**Request**:
```json
{
  "action": "features",
  "plugin": "theme_fresk",
  "version": "2025110401",
  "host": "https://moodle.ejemplo.com",
  "environment": {...}
}
```

**Response** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "features",
  "data": [
    {
      "id": 1,
      "title": "Sistema de Notificaciones",
      "description": "Notificaciones en tiempo real",
      "content_html": "<p>Contenido...</p>",
      "thumbnail_url": "https://...",
      "header_url": "https://...",
      "sort_order": 1
    }
  ]
}
```

#### 3.3.9. Tutorials

**Acción**: `tutorials`

**Descripción**: Obtiene tutoriales publicados del producto.

**Request**: Similar a `features`

**Response** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "tutorials",
  "data": [
    {
      "id": 1,
      "title": "Cómo configurar el tema",
      "desc": "Tutorial paso a paso",
      "video_id": "dQw4w9WgXcQ",
      "platform": "youtube",
      "embed_url": "https://www.youtube.com/embed/dQw4w9WgXcQ",
      "video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "sort_order": 1
    }
  ]
}
```

#### 3.3.10. Resources

**Acción**: `resources`

**Descripción**: Obtiene recursos publicados y públicos del producto.

**Request**: Similar a `features`

**Response** (200):
```json
{
  "success": true,
  "error": "",
  "code": 0,
  "action": "resources",
  "data": [
    {
      "id": 1,
      "title": "Manual de Usuario",
      "description": "Guía completa",
      "type": "file",
      "file_url": "https://...",
      "read_time": 15,
      "sort_order": 1
    },
    {
      "id": 2,
      "title": "Documentación Externa",
      "type": "link",
      "url": "https://docs.ejemplo.com",
      "sort_order": 2
    }
  ]
}
```

#### 3.3.11. Data

**Acción**: `data`

**Descripción**: Envía datos de telemetría del entorno.

**Request**:
```json
{
  "action": "data",
  "plugin": "local_tresipunt",
  "host": "https://moodle.ejemplo.com",
  "version": "2025110401",
  "environment": {...},
  "data": {
    "users": 150,
    "courses": 25,
    "plugins": [...]
  }
}
```

#### 3.3.12. Plugins

**Acción**: `plugins`

**Descripción**: Envía información de plugins instalados en el entorno.

**Request**: Similar a `data`, con información de plugins en `data.plugins`

### 3.4. Códigos de Error

| Código HTTP | Código Interno | Descripción |
|-------------|----------------|-------------|
| 200 | 0 | Éxito |
| 400 | 400 | Error de validación |
| 401 | 401 | Token no válido o no proporcionado |
| 401 | 2001 | Licencia no incluye este plugin |
| 401 | 2002 | Entorno no encontrado o plugin no encontrado |
| 401 | 3000 | Producto no validado (SCSS/SCSS CDN/Setup/Features) |
| 404 | 3002 | No se encontró versión compatible o archivos |
| 500 | 3003 | Formato de versión inválido o archivo inválido |
| 401 | 4000 | Producto no validado (JS/Tutorials) |
| 404 | 4002 | No se encontró versión compatible o archivos (JS/Tutorials) |
| 500 | 4003 | Formato de versión inválido (JS/Tutorials) |
| 401 | 5000 | Producto no validado (Resources) |
| 404 | 5002 | No se encontró versión compatible de recursos |
| 500 | 5003 | Formato de versión inválido (Resources) |
| 403 | 403 | Token inactivo, expirado o sin permisos |
| 429 | 429 | Límite de peticiones excedido |
| 500 | 500 | Error interno del servidor |

### 3.5. Rate Limiting

**Configuración**:
- Límite por token: Configurable en campo `usage_limit` del token
- Límite por defecto: 10000 peticiones si no se especifica
- Ventana: 60 segundos

**Comportamiento**:
- Cada petición incrementa el contador
- Si se excede el límite, devuelve error 429
- El contador se resetea cada 60 segundos

**Ejemplo de error**:
```json
{
  "success": false,
  "error": "Límite de peticiones excedido. Intente nuevamente en 5 minuto(s)",
  "code": 429,
  "action": "licence",
  "data": {}
}
```

### 3.6. Validaciones del Middleware

El middleware `ProductToken` valida en cada petición:

1. **Token existe**: El token debe existir en la base de datos
2. **Token activo**: `active = true`
3. **Fechas válidas**:
   - Si `start_at` existe: `ahora >= start_at`
   - Si `end_at` existe: `ahora <= end_at`
4. **Rate limiting**: No exceder `usage_limit`
5. **Host vinculado**: El host debe estar asociado al token (excepto `sync`)
6. **Producto con licencia**: Para acciones que requieren producto, el token debe tener licencia activa

---

## 4. Despliegue

### 4.1. Entornos

El sistema está preparado para múltiples entornos, aunque no hay documentación específica de PRO/PRE. Se recomienda seguir estándares de Laravel:

- **Local**: Desarrollo local (Laragon)
- **Desarrollo**: Servidor de desarrollo
- **Pre-producción**: Servidor de pruebas
- **Producción**: Servidor en vivo

### 4.2. Variables Sensibles - Checklist

Antes de desplegar, verificar estas variables en `.env`:

**Aplicación**:
- [ ] `APP_ENV=production`
- [ ] `APP_DEBUG=false`
- [ ] `APP_KEY` generada y segura
- [ ] `APP_URL` correcta (URL de producción)

**Base de Datos**:
- [ ] `DB_HOST` correcto
- [ ] `DB_DATABASE` correcto
- [ ] `DB_USERNAME` seguro
- [ ] `DB_PASSWORD` seguro (no vacío)

**Sesiones y Cache**:
- [ ] `SESSION_DRIVER` configurado (recomendado: `database` o `redis`)
- [ ] `CACHE_STORE` configurado (recomendado: `redis` para producción)

**Correo**:
- [ ] `MAIL_MAILER=smtp`
- [ ] `MAIL_HOST` configurado
- [ ] `MAIL_USERNAME` configurado
- [ ] `MAIL_PASSWORD` configurado
- [ ] `MAIL_FROM_ADDRESS` configurado
- [ ] `MAIL_FROM_NAME` configurado

**AWS (si se usa S3)**:
- [ ] `AWS_ACCESS_KEY_ID`
- [ ] `AWS_SECRET_ACCESS_KEY`
- [ ] `AWS_DEFAULT_REGION`
- [ ] `AWS_BUCKET`

**Colas**:
- [ ] `QUEUE_CONNECTION` configurado (`database` o `redis`)

### 4.3. Comandos Típicos de Deploy

#### Pre-Deploy

```bash
# 1. Actualizar código
git pull origin main

# 2. Instalar/actualizar dependencias
composer install --optimize-autoloader --no-dev

# 3. Instalar dependencias de Node
npm install

# 4. Compilar assets
npm run build
```

#### Deploy

```bash
# 1. Ejecutar migraciones
php artisan migrate --force

# 2. Limpiar cachés
php artisan config:clear
php artisan cache:clear
php artisan view:clear
php artisan route:clear

# 3. Optimizar para producción
php artisan config:cache
php artisan route:cache
php artisan view:cache

# 4. Crear enlace de storage (si no existe)
php artisan storage:link

# 5. Reiniciar queue workers (si aplica)
# En producción, usar supervisor o similar para gestionar workers
```

#### Post-Deploy

```bash
# Verificar que la aplicación funciona
curl https://tu-dominio.com/up

# Verificar logs
tail -f storage/logs/laravel.log
```

### 4.4. Queue Workers en Producción

En producción, los queue workers deben ejecutarse como procesos persistentes. Opciones:

**Opción 1: Supervisor (Recomendado)**

Configurar supervisor para gestionar workers:

```ini
[program:tresipunt-manager-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /ruta/al/proyecto/artisan queue:work database --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/ruta/al/proyecto/storage/logs/worker.log
stopwaitsecs=3600
```

**Opción 2: Systemd**

Crear servicio systemd para el worker.

**Opción 3: Cron (No recomendado)**

```bash
* * * * * cd /ruta/al/proyecto && php artisan schedule:run >> /dev/null 2>&1
```

### 4.5. Optimizaciones de Producción

**Composer**:
```bash
composer install --optimize-autoloader --no-dev
```

**Laravel**:
```bash
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache  # Si se usan eventos
```

**NPM**:
```bash
npm run build  # Minifica y optimiza assets
```

### 4.6. Seguridad

**Recomendaciones**:
1. **`.env` no debe estar en el repositorio**: Verificar `.gitignore`
2. **Permisos de archivos**: `storage` y `bootstrap/cache` deben ser escribibles
3. **HTTPS**: Usar HTTPS en producción
4. **Tokens seguros**: Los tokens deben ser únicos y complejos
5. **Rate limiting**: Configurar límites apropiados por token
6. **Logs**: Revisar logs regularmente para detectar intentos de acceso no autorizados

---

## Referencias

- [Manual Funcional](MANUAL_FUNCIONAL.md) - Para información operativa
- [Documentación API](API_DOCUMENTATION.md) - Documentación completa de la API
- [Guía de Usuario API](API_USER_GUIDE.md) - Guía para desarrolladores que integran la API
- [Laravel Documentation](https://laravel.com/docs) - Documentación oficial de Laravel
- [Livewire Documentation](https://livewire.laravel.com/docs) - Documentación de Livewire

---

**Última actualización**: 2025-01-XX

