# API tech1218 — accès IA (lecture seule)

Mode d'emploi destiné aux assistants et agents IA. Portail technique du Théâtre
Le Douze Dix-Huit (Le Grand-Saconnex, Genève) : inventaire du parc matériel,
carnets de maintenance, stocks de consommables, climat du bâtiment.

- **Base** : `https://tech.ledouzedixhuit.ch`
- **Format** : JSON (UTF-8), sauf mention contraire. Dates ISO 8601, UTC.
- **L'essentiel est PUBLIC** : inventaire (vue publique), unités, lots, stocks,
  climat se lisent sans authentification.
- **Token de service** (lecture seule) : requis pour les carnets de maintenance,
  les mouvements de stock, le contenu interne (consommables, catégories
  internes) et quelques champs réservés (détail ci-dessous). À présenter par
  `Authorization: Bearer <token>` (préféré) ou `?k=<token>`.
- **Règles** : `GET` uniquement — toute écriture est refusée. Les données
  d'achat (prix, fournisseurs, garanties) ne sont **jamais** renvoyées, avec ou
  sans token. Le token est révocable à tout moment par l'administration.
- **Validation** : `GET /api/ai/docs` (cette page, gatée) répond 200 si le
  token est valide, 403 sinon. La même page est lisible publiquement sur
  `GET /api/docs`. Voir aussi `/llms.txt` à la racine du site.

## Vocabulaire

- **Référence** (`ref`) : une fiche matériel (ex. `pc-1kw`), suivie soit à
  l'**unité** (`tracking: "unit"`, chaque exemplaire a un id du type `pc-1kw-03`)
  soit en **vrac** (`tracking: "bulk"`, quantité globale — consommables, câbles).
- **Parc** (`owner`) : le détenteur d'un ensemble de matériel (le théâtre, une
  compagnie…).
- **Lot** : sous-groupe d'une référence en vrac sous un autre détenteur.
- **Espace** : zone du bâtiment (`01` Plateau … `07`), porteuse des capteurs climat.

## Inventaire (public)

| Endpoint | Réponse |
|---|---|
| `GET /api/equipment?cat=` | `{ refs: Ref[] }` — le parc en vue publique² ; `cat` optionnel (ex. `lumiere`, `son`, `video`, `scene`) filtre côté serveur — sans lui, ~250 réfs d'un coup |
| `GET /api/equipment/:id/units` | `{ units: Unit[] }` — exemplaires d'une réf¹ |
| `GET /api/equipment/units/:uid` | `{ unit, ref }` — fiche terrain d'un exemplaire (id gravé sur l'étiquette QR)¹ |
| `GET /api/equipment/:id/lots` | `{ lots: Lot[] }`¹ |
| `GET /api/categories` | `{ categories: [...] }` — publiques² |
| `GET /api/equipment/links` | `{ links: [...] }` — liens docs/notices par réf |
| `GET /api/stocks` | `{ stocks: [...] }` — les régimes de stock |
| `GET /api/stocks/inventory` | inventaire agrégé par régime (réfs, unités, totaux) |

¹ Sans token, les champs réservés sont rendus `null` : `serial` et `notes` des
unités, `notes` des lots. Avec token, ils sont remplis. `location` est publique.
² Avec token, le contenu interne apparaît en plus : consommables et catégories
internes (fiches et catégories absentes de la vue publique).

`Ref` (public, champ à champ) : `{ id, cat, group, brand, model, type, specs[],
state, link, img, images[], tracking, qty, owner, aliases[], gdtf,
usageUrl, usageEmail, reorderThreshold, fiche, ficheLabel, ficheSection,
fixedInstall }`.
- `gdtf` : données constructeur (dimensions, puissance, DMX…) quand connues, sinon `null`.
- `usageUrl`/`usageEmail` : contact publié par le détenteur du parc pour les conditions
  d'usage d'un matériel prêté (ex. compagnie externe) — volontairement public,
  affiché sur la fiche à tout visiteur ; `null` quand non renseigné.
- `fiche`/`ficheLabel`/`ficheSection`/`fixedInstall` : présence et libellé sur la
  fiche technique du lieu (`/api/lieu/technique`), pas des données d'inventaire.
- Avec token ET portée sur le parc, un bloc supplémentaire s'ajoute :
  `{ suppliers[], supplierNotes, purchaseDate, purchasePrice, warrantyMonths }`
  (données d'achat — **absent** de la vue publique, jamais dans `specs`).
`Unit` : `{ id, refId, owner, state, serial, location, notes, commissioningDate, lotId }`.

## Maintenance et mouvements de stock (token requis)

Réservés parce qu'ils portent des noms de personnes (`by`) et du texte libre
interne (récits d'incidents).

| Endpoint | Réponse |
|---|---|
| `GET /api/equipment/units/:uid/maintenance` | `{ entries: [...] }` — carnet d'un exemplaire |
| `GET /api/equipment/:id/maintenance` | `{ entries: [...] }` — carnet d'une réf en vrac |
| `GET /api/equipment/:id/moves` | `{ moves: [...] }` — mouvements du consommable (sorties, réappro, recomptages) |
| `GET /api/equipment/units/:uid/moves` | `{ moves: [...] }` — consommables posés sur cet exemplaire (« quelles lampes sur ce projecteur ») |

## Climat du bâtiment (public)

| Endpoint | Réponse |
|---|---|
| `GET /api/climat/board` | capteurs intérieurs (dernières valeurs + 5 j), météo extérieure GVE (série 5 j, pluie), agrégats mensuels, météo par spectacle |
| `GET /api/climat/forecast` | prévisions locales MétéoSuisse (PLZ 1218) + avertissements officiels en cours |
| `GET /api/climat` | `{ sensors: [...] }` — capteurs avec batterie et dernier rapport |
| `GET /api/climat/shows` | `{ shows: [...] }` — historique des spectacles pour recoupement climat (les masqués n'apparaissent qu'avec token) |

Météo extérieure : station SwissMetNet Genève-Cointrin (GVE), données 10 min
depuis 2019. **Attribution obligatoire à l'affichage : « Source : MétéoSuisse ».**

## Lieu et documents (public)

| Endpoint | Réponse |
|---|---|
| `GET /api/lieu/technique` | **dimensions & données de plan** : plateau, cadre de scène (4,50–8,00 m), porteuses (numérotation, 10,30 m, 250 kg), niveaux, salle — plus les URLs des plans PDF sources. Le point de départ pour adapter un plan de feu au lieu. |
| `GET /api/spaces` | fiches des espaces (surcharges locales) |
| `GET /api/lieu/images` | banque d'images du lieu (`/api/lieu/images/file/:name` pour l'original) |
| `GET /api/bibliotheque` | bibliothèque documentaire (`/api/bibliotheque/file/:name` pour le fichier) |
| `GET /api/agenda` | agenda technique (extrait de Kairos) |
| `GET /api/securite/venues` | fiches de sécurité par spectacle |
| `GET /api/durabilite/waste` | registre des matières (durabilité) |

## Serveur MCP (recommandé pour les assistants)

Pour les clients qui parlent MCP (claude.ai, Claude Code, etc.), le portail
expose un **serveur MCP distant** (transport Streamable HTTP, stateless) avec
des outils pensés par tâches — plus simple que d'appeler les routes REST :

- **URL** : `https://tech.ledouzedixhuit.ch/api/mcp`
- **Auth** : le même token (`Authorization: Bearer <token>`, ou `?k=<token>`
  dans l'URL du connecteur si le client ne pose pas de header).
- **Outils** (tous en lecture seule) : `chercher_equipement`,
  `fiche_equipement`, `historique_maintenance`, `etat_stock`,
  `inventaire_stocks`, `dimensions_lieu`, `climat`, `meteo_spectacles`,
  `agenda`.
- Même périmètre que le token REST : les carnets et champs réservés sont
  accessibles, les données d'achat jamais.

## Hors périmètre (403/401 quoi qu'il arrive)

Utilisateurs, rôles, demandes de contact, répertoire fournisseurs, données
d'achat, tokens d'ingestion, toute écriture. Inutile d'essayer : le token est
ignoré hors des routes listées ici.

## Erreurs

`401`/`403` avec `{ error: "<message en français>" }`. Un `404` sur une réf ou
unité signifie que l'identifiant n'existe pas (les ids sont sensibles aux
renommages — repartir de `GET /api/equipment`).
