# Commander

> Chiffrer puis créer un service, sans passer par l'espace client.

Deux routes : une qui chiffre sans rien engager, une qui crée. Elles prennent le même
corps, ce qui permet de montrer le prix puis de commander à l'identique.

## Chiffrer

```http
POST /api/order/quote
```

```json
{
  "productSlug": "bases-de-donnees",
  "runtimeId": "cmu5o06zu000011l4y13xhwb1",
  "hostId": "cmr25fjrv000311zcupybejnu",
  "dimensions": { "cpuCores": 1, "ramGb": 1, "storageGb": 10 }
}
```

```json
{
  "productSlug": "bases-de-donnees",
  "dimensions": { "cpuCores": 1, "ramGb": 1, "storageGb": 10 },
  "lines": [
    { "label": "Processeur", "detail": "1 vCPU", "monthlyCents": 42 },
    { "label": "Mémoire", "detail": "1 Go", "monthlyCents": 56 },
    { "label": "Disque", "detail": "10 Go NVMe", "monthlyCents": 8 }
  ],
  "monthlyMillicents": 1060,
  "monthlyCents": 106,
  "hourlyLabel": "0,001 €/h",
  "minBalanceCents": 4,
  "balanceCents": 49583,
  "daysCovered": 468,
  "coversFirstDay": true
}
```

`coversFirstDay` est la barrière : à `false`, la commande sera refusée faute de solde
pour couvrir vingt-quatre heures.

## Commander

```http
POST /api/order
```

Le même corps, plus un nom, et le projet d'accueil :

```json
{
  "productSlug": "bases-de-donnees",
  "runtimeId": "cmu5o06zu000011l4y13xhwb1",
  "hostId": "cmr25fjrv000311zcupybejnu",
  "dimensions": { "cpuCores": 1, "ramGb": 1, "storageGb": 10 },
  "name": "crm-db",
  "projectId": "prj_0d3b6964bcbe4fd8518f",
  "variables": {}
}
```

```json
{
  "instanceId": "cmu5o62vj000111rtnrvd8q93",
  "productSlug": "bases-de-donnees",
  "name": "crm-db",
  "status": "ACTIVE",
  "monthlyMillicents": 1060,
  "href": "/ressources",
  "secrets": [
    { "label": "POSTGRES_PASSWORD", "value": "KAriXBhd6Yubh2FWLqTSXaEfsatr" }
  ]
}
```

<Warning>
`secrets` porte ce qui a été **généré à la création** — un mot de passe de base, par
exemple. Il n'est rendu qu'ici. Pour une base, tu peux toujours le relire ensuite avec
[la connexion](/api/bases-de-donnees#la-connexion) ; pour le reste, garde-le.
</Warning>

## Les champs

| Champ | Obligatoire | Ce qu'il fait |
| --- | --- | --- |
| `productSlug` | oui | Le produit vendu — `bases-de-donnees`, un jeu, une gamme |
| `runtimeId` | non | L'édition, quand le produit en propose plusieurs. Par défaut la première |
| `hostId` | oui | Le nœud d'accueil |
| `dimensions` | oui, sauf avec `presetId` | Processeur, mémoire, disque |
| `presetId` | non | Un gabarit tout fait, à la place de `dimensions` |
| `name` | oui | Le nom du service, 80 caractères au maximum |
| `projectId` | non | Le projet d'accueil. Par défaut, celui du compte |
| `variables` | non | Les réglages saisis à la commande |
| `options` | non | Les options du produit, sous forme `{ optionId, choiceId }` |

Un service commandé apparaît aussitôt dans [`GET /api/resources`](/api/services#lister).
Selon la famille, il naît `ACTIVE` ou `PROVISIONING` — sonde
[`/metrics`](/api/services#létat-en-direct) pour savoir quand il tourne vraiment.
