Repères et icônes
Lire les repères
Section intitulée « Lire les repères »GET /api/rooms/:roomId/markers (token permission: read){ "count": 42, "markers": [ { "id": "marker-…", "latitude": 47.56, "longitude": 7.59, "title": "…" } ] }Créer un repère
Section intitulée « Créer un repère »POST /api/rooms/:roomId/markers (token permission: write)Content-Type: application/jsonSynchrone — renvoie le repère créé. Seuls latitude/longitude sont obligatoires.
{ "latitude": 47.5596, "longitude": 7.5886, "title": "Site A", "description": "first visit", "tags": ["survey"] }→ 201 { "success": true, "marker": { "id": "marker-…", ... } }
Champs facultatifs : color (hexadécimal), tags (≤ 50), eventDate (epoch ms), markerIconId,
markerIconSize (8–256), imageKey/thumbnailKey (issus de markers/upload-image),
embeddedMediaUrl, mediaSize (sm | md | lg).
Lire un repère
Section intitulée « Lire un repère »GET /api/rooms/:roomId/markers/:markerId (token permission: read)→ 200 { "success": true, "marker": { … } }, ou 404 s’il n’existe pas. Les appelants anonymes
peuvent lire un repère dans une salle publique, comme pour le point de terminaison de liste.
Cette vue omet l’adresse e-mail du créateur et les anciens blobs d’image en ligne — récupérez les
images via GET /api/rooms/:roomId/markers/image?key=… à la place.
Modifier un repère
Section intitulée « Modifier un repère »PATCH /api/rooms/:roomId/markers/:markerId (token permission: write)Content-Type: application/jsonN’envoyez que ce qui change ; les champs omis sont laissés tels quels.
curl -X PATCH "$API/api/rooms/$ROOM/markers/$MARKER" -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"title":"Site A (revisited)","description":null,"color":"#ef4444"}'# → 200 { "success": true, "marker": { … } }Accepte les mêmes champs que la création. Les règles à connaître :
nullefface un champ ;""enregistre une chaîne vide — ce n’est pas la même chose.latitude,longitude,titleetcolorpeuvent être modifiés mais pas effacés — un repère a besoin des quatre pour s’afficher.imageKeyetthumbnailKeyvoyagent ensemble : envoyez les deux, ou les deux ànullpour retirer l’image. Les remplacer supprime aussi les EXIF de la photo précédente, afin qu’une nouvelle image n’hérite jamais de l’appareil ni de la position GPS de l’ancienne.- Un corps vide donne
400 empty_update, et les champs inconnus donnent400 unknown_field:<key>—id,createdBy,createdAtet les champs de blob en ligne sont donc en lecture seule ici. - Les titres ne peuvent pas contenir de retours à la ligne.
Un appelant disposant de write mais pas de read ne récupère que les champs qu’il a soumis, jamais le
repère stocké.
Supprimer un repère
Section intitulée « Supprimer un repère »DELETE /api/rooms/:roomId/markers/:markerId (token permission: write)→ 200 { "success": true, "markerId": "marker-…" }, ou 404 s’il a déjà disparu. La suppression retire
également les images du repère du stockage, sauf si un autre repère les référence encore.
Comportements à connaître
Section intitulée « Comportements à connaître »Autres codes de statut : 403 permission insuffisante · 502 la modification n’a pas pu être
diffusée · 503 état de la salle momentanément illisible, réessayez.
Chaque modification et suppression atteint immédiatement les navigateurs ouverts et est consignée dans
l’historique de la salle. Les lectures sont cohérentes à terme — une lecture effectuée juste après une
écriture peut brièvement montrer l’état précédent : interrogez plusieurs fois plutôt que de vous fier à
une seule lecture. Les écritures consécutives sont sûres. Les modifications concurrentes d’un même
repère se résolvent en « dernière écriture gagnante » sur l’ensemble du repère : un PATCH peut donc
écraser une modification que quelqu’un est en train de faire dans l’application au même moment.
Importer des repères en masse
Section intitulée « Importer des repères en masse »POST /api/rooms/:roomId/bulk-import (token permission: write)Content-Type: multipart/form-data # field: file = a point FeatureCollectionAsynchrone → { "jobId": "bulk-import-…" } ; interrogez GET /api/jobs/:jobId. Les properties de
chaque point peuvent porter title, description, tags, eventDate, imageKey/thumbnailKey,
markerIconId et markerIconSize.
Envoyer une photo de repère
Section intitulée « Envoyer une photo de repère »POST /api/rooms/:roomId/markers/upload-image (token permission: write)Content-Type: multipart/form-data # fields: image, thumbnail→ { "imageKey": "markers/…jpg", "thumbnailKey": "markers/…_thumb.jpg" }. Les clés renvoyées doivent
être référencées depuis un repère (via ses properties/champs) pour apparaître sur la carte.
Icônes de repères
Section intitulée « Icônes de repères »GET /api/rooms/:roomId/marker-icons (token permission: read) — list (icon blob omitted)POST /api/rooms/:roomId/marker-icons (token permission: write) — register an SVG/PNG (≤1 MB)Enregistrez une icône réutilisable, puis référencez l’iconId renvoyé depuis les repères via
markerIconId :
curl -X POST "$API/api/rooms/$ROOM/marker-icons" -H "Authorization: Bearer $TOKEN" \ -F "icon=@tree.svg" -F "name=Tree" -F "size=32"# → 201 { "iconId": "icon-api-…" }
