# Documentation API - Variable Schema

## Vue d'ensemble

Cette documentation décrit les endpoints API pour la gestion des **Variable Schemas**.

---

## Concepts

### Variables globales vs Variables recipients

Le système distingue deux types de variables :

1. **Variables globales** (`global_variables`) : Données partagées pour une campagne
   - Exemples : nom du magasin, adresse, horaires d'ouverture
   - Stockées dans `global_data` sur le schema
   - **Données finales** utilisées lors du merge dans les SMS

2. **Variables recipients** (`recipient_variables`) : Données individuelles par destinataire
   - Exemples : prénom, nom, email
   - Stockées dans `recipient_preview_data` pour l'aperçu
   - **Données de prévisualisation** - les vraies valeurs viennent du CSV/API lors de la création de campagne

### Variable Schema (Instance pour une campagne)

Un **Variable Schema** est une instance créée **pour une campagne spécifique**.

**Rôle :**
- Relation 1:1 avec une campagne dans la majorité des cas
- Les `global_data` contiennent les **valeurs finales** de cette campagne
- Utilisé lors du routing pour substituer les variables dans les SMS

**Exemple :** Un schema "Carrefour Nantes" contient les vraies données de ce magasin : nom, adresse, horaires spécifiques.

### Flow de merge des variables (Routing)

Lors de l'envoi des SMS, les variables sont fusionnées dans cet ordre :

```
1. Short URL (si configuré)
2. recipient.additional_information (données du CSV : prenom, nom, etc.)
3. Campaign->variableSchema->global_data (données globales finales du schema)

Résultat final pour le SMS :
{
  "shortUrl": "https://...",
  "prenom": "Marie",                          ← Du CSV
  "nom": "Dupont",                            ← Du CSV
  "nom_magasin": "Carrefour City Nantes",     ← Du schema
  "adresse_magasin": "12 rue de la Paix...",  ← Du schema
  "horaires": "9h-20h"                        ← Du schema
}
```

---

## Authentication

- **Middleware:** `auth.client_or_user` (authentification flexible)
- Accepte soit l'authentification utilisateur (`auth:api`)
- Soit les credentials client (machine-to-machine)

---

## Utilisation du SDK

Le SDK fournit deux façons d'accéder à l'API :

```php
// Via Facade (recommandé)
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$response = VariableSchemaApi::list();

// Via Service (injection de dépendances)
use Wellpack\Sdk\Trigger\Services\VariableSchemaApiService;

public function __construct(private VariableSchemaApiService $schemaApi) {}

$response = $this->schemaApi->list();
```

---

## Variable Schema API

### 1. Lister les schemas

```
GET /api/variable-schemas
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

// Liste simple
$response = VariableSchemaApi::list();

// Avec pagination
$response = VariableSchemaApi::list([
    'page' => 1,
    'perPage' => 20,
]);

// Avec tri (préfixer avec "-" pour ordre décroissant)
$response = VariableSchemaApi::list([
    'sort' => '-created_at',  // ou: name, updated_at, campaigns_count
]);

// Avec filtres
$response = VariableSchemaApi::list([
    'filter' => [
        'name' => 'Carrefour',
        'uuid' => '660e8400-e29b-41d4-a716-446655440111',
    ],
]);

$schemas = $response->json('data');
```

**Réponse:** `200 OK`
```json
{
  "data": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440111",
      "name": "Carrefour City Nantes",
      "global_variables": [
        {
          "id": "...",
          "name": "nom_magasin",
          "is_used": true,
          "is_global": true
        }
      ],
      "recipient_variables": [
        {
          "id": "...",
          "name": "prenom",
          "is_used": true,
          "is_global": false
        }
      ],
      "global_data": [
        {"key": "m1", "data": {"nom_magasin": "Carrefour City Nantes", "horaires": "9h-20h"}},
        {"key": "m2", "data": {"nom_magasin": "Auchan Rennes", "horaires": "8h-21h"}}
      ],
      "recipient_preview_data": {
        "global_parameters_key": "m1",
        "prenom": "Marie",
        "nom": "Dupont"
      },
      "merged_preview_data": {
        "nom_magasin": "Carrefour City Nantes",
        "horaires": "9h-20h",
        "prenom": "Marie",
        "nom": "Dupont"
      },
      "usage_stats": {
        "total": 5,
        "used": 4,
        "unused": 1,
        "global": 3,
        "recipient": 2
      },
      "campaigns_count": 1,
      "created_at": "2026-01-20T10:00:00Z",
      "updated_at": "2026-01-20T10:00:00Z"
    }
  ]
}
```

---

### 2. Créer un schema

```
POST /api/variable-schemas
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$response = VariableSchemaApi::create([
    'name' => 'Carrefour City Nantes',
    'global_variables' => ['nom_magasin', 'adresse_magasin', 'horaires'],
    'recipient_variables' => ['prenom', 'nom'],
    'global_data' => [
        'm1' => ['nom_magasin' => 'Carrefour City Nantes', 'horaires' => '9h-20h'],
        'm2' => ['nom_magasin' => 'Auchan Rennes', 'horaires' => '8h-21h'],
    ],
    'recipient_preview_data' => [
        'global_parameters_key' => 'm1',
        'prenom' => 'Marie',
        'nom' => 'Dupont',
    ],
]);

if ($response->successful()) {
    $schema = $response->json();
    echo "Schema créé avec l'ID: " . $schema['id'];
}
```

**Validation:**
| Champ | Règles |
|-------|--------|
| `name` | requis, string, max 255 |
| `global_variables` | optionnel, array de strings |
| `recipient_variables` | optionnel, array de strings |
| `global_data` | optionnel, object avec clés nommées |
| `recipient_preview_data` | optionnel, object (doit contenir `global_parameters_key` si `global_variables` non vide) |

**Important :** Une variable ne peut pas être à la fois globale ET recipient.

**Réponse:** `201 Created`

---

### 3. Découvrir un schema depuis un fichier

```
POST /api/variable-schemas/discover
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;
use Illuminate\Http\UploadedFile;

// Depuis une requête HTTP
$file = $request->file('csv_file');
$response = VariableSchemaApi::discover('Mon Schema', $file);

// Depuis un fichier local (pour tests ou jobs)
$file = new UploadedFile('/path/to/file.csv', 'data.csv');
$response = VariableSchemaApi::discover('Mon Schema', $file);

if ($response->status() === 201) {
    $schema = $response->json();
}
```

**Content-Type:** `multipart/form-data`

**Paramètres:**
| Champ | Règles |
|-------|--------|
| `name` | requis, string, max 255 |
| `file` | requis, fichier (csv, xlsx, xls, txt), max 10MB |

**Logique métier:**
- Lit la première ligne pour extraire les en-têtes de colonnes
- Filtre les champs techniques: `numero`, `phone`, `phone_number`, `msisdn`
- Détecte automatiquement la colonne clé (label, key, global_key, global_parameters_key)
- Chaque ligne devient un ensemble de données dans `global_data`

**Réponse:** `201 Created`

---

### 4. Prévisualiser un fichier

```
POST /api/variable-schemas/preview
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$file = $request->file('csv_file');
$response = VariableSchemaApi::preview($file);

$preview = $response->json('data');
// $preview['columns']           - Toutes les colonnes
// $preview['variables']         - Variables détectées (sans champs techniques)
// $preview['key_column']        - Colonne clé détectée
// $preview['key_column_detected'] - true si auto-détectée
// $preview['data_keys']         - Valeurs uniques de la colonne clé
// $preview['preview_rows']      - Premières lignes de données
// $preview['file_name']         - Nom du fichier
```

**Content-Type:** `multipart/form-data`

**Réponse:**
```json
{
  "columns": ["key", "ville", "horaires"],
  "variables": ["ville", "horaires"],
  "key_column": "key",
  "key_column_detected": true,
  "data_keys": ["m1", "m2"],
  "preview_rows": [...],
  "file_name": "global.csv"
}
```

---

### 5. Récupérer un schema

```
GET /api/variable-schemas/{schemaUuid}
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$schemaUuid = '660e8400-e29b-41d4-a716-446655440111';

$response = VariableSchemaApi::getOne($schemaUuid);

if ($response->successful()) {
    $schema = $response->json();
} elseif ($response->status() === 404) {
    // Schema non trouvé
}
```

---

### 6. Mettre à jour un schema

```
PATCH /api/variable-schemas/{schemaUuid}
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$schemaUuid = '660e8400-e29b-41d4-a716-446655440111';

// Mise à jour partielle (seuls les champs fournis sont modifiés)
$response = VariableSchemaApi::update($schemaUuid, [
    'name' => 'Updated Schema Name',
]);

// Mise à jour complète
$response = VariableSchemaApi::update($schemaUuid, [
    'name' => 'Updated Schema Name',
    'global_variables' => ['ville', 'code_postal'],
    'recipient_variables' => ['email', 'telephone'],
    'global_data' => [
        'loc1' => ['ville' => 'Paris', 'code_postal' => '75000'],
        'loc2' => ['ville' => 'Lyon', 'code_postal' => '69000'],
    ],
    'recipient_preview_data' => [
        'global_parameters_key' => 'loc1',
        'email' => 'contact@example.com',
        'telephone' => '0612345678',
    ],
]);
```

---

### 7. Supprimer un schema

```
DELETE /api/variable-schemas/{schemaUuid}
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$schemaUuid = '660e8400-e29b-41d4-a716-446655440111';

$response = VariableSchemaApi::delete($schemaUuid);

if ($response->status() === 204) {
    // Supprimé avec succès
} elseif ($response->status() === 422) {
    // Impossible de supprimer : lié à des campagnes actives
    $error = $response->json('message');
}
```

---

### 8. Cloner un schema

```
POST /api/variable-schemas/{schemaUuid}/clone
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$schemaUuid = '660e8400-e29b-41d4-a716-446655440111';

$response = VariableSchemaApi::clone($schemaUuid, [
    'name' => 'Copie de Mon Schema',
]);

if ($response->status() === 201) {
    $clonedSchema = $response->json();
    echo "Clone créé avec l'ID: " . $clonedSchema['id'];
}
```

---

### 9. Attacher/Détacher une référence

```
POST /api/variable-schemas/{schemaUuid}/attach
POST /api/variable-schemas/{schemaUuid}/detach
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$schemaUuid = '660e8400-e29b-41d4-a716-446655440111';

// Attacher une référence (idempotent)
$response = VariableSchemaApi::attach($schemaUuid);

// Détacher une référence
$response = VariableSchemaApi::detach($schemaUuid);
```

---

### 10. Marquer des variables comme utilisées/non utilisées

```
POST /api/variable-schemas/{schemaUuid}/mark-used
POST /api/variable-schemas/{schemaUuid}/mark-unused
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\VariableSchemaApi;

$schemaUuid = '660e8400-e29b-41d4-a716-446655440111';

// Marquer comme utilisées
$response = VariableSchemaApi::markUsed($schemaUuid, ['prenom', 'nom']);

// Marquer comme non utilisées
$response = VariableSchemaApi::markUnused($schemaUuid, ['code_promo']);

// Récupérer les stats mises à jour
$usageStats = $response->json('usage_stats');
// $usageStats['total']   - Nombre total de variables
// $usageStats['used']    - Nombre de variables utilisées
// $usageStats['unused']  - Nombre de variables non utilisées
```

---

## Multiple Global Data Sets

### Overview

Le champ `global_data` supporte **plusieurs ensembles de données** (multi-sets). Chaque destinataire peut référencer un ensemble spécifique via `global_parameters_key`.

### Input Format (Create/Update)

```json
{
  "global_data": {
    "m1": {"ville": "SAINT MOLF", "horaires": "9h-20h"},
    "m2": {"ville": "ESTANCARBON", "horaires": "8h-19h"}
  },
  "recipient_preview_data": {
    "global_parameters_key": "m1",
    "nom": "Dupont"
  }
}
```

### Output Format (GET)

```json
{
  "global_data": [
    {"key": "m1", "data": {"ville": "SAINT MOLF", "horaires": "9h-20h"}},
    {"key": "m2", "data": {"ville": "ESTANCARBON", "horaires": "8h-19h"}}
  ],
  "recipient_preview_data": {
    "global_parameters_key": "m1",
    "nom": "Dupont"
  },
  "merged_preview_data": {
    "ville": "SAINT MOLF",
    "horaires": "9h-20h",
    "nom": "Dupont"
  }
}
```

### CSV/Excel Import

Lors de l'import, chaque ligne représente un ensemble de données.

**Key Column Detection (Priority):**
1. `label`
2. `key`
3. `global_key`
4. `global_parameters_key`
5. **Fallback**: First column value

**Example CSV:**
```csv
key,ville,horaires
m1,SAINT MOLF,9h-20h
m2,ESTANCARBON,8h-19h
```

---

## Campaign Variables API

### 11. Récupérer les variables d'une campagne

```
GET /api/campaigns/{campaignUuid}/variables
```

**SDK:**
```php
use Wellpack\Sdk\Trigger\Facades\CampaignVariableApi;

$campaignUuid = '660e8400-e29b-41d4-a716-446655440111';

$response = CampaignVariableApi::getVariables($campaignUuid);

if ($response->successful()) {
    $data = $response->json('data');

    // Schema associé (peut être null)
    $schema = $data['variable_schema'];

    // Paramètres utilisés dans le contenu du message
    $contentParams = $data['content_parameters'];

    // Statut de validation
    $status = $data['validation_status']; // valid, warning, error

    // Variables manquantes dans le CSV
    $missing = $data['missing_in_csv'];

    // Variables supplémentaires dans le CSV (non déclarées)
    $extra = $data['extra_in_csv'];
}
```

**Réponse:** `200 OK`
```json
{
  "data": {
    "variable_schema": {
      "id": "660e8400-e29b-41d4-a716-446655440111",
      "name": "Carrefour City Nantes",
      "declared_variables": ["prenom", "nom", "nom_magasin"]
    },
    "content_parameters": ["prenom", "nom_magasin"],
    "validation_status": "valid",
    "missing_in_csv": [],
    "extra_in_csv": ["email"]
  }
}
```

**Statuts de validation:**
| Statut | Description |
|--------|-------------|
| `valid` | Toutes les variables du message sont disponibles |
| `warning` | Variables supplémentaires dans le CSV (non utilisées) |
| `error` | Variables manquantes (utilisées dans le message mais absentes du CSV/schema) |

---

## Modèle de données

### Tables

**variable_schemas:**
- `uuid` (unique)
- `name`
- `global_data` (JSON)
- `recipient_preview_data` (JSON)

**variable_fields:**
- `uuid` (unique)
- `variable_schema_id` (FK, cascade delete)
- `name`
- `is_used` (boolean, default: false)
- `is_global` (boolean, default: false)
- Contrainte unique: `(variable_schema_id, name)`
