RAS API v2¶
RAS API v2 e una facade compatibile costruita sopra il backend legacy del compilatore RAS.
Obiettivi:
- non rompere il compila web esistente
- offrire un contratto piu pulito per client futuri
- mantenere compatibilita con il payload legacy durante la transizione
Base path:
- /api/ras/v2
Endpoint MVP:
- GET /api/ras/v2/documents/<document_id>/export
- GET /api/ras/v2/documents/<document_id>/draft
- PUT /api/ras/v2/documents/<document_id>/draft
- PUT /api/ras/v2/documents/<document_id>/answers
- GET /api/ras/v2/documents/<document_id>/lease
- POST /api/ras/v2/documents/<document_id>/lease/acquire
- POST /api/ras/v2/documents/<document_id>/lease/renew
- POST /api/ras/v2/documents/<document_id>/lease/release
- POST /api/ras/v2/documents/<document_id>/media
- GET /api/ras/v2/media/<object_key>/url
- GET /api/ras/v2/media/<object_key>
Formato risposta:
{
"ok": true,
"data": {}
}
Formato errore:
{
"ok": false,
"error": {
"code": "lease_conflict",
"message": "Istanza gia in checkout"
}
}
Note di compatibilita:
- la facade continua a riusare internamente il modello legacy istanza_id
- export include anche legacy.pack per una migrazione graduale
- answers accetta sia items[{question_id,value}] sia una mappa answers
- finalizzazione e stampa non fanno parte del perimetro v2 iniziale
Media:
- POST /documents/<id>/media richiede lease valido e carica il file su MinIO tenant-aware
- GET /media/<object_key>/url restituisce metadata minimi e presigned url
- GET /media/<object_key> effettua redirect alla presigned url
Endpoint¶
GET /api/ras/v2/documents/<document_id>/export¶
Restituisce il payload principale per aprire un compilatore RAS o un client standalone.
Risposta tipica:
{
"ok": true,
"data": {
"document": {
"id": 171,
"title": "RAS Cliente",
"type": "ras",
"status": "draft",
"tenant_id": "tenant_safecondo",
"cliente_id": 42,
"version": 0,
"updated_at": null
},
"lease": {
"document_id": 171,
"locked": false,
"mine": false,
"owner_user_id": null,
"owner_username": null,
"expires_at": null,
"status": "free"
},
"schema": {
"sections": []
},
"answers": {},
"draft": {
"document_id": 171,
"rev": 3348,
"exists": true,
"payload": {},
"updated_at": "2026-03-15T10:42:04",
"updated_by": 1,
"readonly": false
},
"context": {
"anagrafica": {},
"meta": {},
"whoami": {
"id": 1,
"username": "admin"
},
"permissions": {
"can_edit": true,
"can_finalize": true
}
},
"legacy": {
"pack": {}
}
}
}
Note:
- legacy.pack resta presente per compatibilita con il frontend legacy.
- schema.sections e answers sono il punto di partenza consigliato per i client nuovi.
GET /api/ras/v2/documents/<document_id>/draft¶
Restituisce la bozza corrente.
Risposta tipica:
{
"ok": true,
"data": {
"document_id": 171,
"rev": 3348,
"exists": true,
"payload": {
"_meta": {
"istanza_id": "171"
}
},
"updated_at": "2026-03-15T10:42:04",
"updated_by": 1,
"readonly": false
}
}
PUT /api/ras/v2/documents/<document_id>/draft¶
Salva una bozza completa o parziale.
Request:
{
"base_rev": 3348,
"payload": {
"_meta": {
"note_test_v2": "smoke_test"
}
}
}
Risposta:
{
"ok": true,
"data": {
"document_id": 171,
"rev": 3349
}
}
Errore conflitto:
{
"ok": false,
"error": {
"code": "version_conflict",
"message": "Documento aggiornato, rev server 3350"
}
}
PUT /api/ras/v2/documents/<document_id>/answers¶
Richiede lease valido. Accetta sia items sia answers.
Request con items:
{
"token": "LEASE_TOKEN",
"items": [
{
"field_id": "campo_demo",
"value": "ok"
}
]
}
Request con mappa answers:
{
"token": "LEASE_TOKEN",
"answers": {
"campo_demo": "ok"
}
}
Risposta:
{
"ok": true,
"data": {
"document_id": 171,
"saved": 1,
"errors": []
}
}
Lease¶
GET /api/ras/v2/documents/<document_id>/lease¶
{
"ok": true,
"data": {
"document_id": 171,
"expires_at": null,
"locked": false,
"mine": false,
"owner_user_id": null,
"owner_username": null,
"status": "free"
}
}
POST /api/ras/v2/documents/<document_id>/lease/acquire¶
{
"ok": true,
"data": {
"document_id": 171,
"expires_at": "2026-03-15T19:29:25Z",
"locked": true,
"mine": true,
"owner_user_id": 1,
"owner_username": "admin",
"status": "owned",
"token": "LEASE_TOKEN",
"ttl_seconds": 900
}
}
POST /api/ras/v2/documents/<document_id>/lease/renew¶
Request:
{
"token": "LEASE_TOKEN"
}
POST /api/ras/v2/documents/<document_id>/lease/release¶
Request:
{
"token": "LEASE_TOKEN"
}
Media¶
POST /api/ras/v2/documents/<document_id>/media¶
Richiede multipart form-data e lease valido.
Campi attesi:
- file oppure blob
- token oppure lease_token
Risposta:
{
"ok": true,
"data": {
"document_id": 171,
"object_key": "legacy-dynamic/416ab60e7a264fe1a9bf8fe8aa0a4d6d.jpg",
"filename": "photo.jpg",
"content_type": "image/jpeg",
"size_bytes": 12345,
"url": "https://..."
}
}
GET /api/ras/v2/media/<object_key>/url¶
Restituisce metadata minimi e URL firmata MinIO:
{
"ok": true,
"data": {
"object_key": "legacy-dynamic/416ab60e7a264fe1a9bf8fe8aa0a4d6d.jpg",
"filename": "photo.jpg",
"content_type": "image/jpeg",
"size_bytes": 12345,
"url": "https://..."
}
}
GET /api/ras/v2/media/<object_key>¶
Effettua redirect HTTP verso la presigned url.
Note client¶
- I client nuovi dovrebbero usare
document_id, nonistanza_id. - Il lease va acquisito prima di
answers,draft saveemedia upload. tokenviene normalizzato internamente inlease_tokenper compatibilita col legacy.draft.payloadelegacy.packrestano legacy-heavy: i client nuovi dovrebbero preferireschema,answers,draft.rev,leaseemedia.