Restores the /ping endpoint for health checks and adds 429 Too Many Requests response handling to improve API robustness.
571 lines
16 KiB
YAML
571 lines
16 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Arcadia API
|
|
description: |
|
|
Arcadia API in order to abstract corporate metamodel to a proper and stable implemented API.
|
|
Architecture Clean Architecture, Domain-Driven Design (DDD) & Ports & Adapters (Hexagonale).
|
|
contact:
|
|
name: Uwil Engineering Team
|
|
email: digital@ldc.fr
|
|
license:
|
|
name: MIT
|
|
url: https://opensource.org/licenses/MIT
|
|
version: 1.0.0
|
|
|
|
servers:
|
|
- url: http://127.0.0.1:8000/api/v1
|
|
description: Serveur de développement local v1
|
|
|
|
security:
|
|
- HmacClientId: []
|
|
HmacTimestamp: []
|
|
HmacSignature: []
|
|
|
|
tags:
|
|
- name: Employees
|
|
description: Gestion et consultation du référentiel RH des employés.
|
|
|
|
paths:
|
|
|
|
/employees:
|
|
get:
|
|
tags:
|
|
- Employees
|
|
summary: Liste paginée des employés
|
|
description: |
|
|
Retourne la liste paginée des employés du système Arcadia.
|
|
Prend en charge le filtrage par date de modification (`since`), code établissement (`establishment`),
|
|
code site (`siteId`), code service (`serviceId`), ainsi que le tri et la pagination HATEOAS.
|
|
operationId: listEmployees
|
|
parameters:
|
|
- $ref: '#/components/parameters/Page'
|
|
- $ref: '#/components/parameters/PageSize'
|
|
- $ref: '#/components/parameters/Offset'
|
|
- $ref: '#/components/parameters/Limit'
|
|
- $ref: '#/components/parameters/Since'
|
|
- $ref: '#/components/parameters/Establishment'
|
|
- $ref: '#/components/parameters/SiteId'
|
|
- $ref: '#/components/parameters/ServiceId'
|
|
- $ref: '#/components/parameters/SortBy'
|
|
- $ref: '#/components/parameters/SortDirection'
|
|
responses:
|
|
'200':
|
|
description: Page d'employés récupérée avec succès.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EmployeeListResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'422':
|
|
$ref: '#/components/responses/UnprocessableEntity'
|
|
'429':
|
|
$ref: '#/components/responses/TooManyRequests'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
'503':
|
|
$ref: '#/components/responses/ServiceUnavailable'
|
|
|
|
/employees/{employeeId}:
|
|
get:
|
|
tags:
|
|
- Employees
|
|
summary: Détail d'un employé par son identifiant
|
|
description: |
|
|
Retourne la fiche détaillée d'un employé spécifié par son matricule public unique.
|
|
operationId: getEmployee
|
|
parameters:
|
|
- $ref: '#/components/parameters/EmployeeIdPath'
|
|
responses:
|
|
'200':
|
|
description: Fiche employé trouvée.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EmployeeItemResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'422':
|
|
$ref: '#/components/responses/UnprocessableEntity'
|
|
'429':
|
|
$ref: '#/components/responses/TooManyRequests'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
'503':
|
|
$ref: '#/components/responses/ServiceUnavailable'
|
|
|
|
components:
|
|
securitySchemes:
|
|
HmacClientId:
|
|
type: apiKey
|
|
in: header
|
|
name: X-Client-Id
|
|
description: Identifiant public du client API autorisé.
|
|
HmacTimestamp:
|
|
type: apiKey
|
|
in: header
|
|
name: X-Timestamp
|
|
description: Horodatage au format ISO8601 / RFC3339 (tolérance anti-replay ±5 minutes).
|
|
HmacSignature:
|
|
type: apiKey
|
|
in: header
|
|
name: X-Signature
|
|
description: Signature HMAC-SHA256 calculée avec la clé secrète partagée.
|
|
|
|
parameters:
|
|
EmployeeIdPath:
|
|
name: employeeId
|
|
in: path
|
|
required: true
|
|
description: Matricule public unique de l'employé (7 ou 8 chiffres).
|
|
schema:
|
|
type: string
|
|
pattern: '^\d{7,8}$'
|
|
example: '01155902'
|
|
|
|
Page:
|
|
name: page
|
|
in: query
|
|
required: false
|
|
description: Numéro de page (1-based).
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
default: 1
|
|
example: 1
|
|
|
|
PageSize:
|
|
name: pageSize
|
|
in: query
|
|
required: false
|
|
description: Nombre d'éléments par page (max 10000).
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 10000
|
|
default: 25
|
|
example: 25
|
|
|
|
Offset:
|
|
name: offset
|
|
in: query
|
|
required: false
|
|
description: Décalage d'index pour la pagination basée sur l'offset.
|
|
schema:
|
|
type: integer
|
|
minimum: 0
|
|
example: 0
|
|
|
|
Limit:
|
|
name: limit
|
|
in: query
|
|
required: false
|
|
description: Nombre maximal d'enregistrements pour la pagination par offset.
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 10000
|
|
example: 25
|
|
|
|
Since:
|
|
name: since
|
|
in: query
|
|
required: false
|
|
description: Horodatage au format RFC3339 (borne inférieure sur updatedAt).
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
example: '2026-01-01T00:00:00Z'
|
|
|
|
Establishment:
|
|
name: establishment
|
|
in: query
|
|
required: false
|
|
description: "Filtrer par code établissement (ex: 01, PA, LY)."
|
|
schema:
|
|
type: string
|
|
pattern: '^[\dA-Z]{2,}$'
|
|
example: '01'
|
|
|
|
SiteId:
|
|
name: siteId
|
|
in: query
|
|
required: false
|
|
description: "Filtrer par code site (ex: LDCSER, SLELA)."
|
|
schema:
|
|
type: string
|
|
pattern: '^[A-Z]{2,}$'
|
|
example: 'LDCSER'
|
|
|
|
ServiceId:
|
|
name: serviceId
|
|
in: query
|
|
required: false
|
|
description: "Filtrer par identifiant de service (ex: 097, 101)."
|
|
schema:
|
|
type: string
|
|
pattern: '^\d{1,}$'
|
|
example: '097'
|
|
|
|
SortBy:
|
|
name: sortBy
|
|
in: query
|
|
required: false
|
|
description: Champ d'ordonnancement des employés.
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- arcadiaId
|
|
- startDate
|
|
- endDate
|
|
- plannedEndDate
|
|
- createdAt
|
|
- updatedAt
|
|
default: arcadiaId
|
|
example: arcadiaId
|
|
|
|
SortDirection:
|
|
name: sortDirection
|
|
in: query
|
|
required: false
|
|
description: Sens du tri.
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- Ascending
|
|
- Descending
|
|
default: Ascending
|
|
example: Ascending
|
|
|
|
responses:
|
|
BadRequest:
|
|
description: Erreurs de forme de la requête HTTP (validation FormRequest) (400 Bad Request).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProblemDetails'
|
|
|
|
Unauthorized:
|
|
description: Échec d'authentification HMAC ou signature invalide (401 Unauthorized).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProblemDetails'
|
|
|
|
Forbidden:
|
|
description: Client non autorisé à accéder à cette ressource (403 Forbidden).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProblemDetails'
|
|
|
|
NotFound:
|
|
description: Ressource introuvable (404 Not Found).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProblemDetails'
|
|
|
|
UnprocessableEntity:
|
|
description: Erreur sémantique ou violation des règles du domaine (422 Unprocessable Entity).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/ValidationErrorProblemDetails'
|
|
|
|
TooManyRequests:
|
|
description: Trop de requêtes envoyées dans un laps de temps donné (429 Too Many Requests).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProblemDetails'
|
|
headers:
|
|
Retry-After:
|
|
description: Le nombre de secondes avant de pouvoir réessayer.
|
|
schema:
|
|
type: integer
|
|
X-RateLimit-Limit:
|
|
description: La limite de requêtes par minute.
|
|
schema:
|
|
type: integer
|
|
X-RateLimit-Remaining:
|
|
description: Le nombre de requêtes restantes avant blocage.
|
|
schema:
|
|
type: integer
|
|
|
|
InternalServerError:
|
|
description: Erreur interne du serveur (500 Internal Server Error).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProblemDetails'
|
|
|
|
ServiceUnavailable:
|
|
description: Service temporairement indisponible (503 Service Unavailable).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: '#/components/schemas/ProblemDetails'
|
|
|
|
schemas:
|
|
Employee:
|
|
type: object
|
|
description: Représentation canonique d'un employé dans le métamodèle Arcadia.
|
|
required:
|
|
- id
|
|
- firstName
|
|
- lastName
|
|
- establishment
|
|
- site
|
|
- service
|
|
- startDate
|
|
properties:
|
|
id:
|
|
type: string
|
|
pattern: '^\d{7,8}$'
|
|
description: Matricule public unique de l'employé.
|
|
example: '01155902'
|
|
firstName:
|
|
type: string
|
|
description: Prénom de l'employé.
|
|
example: John
|
|
lastName:
|
|
type: string
|
|
description: Nom de famille de l'employé.
|
|
example: DOE
|
|
establishment:
|
|
type: string
|
|
pattern: '^[\dA-Z]{2,}$'
|
|
description: Code de l'établissement d'affectation.
|
|
example: '01'
|
|
site:
|
|
type: string
|
|
pattern: '^[A-Z]{2,}$'
|
|
description: Code du site géographique.
|
|
example: LDCSER
|
|
service:
|
|
type: string
|
|
pattern: '^\d{1,}$'
|
|
description: Identifiant du service interne.
|
|
example: '097'
|
|
startDate:
|
|
type: string
|
|
format: date
|
|
description: Date de prise de poste (YYYY-MM-DD).
|
|
example: '2024-01-15'
|
|
endDate:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
format: date
|
|
description: Date de fin de contrat effective (optionnelle).
|
|
example: null
|
|
plannedEndDate:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
format: date
|
|
description: Date de fin de contrat prévue (optionnelle).
|
|
example: null
|
|
createdAt:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
format: date-time
|
|
description: Date d'enregistrement dans le système.
|
|
example: '2026-08-11T14:00:00Z'
|
|
updatedAt:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
format: date-time
|
|
description: Date de dernière mise à jour.
|
|
example: '2026-08-11T14:00:00Z'
|
|
|
|
PaginationLinks:
|
|
type: object
|
|
description: Liens de navigation HATEOAS pour la pagination.
|
|
required:
|
|
- self
|
|
- first
|
|
- last
|
|
properties:
|
|
self:
|
|
type: string
|
|
format: uri
|
|
description: Lien vers la page courante.
|
|
example: 'http://127.0.0.1:8000/api/v1/employees?page=1&pageSize=25'
|
|
first:
|
|
type: string
|
|
format: uri
|
|
description: Lien vers la première page.
|
|
example: 'http://127.0.0.1:8000/api/v1/employees?page=1&pageSize=25'
|
|
prev:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
format: uri
|
|
description: Lien vers la page précédente (null si première page).
|
|
example: null
|
|
next:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
format: uri
|
|
description: Lien vers la page suivante (null si dernière page).
|
|
example: 'http://127.0.0.1:8000/api/v1/employees?page=2&pageSize=25'
|
|
last:
|
|
type: string
|
|
format: uri
|
|
description: Lien vers la dernière page.
|
|
example: 'http://127.0.0.1:8000/api/v1/employees?page=2&pageSize=25'
|
|
|
|
PaginationMeta:
|
|
type: object
|
|
description: Métadonnées de pagination.
|
|
required:
|
|
- page
|
|
- pageSize
|
|
- totalItems
|
|
- totalPages
|
|
- links
|
|
properties:
|
|
page:
|
|
type: integer
|
|
minimum: 1
|
|
description: Index de la page courante (1-based).
|
|
example: 1
|
|
pageSize:
|
|
type: integer
|
|
minimum: 1
|
|
description: Nombre d'éléments par page.
|
|
example: 25
|
|
totalItems:
|
|
type: integer
|
|
minimum: 0
|
|
description: Nombre total d'éléments correspondant aux filtres.
|
|
example: 42
|
|
totalPages:
|
|
type: integer
|
|
minimum: 0
|
|
description: Nombre total de pages disponibles.
|
|
example: 2
|
|
links:
|
|
$ref: '#/components/schemas/PaginationLinks'
|
|
|
|
EmployeeListResponse:
|
|
type: object
|
|
description: Enveloppe de réponse pour la liste paginée des employés.
|
|
required:
|
|
- employees
|
|
- pagination
|
|
properties:
|
|
employees:
|
|
type: array
|
|
description: Collection des employés de la page.
|
|
items:
|
|
$ref: '#/components/schemas/Employee'
|
|
pagination:
|
|
$ref: '#/components/schemas/PaginationMeta'
|
|
|
|
EmployeeItemResponse:
|
|
type: object
|
|
description: Enveloppe de réponse pour le détail d'un employé.
|
|
required:
|
|
- employee
|
|
properties:
|
|
employee:
|
|
$ref: '#/components/schemas/Employee'
|
|
|
|
ProblemDetails:
|
|
type: object
|
|
description: Format d'erreur standardisé RFC 7807 (Problem Details for HTTP APIs).
|
|
required:
|
|
- type
|
|
- title
|
|
- status
|
|
- detail
|
|
properties:
|
|
type:
|
|
type: string
|
|
format: uri
|
|
description: URI identifiant le type de problème.
|
|
example: 'http://127.0.0.1:8000/errors/not-found'
|
|
title:
|
|
type: string
|
|
description: Titre court lisible résumant le problème.
|
|
example: 'Resource Not Found'
|
|
status:
|
|
type: integer
|
|
description: Code statut HTTP.
|
|
example: 404
|
|
detail:
|
|
type: string
|
|
description: Explication humaine détaillée de l'erreur.
|
|
example: "Employee '9999999' not found."
|
|
instance:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
format: uri-reference
|
|
description: URI de l'endpoint ayant généré l'erreur.
|
|
example: '/api/v1/employees/9999999'
|
|
|
|
InvalidParamItem:
|
|
type: object
|
|
description: Détail d'une erreur de validation sur un paramètre.
|
|
required:
|
|
- name
|
|
- reason
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Nom du champ ou paramètre invalide.
|
|
example: employeeId
|
|
reason:
|
|
type: string
|
|
description: Raison du rejet de validation.
|
|
example: 'The employeeId pattern must be 7 or 8 digits.'
|
|
|
|
ValidationErrorProblemDetails:
|
|
type: object
|
|
description: Format RFC 7807 pour les erreurs de validation HTTP (422 Unprocessable Entity).
|
|
required:
|
|
- type
|
|
- title
|
|
- status
|
|
- detail
|
|
- invalidParams
|
|
properties:
|
|
type:
|
|
type: string
|
|
format: uri
|
|
description: URI identifiant l'erreur de validation.
|
|
example: 'http://127.0.0.1:8000/errors/validation-error'
|
|
title:
|
|
type: string
|
|
description: Titre de l'erreur.
|
|
example: 'Unprocessable Entity'
|
|
status:
|
|
type: integer
|
|
description: Code HTTP (422).
|
|
example: 422
|
|
detail:
|
|
type: string
|
|
description: Message d'ensemble.
|
|
example: 'The given data was invalid.'
|
|
invalidParams:
|
|
type: array
|
|
description: Liste des paramètres invalides et motifs.
|
|
items:
|
|
$ref: '#/components/schemas/InvalidParamItem'
|