openapi: 3.1.0
info:
  title: "NIOS #4 web API"
  description: >
    I web service consentono di fare interagire Nios4 con altre applicazioni. Indipendentemente dal sistema operativo
    su cui girano e dal linguaggio di programmazione utilizzato.
    Si ricorda che per il corretto funzionamento occorrerà avere delle credenziali valide di un account D-One e un database cloud attivo.
    
    
    L’utente partendo dal suo gestionale o applicazione attraverso le web api comunica direttamente con il database cloud.
    Il database cloud è collegato al server che gestisce la sincronizzazione delle informazioni tra i vari client. Questo permette di inviare solo i dati effettivamente modificati di volta in volta.
    Per questo è importante dopo aver modificato i dati del database cloud inviare anche il comando di sincronizzazione (sync) per poter distribuirli su tutti i dispositivi collegati.
  version: 1.0.0

servers:
  - url: https://web.nios4.com/ws/

security:
  - token: []

paths:
  /?action=user_login:
    get:
      tags: [ Accesso ]
      description: >
        La chiamata user_login è la prima chiamata da eseguire per poter recuperare i dati principali dell’utente e
        l’elenco dei database a cui può accedere. All’interno di questo elenco saranno presenti sia i database di cui
        lui è amministratore. Sia quelli dove l’utente è stato invitato.
      security: []
      parameters:
        - in: query
          name: email
          description: Email dell’utente utilizzata per creare l’account D-One
          schema:
            type: string
            format: email
        - in: query
          name: password
          description: La password dell’account D-One
          schema:
            type: string
            format: password
        - in: query
          name: token
          description: Il token di accesso. Facoltativo da usare al posto delle credenziali.
          schema:
            type: string
      responses:
        "200":
          description: >
            L’id globale dell’utente è il numero univoco che lo identifica all’interno dei server D-One. 
            La chiave db contiene tutti i database suoi e quelli dove è ospite. Viene riportato il nome assegnato
            automaticamente dal server, l’etichetta e il tipo di seme che identifica la sua tipologia.
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: L’id globale dell’utente è il numero univoco che lo identifica all’interno dei server D-One.
                        example: 1
                      email:
                        type: string
                        description: Mail Utente
                        example: "xx@xx.com"
                      token:
                        type: string
                        description: Token Utente
                        example: "00000000"
                  db:
                    type: array
                    description: >
                      La chiave db contiene tutti i database suoi e quelli dove è ospite. Viene riportato il nome
                      assegnato automaticamente dal server, l’etichetta e il tipo di seme che identifica la sua tipologia.
                    items:
                      $ref: "#/components/schemas/db"
  /?action=database_list:
    get:
      tags: [ Accesso ]
      description: >
        Il comando recupera l’elenco dei database attualmente utilizzabili dall’utente. Sono compresi sia i database 
        suoi che quelli dove è ospite. Si ricorda che le regole dei permessi di Nios4 rimangono valide anche attraverso 
        i servizi web.
        Quindi avere accesso a un database come ospite non è detto che permetta di avere il suo completo accesso.
      responses:
        "200":
          content:
            application/json:
              schema:
                type: object
                properties:
                  db:
                    type: array
                    items:
                      $ref: "#/components/schemas/db"
  /?action=users:
    get:
      tags: [ Accesso ]
      description: >
        La richiesta permette di recuperare gli utenti collegati al database richiesto.
      parameters:
        - $ref: "#/components/parameters/db"
      responses:
        "200":
          description: >
            La risposta contiene l’array di tutti gli utenti riportando il loro nome e l’id del loro account D-One.
          content:
            application/json:
              schema:
                type: object
                properties:
                  users:
                    type: array
                    items:
                      type: object
                      properties:
                        username:
                          type: string
                          example: "user1@example.com"
                        id:
                          type: integer
                          example: 1
                    example:
                      - username: "user1@example.com"
                        id: 1
                      - username: "user2@example.com"
                        id: 2
  /?action=table_list:
    get:
      tags: [ Dati ]
      description: >
        Il comando permette di recuperare tutte le tabelle che compongono il database richiesto. 
        Il server per ogni tabella include le sue caratteristiche e proprietà.
      parameters:
        - $ref: "#/components/parameters/db"
      responses:
        "200":
          content:
            application/json:
              schema:
                type: object
                properties:
                  tables:
                    type: array
                    items:
                      $ref: "#/components/schemas/table"
  /?action=table_info:
    get:
      tags: [ Dati ]
      description: >
        Il comando permette di recuperare le caratteristiche e le proprietà di una tabella specifica all’interno
        del database richiesto. Oltre alle caratteristiche della tabella saranno disponibili anche tutti i campi
        che la compongono con le loro caratteristiche.
      parameters:
        - $ref: "#/components/parameters/db"
        - in: query
          name: tablename
          required: true
          description: Nome della tabella da recuperare
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                type: object
                properties:
                  table:
                    $ref: "#/components/schemas/table"
                  fields:
                    type: array
                    items:
                      $ref: "#/components/schemas/field"
                  record:
                    type: object
                    description: Template di riferimento per il record utilizzabile nelle altre chiamate per aggiungere e modificare i valori nella tabella
                    $ref: "#/components/schemas/record_template"
                  archives:
                    type: array
                    description: Elenco degli archivi disponibili per la tabella
                    items:
                      $ref: "#/components/schemas/archive"
                  scripts:
                    type: array
                    description: Elenco degli script associati alla tabella
                    items:
                      $ref: "#/components/schemas/script"
                  preferences:
                    type: array
                    description: Preferenze standard di impaginazione sulla scheda
                    items:
                      $ref: "#/components/schemas/column_preference"
  /?action=model:
    parameters:
      - $ref: "#/components/parameters/db"
      - in: query
        name: tablename
        required: true
        description: Nome della tabella da interrogare
        schema:
          type: string
      - in: query
        name: gguid
        description: GGUID del record da leggere, opzionale, se specificato ritorna un solo record e tutti i parametri seguenti sono ignorati
        schema:
          type: string
      - in: query
        name: page
        description: numero di pagina 1-based, vuoto per non fare la paginazione, opzionale
        schema:
          type: integer
      - in: query
        name: perpage
        description: numero di record per pagina
        schema:
          type: integer
    get:
      tags: [ Dati ]
      description: >
        Il comando permette di recuperare tutti i record contenuti all’interno di una specifica tabella.
        Anche in questo caso i dati vengono inviati solo se l’utente possiede i permessi di visualizzazione.
      responses:
        "200":
          $ref: "#/components/responses/model"
    post:
      tags: [ Dati ]
      description: >
        Il comando permette di recuperare tutti i record contenuti all’interno di una specifica tabella.
        Anche in questo caso i dati vengono inviati solo se l’utente possiede i permessi di visualizzazione.
        E’ possibile inoltre aggiungere un post alla chiamata per poter filtrare i record (facoltativo).
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                fields:
                  type: array
                  description: array dei nomi dei campi da ritornare, di default tutti
                  items:
                    type: string
                search:
                  type: object
                  description: opzionale
                  properties:
                    fields:
                      type: array
                      description: array dei campi sui quali effettuare la ricerca testuale
                    query:
                      type: string
                      description: stringa da cercare in almeno uno dei campi specificati
                conditions:
                  type: object
                  description: coppie campo/valore in AND
                timerange:
                  type: object
                  description: filtro per l'agenda, opzionale
                  properties:
                    field_from:
                      type: string
                      description: nome del campo FROM
                    field_to:
                      type: string
                      description: nome del campo TO
                    tid_from:
                      type: integer
                      description: TID di inizio
                    tid_to:
                      type: integer
                      description: TID di fine
                order_info:
                  type: array
                  items:
                    type: array
                    example:
                      - "nome campo"
                      - true
                    items:
                      oneOf:
                        - type: string
                          description: nome campo
                        - type: integer
                          description: true per ASC
                    minItems: 2
                    maxItems: 2
                group_by:
                  type: array
                  description: array dei nomi dei campi per il GROUP BY
                  items:
                    type: string
      responses:
        "200":
          $ref: "#/components/responses/model"
  /?action=table_save:
    post:
      tags: [ Dati ]
      description: >
        Il comando viene utilizzato per aggiungere, modificare o eliminare i record da una specifica tabella. Il body
        è composto da due array. Uno con i record da aggiungere o modificare e l’altro contenente gli identificatori
        globali dei record da eliminare.
        Per aggiungere un nuovo record si dovrà passare un guid non esistente attualmente dentro la tabella. In caso
        si voglia eseguire una modifica si passerà il guid del record stesso.
      parameters:
        - $ref: "#/components/parameters/db"
        - in: query
          name: tablename
          required: true
          description: Nome della tabella da interrogare
          schema:
            type: string
      requestBody:
        description: >
          Il dizionario da utilizzare all’interno dell’array rows può essere il template record ottenibile attraverso il
          comando table_info. E’ comunque possibile passare solo i valori che si intendano modificare o aggiungere. 
          L’importante e che la chiave guid sia comunque sempre presente.
        content:
          application/json:
            schema:
              type: object
              properties:
                rows:
                  type: array
                  items:
                    type: object
                    description: dizionario dei valori del record, deve avere il GGUID impostato
                delete:
                  type: array
                  items:
                    type: string
                    description: array dei GGUID da eliminare
      responses:
        "200":
          content:
            application/json:
              schema:
                type: object
  /?action=sync:
    get:
      tags: [ Dati ]
      description: >
        Il comando forza la sincronizzazione del database cloud con il server di sincronizzazione. E’ necessario
        ricordare che le operazioni eseguite attraverso le api modificano i dati della versione cloud del database.
        Questo significa che fino a che non venga eseguita una operazione di sincronizzazione attraverso l’interfaccia
        web o attraverso il comando api, gli altri dispositivi non riceveranno le modifiche apportate sui dati.
      parameters:
        - $ref: "#/components/parameters/db"
        - in: query
          name: partial_from
          description: Numero intero per abilitare la ricezione parziale. Opzionale, se non presente disabilita la frammentazione della sincronizzazione.
          example: 0
          schema:
            type: integer
      responses:
        "200":
          description: >
            La risposta contiene tutti i valori per poter continuare a eseguire una sincronizzazione a 
            pacchetti, ossia spedendo le righe dei valori divise e non tutte insieme e il riferimento temporale da 
            utilizzare per la prossima sincronizzazione se utilizzato.
          content:
            application/json:
              schema:
                type: object
                properties:
                  sync:
                    type: object
                    properties:
                      partial:
                        type: boolean
                        description: true se devo continuare con il prossimo passo della ricezione parziale
                      partial_from:
                        type: integer
                        description: "il prossimo da usare per continuare, se `\"partial\": true`"
                        example: 1000
                      partial_total:
                        type: integer
                        description: "numero totale di record da ricevere, se `\"partial\": true`"
                        example: 1234
                  sync_last_tid:
                    type: integer
                    description: TID per avere la data/ora dell'ultima sincronizzazione completata
                  sync_first:
                    type: boolean
                    description: true se questa è stata la prima sincronizzazione da zero del database

components:
  securitySchemes:
    token:
      type: apiKey
      in: query
      name: token
      description: Token dell’utente per autenticare la richiesta, recuperabile con le credeziali utenti usando la chiamata `/?action=user_login`.
  parameters:
    db:
      in: query
      name: db
      required: true
      description: Nome del database sul quale operare.
      schema:
        type: string
    model:
      - $ref: "#/components/parameters/db"
      - in: query
        name: tablename
        required: true
        description: Nome della tabella da interrogare
        schema:
          type: string
      - in: query
        name: gguid
        description: GGUID del record da leggere, opzionale, se specificato ritorna un solo record e tutti i parametri seguenti sono ignorati
        schema:
          type: string
      - in: query
        name: page
        description: numero di pagina 1-based, vuoto per non fare la paginazione, opzionale
        schema:
          type: integer
      - in: query
        name: perpage
        description: numero di record per pagina
        schema:
          type: integer
  schemas:
    db:
      type: object
      properties:
        name:
          type: string
          description: Nome univoco del database
          example: "crm"
        label:
          type: string
          description: Etichetta del database
          example: "My Crm"
        seed:
          type: string
          description: Seme del database
          example: "CRM-ES"
    table:
      type: object
      properties:
        gguid:
          type: string
          description: Id globale
          example: "g"
        tid:
          type: integer
          description: Identificatore temporale
          example: 20180607093840
        eli:
          type: integer
          description: Se la tabella è eliminata
          example: 0
        arc:
          type: integer
          description: Indice archivio
          example: 0
        ut:
          type: string
          description: Ultimo utente
          example: "admin"
        ind:
          type: integer
          description: Indice di ordinamento
          example: 0
        displayable:
          type: integer
          description: Permesso di visualizzazione
          example: 1
        eliminable:
          type: integer
          description: Permesso di eliminazione
          example: 1
        editable:
          type: integer
          description: Permesso di editazione
          example: 1
        tablename:
          type: string
          description: Nome effettivo tabella
          example: "customers"
        syncyes:
          type: integer
          description: Permesso di sincronizzazione
          example: 1
        syncsel:
          type: integer
          description: Permesso di sincro selettiva
          example: 1
        syncno:
          type: integer
          description: Permesso di sincro opzionale
          example: 0
        param:
          type: string
          description: Parametri tabella
          example: "{}"
        tablelabel:
          type: string
          description: Etichetta tabella
          example: "Customer"
        newlabel:
          type: string
          description: Etichetta su nuovo record
          example: "New Custom."
        expressions:
          type: string
          description: Espressioni di calcolo
          example: "[]"
        lgroup:
          type: string
          description: Gruppo di appartenenza
          example: ""
    field:
      type: object
      properties:
        gguid:
          type: string
          description: Id globale campo
          example: "g"
        tid:
          type: integer
          description: Identificatore temporale
          example: 20190923135015
        eli:
          type: integer
          description: Se il campo è eliminato
          example: 0
        arc:
          type: integer
          description: Indice archivio
          example: 0
        ut:
          type: string
          description: Ultimo utente
          example: "user"
        ind:
          type: integer
          description: Indice di ordinamento
          example: 1001
        displayable:
          type: integer
          description: Permesso di visualizzazione
          example: 1
        eliminable:
          type: integer
          description: Permesso di eliminazione
          example: 1
        editable:
          type: integer
          description: Permesso di editazione
          example: 1
        tablename:
          type: string
          description: Tabella di appartenenza
          example: "customer"
        fieldname:
          type: string
          description: Nome effettivo del campo
          example: "name"
        fieldlabel:
          type: string
          description: Etichetta del campo
          example: "Name"
        fieldtype:
          type: integer
          description: Tipo campo
          example: 11
        viewcolumn:
          type: integer
          description: Se la colonna è visibile
          example: 1
        columnwidth:
          type: integer
          description: Larghezza colonna
          example: 200
        obligatory:
          type: integer
          description: Se il campo è obbligatorio
          example: 0
        param:
          type: string
          description: Parametri campo
          example: "{}"
        ofsystem:
          type: integer
          description: Se il campo è di sistema
          example: 1
        expression:
          type: string
          description: Espressioni campo (non usato)
          example: "{}"
        style:
          type: string
          description: Stile del campo
          example: "{}"
        panel:
          type: string
          description: Pannello contenente il campo
          example: ""
        panelindex:
          type: integer
          description: Indice del pannello
          example: 0
        fieldlabel2:
          type: string
          description: Etichetta sulla colonna
          example: "C Name"
        columnindex:
          type: integer
          description: Indice della colonna
          example: 1
    record:
      type: object
      example:
        gguid: "g"
        tid: 20191126145027
        eli: 1
        arc: 0
        ut: "user"
        ind: 0
        gguidp: ""
        exp: ""
        uta: "1070"
        tap: ""
        dsp: ""
        dsc: ""
        dsq1: 0
        dsq2: 0
        utc: "user"
        tidc: 20180618182500
        name: "Customer"
    record_template:
      type: object
      example:
        gguid: ""
        tid: 0
        eli: 0
        arc: 0
        ut: ""
        ind: 0
        exp: ""
        gguidp: ""
        uta: ""
        tap: ""
        dsp: ""
        dsc: ""
        dsq1: 0
        dsq2: 0
        utc: ""
        tidc: 0
        name: ""
    archive:
      type: object
      example:
        gguid: "g"
        tid: 20200323110641
        eli: 0
        arc: 0
        ut: "user"
        ind: 2
        gguidp: ""
        exp: ""
        uta: "1050"
        tap: ""
        dsp: ""
        dsc: ""
        dsq1: 0
        dsq2: 0
        utc: "user"
        tidc: 20191023132749
        tablename: "customer"
        arcindex: 2
        archivename: "old"
    script:
      type: object
      example:
        gguid: "g"
        ind: 7
        tablename: "customer"
        scriptname: "script"
        scripttype: 3
    column_preference:
      type: object
      example:
        NC: "ind"
        IN: 0
        VS: 0
        WD: 40
        SO: 0
  responses:
    model:
      description: >
        La risposta contiene tutti i record richiesti (o quello specifico attraverso il suo identificativo
        globale) contenente tutti i valori. I record sono inoltre filtrati in base ai permessi dell’utente.
        E’ presente anche la chiave total per identificare rapidamente il numero dei record ritornati.
      content:
        application/json:
          schema:
            type: object
            properties:
              records:
                type: array
                items:
                  $ref: "#/components/schemas/record"
              total:
                type: integet
                example: 1