docs: update README with comprehensive quickstart, services, pagination and error handling guides

This commit is contained in:
Jérémy Munsch 2026-09-16 12:45:51 +02:00
parent 892ae4b83e
commit 6d531aa559
Signed by: forge-joniko
GPG key ID: D7EFE2F5CB6CC0E4

343
README.md
View file

@ -1,42 +1,325 @@
# Arcadia Api PHP Client
# Arcadia API PHP Client
## Mappers
[![PHP Version](https://img.shields.io/badge/php-^8.5-blue.svg)](https://www.php.net/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Tests: Pest](https://img.shields.io/badge/tests-Pest%20PHP-purple.svg)](https://pestphp.com/)
[![PHPStan: Level 10](https://img.shields.io/badge/phpstan-level%2010-brightgreen.svg)](https://phpstan.org/)
### Employee
Client PHP haut niveau, fortement typé et orienté domaine pour l'API Arcadia.
Il s'appuie sur le client OpenAPI généré par Kiota (`uwil/arcadia-kiota-open-api-client`) et fournit :
- Une couche de services métier (`EmployeeService`, `IncoService`, `BrandService`, `ApiService`).
- Des Value Objects stricts (`ArcadiaEmployeeId`, `IncoId`, `IncoCompoId`, `BrandCode`, `SiteId`, etc.).
- Des DTOs riches (`Employee`, `Inco`, `IncoCompo`, `IncoShort`, `Brand`) avec typage complet et conformité `JsonSerializable`.
- Une gestion unifiée de la pagination (`PageOf`, `Pagination`) et du parcours continu par flux (`StreamOf`).
- L'authentification automatique avec signature HMAC (`HMAC-SHA256`) et gestion des nonces.
- Le support de la journalisation (PSR-3 `LoggerInterface`) et de l'observabilité (OpenTelemetry).
- Une gestion explicite des erreurs via la hiérarchie `ApiError`.
#### Props
---
```php
public string $matricule;
public string $lastname;
public string $firstname;
public string $start_date;
public string|null $end_date;
public string|null $planned_end_date;
public string $establishment;
public string $site;
public string $service;
## Sommaire
- [Prérequis](#prérequis)
- [Installation](#installation)
- [Initialisation](#initialisation)
- [Services et Utilisation](#services-et-utilisation)
- [Vérification de l'API (`apiService`)](#vérification-de-lapi-apiservice)
- [Gestion des Collaborateurs (`employees`)](#gestion-des-collaborateurs-employees)
- [Fiches INCO & Compositions (`incoSheets`)](#fiches-inco--compositions-incosheets)
- [Gestion des Marques (`brands`)](#gestion-des-marques-brands)
- [Pagination et Streaming](#pagination-et-streaming)
- [Gestion des Erreurs](#gestion-des-erreurs)
- [Tests et Qualité](#tests-et-qualité)
- [Licence](#licence)
---
## Prérequis
- **PHP 8.5+**
- Extensions PHP : `ext-curl`, `ext-mbstring`
- Accès au registre GitLab Composer de LDC Digital
---
## Installation
Comme cette bibliothèque et sa sous-dépendance Kiota sont hébergées sur le registre privé GitLab de LDC, configurez le dépôt Composer dans le `composer.json` de votre projet :
```json
{
"repositories": [
{
"type": "composer",
"url": "https://lab.s-web.fr/api/v4/group/23/-/packages/composer/packages.json"
}
]
}
```
#### Usage
Puis installez le client via Composer :
```php
<?php
use Uwil\ArcadiaApiPhpClient\Datas\EmployeesDatas;
require_once 'vendor/autoload.php';
$employee = EmployeesDatas::getById("0115590");
var_dump($employee);
?>
```bash
composer require uwil/arcadia-api-php-client
```
### INCO
Assurez-vous d'avoir configuré vos identifiants d'accès GitLab pour Composer (via `auth.json` ou variable d'environnement CI) :
TODO
```bash
composer config gitlab-token.lab.s-web.fr <deploy-token-user> <deploy-token-password>
```
## TESTS
---
[coverage](./coverage/index.html)
## Initialisation
L'entrée principale de la bibliothèque est [`ArcadiaApiClient`](src/ArcadiaApiClient.php), configurée avec [`ApiConfig`](src/Lib/ApiConfig.php) :
```php
use GuzzleHttp\Psr7\Utils;
use Uwil\ArcadiaApiPhpClient\ArcadiaApiClient;
use Uwil\ArcadiaApiPhpClient\Auth\ClientIdentifier;
use Uwil\ArcadiaApiPhpClient\Auth\ClientSecret;
use Uwil\ArcadiaApiPhpClient\Lib\ApiConfig;
$config = new ApiConfig(
endpoint: Utils::uriFor('https://arcadia-api.domain.tld/api'),
apiKey: new ClientIdentifier('VOTRE_API_KEY'),
secret: new ClientSecret('VOTRE_SECRET_KEY'),
curlTimeOut: 20.0, // secondes (optionnel, défaut: 20.0)
maxRetries: 3, // tentatives en cas d'erreur réseau (optionnel, défaut: 0)
retryDelaySeconds: 1, // délai entre les retries (optionnel, défaut: 1)
ignoreSelfSignedCert: false, // pour environnements locaux de test (défaut: false)
logger: null, // ?Psr\Log\LoggerInterface
tracer: null, // ?OpenTelemetry\API\Trace\TracerInterface
);
$client = new ArcadiaApiClient($config);
```
---
## Services et Utilisation
### Vérification de l'API (`apiService`)
Permet de vérifier la disponibilité et la santé de l'API Arcadia :
```php
$isAlive = $client->apiService()->isAlive();
if ($isAlive) {
echo "L'API Arcadia est joignable et opérationnelle.\n";
}
```
---
### Gestion des Collaborateurs (`employees`)
Le service [`EmployeeService`](src/Service/EmployeeService.php) permet de consulter et rechercher les salariés.
#### Récupérer par identifiant
```php
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\ArcadiaEmployeeId;
use Uwil\ArcadiaApiPhpClient\Error\ApiError;
$employee = $client->employees()->findBy(new ArcadiaEmployeeId('0115590'));
if ($employee instanceof ApiError) {
echo "Erreur API: " . $employee->getMessage();
} elseif ($employee === null) {
echo "Collaborateur non trouvé (404).\n";
} else {
echo "Salarié: {$employee->firstname} {$employee->lastname} (Site: {$employee->site})\n";
}
```
#### Récupérer par site(s)
```php
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\SiteId;
use Uwil\ArcadiaApiPhpClient\Lib\ApiSorter\EmployeeSorter;
use Uwil\ArcadiaApiPhpClient\Lib\ApiSorter\EmployeeSortColumn;
// Pour un site unique avec tri par matricule
$page = $client->employees()->getAllOfSites(
new SiteId('01'),
new EmployeeSorter(EmployeeSortColumn::MATRICULE, 'asc')
);
// Pour plusieurs sites modifiés depuis une date
$page = $client->employees()->getAllOfSitesSince(
[new SiteId('01'), new SiteId('02')],
new DateTimeImmutable('2026-01-01')
);
```
#### Streaming de tous les collaborateurs
Le streaming parcourt automatiquement toutes les pages de façon transparente grâce à un générateur PHP :
```php
foreach ($client->employees()->streamAll() as $employee) {
echo "{$employee->matricule} - {$employee->lastname}\n";
}
```
---
### Fiches INCO & Compositions (`incoSheets`)
Le service [`IncoService`](src/Service/IncoService.php) gère les fiches techniques produit (INCO) et leurs compositions nutritionnelles détaillées.
#### Consulter une fiche INCO
```php
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\IncoId;
$inco = $client->incoSheets()->findBy(new IncoId('12345'));
if ($inco !== null && !($inco instanceof ApiError)) {
echo "Fiche: {$inco->commercialLabel}\n";
echo "Nutri-Score: {$inco->nutriscore?->grade}\n";
}
```
#### Consulter la composition nutritionnelle
Vous pouvez interroger la composition par son `IncoCompoId` ou directement par l'`IncoId` :
```php
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\IncoCompoId;
// Directement via IncoCompoId
$compo = $client->incoSheets()->findCompo(new IncoCompoId('98765'));
// Ou via IncoId
$compo = $client->incoSheets()->findCompo(new IncoId('12345'));
if ($compo !== null && !($compo instanceof ApiError)) {
echo "Énergie (kJ): {$compo->energy?->kJ?->value}\n";
echo "Acides gras saturés: {$compo->fattyAcids?->saturatedFattyAcids?->value}\n";
echo "Points Nutri-Score: {$compo->nutriScorePoints?->totalPoints}\n";
}
```
#### Recherche et listage par marque
```php
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\BrandCode;
// Liste courte (IncoShort) pour optimiser les performances d'affichage
$shortsPage = $client->incoSheets()->getAllShortOfBrands(new BrandCode('GAULOIS'));
// Recherche par motif d'identifiant
$results = $client->incoSheets()->findByIncoIdLike('POULET%', new BrandCode('GAULOIS'));
// Streaming de toutes les fiches d'une marque
foreach ($client->incoSheets()->streamAllOfBrands(new BrandCode('LEGAULOIS')) as $sheet) {
echo "Fiche #{$sheet->id->value}: {$sheet->commercialLabel}\n";
}
```
---
### Gestion des Marques (`brands`)
Le service [`BrandService`](src/Service/BrandService.php) donne accès aux marques référencées :
```php
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\BrandCode;
// Récupérer une marque
$brand = $client->brands()->findBy(new BrandCode('GAULOIS'));
// Parcourir toutes les marques
foreach ($client->brands()->streamAll() as $brand) {
echo "Marque [{$brand->code->value}] : {$brand->label}\n";
}
```
---
## Pagination et Streaming
### Objet `PageOf`
Toutes les méthodes de liste paginées retournent un objet [`PageOf<T>`](src/Lib/ApiDto/Dto/PageOf.php) contenant les éléments et les métadonnées de pagination :
```php
$page = $client->employees()->getAll();
// Éléments de la page courante
$employees = $page->items;
// Métadonnées
echo "Page actuelle : " . $page->pagination->pageNumber->value . "\n";
echo "Taille de page : " . $page->pagination->pageSize->value . "\n";
echo "Total éléments : " . $page->pagination->totalItems . "\n";
echo "Total pages : " . $page->pagination->totalPages . "\n";
```
### Objet `StreamOf`
Toutes les méthodes `stream*()` retournent un [`StreamOf<T>`](src/Lib/Pagination/StreamOf.php) qui implémente `\IteratorAggregate`. Il effectue les requêtes de page suivante automatiquement à la demande :
```php
$stream = $client->employees()->streamAll();
foreach ($stream as $employee) {
// Les pages suivantes sont chargées en arrière-plan au fur et à mesure de l'itération
}
```
---
## Gestion des Erreurs
Les méthodes du client ne lancent pas d'exceptions inattendues pour les erreurs HTTP ou de communication ; elles renvoient une instance de [`ApiError`](src/Error/ApiError.php) (ou ses sous-classes spécialisées) :
```php
use Uwil\ArcadiaApiPhpClient\Error\AuthenticationError;
use Uwil\ArcadiaApiPhpClient\Error\ValidationError;
use Uwil\ArcadiaApiPhpClient\Error\NetworkError;
use Uwil\ArcadiaApiPhpClient\Error\RateLimitError;
use Uwil\ArcadiaApiPhpClient\Error\ServerError;
use Uwil\ArcadiaApiPhpClient\Error\ApiError;
$result = $client->employees()->findBy(new ArcadiaEmployeeId('0115590'));
match (true) {
$result instanceof AuthenticationError => logAuthFailure($result),
$result instanceof ValidationError => logValidationDetails($result->getViolations()),
$result instanceof NetworkError => retryLater($result),
$result instanceof RateLimitError => handleRateLimit($result),
$result instanceof ServerError => notifyAdmin($result),
$result instanceof ApiError => logGenericError($result),
$result === null => handleNotFound(),
default => handleEmployee($result),
};
```
---
## Tests et Qualité
Le projet est rigoureusement testé avec une suite complète de tests unitaires et d'architecture.
```bash
# Lancer les tests unitaires
composer test
# Vérifier la couverture de code (seuil minimal 85% configuré)
composer test:coverage
# Analyse statique PHPStan (niveau 10)
composer lint:phpstan
# Vérifier le style du code (Laravel Pint)
composer lint:pint
# Formater le code automatiquement
composer format
```
---
## Licence
Ce projet est sous licence MIT. Consultez le fichier [LICENSE](LICENSE) pour plus d'informations.