# API Reference Base URL : `http://localhost:8080` Toutes les réponses sont en `application/json`. Les erreurs retournent `{"error": "message"}`. --- ## Health ### `GET /health` Vérifie la disponibilité du serveur et de la base de données. **Réponse `200`** ```json { "status": "ok" } ``` **Réponse `503`** — base indisponible --- ## Instruments Un instrument représente tout actif coté : devise (EUR), action, ETF, crypto. Le prix EUR vaut toujours 1 et est inséré automatiquement au démarrage. ### `GET /instruments` Liste tous les instruments. **Réponse `200`** ```json [ { "id": 1, "type": "devise", "code": "EUR", "name": "Euro", "devise_cotation": "EUR" }, { "id": 2, "type": "etf", "code": "LU1681043599", "name": "Amundi MSCI World", "devise_cotation": "EUR" } ] ``` --- ### `GET /instruments/{id}` **Réponse `200`** ```json { "id": 2, "type": "etf", "code": "LU1681043599", "name": "Amundi MSCI World", "devise_cotation": "EUR" } ``` **Réponse `404`** — instrument introuvable --- ### `POST /instruments` **Corps** | Champ | Type | Requis | Description | |---|---|---|---| | `type` | string | ✅ | `devise`, `action`, `etf`, `crypto` | | `code` | string | ✅ | ISIN (actions/ETF), ticker (crypto), code devise | | `name` | string | ✅ | Nom lisible | | `devise_cotation` | string | | Devise de cotation (défaut : `EUR`) | **Réponse `201`** ```json { "id": 3, "type": "crypto", "code": "BTC", "name": "Bitcoin", "devise_cotation": "EUR" } ``` > **Pipeline de prix** : le ticker Yahoo Finance (actions/ETF) est résolu automatiquement via OpenFIGI au prochain cycle. L'ID CoinGecko (crypto) est résolu via l'API search CoinGecko. Les résolutions sont mises en cache dans `instrument_ticker_cache`. --- ### `PUT /instruments/{id}` Même corps que `POST`. Retourne l'instrument mis à jour. --- ### `DELETE /instruments/{id}` **Réponse `204`** — supprimé --- ## Comptes Un compte est un conteneur de positions. Son solde est entièrement dérivé des transactions (aucun solde stocké). Les enveloppes sont des sous-comptes monétaires liés à un compte maître (voir section Enveloppes). `GET /accounts/{id}` retourne toujours le compte avec sa liste d'enveloppes. ### `GET /accounts` Liste les comptes maîtres (sans les enveloppes). **Réponse `200`** ```json [ { "id": 1, "nom": "Livret A", "type": "livret", "devise_reference": "EUR", "plafond": 22950 } ] ``` --- ### `GET /accounts/{id}` Retourne le compte et ses enveloppes. **Réponse `200`** ```json { "id": 1, "nom": "Livret A", "type": "livret", "devise_reference": "EUR", "plafond": 22950, "envelopes": [ { "id": 3, "nom": "Vacances", "type": "livret", "devise_reference": "EUR", "master_account_id": 1, "objectif": "Road trip USA" } ] } ``` **Réponse `404`** — compte introuvable --- ### `POST /accounts` Crée un compte maître. **Corps** | Champ | Type | Requis | Description | |---|---|---|---| | `nom` | string | ✅ | Nom du compte | | `type` | string | ✅ | `courant`, `livret`, `pea`, `cto`, `crypto`, ... | | `devise_reference` | string | | Devise de référence (défaut : `EUR`) | | `plafond` | number | | Plafond réglementaire (indicatif) | **Réponse `201`** ```json { "id": 1, "nom": "Livret A", "type": "livret", "devise_reference": "EUR", "plafond": 22950 } ``` --- ### `PUT /accounts/{id}` Met à jour un compte maître. Même corps que `POST`. --- ### `DELETE /accounts/{id}` Supprime le compte **et toutes ses enveloppes** (CASCADE). **Réponse `204`** --- ## Enveloppes Une enveloppe est un sous-compte monétaire rattaché à un compte maître. Elle hérite automatiquement du `type` et de la `devise_reference` de son maître. Le solde est dérivé des transactions, comme pour tout compte. Règles : - Un compte maître ne peut pas lui-même être une enveloppe (pas de chaînage) - Supprimée automatiquement avec son compte maître ### `GET /accounts/{id}/envelopes` Liste les enveloppes d'un compte. **Réponse `200`** ```json [ { "id": 3, "nom": "Vacances", "type": "livret", "devise_reference": "EUR", "master_account_id": 1, "objectif": "Road trip USA" } ] ``` --- ### `POST /accounts/{id}/envelopes` Crée une enveloppe sous le compte `{id}`. **Corps** | Champ | Type | Requis | Description | |---|---|---|---| | `nom` | string | ✅ | Nom de l'enveloppe | | `objectif` | string | | Description libre de l'objectif | **Réponse `201`** ```json { "id": 3, "nom": "Vacances", "type": "livret", "devise_reference": "EUR", "master_account_id": 1, "objectif": "Road trip USA" } ``` **Réponse `400`** — le compte est lui-même une enveloppe (chaînage interdit) **Réponse `404`** — compte introuvable --- ### `PUT /envelopes/{id}` Met à jour le nom et/ou l'objectif d'une enveloppe. **Corps** | Champ | Type | Requis | Description | |---|---|---|---| | `nom` | string | ✅ | Nouveau nom | | `objectif` | string | | Nouvel objectif | **Réponse `200`** — enveloppe mise à jour **Réponse `404`** — enveloppe introuvable --- ### `DELETE /envelopes/{id}` Supprime l'enveloppe. **Réponse `204`** --- ## Transactions Une transaction est un échange atomique entre deux participants (comptes ou enveloppes) via des instruments. Chaque côté (source, dest) est soit entièrement renseigné soit entièrement null. Au moins un côté doit exister. **Cas couverts :** | Cas | Source | Dest | |---|---|---| | Flux entrant (salaire, dépôt) | null | compte + instrument + quantité | | Flux sortant (dépense) | compte + instrument + quantité | null | | Virement / allocation enveloppe | compte + instrument + quantité | compte + instrument + quantité | | Achat de titres | compte, EUR, montant | compte, ETF, nb parts | | Swap crypto | wallet, BTC, qté | wallet, ETH, qté | Le champ `validated` indique si la transaction est réelle (`true`) ou prévisionnelle (`false`). Les transactions non validées à date dépassée remontent dans `?pending=true` (liste "à traiter"). --- ### `GET /accounts/{id}/transactions` Vue centrée sur le compte : le `montant` est signé (positif = crédit, négatif = débit). `instrument_id` est celui du côté du compte concerné. `contrepartie_account_id` est le compte en face (null si flux externe). **Paramètres de filtre** | Paramètre | Type | Description | |---|---|---| | `validated` | boolean | `true` ou `false` | | `pending` | boolean | `true` → non validées avec date ≤ aujourd'hui | | `from` | string | Date de début `YYYY-MM-DD` | | `to` | string | Date de fin `YYYY-MM-DD` | **Réponse `200`** — triée par date DESC ```json [ { "id": 1, "date": "2026-06-13", "montant": 2800.00, "instrument_id": 1, "tiers": "Employeur", "label": "Salaire juin", "categorie": "salaire", "validated": true }, { "id": 2, "date": "2026-06-10", "montant": -50.00, "instrument_id": 1, "label": "Courses", "categorie": "alimentation", "validated": true } ] ``` --- ### `GET /transactions/{id}` Retourne la transaction brute (tous les champs source/dest). **Réponse `200`** ```json { "id": 1, "date": "2026-06-13", "account_dest_id": 1, "instrument_dest_id": 1, "quantite_dest": 2800, "tiers": "Employeur", "label": "Salaire juin", "categorie": "salaire", "validated": true } ``` **Réponse `404`** — introuvable --- ### `POST /transactions` **Corps** | Champ | Type | Requis | Description | |---|---|---|---| | `date` | string | ✅ | `YYYY-MM-DD` | | `label` | string | ✅ | Libellé | | `validated` | boolean | | Défaut `false` | | `account_source_id` | integer | | Compte source | | `instrument_source_id` | integer | | Instrument source | | `quantite_source` | number | | Quantité source | | `account_dest_id` | integer | | Compte dest | | `instrument_dest_id` | integer | | Instrument dest | | `quantite_dest` | number | | Quantité dest | | `tiers` | string | | Tiers externe (employeur, commerçant…) | | `categorie` | string | | Catégorie libre | > Les trois champs de chaque côté (account, instrument, quantite) doivent être tous renseignés ou tous null. **Réponse `201`** — transaction créée (format brut) **Réponse `400`** — body invalide, label manquant, date manquante, ou violation de la contrainte source/dest --- ### `PUT /transactions/{id}` Mise à jour complète. Même corps que `POST`. **Réponse `200`** — transaction mise à jour (format brut) **Réponse `404`** — introuvable --- ### `PATCH /transactions/{id}/validate` Valide ou dé-valide une transaction. **Corps** ```json { "validated": true } ``` **Réponse `200`** — transaction avec le nouveau statut **Réponse `404`** — introuvable --- ### `DELETE /transactions/{id}` **Réponse `204`**