provapraticabackend/src/openapi/openapi.json

680 lines
21 KiB
JSON
Raw Normal View History

2026-06-09 14:57:40 +02:00
{
"openapi": "3.0.3",
"info": {
"title": "API Gestione Rimborsi Spese Aziendali",
"version": "1.0.0",
"description": "Backend prova pratica S5 Gestione rimborsi spese aziendali"
},
"servers": [
{
"url": "http://localhost:3003",
"description": "Sviluppo locale"
}
],
"tags": [
{ "name": "Sistema", "description": "Health check" },
{ "name": "Autenticazione", "description": "Login e sessione Auth.js" },
{ "name": "Utenti", "description": "Registrazione e profilo" },
{ "name": "Categorie", "description": "Categorie di spesa" },
{ "name": "Rimborsi", "description": "Richieste di rimborso" },
{ "name": "Statistiche", "description": "Report amministrativi" }
],
"components": {
"securitySchemes": {
"cookieAuth": {
"type": "apiKey",
"in": "cookie",
"name": "authjs.session-token",
"description": "Cookie di sessione impostato dopo il login. In produzione il nome può essere __Secure-authjs.session-token."
}
},
"schemas": {
"Error": {
"type": "object",
"properties": {
"error": { "type": "string" }
},
"required": ["error"]
},
"Message": {
"type": "object",
"properties": {
"message": { "type": "string" }
},
"required": ["message"]
},
"Ruolo": {
"type": "string",
"enum": ["DIPENDENTE", "RESPONSABILE_AMMINISTRATIVO"]
},
"StatoRichiesta": {
"type": "string",
"enum": ["IN_ATTESA", "APPROVATA", "RIFIUTATA", "LIQUIDATA"]
},
"Utente": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"nome": { "type": "string" },
"cognome": { "type": "string" },
"email": { "type": "string", "format": "email" },
"ruolo": { "$ref": "#/components/schemas/Ruolo" }
},
"required": ["id", "nome", "cognome", "email", "ruolo"]
},
"UtenteSintetico": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"nome": { "type": "string" },
"cognome": { "type": "string" }
},
"required": ["id", "nome", "cognome"]
},
"RegistrazioneInput": {
"type": "object",
"required": ["nome", "cognome", "email", "password", "confermaPassword"],
"properties": {
"nome": { "type": "string", "example": "Mario" },
"cognome": { "type": "string", "example": "Rossi" },
"email": { "type": "string", "format": "email", "example": "mario.rossi@azienda.it" },
"password": { "type": "string", "format": "password" },
"confermaPassword": { "type": "string", "format": "password" },
"ruolo": { "$ref": "#/components/schemas/Ruolo" }
}
},
"RegistrazioneResponse": {
"type": "object",
"properties": {
"message": { "type": "string" },
"utente": { "$ref": "#/components/schemas/Utente" }
},
"required": ["message", "utente"]
},
"CategoriaSpesa": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"descrizione": { "type": "string" }
},
"required": ["id", "descrizione"]
},
"Rimborso": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"dataInserimento": { "type": "string", "format": "date-time" },
"dataSpesa": { "type": "string", "format": "date" },
"categoriaId": { "type": "integer" },
"categoria": { "type": "string" },
"importo": { "type": "number" },
"descrizione": { "type": "string" },
"riferimentoGiustificativo": { "type": "string", "nullable": true },
"stato": { "$ref": "#/components/schemas/StatoRichiesta" },
"dipendenteId": { "type": "integer" },
"dipendenteNome": { "type": "string" },
"dataValutazione": { "type": "string", "format": "date-time", "nullable": true },
"responsabileValutazioneId": { "type": "integer", "nullable": true },
"responsabileNome": { "type": "string", "nullable": true },
"motivazioneRifiuto": { "type": "string", "nullable": true },
"dataLiquidazione": { "type": "string", "format": "date-time", "nullable": true }
},
"required": [
"id",
"dataInserimento",
"dataSpesa",
"categoriaId",
"categoria",
"importo",
"descrizione",
"stato",
"dipendenteId",
"dipendenteNome"
]
},
"RimborsoInput": {
"type": "object",
"required": ["dataSpesa", "categoriaId", "importo", "descrizione"],
"properties": {
"dataSpesa": { "type": "string", "format": "date", "example": "2025-06-01" },
"categoriaId": { "type": "integer", "example": 1 },
"importo": { "type": "number", "minimum": 0.01, "example": 45.5 },
"descrizione": { "type": "string", "example": "Pranzo di lavoro con cliente" },
"riferimentoGiustificativo": { "type": "string", "nullable": true, "example": "FATT-2025-001" }
}
},
"RifiutaInput": {
"type": "object",
"properties": {
"motivazione": { "type": "string", "nullable": true, "example": "Manca il giustificativo" }
}
},
"StatisticaRimborso": {
"type": "object",
"properties": {
"mese": { "type": "string", "example": "2025-06" },
"categoria": { "type": "string" },
"numeroRichieste": { "type": "integer" },
"totaleRichiesto": { "type": "number" },
"totaleApprovato": { "type": "number" },
"totaleLiquidato": { "type": "number" }
},
"required": [
"mese",
"categoria",
"numeroRichieste",
"totaleRichiesto",
"totaleApprovato",
"totaleLiquidato"
]
},
"CsrfResponse": {
"type": "object",
"properties": {
"csrfToken": { "type": "string" }
},
"required": ["csrfToken"]
}
},
"responses": {
"Unauthorized": {
"description": "Autenticazione richiesta",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Error" }
}
}
},
"Forbidden": {
"description": "Operazione non consentita per il ruolo corrente",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Error" }
}
}
},
"NotFound": {
"description": "Risorsa non trovata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Error" }
}
}
},
"BadRequest": {
"description": "Richiesta non valida",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Error" }
}
}
}
}
},
"paths": {
"/api/health": {
"get": {
"tags": ["Sistema"],
"summary": "Health check",
"responses": {
"200": {
"description": "Servizio attivo",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": { "type": "string", "example": "ok" }
}
}
}
}
}
}
}
},
"/api/auth/csrf": {
"get": {
"tags": ["Autenticazione"],
"summary": "Ottieni token CSRF per login/logout",
"responses": {
"200": {
"description": "Token CSRF",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CsrfResponse" }
}
}
}
}
}
},
"/api/auth/callback/credentials": {
"post": {
"tags": ["Autenticazione"],
"summary": "Login con email e password",
"description": "Invia i dati come application/x-www-form-urlencoded. Imposta il cookie di sessione in caso di successo.",
"requestBody": {
"required": true,
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"type": "object",
"required": ["csrfToken", "email", "password"],
"properties": {
"csrfToken": { "type": "string" },
"email": { "type": "string", "format": "email" },
"password": { "type": "string", "format": "password" },
"redirect": { "type": "string", "example": "false" }
}
}
}
}
},
"responses": {
"200": { "description": "Login riuscito" },
"401": { "description": "Credenziali non valide" }
}
}
},
"/api/auth/signout": {
"post": {
"tags": ["Autenticazione"],
"summary": "Logout",
"requestBody": {
"required": true,
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"type": "object",
"required": ["csrfToken"],
"properties": {
"csrfToken": { "type": "string" }
}
}
}
}
},
"responses": {
"200": { "description": "Logout effettuato" }
}
}
},
"/api/utenti/register": {
"post": {
"tags": ["Utenti"],
"summary": "Registrazione nuovo utente",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/RegistrazioneInput" }
}
}
},
"responses": {
"201": {
"description": "Utente registrato",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/RegistrazioneResponse" }
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"409": {
"description": "Email già registrata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Error" }
}
}
}
}
}
},
"/api/utenti/me": {
"get": {
"tags": ["Utenti"],
"summary": "Profilo utente corrente",
"responses": {
"200": {
"description": "Profilo utente",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Utente" }
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" }
}
}
},
"/api/utenti/dipendenti": {
"get": {
"tags": ["Utenti"],
"summary": "Elenco dipendenti",
"description": "Solo per RESPONSABILE_AMMINISTRATIVO",
"security": [{ "cookieAuth": [] }],
"responses": {
"200": {
"description": "Lista dipendenti",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/UtenteSintetico" }
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" }
}
}
},
"/api/categorie-spesa": {
"get": {
"tags": ["Categorie"],
"summary": "Elenco categorie di spesa",
"security": [{ "cookieAuth": [] }],
"responses": {
"200": {
"description": "Lista categorie",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/CategoriaSpesa" }
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" }
}
}
},
"/api/rimborsi": {
"get": {
"tags": ["Rimborsi"],
"summary": "Elenco richieste di rimborso",
"security": [{ "cookieAuth": [] }],
"parameters": [
{
"name": "stato",
"in": "query",
"schema": { "$ref": "#/components/schemas/StatoRichiesta" }
},
{
"name": "categoriaId",
"in": "query",
"schema": { "type": "integer" }
},
{
"name": "mese",
"in": "query",
"description": "Formato YYYY-MM",
"schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}$", "example": "2025-06" }
},
{
"name": "dipendenteId",
"in": "query",
"schema": { "type": "integer" }
}
],
"responses": {
"200": {
"description": "Lista rimborsi",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/Rimborso" }
}
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" }
}
},
"post": {
"tags": ["Rimborsi"],
"summary": "Crea nuova richiesta di rimborso",
"description": "Solo per DIPENDENTE",
"security": [{ "cookieAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/RimborsoInput" }
}
}
},
"responses": {
"201": {
"description": "Richiesta creata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Rimborso" }
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" }
}
}
},
"/api/rimborsi/{id}": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": { "type": "integer" }
}
],
"get": {
"tags": ["Rimborsi"],
"summary": "Dettaglio richiesta di rimborso",
"security": [{ "cookieAuth": [] }],
"responses": {
"200": {
"description": "Dettaglio rimborso",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Rimborso" }
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"404": { "$ref": "#/components/responses/NotFound" }
}
},
"put": {
"tags": ["Rimborsi"],
"summary": "Modifica richiesta (solo stato IN_ATTESA)",
"security": [{ "cookieAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/RimborsoInput" }
}
}
},
"responses": {
"200": {
"description": "Richiesta aggiornata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Rimborso" }
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"404": { "$ref": "#/components/responses/NotFound" }
}
},
"delete": {
"tags": ["Rimborsi"],
"summary": "Elimina richiesta (solo stato IN_ATTESA)",
"security": [{ "cookieAuth": [] }],
"responses": {
"200": {
"description": "Richiesta eliminata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Message" }
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" },
"404": { "$ref": "#/components/responses/NotFound" }
}
}
},
"/api/rimborsi/{id}/approva": {
"put": {
"tags": ["Rimborsi"],
"summary": "Approva richiesta",
"description": "Solo RESPONSABILE_AMMINISTRATIVO. La richiesta deve essere IN_ATTESA.",
"security": [{ "cookieAuth": [] }],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": { "type": "integer" }
}
],
"responses": {
"200": {
"description": "Richiesta approvata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Rimborso" }
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" }
}
}
},
"/api/rimborsi/{id}/rifiuta": {
"put": {
"tags": ["Rimborsi"],
"summary": "Rifiuta richiesta",
"description": "Solo RESPONSABILE_AMMINISTRATIVO. La richiesta deve essere IN_ATTESA.",
"security": [{ "cookieAuth": [] }],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": { "type": "integer" }
}
],
"requestBody": {
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/RifiutaInput" }
}
}
},
"responses": {
"200": {
"description": "Richiesta rifiutata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Rimborso" }
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" }
}
}
},
"/api/rimborsi/{id}/liquida": {
"put": {
"tags": ["Rimborsi"],
"summary": "Liquida richiesta approvata",
"description": "Solo RESPONSABILE_AMMINISTRATIVO. La richiesta deve essere APPROVATA.",
"security": [{ "cookieAuth": [] }],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": { "type": "integer" }
}
],
"responses": {
"200": {
"description": "Richiesta liquidata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Rimborso" }
}
}
},
"400": { "$ref": "#/components/responses/BadRequest" },
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" }
}
}
},
"/api/statistiche/rimborsi": {
"get": {
"tags": ["Statistiche"],
"summary": "Statistiche rimborsi aggregate",
"description": "Solo RESPONSABILE_AMMINISTRATIVO",
"security": [{ "cookieAuth": [] }],
"parameters": [
{
"name": "mese",
"in": "query",
"description": "Formato YYYY-MM",
"schema": { "type": "string", "pattern": "^\\d{4}-\\d{2}$", "example": "2025-06" }
},
{
"name": "categoriaId",
"in": "query",
"schema": { "type": "integer" }
},
{
"name": "dipendenteId",
"in": "query",
"schema": { "type": "integer" }
}
],
"responses": {
"200": {
"description": "Statistiche aggregate",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": { "$ref": "#/components/schemas/StatisticaRimborso" }
}
}
}
},
"401": { "$ref": "#/components/responses/Unauthorized" },
"403": { "$ref": "#/components/responses/Forbidden" }
}
}
}
}
}