Files
ScommettiApp/backend-node/openapi.yaml
T
2026-03-26 22:46:03 +01:00

1065 lines
28 KiB
YAML

openapi: 3.0.3
info:
title: Amici Scommesse API
version: 1.1.0
description: |
API per l'applicazione Amici Scommesse - Sistema di gestione scommesse tra amici.
**Architettura**: L'API utilizza una architettura a layer con dependency injection,
validazione automatica input, e formato risposte standardizzato.
**Versioning**:
- `/api/v1/*` - API corrente (formato standardizzato)
- `/api/legacy/*` - API legacy (backward compatibility)
**Autenticazione**: Mock authentication (Mario Rossi hardcoded). JWT da implementare.
contact:
name: API Support
email: support@amiciscommesse.com
license:
name: ISC
servers:
- url: http://localhost:3000/api/v1
description: Development server (v1)
- url: http://localhost:3000/api/legacy
description: Legacy API (backward compatibility)
tags:
- name: Groups
description: Gestione gruppi di utenti
- name: Bets
description: Gestione scommesse
- name: Friend Requests
description: Gestione richieste di amicizia
- name: Users
description: Gestione profilo utente
- name: Initial Data
description: Caricamento dati iniziali
- name: Health
description: Health check endpoint
components:
schemas:
# ===== Success Response Wrapper =====
SuccessResponse:
type: object
required:
- success
- timestamp
properties:
success:
type: boolean
example: true
message:
type: string
example: Operation successful
data:
type: object
timestamp:
type: string
format: date-time
example: '2024-01-01T00:00:00.000Z'
# ===== Error Response Wrapper =====
ErrorResponse:
type: object
required:
- success
- message
- timestamp
properties:
success:
type: boolean
example: false
message:
type: string
example: Error message
errors:
type: array
items:
type: object
properties:
field:
type: string
example: name
message:
type: string
example: Name is required
timestamp:
type: string
format: date-time
example: '2024-01-01T00:00:00.000Z'
# ===== User =====
User:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: Mario Rossi
email:
type: string
format: email
example: mario.rossi@example.com
avatarUrl:
type: string
nullable: true
example: https://example.com/avatar.jpg
score:
type: integer
example: 100
# ===== Group =====
Group:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: Gruppo Calcio
members:
type: array
items:
$ref: '#/components/schemas/User'
# ===== Participant =====
Participant:
type: object
properties:
user:
oneOf:
- type: integer
- $ref: '#/components/schemas/User'
role:
type: string
enum: [PARTICIPANT, OBSERVER]
example: PARTICIPANT
# ===== Bet =====
Bet:
type: object
properties:
id:
type: string
example: 507f1f77bcf86cd799439011
title:
type: string
example: Chi vince il campionato?
description:
type: string
nullable: true
example: Scommessa sul vincitore del campionato 2024
stake:
type: string
example: 50 euro
participants:
type: array
items:
$ref: '#/components/schemas/Participant'
status:
type: string
enum: [ACTIVE, AWAITING_VALIDATION, COMPLETED, EXPIRED]
example: ACTIVE
startDate:
type: string
format: date-time
example: '2024-01-01T00:00:00.000Z'
endDate:
type: string
format: date-time
nullable: true
example: '2024-12-31T23:59:59.000Z'
isPublic:
type: boolean
example: false
groupId:
type: string
nullable: true
example: '1'
winner:
oneOf:
- type: integer
- $ref: '#/components/schemas/User'
nullable: true
# ===== Friend Request =====
FriendRequest:
type: object
properties:
id:
type: integer
example: 1
fromUserId:
type: integer
example: 1
toUserId:
type: integer
example: 2
status:
type: string
enum: [PENDING, ACCEPTED, REJECTED]
example: PENDING
fromUser:
$ref: '#/components/schemas/User'
toUser:
$ref: '#/components/schemas/User'
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
# ===== Create Group Request =====
CreateGroupRequest:
type: object
required:
- name
- members
properties:
name:
type: string
minLength: 1
maxLength: 100
example: Gruppo Calcio
members:
type: array
minItems: 1
items:
type: integer
example: [1, 2, 3]
# ===== Update Group Request =====
UpdateGroupRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
example: Nuovo Nome Gruppo
# ===== Add Members Request =====
AddMembersRequest:
type: object
required:
- userIds
properties:
userIds:
type: array
minItems: 1
items:
type: integer
example: [4, 5]
# ===== Create Bet Request =====
CreateBetRequest:
type: object
required:
- title
- stake
- participants
properties:
title:
type: string
minLength: 1
maxLength: 200
example: Chi vince il campionato?
description:
type: string
maxLength: 1000
example: Scommessa sul vincitore
stake:
type: string
minLength: 1
example: 50 euro
participants:
type: array
minItems: 1
items:
type: object
required:
- user
- role
properties:
user:
type: integer
role:
type: string
enum: [PARTICIPANT, OBSERVER]
example:
- user: 1
role: PARTICIPANT
- user: 2
role: PARTICIPANT
isPublic:
type: boolean
default: false
example: false
groupId:
type: string
nullable: true
example: '1'
# ===== Update Bet Request =====
UpdateBetRequest:
type: object
properties:
title:
type: string
minLength: 1
maxLength: 200
description:
type: string
maxLength: 1000
stake:
type: string
minLength: 1
status:
type: string
enum: [ACTIVE, AWAITING_VALIDATION, COMPLETED, EXPIRED]
endDate:
type: string
format: date-time
winner:
type: integer
nullable: true
# ===== Send Friend Request =====
SendFriendRequestRequest:
type: object
required:
- identifier
properties:
identifier:
oneOf:
- type: integer
- type: string
example: 2
description: User ID, name, or email
# ===== Update User Request =====
UpdateUserRequest:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 100
example: Mario Rossi
email:
type: string
format: email
example: mario.rossi@example.com
avatarUrl:
type: string
format: uri
nullable: true
example: https://example.com/avatar.jpg
# ===== Initial Data =====
InitialData:
type: object
properties:
currentUser:
$ref: '#/components/schemas/User'
users:
type: array
items:
$ref: '#/components/schemas/User'
friends:
type: array
items:
$ref: '#/components/schemas/User'
friendRequests:
type: array
items:
$ref: '#/components/schemas/FriendRequest'
groups:
type: array
items:
$ref: '#/components/schemas/Group'
userBets:
type: array
items:
$ref: '#/components/schemas/Bet'
publicBets:
type: array
items:
$ref: '#/components/schemas/Bet'
# ===== Health Status =====
HealthStatus:
type: object
properties:
status:
type: string
enum: [healthy, unhealthy]
example: healthy
timestamp:
type: string
format: date-time
services:
type: object
properties:
postgres:
type: string
example: connected
mongodb:
type: string
example: connected
responses:
ValidationError:
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
success: false
message: Validation failed
errors:
- field: name
message: Name is required
timestamp: '2024-01-01T00:00:00.000Z'
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
success: false
message: Resource not found
timestamp: '2024-01-01T00:00:00.000Z'
InternalError:
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
success: false
message: Internal server error
timestamp: '2024-01-01T00:00:00.000Z'
paths:
# ==================== GROUPS ====================
/groups:
get:
tags:
- Groups
summary: Lista tutti i gruppi
description: Recupera la lista di tutti i gruppi con i loro membri
responses:
'200':
description: Lista gruppi recuperata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Group'
'500':
$ref: '#/components/responses/InternalError'
post:
tags:
- Groups
summary: Crea un nuovo gruppo
description: Crea un nuovo gruppo con i membri specificati
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateGroupRequest'
responses:
'201':
description: Gruppo creato con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Group'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
/groups/{id}:
get:
tags:
- Groups
summary: Dettaglio gruppo
description: Recupera i dettagli di un gruppo specifico con i membri
parameters:
- name: id
in: path
required: true
schema:
type: integer
example: 1
responses:
'200':
description: Gruppo recuperato con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Group'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
put:
tags:
- Groups
summary: Aggiorna gruppo
description: Aggiorna le informazioni di un gruppo
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateGroupRequest'
responses:
'200':
description: Gruppo aggiornato con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Group'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
delete:
tags:
- Groups
summary: Elimina gruppo
description: Elimina un gruppo esistente
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Gruppo eliminato con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
type: 'null'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
/groups/{id}/members:
put:
tags:
- Groups
summary: Aggiungi membri al gruppo
description: Aggiunge uno o più membri a un gruppo esistente
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AddMembersRequest'
responses:
'200':
description: Membri aggiunti con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Group'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
/groups/{id}/members/{userId}:
delete:
tags:
- Groups
summary: Rimuovi membro dal gruppo
description: Rimuove un membro da un gruppo
parameters:
- name: id
in: path
required: true
schema:
type: integer
- name: userId
in: path
required: true
schema:
type: integer
responses:
'200':
description: Membro rimosso con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Group'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
# ==================== BETS ====================
/bets:
get:
tags:
- Bets
summary: Lista tutte le scommesse
description: Recupera la lista di tutte le scommesse con dati utente popolati
responses:
'200':
description: Lista scommesse recuperata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Bet'
'500':
$ref: '#/components/responses/InternalError'
post:
tags:
- Bets
summary: Crea una nuova scommessa
description: Crea una nuova scommessa con partecipanti
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateBetRequest'
responses:
'201':
description: Scommessa creata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Bet'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
/bets/{id}:
get:
tags:
- Bets
summary: Dettaglio scommessa
description: Recupera i dettagli di una scommessa specifica
parameters:
- name: id
in: path
required: true
schema:
type: string
example: 507f1f77bcf86cd799439011
responses:
'200':
description: Scommessa recuperata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Bet'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
put:
tags:
- Bets
summary: Aggiorna scommessa
description: Aggiorna i dettagli di una scommessa
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateBetRequest'
responses:
'200':
description: Scommessa aggiornata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/Bet'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
delete:
tags:
- Bets
summary: Elimina scommessa
description: Elimina una scommessa esistente
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Scommessa eliminata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
type: 'null'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
# ==================== FRIEND REQUESTS ====================
/friend-requests:
get:
tags:
- Friend Requests
summary: Lista amici
description: Recupera la lista di amici dell'utente corrente
responses:
'200':
description: Lista amici recuperata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
'500':
$ref: '#/components/responses/InternalError'
post:
tags:
- Friend Requests
summary: Invia richiesta di amicizia
description: Invia una richiesta di amicizia a un utente
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SendFriendRequestRequest'
responses:
'201':
description: Richiesta inviata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/FriendRequest'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'409':
description: Conflict - Already friends or request exists
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
$ref: '#/components/responses/InternalError'
/friend-requests/pending:
get:
tags:
- Friend Requests
summary: Lista richieste pending
description: Recupera le richieste di amicizia pending per l'utente corrente
responses:
'200':
description: Lista richieste recuperata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/FriendRequest'
'500':
$ref: '#/components/responses/InternalError'
/friend-requests/{id}/accept:
post:
tags:
- Friend Requests
summary: Accetta richiesta di amicizia
description: Accetta una richiesta di amicizia pending
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Richiesta accettata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
type: object
properties:
message:
type: string
example: Friend request accepted successfully
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
/friend-requests/{id}:
delete:
tags:
- Friend Requests
summary: Rifiuta/cancella richiesta
description: Rifiuta o cancella una richiesta di amicizia
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Richiesta rifiutata con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
type: object
properties:
message:
type: string
example: Friend request rejected successfully
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
# ==================== USERS ====================
/users/current:
put:
tags:
- Users
summary: Aggiorna profilo utente
description: Aggiorna il profilo dell'utente corrente
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
'200':
description: Profilo aggiornato con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalError'
# ==================== INITIAL DATA ====================
/initial-data:
get:
tags:
- Initial Data
summary: Carica dati iniziali
description: |
Carica tutti i dati iniziali necessari per l'applicazione in una singola chiamata.
Include: utente corrente, lista utenti, amici, richieste di amicizia, gruppi, scommesse.
responses:
'200':
description: Dati iniziali caricati con successo
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SuccessResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/InitialData'
'500':
$ref: '#/components/responses/InternalError'
# Health Check (non versioned)
/health:
get:
tags:
- Health
summary: Health check
description: Verifica lo stato dei database (PostgreSQL e MongoDB)
servers:
- url: http://localhost:3000
description: Health check endpoint (non versioned)
responses:
'200':
description: Sistema healthy
content:
application/json:
schema:
$ref: '#/components/schemas/HealthStatus'
'503':
description: Sistema unhealthy
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: unhealthy
timestamp:
type: string
format: date-time
error:
type: string
example: Database connection failed