From 77bf9738600e718566c8ca076208f7cb0ecc4452 Mon Sep 17 00:00:00 2001 From: Imugiii Date: Fri, 19 Jun 2026 18:27:08 +0000 Subject: [PATCH] feat(api): endpoint public /api/allergens + decision prix (P4 optionnel) - GET /api/allergens (public anonyme, lecture seule) : les 14 allergenes INCO (id/code/name) via App\Catalogue\AllergenRepository. CatalogueController::allergens (meme enveloppe {data,total} + present que les autres lectures catalogue). - La borne CONSERVE son JSON statique (data/allergens.json) : il porte les descriptions riches, absentes du schema allergen (code+name seulement). Le swap reste possible si les descriptions sont ajoutees cote API ; commentaire data.js maj. - Prix : decision confirmee -- centimes en stockage/API (price_cents), euros a l'affichage (state.formatPrice). Aucun changement de convention requis. - Test : AllergenReadDbTest (integration, vraie DB : les 14 INCO). 351 PHP verts, PHPStan L6 propre, /api/allergens verifie live (200, total 14, same-origin). --- src/app/Catalogue/AllergenRepository.php | 32 ++++++++++++++ src/app/Controllers/CatalogueController.php | 34 +++++++++++++++ src/public/admin/index.php | 3 ++ src/public/borne/assets/js/data.js | 6 ++- tests/Integration/AllergenReadDbTest.php | 48 +++++++++++++++++++++ 5 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 src/app/Catalogue/AllergenRepository.php create mode 100644 tests/Integration/AllergenReadDbTest.php diff --git a/src/app/Catalogue/AllergenRepository.php b/src/app/Catalogue/AllergenRepository.php new file mode 100644 index 0000000..7b916dd --- /dev/null +++ b/src/app/Catalogue/AllergenRepository.php @@ -0,0 +1,32 @@ + double sans base). + */ +class AllergenRepository +{ + public function __construct(private readonly DatabaseInterface $db) + { + } + + /** + * Les allergenes references, tries par id (ordre INCO du seed). + * + * @return list> + */ + public function all(): array + { + return $this->db->fetchAll('SELECT id, code, name FROM allergen ORDER BY id'); + } +} diff --git a/src/app/Controllers/CatalogueController.php b/src/app/Controllers/CatalogueController.php index c7b2acf..5e8596a 100644 --- a/src/app/Controllers/CatalogueController.php +++ b/src/app/Controllers/CatalogueController.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Controllers; +use App\Catalogue\AllergenRepository; use App\Catalogue\CategoryRepository; use App\Catalogue\MenuRepository; use App\Catalogue\ProductRepository; @@ -111,6 +112,21 @@ class CatalogueController extends Controller return $this->json(['data' => $menu]); } + /** + * Allergenes INCO (info generale, 14 categories). Public anonyme, lecture seule. + * + * @param array $params + */ + public function allergens(array $params = []): Response + { + $rows = array_map( + fn (array $row): array => $this->presentAllergen($row), + $this->allergensRepo()->all(), + ); + + return $this->json(['data' => $rows, 'total' => count($rows)]); + } + protected function categoriesRepo(): CategoryRepository { return new CategoryRepository($this->db()); @@ -126,6 +142,11 @@ class CatalogueController extends Controller return new MenuRepository($this->db()); } + protected function allergensRepo(): AllergenRepository + { + return new AllergenRepository($this->db()); + } + /** * Acces BDD comme DatabaseInterface (seam de test). Database l'implemente. */ @@ -134,6 +155,19 @@ class CatalogueController extends Controller return $this->database; } + /** + * @param array $row + * @return array{id: int, code: string, name: string} + */ + private function presentAllergen(array $row): array + { + return [ + 'id' => (int) ($row['id'] ?? 0), + 'code' => (string) ($row['code'] ?? ''), + 'name' => (string) ($row['name'] ?? ''), + ]; + } + /** * @param array $row * @return array{id: int, name: string, slug: string, image_path: ?string, display_order: int} diff --git a/src/public/admin/index.php b/src/public/admin/index.php index 9eabba1..61ddd36 100644 --- a/src/public/admin/index.php +++ b/src/public/admin/index.php @@ -99,6 +99,9 @@ try { // Menus composes : liste legere + detail avec slots (B1 burger impose, B2 Normal/Maxi). $router->add('GET', '/api/menus', [CatalogueController::class, 'menus']); $router->add('GET', '/api/menus/{id}', [CatalogueController::class, 'menu']); + // Allergenes INCO (info generale, 14 categories). La borne garde son JSON statique + // (descriptions riches) ; l'endpoint sert d'autres consommateurs eventuels. + $router->add('GET', '/api/allergens', [CatalogueController::class, 'allergens']); // Back-office (P3) : pages rendues serveur sous /admin, gardees par SessionGuard. $router->add('GET', '/admin/dashboard', [DashboardController::class, 'index']); diff --git a/src/public/borne/assets/js/data.js b/src/public/borne/assets/js/data.js index 77c945d..7977842 100644 --- a/src/public/borne/assets/js/data.js +++ b/src/public/borne/assets/js/data.js @@ -17,8 +17,10 @@ const CATEGORIES_URL = '/api/categories'; const PRODUCTS_URL = '/api/products'; const MENUS_URL = '/api/menus'; -/* Liste fixe des 14 allergenes INCO (info generale, modale borne). Repli statique - * encore en place : bascule sur '/api/allergens' differee. */ +/* Liste fixe des 14 allergenes INCO (info generale, modale borne). L'endpoint + * /api/allergens existe desormais (id/code/name), mais la borne garde ce JSON + * statique : il porte les DESCRIPTIONS riches, absentes du schema allergen. Bascule + * possible si les descriptions sont ajoutees cote API. */ const ALLERGENS_URL = 'data/allergens.json'; /* Memoisation par PROMESSE (pas par resultat) : N appelants concurrents au meme diff --git a/tests/Integration/AllergenReadDbTest.php b/tests/Integration/AllergenReadDbTest.php new file mode 100644 index 0000000..22e9003 --- /dev/null +++ b/tests/Integration/AllergenReadDbTest.php @@ -0,0 +1,48 @@ +db = new Database(new Config()); + + try { + $this->db->fetch('SELECT 1'); + } catch (Throwable $exception) { + self::markTestSkipped('Base injoignable: ' . $exception->getMessage()); + } + } + + public function testListsIncoReferenceWithCodeAndName(): void + { + $rows = (new AllergenRepository($this->db))->all(); + + self::assertGreaterThanOrEqual(14, count($rows), 'les 14 allergenes INCO doivent etre references'); + foreach ($rows as $a) { + self::assertArrayHasKey('code', $a); + self::assertArrayHasKey('name', $a); + self::assertNotSame('', (string) ($a['name'] ?? '')); + } + } +} -- 2.45.3