{"openapi":"3.1.0","info":{"title":"123 Consulenza Open Data API","version":"1.0.0","description":"API REST pubblica gratuita per dati su enti competenti (ASL/INL/VVF per provincia) e calcolo scadenze formazione sicurezza sul lavoro. Nessuna autenticazione richiesta. JSON, CORS aperto.","contact":{"name":"123 Consulenza — Sviluppatori","url":"https://www.123consulenza.com/sviluppatori/","email":"info@123consulenza.com"},"license":{"name":"CC BY 4.0","url":"https://creativecommons.org/licenses/by/4.0/"},"termsOfService":"https://www.123consulenza.com/termini-condizioni/"},"servers":[{"url":"https://www.123consulenza.com/api/v1","description":"Produzione"}],"tags":[{"name":"enti","description":"Enti competenti per provincia (ASL/INL/VVF)."},{"name":"formazione","description":"Engine scadenze attestati formazione."},{"name":"sistema","description":"Health check e metadata di servizio."}],"paths":{"/enti":{"get":{"tags":["enti"],"summary":"Elenco enti competenti","description":"Restituisce l’elenco degli enti competenti per provincia. Paginabile, filtrabile per regione (slug).","operationId":"listEnti","parameters":[{"name":"regione","in":"query","required":false,"description":"Slug regione (es. lazio, lombardia).","schema":{"type":"string","example":"lazio"}},{"name":"limit","in":"query","required":false,"description":"Numero massimo risultati (1–200).","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}},{"name":"offset","in":"query","required":false,"description":"Offset di paginazione.","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Elenco enti","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Ente"}},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/enti/{provincia}":{"get":{"tags":["enti"],"summary":"Dettaglio ente per provincia","description":"Restituisce ASL/INL/VVF competenti per la provincia indicata (slug).","operationId":"getEnteByProvincia","parameters":[{"name":"provincia","in":"path","required":true,"description":"Slug provincia (es. milano, roma, napoli).","schema":{"type":"string","example":"milano"}}],"responses":{"200":{"description":"Ente competente","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Ente"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/scadenza-formazione":{"post":{"tags":["formazione"],"summary":"Calcolo scadenza attestato formazione","description":"Calcola la data di scadenza dell’attestato dato il ruolo, il tipo (iniziale/aggiornamento) e la data di rilascio. Risultato indicativo.","operationId":"calcolaScadenzaFormazione","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScadenzaRequest"}}}},"responses":{"200":{"description":"Scadenza calcolata","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ScadenzaResponse"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}},"/health":{"get":{"tags":["sistema"],"summary":"Health check","description":"Stato del servizio e versione corrente.","operationId":"healthCheck","responses":{"200":{"description":"Servizio attivo","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"version":{"type":"string","example":"1.0"},"timestamp":{"type":"string","format":"date-time"}},"required":["status","version","timestamp"]},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]}}}}}}}},"components":{"schemas":{"Meta":{"type":"object","properties":{"version":{"type":"string","example":"1.0"},"total":{"type":"integer","example":107},"limit":{"type":"integer","example":100},"offset":{"type":"integer","example":0},"license":{"type":"string","example":"CC BY 4.0"},"source":{"type":"string","example":"www.123consulenza.com"}},"required":["version"]},"Provincia":{"type":"object","properties":{"slug":{"type":"string","example":"milano"},"nome":{"type":"string","example":"Milano"},"regione":{"type":"string","example":"Lombardia"}},"required":["slug","nome","regione"]},"EnteContatto":{"type":"object","properties":{"nome":{"type":"string"},"indirizzo":{"type":"string"},"telefono":{"type":"string"},"email":{"type":"string","format":"email"},"url":{"type":"string","format":"uri"}}},"Ente":{"type":"object","description":"Set di enti competenti per una provincia.","properties":{"provincia":{"type":"string","example":"Milano"},"regione":{"type":"string","example":"Lombardia"},"asl":{"$ref":"#/components/schemas/EnteContatto"},"inl":{"$ref":"#/components/schemas/EnteContatto"},"vvf":{"$ref":"#/components/schemas/EnteContatto"}},"required":["provincia","regione"]},"ScadenzaRequest":{"type":"object","properties":{"ruolo":{"type":"string","description":"Identificativo del ruolo formativo.","enum":["lavoratore-basso","lavoratore-medio","lavoratore-alto","preposto","dirigente","rspp-dl","rls","antincendio-l1","antincendio-l2","antincendio-l3","primo-soccorso-a","primo-soccorso-b","primo-soccorso-c"]},"tipo":{"type":"string","enum":["iniziale","aggiornamento"],"default":"iniziale"},"dataRilascio":{"type":"string","format":"date","example":"2024-04-10"}},"required":["ruolo","dataRilascio"]},"ScadenzaResponse":{"type":"object","properties":{"ruolo":{"type":"string"},"tipo":{"type":"string","enum":["iniziale","aggiornamento"]},"dataRilascio":{"type":"string","format":"date"},"scadenza":{"type":"string","format":"date"},"giorniMancanti":{"type":"integer"},"stato":{"type":"string","enum":["valido","in-scadenza","scaduto"]}},"required":["ruolo","tipo","dataRilascio","scadenza"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"invalid_input"},"message":{"type":"string","example":"Body JSON non valido"}},"required":["code","message"]}},"required":["error"]}},"responses":{"BadRequest":{"description":"Richiesta non valida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Risorsa non trovata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}