Vai al contenuto

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, non istanza_id.
  • Il lease va acquisito prima di answers, draft save e media upload.
  • token viene normalizzato internamente in lease_token per compatibilita col legacy.
  • draft.payload e legacy.pack restano legacy-heavy: i client nuovi dovrebbero preferire schema, answers, draft.rev, lease e media.