# Tekshelf — API du tenant
## Intégration No Waste · Bacs promo

Version 0.4 — 23 octobre 2026.

Documentation des appels utilisés pour intégrer les bacs promo dans No Waste. Les choix encore ouverts sont regroupés dans la section « Points à confirmer ».

## 1. Objectif de l’intégration

Permettre à une pharmacie équipée de deux ou trois bacs promo de consulter et de gérer ses bacs depuis l’interface No Waste, sans utiliser une seconde interface au quotidien.

Le périmètre cible comprend :

- L’identification de la pharmacie et de ses bacs.
- L’affichage des visuels Tekshelf et des produits présents dans les bacs.
- La consultation des remontées de données, des indicateurs, de leur date de mise à jour et de l’historique.
- La recherche et la gestion des produits, ainsi que leur association aux bacs.
- Les opérations de mise en service et de maintenance accessibles au partenaire, selon les capacités du matériel.
- À terme, les notes, commentaires, recommandations et alertes dont la disponibilité devra être confirmée.

## 2. Adresse d’API propre à chaque tenant

L’adresse de l’API est fournie par Tekshelf pour chaque tenant. Les chemins décrits dans cette documentation s’ajoutent à cette adresse.

Un tenant correspond à un périmètre client. Un filtre `storeId` permet de cibler un magasin dans les appels qui le proposent.

### 2.1 Configuration de connexion

| Information | Règle d’intégration |
|---|---|
| Origine de l’API | Adresse HTTPS propre au tenant, fournie par Tekshelf. |
| Environnement | Test ou production, explicitement identifié. |
| Accès partenaire | Accès fourni par Tekshelf pour les magasins autorisés ; procédure de connexion à compléter. |
| Magasin | Identifiant `storeId` utilisé lorsque l’appel le demande. |
| Ressources | Identifiants Tekshelf des bacs, dispositifs, balances et produits ; à conserver avec le contexte du tenant. |

**Convention de cette documentation :** `TENANT_ORIGIN` désigne uniquement le protocole et l’hôte, sans barre finale ni suffixe `/api`.

Exemple d’assemblage, avec un domaine fictif non opérationnel :

```text
TENANT_ORIGIN = https://tenant-a.example.invalid
Chemin = /api/furnitures?storeId={storeId}
URL appelée = TENANT_ORIGIN + chemin
```

Les adresses de test et de production se configurent séparément dans No Waste.

### 2.2 Gestion de plusieurs tenants par No Waste

No Waste conserve, pour chaque connexion client, l’origine du tenant, l’environnement, les accès associés et la correspondance avec les magasins. Une requête est toujours envoyée au tenant de la ressource concernée.

Les identifiants sont à considérer dans leur contexte : le stockage côté No Waste doit associer au minimum l’environnement, le tenant et l’identifiant de ressource. Une connexion accordée à un tenant n’autorise pas à lire ou modifier un autre tenant.

Un `storeId` est un filtre et un contexte métier ; il ne remplace pas le contrôle des droits côté serveur. L’absence de filtre ne doit jamais ouvrir l’accès à des magasins non autorisés.

Aucune API centrale de découverte de tous les tenants n’est définie ici. Les adresses initiales sont fournies par Tekshelf ; leur provisionnement automatisé pourra être spécifié séparément si nécessaire.

## 3. Actions à permettre ou à exclure pour No Waste

Périmètre proposé pour No Waste. Les actions de gestion restent à arrêter entre les deux équipes avant l’ouverture des accès.

| Action métier | Décision proposée | Conditions et limites |
| --- | --- | --- |
| Consulter les magasins autorisés | Autoriser | Uniquement dans le périmètre de la connexion partenaire. Route et réponse à compléter. |
| Consulter les bacs promo | Autoriser | Détail, état et emplacement dans le magasin autorisé. |
| Afficher les visuels Tekshelf dans No Waste | Autoriser | Format intégré à préciser ; les droits restent limités au magasin. |
| Consulter poids, quantités et remplissage | Autoriser | Exposer uniquement les indicateurs disponibles et interprétables ; afficher leur fraîcheur et leur validité. |
| Consulter note, commentaire et recommandation | Autoriser à terme | Disponibilité à confirmer ; résultats calculés par Tekshelf, algorithmes conservés en interne. |
| Consulter historique, sorties et réassorts | Autoriser | Historique filtré et paginé ; une sortie détectée n’est pas une vente encaissée. |
| Consulter les alertes et leur état | Autoriser | Contrat des alertes à compléter. |
| Acquitter ou résoudre une alerte | Prévoir après validation métier | Distinguer « vu par l’utilisateur » de « problème effectivement résolu » ; aucune route partenaire validée à ce stade. |
| Rechercher un produit par EAN/CIP ou nom | Autoriser | Catalogue accessible au tenant ; identifiant produit Tekshelf conservé. |
| Créer un produit local absent du catalogue | Autoriser sous conditions | Champs requis, détection des doublons, unités et responsabilité des données à préciser. |
| Modifier les informations utiles d’un produit | Autoriser sous conditions | Liste de champs autorisés à fixer. Si la fiche sert à plusieurs emplacements, l’effet doit être explicite. |
| Modifier un poids unitaire de référence | Autoriser via un parcours validé | Changement ayant un effet sur le comptage ; nouvelle association ou nouvelle initialisation selon le backend. |
| Ajouter, retirer et ordonner les produits affichés dans le bac | Autoriser | Remplacement de la liste déclarative ; sans modifier implicitement le comptage. |
| Associer ou dissocier le produit de comptage | Autoriser | Parcours explicite ; valeurs de l’ancien produit réinitialisées ; nouvelle mesure attendue. |
| Scanner un QR code pour identifier un bac | Autoriser | Contrat de résolution du QR et vérification de propriété à définir. |
| Activer un bac déjà provisionné par Tekshelf | Autoriser via un parcours validé | Distinguer le rattachement logiciel de l’installation physique ; ne pas réattribuer un bac d’un autre client. |
| Créer la représentation logicielle d’un bac | Autoriser sous conditions | Bac de type `promo_bin`, magasin autorisé, prévention des doublons, lien au dispositif à définir. |
| Renommer ou modifier l’emplacement métier d’un bac | Autoriser | Même tenant et magasin autorisé ; champs et parcours de déplacement à fixer. |
| Passer un bac en maintenance et en sortir | Autoriser | État logiciel, délai matériel et sortie de maintenance à documenter séparément. |
| Déclarer le retrait d’un bac de l’affichage | Prévoir une désactivation réversible | Fonction cible à définir ; la suppression destructive n’est pas retenue pour le partenaire. |
| Recevoir les mises à jour automatiquement | Autoriser si disponible | Choix entre interrogation périodique et notifications à valider ; aucun webhook partenaire n’est présumé existant. |
| Enregistrer directement une mesure, une quantité calculée ou une note | Exclure | Les résultats proviennent du système Tekshelf. Une correction métier éventuelle nécessite une action spécifique et historisée. |
| Effacer ou réécrire l’historique des mesures/événements | Exclure | Préserver la traçabilité. |
| Supprimer définitivement un bac, un dispositif ou un produit partagé | Exclure du périmètre initial | Préférer une dissociation ou une désactivation explicitement définie. |
| Modifier calibration, coefficients, firmware ou configuration matérielle | Réserver à Tekshelf | Hors gestion quotidienne du partenaire. Une prise de poids unitaire produit n’est pas une calibration électronique. |
| Créer des tenants, changer leurs domaines ou transférer du matériel entre tenants | Réserver à Tekshelf | Administration de la plateforme. |
| Gérer comptes administrateurs, rôles ou secrets de la plateforme | Réserver à Tekshelf | Aucun droit administrateur global requis pour No Waste. |
| Accéder aux linéaires, TG et autres fonctions non liées aux bacs | Hors périmètre initial | Extension possible via une spécification dédiée. |

### 3.1 Droits d’accès

Les accès partenaires doivent être limités aux ressources des magasins autorisés. Les droits d’écriture sont définis lors de l’ouverture des accès.

### 3.2 Périmètre de gestion

L’objectif est de couvrir le parcours quotidien complet de la pharmacie : consulter ses bacs, gérer leurs produits, suivre leur performance et effectuer les changements autorisés. L’administration technique de la plateforme demeure assurée par Tekshelf.

## 4. Comprendre les objets

| Terme utilisé dans cette documentation | Objet de l’API | Rôle |
|---|---|---|
| Pharmacie / magasin | `store` | Périmètre métier auquel rattacher les bacs et les droits d’accès. |
| Zone | `zone` | Regroupement des meubles dans le magasin. |
| Bac promo | `furniture` de type `promo_bin` | Représentation métier du bac. |
| Niveau | `shelf` | Niveau du meuble auquel est rattaché le dispositif ; le code prévoit un seul niveau pour un bac promo. |
| Dispositif peseur | `device` | Dispositif associé au niveau. |
| Balance / emplacement de mesure | `scale` et `scaleStock` | Emplacement de mesure et association au produit de comptage. |
| Produit affiché | `displayProducts` | Produit présenté dans le bac, indépendamment de l’association de comptage. |
| Événement | `event` | Événement historisé, filtrable notamment par magasin, dispositif et produit. |

### Produits affichés et comptage par poids

L’intégration distingue deux opérations :

1. Déclarer les produits affichés dans un bac et leur ordre de présentation.
2. Associer un produit à un emplacement de mesure pour le comptage par poids.

Modifier les produits affichés ne modifie pas l’association de comptage. Une liste de plusieurs produits affichés ne garantit donc pas une mesure distincte de la quantité de chaque référence. La disponibilité d’un détail par référence dans un bac mixte fait partie des points ouverts.

## 5. Référence technique

Les exemples utilisent des identifiants fictifs. Les schémas détaillés non renseignés sont signalés ; la procédure d’authentification et les données de test restent à fournir par Tekshelf.

### 5.1 Consulter les bacs

| Méthode | Chemin | Utilisation |
|---|---|---|
| `GET` | `/api/furnitures?storeId={storeId}&page=1&limit=100` | Lister les meubles d’une pharmacie. |
| `GET` | `/api/furnitures/map?storeId={storeId}` | Récupérer une vue enrichie des meubles, niveaux et données de stock. |
| `GET` | `/api/furnitures/{furnitureId}` | Consulter un meuble et ses niveaux. |

La liste est paginée et renvoie les clés `items`, `total`, `page` et `limit`. Pour cette route, `page` vaut 1 par défaut et `limit` vaut 100 par défaut, avec un maximum de 100. Un filtre `zoneId` est également présent.

La liste contient les meubles du magasin. Les bacs promo se distinguent par le type `promo_bin`.

La vue enrichie comprend notamment les champs suivants au niveau des emplacements :

| Champ | Signification à documenter |
|---|---|
| `productId`, `productName`, `thumbnailUrl` | Produit de comptage et visuel associé. |
| `currentCount` | Quantité renvoyée par cette vue. Distinguer une mesure absente d’une quantité nulle. |
| `stockMin` | Seuil de stock configuré sur le produit. |
| `status` | État de stock : `in_stock`, `low_stock` ou `out_of_stock`. |
| `lastUpdateAt` | Date de mise à jour de la donnée de stock, ou absence de date. |
| `fillPercent`, `fillStatus` | Indicateurs de remplissage. Le détail des valeurs de statut reste à compléter. |
| `maxStableWeight` | Valeur de poids de référence. Unité à renseigner dans le schéma détaillé. |

La vue inclut également des informations telles que `deviceStatus`, `maintenanceExpiresAt`, `stockSummary` et `stockStatus`. Le schéma détaillé de cette réponse reste à compléter.

**Précaution d’interprétation :** le code de cette vue remplace certains comptages absents par zéro. Le partenaire ne doit pas assimiler automatiquement zéro à une rupture sans disposer des informations de validité et de fraîcheur appropriées. Le contrat devra lever cette ambiguïté.

### 5.2 Rechercher et gérer les produits

| Méthode | Chemin | Utilisation |
|---|---|---|
| `GET` | `/api/products?ean={code}&page=1&limit=20` | Rechercher un produit par code exact. |
| `GET` | `/api/products?search={texte}&page=1&limit=20` | Rechercher dans le catalogue. |
| `GET` | `/api/products/{productId}` | Consulter un produit. |
| `POST` | `/api/products` | Créer un produit ; corps et droits à documenter. |
| `PUT` / `PATCH` | `/api/products/{productId}` | Modifier un produit ; champs autorisés à documenter. |

Le paramètre `ean` recherche dans les champs EAN, master CIP et CIP13. Lorsqu’il est présent, il prend la priorité sur `search`. Le code limite la taille des pages à 100 ; la taille par défaut de la liste produits est 20.

Les règles de rapprochement entre les identifiants produits No Waste et Tekshelf restent à définir, notamment si un code est absent ou partagé entre plusieurs fiches.

### 5.3 Déclarer les produits affichés dans le bac

`PUT /api/furnitures/{furnitureId}/display-products`

Exemple de corps :

```json
[
  { "productId": "{productIdA}", "position": 0 },
  { "productId": "{productIdB}", "position": 1 }
]
```

- Le corps doit être un tableau JSON.
- La liste remplace intégralement la liste existante.
- Un tableau vide `[]` vide la liste des produits affichés. Cela ne signifie pas que le bac a été physiquement vidé.
- Chaque produit doit exister, ne pas être supprimé et n’apparaître qu’une fois dans la requête.
- La limite observée est de 100 éléments.
- Si `position` est fournie, elle doit être un entier. Les positions sont normalisées après tri.
- Rejouer la même liste produit le même état déclaré.
- Une modification concurrente peut entraîner une réponse `409`.

Cet appel ne configure pas le produit de comptage par poids.

### 5.4 Associer un produit au comptage

`PUT /api/devices/{deviceId}/scales/{scaleIndex}/product`

```json
{ "productId": "{productId}" }
```

Réponse de succès :

```json
{ "ok": true }
```

Le changement d’association réinitialise les valeurs de comptage et certaines références liées à l’ancien produit. Une réponse de succès confirme l’association dans le logiciel ; elle ne garantit pas qu’une nouvelle mesure physique soit déjà disponible.

Erreurs métier :

| HTTP | Cas |
|---|---|
| `400` | Index de balance invalide. |
| `404` | Dispositif ou produit introuvable. |
| `409` | Emplacement pas encore découvert ; code `SCALE_NOT_READY`. |
| `410` | Produit supprimé ; code `GONE`. |

Une route de retrait d’association existe également : `DELETE /api/devices/{deviceId}/scales/{scaleIndex}/product`. Son succès renvoie `204`, sans corps. Le parcours physique d’association, le choix de l’index et la reprise d’une mesure fiable devront être validés pour le bac promo autonome.

### 5.5 Déclarer une période de maintenance

`POST /api/furnitures/{furnitureId}/maintenance`

Exemple de démarrage :

```json
{ "action": "start", "duration": 900, "reason": "Changement de produits" }
```

Le code prévoit une durée par défaut de 900 secondes et une durée comprise entre 60 et 86 400 secondes au démarrage. Le champ `reason` est limité à 255 caractères. La réponse comprend notamment `furnitureId`, `furnitureName`, `action`, `updated` et `devices`.

Cet appel déclare la maintenance dans le logiciel. Le réveil d’un bac en sommeil et le délai avant une nouvelle mesure restent à préciser pour le bac autonome : voir les points ouverts sur le parcours d’installation et de maintenance.

### 5.6 Récupérer les événements

`GET /api/events?storeId={storeId}&deviceId={deviceId}&page=1&limit=100`

Paramètres : `storeId`, `deviceId`, `productId`, `scaleIndex`, `type`, `from`, `to`, `period`, `search`, `sort`, `order`, `alertSeverity` et `excludePositive`.

- Réponse paginée : `items`, `total`, `page`, `limit`.
- Taille par défaut : 20 ; maximum : 100.
- Avec `from` et `to`, la borne de début est incluse et la borne de fin est exclue.
- Éviter de combiner `period` avec `from`/`to` : dans le code observé, une période nommée prend la priorité.
- `excludePositive=true` exclut les événements dont `differenceProduct` est strictement positif ; ce filtre ne signifie pas « ventes uniquement ».
- Les dates explicites devront utiliser un fuseau indiqué. Le format exact accepté et les erreurs de dates restent à vérifier.

La liste des types, le schéma des événements, la rétention, la déduplication et une méthode fiable de synchronisation incrémentale restent à documenter. Une pagination par numéro de page ne suffit pas, à elle seule, à garantir l’absence de doublons ou d’omissions si de nouveaux événements arrivent pendant la lecture.

## 6. Parcours d’intégration à couvrir

Les parcours d’installation et de changement de produit ci-dessous décrivent la cible d’intégration. Les étapes dépendant du matériel restent à préciser avant mise en service.

### 6.1 Ouvrir l’espace bacs d’une pharmacie

1. Retrouver la connexion client No Waste : tenant, environnement et magasin.
2. Utiliser l’origine d’API propre à ce tenant et les accès associés.
3. Récupérer les meubles du magasin et identifier les bacs promo.
4. Afficher les produits, les indicateurs disponibles et leurs dates.
5. Présenter distinctement une donnée valide, une donnée absente, une donnée ancienne et un bac en maintenance.
6. Rafraîchir les données selon la cadence et les limites convenues avec Tekshelf.

L’ouverture de l’écran ne doit pas être présentée comme un réveil ou une nouvelle pesée du matériel.

### 6.2 Changer les produits d’un bac

1. Identifier le bac et contrôler qu’il appartient au périmètre de la pharmacie.
2. Déclarer la maintenance si le parcours validé la prévoit.
3. Rechercher ou créer les produits nécessaires.
4. Mettre à jour la liste des produits affichés.
5. Si nécessaire, modifier séparément le produit de comptage.
6. Effectuer les manipulations physiques demandées par le parcours validé.
7. Attendre une donnée exploitable pour la nouvelle association ; afficher « en attente de mesure » entre-temps.
8. Terminer la maintenance selon la règle validée et reprendre le suivi.

Les modifications de la liste d’affichage et de l’association de comptage sont actuellement des opérations distinctes. Le parcours doit prévoir une reprise si l’une réussit et l’autre échoue. Une opération globale atomique ne doit pas être annoncée sans implémentation correspondante.

**Bac multiréférences :** la mise à jour de plusieurs visuels ne suffit pas à établir le stock de chaque référence. L’intégration doit afficher les informations au niveau réellement mesuré : bac, groupe ou produit selon le mode validé par Tekshelf.

### 6.3 Installer ou rattacher un bac

La cible est un parcours utilisable depuis No Waste : identifier le dispositif à partir du QR, vérifier son appartenance, le rattacher au bon magasin et au bon bac, associer les produits et confirmer la réception de la première donnée valide.

Les appels de résolution du QR, de rattachement et de contrôle de la première mesure restent à documenter. La simple création d’un objet `furniture` ne provisionne pas à elle seule un dispositif physique.

### 6.4 Gérer une indisponibilité

No Waste conserve la dernière donnée connue avec sa date et signale son ancienneté. Une perte de connexion ne transforme pas un bac en rupture. Après reprise, la synchronisation doit permettre de retrouver l’état courant et les événements manqués selon une stratégie validée.

Les écritures ne sont pas rejouées automatiquement sans vérifier leur sémantique. Une absence de réponse peut signifier qu’une action a été appliquée sans que le client ait reçu l’accusé de réception.

## 7. Données et règles d’affichage

### 7.1 Informations à afficher

Informations à présenter dans No Waste et règles d’interprétation associées.

| Information | Règle d’affichage |
|---|---|
| Identité du bac | Identifiant, nom et magasin, interprétés dans le contexte du tenant. |
| Produits présentés | Liste déclarative ordonnée et visuels disponibles. |
| Association de comptage | Produit ou groupe réellement utilisé pour interpréter le poids, distinct de la liste d’affichage. |
| Poids | Unité, poids net/brut, validité et horodatage à préciser avant exposition. |
| Quantité | Indiquer qu’il s’agit d’une estimation lorsqu’elle est dérivée du poids ; ne pas inventer une ventilation par référence. |
| Remplissage | Expliquer la référence utilisée ; ne pas assimiler automatiquement le pourcentage à la capacité physique maximale du bac. |
| Dernière mise à jour | Distinguer date de la mesure, date de réception serveur et date de consultation lorsque ces informations existent. |
| Connexion et maintenance | États distincts de la disponibilité du stock. |
| Note sur 100 | Disponibilité et champ API à préciser avant intégration. |
| Commentaire et recommandation | Textes et action proposée, si disponibles ; leur exécution est un acte distinct. |
| Historique et alertes | Type, date, périmètre et statut selon les schémas validés. |

### 7.2 Valeurs absentes et fraîcheur

- `null` ou absence de mesure signifie « inconnu » ; ce n’est pas équivalent à zéro.
- Zéro ne doit être affiché comme rupture que dans un contexte où la mesure ou l’estimation est valide.
- Une association modifiée entraîne un état d’attente tant que la nouvelle donnée exploitable n’est pas disponible.
- Une mesure ancienne peut rester visible avec sa date et une indication de fraîcheur.
- Les règles qui rendent une donnée « ancienne » dépendent de la cadence du bac et doivent être fixées avec Tekshelf.
- La consultation fréquente de l’API n’augmente pas la fréquence des relevés physiques. La cadence des relevés et la fréquence de synchronisation sont précisées dans le cadre de l’intégration.

### 7.3 Traçabilité des actions

La cible est de pouvoir identifier le partenaire et, si le dispositif le permet, l’utilisateur No Waste ayant effectué un changement, le tenant et le magasin concernés, la date et la nature de l’action. Le mécanisme d’audit et les informations utilisateur associées restent à documenter.

Prévoir la gestion des modifications simultanées depuis No Waste et une interface Tekshelf. Les droits et les données doivent rester cohérents dans les deux interfaces.

## 8. Intégration des visuels dans No Waste

L’API de données et l’intégration de l’interface doivent être décrites séparément.

| Mode envisagé | Principe | À vérifier |
|---|---|---|
| Vue Tekshelf intégrée | No Waste affiche une vue hébergée par Tekshelf dans son interface. | Existence d’une vue intégrable, connexion transparente, droits limités à la pharmacie, navigation et adaptation mobile. |
| Interface développée par No Waste | No Waste construit les écrans à partir de l’API et des références visuelles Tekshelf. | Schémas stables, règles d’affichage, états sans données et maintenance des visuels. |

Le choix entre ces deux modes reste à arrêter : Tekshelf précise les vues et données qu’il peut fournir ; No Waste précise ce que son interface permet d’intégrer. Les deux équipes choisissent ensuite le mode retenu.

## 9. Points à confirmer

| Sujet | Qui confirme ? | Question à régler |
|---|---|---|
| Accès API et informations manquantes | Tekshelf | Fournir l’adresse et les accès de test, la procédure d’authentification et les schémas de requêtes/réponses encore incomplets. |
| Intégration des visuels | Les deux | Intégrer une vue Tekshelf ou construire les écrans dans No Waste ? Préciser les possibilités des deux solutions puis retenir un mode. |
| Actions de gestion | Les deux | Ouvrir ou non la création de bacs, la modification des fiches et poids unitaires, ainsi que les actions sur les alertes. |
| Bacs multiréférences | Tekshelf | Quelles données peuvent être restituées par référence lorsque plusieurs produits partagent un bac ? |
| Installation et maintenance | Les deux | Définir le parcours QR et le changement de produit, en tenant compte du sommeil du bac et du délai avant une mesure fiable. Tekshelf précise les capacités matérielles. |
| Note et recommandations | Tekshelf | Préciser si le scoring, les commentaires et recommandations sont exposés par l’API et les champs correspondants. |
| Données produits No Waste | No Waste | Préciser les identifiants et informations produits disponibles pour leur rapprochement avec les fiches Tekshelf. |
| Synchronisation | Les deux | Choisir le mode de récupération disponible, sa cadence, les limites d’usage et la reprise après coupure. |
