Refactor error handling and enhance API interactions across Filament pages

- Introduced `ApiErrorTranslator` to normalize and translate API error messages, providing clearer feedback in French.
- Updated all Filament pages (Articles, Documents, Divers, Journaux, Tiers, TablesExplorer) to utilize the new error translation mechanism, improving user experience during API interactions.
- Added validation for required fields before API calls, ensuring users receive immediate feedback when mandatory inputs are missing.
- Implemented tracking properties to distinguish between "never searched" and "searched without results," enhancing the user interface.
- Removed the obsolete `$results` property from the Articles page and added a new `$barcode` property to align with API requirements.
- Updated documentation to reflect changes in API behavior and error handling, including new metadata returned by the `art_list` endpoint.
- Added new tests to verify the functionality of the barcode handling and validation logic.
This commit is contained in:
2026-02-23 10:15:17 +01:00
parent 7df94b64fa
commit bb1bbc2904
29 changed files with 1075 additions and 157 deletions

View File

@@ -1,6 +1,6 @@
# Memory Bank
Dernière mise à jour : 2026-02-20
Dernière mise à jour : 2026-02-23
## Présentation

View File

@@ -1,11 +1,21 @@
# Active Context
Dernière mise à jour : 2026-02-21
Dernière mise à jour : 2026-02-23
## Travail en cours
Aucun travail en cours.
## Changements récents (2026-02-23, session investigation art_list)
- **Investigation du paramètre `results`** : tests systématiques via appels API directs. Le paramètre `results` n'a aucun effet observable sur `art_list` (toujours 5 résultats max) ni sur `third_list` (toujours 10 résultats max). Testé avec les valeurs 1, 3, 5, 10, 20, en int et en string, et avec omission. La limite est fixée côté serveur et non configurable.
- **Investigation du paramètre `barcode`** : tests systématiques via appels API directs. Le paramètre `barcode` est accepté par l'API mais n'a aucun effet observable sur les résultats de `art_list`. Les données retournées sont strictement identiques avec ou sans `barcode`. De plus, le paramètre `search` reste obligatoire même quand `barcode` est fourni (l'API retourne "Search terms are required" sinon).
- **Métadonnées `art_list`** : l'API retourne des métadonnées spécifiques : `rowCount` (camelCase), `source`, `executionTimeMs`, `searchColumns` (toujours "artid,name1"), `selectColumns`, `searchTerms`. Structure différente de celle documentée initialement.
- **Page Articles modifiée** : propriété `$results` (int) supprimée, propriété `$barcode` (string) ajoutée. Le champ "Nombre de résultats" remplacé par "Code-barres (barcode)" dans le formulaire.
- **Documentation mise à jour** : `WEB-A-1 (3).md` et `documentation_api_logistics.md` corrigés pour refléter les comportements réels de `results` et `barcode` sur `art_list` et `third_list`. Ajout des métadonnées spécifiques et d'un exemple de réponse complet.
- **2 nouveaux tests Pest** ajoutés dans `ArticlesPageTest.php` : vérification que `barcode` est envoyé quand renseigné, et omis quand vide.
- Total : 124 tests passent, 1 test pré-existant en échec (FilamentDashboardTest).
## Décisions récentes
- **Toggle Lecture/Ecriture** (2026-02-21) : Toutes les pages entité (Articles, Documents, Journaux, Tiers, Divers) disposent d'un toggle en haut de page permettant de basculer entre le mode Lecture (endpoints de récupération de données) et le mode Ecriture (endpoints d'envoi de données). Les pages sans endpoint d'écriture (Articles, Journaux, Tiers) affichent un état vide en mode écriture. TablesExplorer ne reçoit pas ce toggle (page de structure).
@@ -67,6 +77,24 @@ Aucun travail en cours.
- LogisticsService créé avec 17 endpoints.
- Migration api_request_logs créée.
## Changements récents (2026-02-23, session gestion erreurs et validation)
- Création de `app/Support/ApiErrorTranslator.php` : normalisation du champ `error` API (null/string/array), mapping de patterns d'erreurs connus vers des explications en français.
- Composant `error-banner.blade.php` : supporte désormais les sauts de ligne via `nl2br(e($message))` pour afficher les explications sur plusieurs lignes.
- Composant `json-block.blade.php` : nouvelle prop `$searched` (défaut `false`). Affiche un `empty-state` "Aucune donnée n'a été trouvée" quand `$searched` est `true` et `$data` est vide.
- Badge de comptage : remplacé `$metadata['rowcount'] ?? 0` par `count($data)` dans les 4 vues (articles, documents, journaux, tiers) pour un comptage fiable.
- Toutes les 6 pages API (Articles, Documents, Divers, Journaux, Tiers, TablesExplorer) utilisent désormais `ApiErrorTranslator::translate()` pour les messages d'erreur.
- Ajout de propriétés de tracking (`$hasSearched`, `$hasCheckedStock`, etc.) sur toutes les pages pour distinguer "jamais recherché" de "recherché sans résultat".
- Ajout de validation des champs obligatoires avant chaque appel API avec messages en français (au lieu de `return` silencieux). Règles basées sur `documentation/WEB-A-1 (3).md`.
- Validation ajoutée : `TYPE` obligatoire pour `jnl_list`, `search` obligatoire pour `third_list`, `ARTID` obligatoire pour `art_getstk`, `code` obligatoire pour `codes_list`, champs obligatoires pour tous les endpoints Documents.
- 4 nouveaux fichiers de tests : `ArticlesPageTest.php`, `JournauxPageTest.php`, `TiersPageTest.php`, `ApiErrorTranslatorTest.php`.
- Tests existants mis à jour : `DiversPageTest.php`, `DocumentsPageTest.php` (ajout tests de validation, mise à jour assertions pour les messages traduits).
- Total : 122 tests passent (302 assertions), 1 test pré-existant en échec (FilamentDashboardTest).
### 2026-02-23 (session investigation art_list)
- Voir section "Changements récents" ci-dessus.
## Prochaines étapes
- Corriger le test pré-existant `FilamentDashboardTest > it displays project statistics`.

View File

@@ -1,6 +1,6 @@
# Product Context
Dernière mise à jour : 2026-02-21
Dernière mise à jour : 2026-02-23
## Pourquoi ce projet existe
@@ -16,7 +16,8 @@ L'API Logistics (Flex/ESI Gescom) est un système de gestion commerciale accessi
- **Compréhension de la structure** : La page "Tables" permet de découvrir les tables et colonnes disponibles dans l'API, avec déduplication automatique des colonnes retournées en double par l'API.
- **Documentation intégrée** : La page "Documentation" affiche le markdown de la documentation API avec un rendu stylisé (typographie, tableaux, blocs de code) et propose un export PDF.
- **Traçabilité** : Chaque requête effectuée (réussie ou échouée) est enregistrée dans `api_request_logs` pour pouvoir analyser les échanges.
- **Résilience** : Les erreurs de connexion sont gérées avec retry automatique et messages explicites en français.
- **Résilience** : Les erreurs de connexion sont gérées avec retry automatique et messages explicites en français. Les erreurs API sont traduites et enrichies d'explications via `ApiErrorTranslator`.
- **Validation** : Les champs obligatoires sont validés avant chaque appel API avec des messages en français. Les pages distinguent "jamais recherché" de "recherché sans résultat" grace aux propriétés de tracking.
- **Cohérence visuelle** : Un système de design unifié (composants `x-logistics.*`) garantit une présentation homogène sur toutes les pages.
- **Couverture complète des endpoints** : Les 19 endpoints disponibles dans le service sont tous accessibles depuis l'interface, y compris les 2 non fonctionnels (avec avertissement).
@@ -26,7 +27,7 @@ L'utilisateur accède au dashboard Filament sur `http://api-logistics.test/admin
1. **Documentation** : Affichage stylisé de la documentation API complète (markdown converti en HTML). Actions : télécharger en PDF, ouvrir dans un nouvel onglet.
2. **Tables** : Barre de statistiques (endpoint, type base, nombre de tables). Liste filtrable des tables avec compteur de colonnes. Clic sur une table pour voir ses colonnes avec badges de type colorés.
3. **Articles** : Toggle Lecture/Ecriture. En lecture : formulaire de recherche (search, select, results) + vérification du stock d'un article par son ARTID. En écriture : état vide (aucun endpoint d'écriture disponible).
3. **Articles** : Toggle Lecture/Ecriture. En lecture : formulaire de recherche (search, select, barcode) + vérification du stock d'un article par son ARTID. L'API retourne un maximum fixe de 5 résultats (non configurable). Le paramètre `barcode` est présent dans le formulaire mais son effet côté API n'est pas observable. En écriture : état vide (aucun endpoint d'écriture disponible).
4. **Documents** : Toggle Lecture/Ecriture. En lecture : 7 formulaires (document_list, document_detail, Document_GetStatusList, Document_GetUnitPriceAndVat, Document_GetDueDate, Document_GetAttachListThumbnail, Document_GetPDF). En écriture : 2 formulaires (document_add, document_mod). Le formulaire Document_GetPDF affiche un bandeau d'avertissement (endpoint non fonctionnel).
5. **Journaux** : Toggle Lecture/Ecriture. En lecture : recherche par type de journal (TYPE). En écriture : état vide.
6. **Tiers** : Toggle Lecture/Ecriture. En lecture : recherche de tiers (search obligatoire) + historique des articles d'un tiers. En écriture : état vide.

View File

@@ -1,6 +1,6 @@
# Progress
Dernière mise à jour : 2026-02-21
Dernière mise à jour : 2026-02-23
## Ce qui fonctionne
@@ -35,6 +35,20 @@ Dernière mise à jour : 2026-02-21
- [x] `README.md` créé
- [x] Formatage Pint validé
- [x] CI GitHub Actions (lint + tests)
- [x] `ApiErrorTranslator` créé (`app/Support/ApiErrorTranslator.php`) : normalisation et traduction des erreurs API
- [x] Composant `error-banner` amélioré (supporte `nl2br` pour les explications)
- [x] Composant `json-block` amélioré (prop `$searched` + état vide)
- [x] Badge de comptage corrigé (`count($data)` au lieu de `$metadata['rowcount']`)
- [x] Validation des champs obligatoires sur toutes les pages API (messages en français)
- [x] Propriétés de tracking (`$hasSearched`, etc.) sur toutes les pages
- [x] `ApiErrorTranslator` intégré dans toutes les pages API (Articles, Documents, Divers, Journaux, Tiers, TablesExplorer)
- [x] 4 nouveaux fichiers de tests : ArticlesPageTest, JournauxPageTest, TiersPageTest, ApiErrorTranslatorTest
- [x] Tests existants mis à jour (DiversPageTest, DocumentsPageTest) avec validation et tracking
- [x] Investigation paramètre `results` : sans effet sur `art_list` (5 max) et `third_list` (10 max), limite fixe côté serveur
- [x] Investigation paramètre `barcode` : sans effet observable sur `art_list`, `search` reste obligatoire
- [x] Page Articles : `$results` supprimé, `$barcode` ajouté, formulaire mis à jour
- [x] Documentation `art_list` et `third_list` corrigée (métadonnées réelles, paramètres inefficaces documentés)
- [x] 2 nouveaux tests barcode dans ArticlesPageTest (envoi quand renseigné, omission quand vide)
## Ce qui reste à faire
@@ -48,13 +62,16 @@ Dernière mise à jour : 2026-02-21
- Le test `FilamentDashboardTest > it displays project statistics` échoue car le dashboard ne contient pas la section "Endpoints API" / "Tables accessibles" / "Pages Filament" / "Tests Pest". Le test a été créé avant la refonte du dashboard.
- L'erreur `SQLSTATE[HY000] [1049] Unknown database` peut apparaître lors de `composer update` si la base n'est pas encore créée (script `boost:update`). Sans impact une fois la base créée.
- L'API retourne chaque colonne en double dans `column_list`. Le `TablesExplorer` déduplique côté client.
- Le paramètre `results` n'a aucun effet sur `art_list` (toujours 5 max) ni sur `third_list` (toujours 10 max). Limite fixe côté serveur.
- Le paramètre `barcode` n'a aucun effet observable sur `art_list`. Le paramètre `search` reste obligatoire même avec `barcode`.
## Métriques
- Tests : 84 passent, 1 en échec pré-existant (205 assertions)
- Tests : 124 passent, 1 en échec pré-existant
- Pages Filament : 7 (Documentation, TablesExplorer, Articles, Documents, Journaux, Tiers, Divers)
- Composants Blade design system : 10
- Endpoints API couverts par LogisticsService : 19
- Endpoints accessibles depuis l'interface : 19 (dont 2 non fonctionnels)
- Migrations : 5 (users, cache, jobs, two_factor, api_request_logs)
- Règles Cursor : 4 (laravel-boost, memory-bank, design-system, update-documentation)
- Classes support : 1 (ApiErrorTranslator)

View File

@@ -1,6 +1,6 @@
# Project Brief
Dernière mise à jour : 2026-02-21
Dernière mise à jour : 2026-02-23
## Vision
@@ -22,7 +22,9 @@ Application Laravel de test dont l'objectif est de comprendre le fonctionnement
- Affichage des résultats sous forme de tableaux structurés et de blocs JSON formatés.
- Système de design unifié avec composants Blade réutilisables (`x-logistics.*`).
- Traçage des requêtes effectuées dans une table `api_request_logs`.
- Gestion robuste des erreurs API (timeout, retry, messages utilisateur en français).
- Gestion robuste des erreurs API (timeout, retry, messages utilisateur en français, traduction avec explications via `ApiErrorTranslator`).
- Validation des champs obligatoires avant chaque appel API avec messages en français.
- Distinction "jamais recherché" / "recherché sans résultat" via propriétés de tracking.
- Avertissements visuels pour les endpoints non fonctionnels (Document_GetPDF, custom_geninv_updatestock).
## Contraintes

View File

@@ -1,6 +1,6 @@
# System Patterns
Dernière mise à jour : 2026-02-21
Dernière mise à jour : 2026-02-23
## Architecture applicative
@@ -70,6 +70,23 @@ Le toggle est implémenté avec deux boutons et un `wire:click="$set('mode', 're
La page Documents utilise une méthode privée `splitCsv(string $value): array` qui convertit les champs de formulaire (texte séparé par virgules) en tableaux PHP pour les paramètres d'API qui attendent des arrays (Artid, Qty, Saleprice, Discount, Vatid, Vatpc). Exemple : `"ART001,ART002"` devient `["ART001", "ART002"]`.
### Traduction et normalisation des erreurs API
`App\Support\ApiErrorTranslator` centralise le traitement des erreurs retournées par l'API :
- **Normalisation** : Le champ `error` de l'API peut être `null`, une chaîne ou un tableau de chaînes. La méthode `normalize()` convertit tout en chaîne lisible.
- **Traduction** : La méthode `translate()` ajoute une explication en français aux messages d'erreur connus (ex: "Search terms are required" -> "Le champ de recherche est obligatoire.").
- **Format de sortie** : Quand une explication est trouvée, le message est formaté sur plusieurs lignes : `{message original}\n\nExplication : {explication}`.
### Validation et tracking des appels API
Chaque page Filament implémente :
- **Validation** : Les champs obligatoires sont vérifiés avant chaque appel API. Si un champ requis est vide, un message d'erreur en français est affiché via `$this->errorMessage` et la méthode retourne sans appeler l'API. Les règles de validation sont basées sur la documentation fournisseur (`documentation/WEB-A-1 (3).md`).
- **Tracking** : Des propriétés booléennes publiques (`$hasSearched`, `$hasCheckedStock`, etc.) sont mises à `true` après chaque appel API (succès ou erreur). Cela permet de distinguer "jamais recherché" de "recherché sans résultat" dans les vues Blade.
- **État vide** : Le composant `json-block` accepte une prop `$searched`. Quand `$searched` est `true` et `$data` est vide, un état vide est affiché. Pour les `data-table`, les vues vérifient `$hasSearched && count($data) === 0`.
- **Badge de comptage** : Les badges de résultats utilisent `count($data)` (comptage réel PHP) au lieu de `$metadata['rowcount']` (retourné par l'API, parfois incorrect).
### Endpoints non fonctionnels
Certains endpoints (Document_GetPDF, custom_geninv_updatestock) sont présents dans l'interface avec un bandeau d'avertissement ambre expliquant pourquoi ils ne fonctionnent pas. Les méthodes service existent dans LogisticsService pour permettre le test.
@@ -146,6 +163,8 @@ app/
AppServiceProvider.php # Config globale (CarbonImmutable, DB safety)
Services/
LogisticsService.php # Service centralisé API Logistics (19 méthodes)
Support/
ApiErrorTranslator.php # Normalisation et traduction des erreurs API
config/
logistics.php # Configuration API Logistics (URL, clé, timeout, retry)
@@ -174,14 +193,19 @@ database/
...create_api_request_logs_table.php
tests/Feature/
ArticlesPageTest.php # 8 tests page Articles (toggle, validation, tracking, erreurs)
DocumentationTest.php # 5 tests page Documentation (Livewire + PDF)
DocumentsPageTest.php # 13 tests page Documents (toggle, 9 endpoints, erreurs)
DiversPageTest.php # 8 tests page Divers (toggle, 3 endpoints, erreurs)
DocumentsPageTest.php # 21 tests page Documents (toggle, 9 endpoints, validation, erreurs)
DiversPageTest.php # 8 tests page Divers (toggle, 3 endpoints, validation, erreurs)
JournauxPageTest.php # 6 tests page Journaux (toggle, validation, tracking, erreurs)
LogisticsServiceTest.php # 14 tests service API (mocks HTTP)
TablesExplorerTest.php # 6 tests page TablesExplorer (Livewire)
TiersPageTest.php # 8 tests page Tiers (toggle, validation, tracking, erreurs)
FilamentDashboardTest.php # Tests dashboard Filament (1 test en échec pré-existant)
DashboardTest.php # Tests dashboard
ExampleTest.php # Test d'exemple Laravel
tests/Unit/
ApiErrorTranslatorTest.php # 9 tests normalisation et traduction des erreurs API
routes/
web.php # Routes web (home, dashboard, documentation PDF)

View File

@@ -1,6 +1,6 @@
# Tech Context
Dernière mise à jour : 2026-02-21
Dernière mise à jour : 2026-02-23
## Stack technique
@@ -98,7 +98,7 @@ Réponse `column_list` : chaque colonne a `name`, `dataType` (C/N/T/D/L/M), `len
|----------|----------------|------|-------------|-----------------------|
| `tables_list` | `tablesList()` | Lecture | Liste des tables | - |
| `column_list/{table}` | `columnList(string)` | Lecture | Colonnes d'une table | table (URL) |
| `art_list` | `artList(array)` | Lecture | Liste d'articles | select, results, search, barcode |
| `art_list` | `artList(array)` | Lecture | Liste d'articles (max 5 résultats, limite fixe serveur) | select, search, barcode (results sans effet) |
| `art_getstk` | `artGetStock(string)` | Lecture | Stock d'un article | ARTID |
| `jnl_list` | `jnlList(array)` | Lecture | Liste des journaux | select, results, TYPE |
| `document_list` | `documentList(array)` | Lecture | Liste des documents | select, thirdid |
@@ -108,7 +108,7 @@ Réponse `column_list` : chaque colonne a `name`, `dataType` (C/N/T/D/L/M), `len
| `Document_GetDueDate` | `documentGetDueDate(string, string)` | Lecture | Échéance | paydelay, date |
| `Document_GetAttachListThumbnail` | `documentGetAttachListThumbnail(string, string)` | Lecture | Miniatures annexes | JNL, NUMBER |
| `Document_GetPDF` | `documentGetPdf(string, string, string)` | Lecture | Génération PDF | JNL, NUMBER, LAYOUT |
| `third_list` | `thirdList(array)` | Lecture | Liste des tiers | select, results, search |
| `third_list` | `thirdList(array)` | Lecture | Liste des tiers (max 10 résultats, limite fixe serveur) | select, search (results sans effet) |
| `third_GetArtHistory` | `thirdGetArtHistory(string)` | Lecture | Historique articles tiers | thirdid |
| `getserialnumber` | `getSerialNumber()` | Lecture | Numéro de série | - |
| `codes_list` | `codesList(array)` | Lecture | Données par code | code |