Segnaposto e icone
Leggere i segnaposto
Sezione intitolata “Leggere i segnaposto”GET /api/rooms/:roomId/markers (token permission: read){ "count": 42, "markers": [ { "id": "marker-…", "latitude": 47.56, "longitude": 7.59, "title": "…" } ] }Creare un segnaposto
Sezione intitolata “Creare un segnaposto”POST /api/rooms/:roomId/markers (token permission: write)Content-Type: application/jsonSincrono — restituisce il segnaposto creato. Solo latitude/longitude sono obbligatori.
{ "latitude": 47.5596, "longitude": 7.5886, "title": "Site A", "description": "first visit", "tags": ["survey"] }→ 201 { "success": true, "marker": { "id": "marker-…", ... } }
Campi facoltativi: color (esadecimale), tags (≤ 50), eventDate (epoch ms), markerIconId,
markerIconSize (8–256), imageKey/thumbnailKey (da markers/upload-image), embeddedMediaUrl,
mediaSize (sm | md | lg).
Leggere un singolo segnaposto
Sezione intitolata “Leggere un singolo segnaposto”GET /api/rooms/:roomId/markers/:markerId (token permission: read)→ 200 { "success": true, "marker": { … } }, oppure 404 se non esiste. I chiamanti anonimi possono
leggere un segnaposto in una stanza pubblica, esattamente come per l’endpoint di elenco.
Questa vista omette l’e-mail di chi l’ha creato e i vecchi blob di immagine in linea — recupera le
immagini tramite GET /api/rooms/:roomId/markers/image?key=….
Aggiornare un segnaposto
Sezione intitolata “Aggiornare un segnaposto”PATCH /api/rooms/:roomId/markers/:markerId (token permission: write)Content-Type: application/jsonInvia solo ciò che cambia; i campi omessi restano invariati.
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": { … } }Accetta gli stessi campi della creazione. Le regole da conoscere:
nullazzera un campo;""memorizza una stringa vuota — non sono la stessa cosa.latitude,longitude,titleecolorpossono essere modificati ma non azzerati — a un segnaposto servono tutti e quattro per essere disegnato.imageKeyethumbnailKeyviaggiano insieme: inviali entrambi, oppure entrambi anullper rimuovere l’immagine. Sostituirli elimina anche gli EXIF della foto precedente, così una nuova immagine non eredita mai la fotocamera o la provenienza GPS della vecchia.- Un corpo vuoto dà
400 empty_updatee i campi sconosciuti danno400 unknown_field:<key>— quindiid,createdBy,createdAte i campi blob in linea qui sono in sola lettura. - I titoli non possono contenere ritorni a capo.
Un chiamante che possiede write ma non read riceve indietro solo i campi che ha inviato, mai il
segnaposto memorizzato.
Eliminare un segnaposto
Sezione intitolata “Eliminare un segnaposto”DELETE /api/rooms/:roomId/markers/:markerId (token permission: write)→ 200 { "success": true, "markerId": "marker-…" }, oppure 404 se è già stato rimosso.
L’eliminazione rimuove anche le immagini del segnaposto dall’archivio, a meno che un altro segnaposto
le referenzi ancora.
Comportamenti da conoscere
Sezione intitolata “Comportamenti da conoscere”Altri codici di stato: 403 permesso insufficiente · 502 la modifica non ha potuto essere
trasmessa · 503 stato della stanza momentaneamente illeggibile, riprova.
Ogni aggiornamento ed eliminazione raggiunge subito i browser aperti e viene registrato nella cronologia
della stanza. Le letture sono coerenti a termine — una lettura effettuata subito dopo una scrittura può
mostrare brevemente lo stato precedente: interroga più volte anziché fidarti di una singola lettura. Le
scritture consecutive sono sicure. Le modifiche concorrenti a uno stesso segnaposto si risolvono con
«vince l’ultima scrittura» sull’intero segnaposto, quindi un PATCH può sovrascrivere una modifica che
qualcuno sta facendo nell’app nello stesso momento.
Importare segnaposto in blocco
Sezione intitolata “Importare segnaposto in blocco”POST /api/rooms/:roomId/bulk-import (token permission: write)Content-Type: multipart/form-data # field: file = a point FeatureCollectionAsincrono → { "jobId": "bulk-import-…" }; interroga GET /api/jobs/:jobId. Le properties di ogni
punto possono contenere title, description, tags, eventDate, imageKey/thumbnailKey,
markerIconId e markerIconSize.
Caricare la foto di un segnaposto
Sezione intitolata “Caricare la foto di un segnaposto”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" }. Le chiavi restituite devono
essere referenziate da un segnaposto (tramite le sue properties/campi) per comparire sulla mappa.
Icone dei segnaposto
Sezione intitolata “Icone dei segnaposto”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)Registra un’icona riutilizzabile, poi referenzia l’iconId restituito dai segnaposto tramite
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-…" }
