openapi: 3.1.0 info: title: Arcadia API description: | Arcadia API in order to abstract corporate metamodel to a proper and stable implemented API. ### ⏱️ Gestion Temporelle & Fuseaux Horaires (RFC 3339 / UTC) Tous les horodatages transmis en entrée (ex: paramètre de filtrage `since`) ou restitués dans les réponses JSON (ex: `created_at`, `updated_at`, `timestamp`) sont strictement normalisés au format standard **RFC 3339 / ISO-8601** en temps universel coordonné avec le suffixe `Z` (ex: `2026-08-21T14:30:00Z`). 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: [] HmacNonce: [] HmacSignature: [] tags: - name: System description: Points d'entrée système et sondes de disponibilité. - name: Employees description: Gestion et consultation du référentiel RH des employés. - name: Brands description: Consultation et référentiel des marques. - name: IncoSheets description: Consultation et recherche des fiches produits INCO. - name: IncoComposition description: Consultation des compositions nutritionnelles et détaillées des produits INCO. paths: /health: get: tags: - System summary: Sonde de santé et de disponibilité du système description: | Vérifie l'état de fonctionnement et la connectivité de l'ensemble des dépendances d'infrastructure (base de données par défaut, base de données Arcadia, cache et serveur SMTP). operationId: checkHealth security: [] responses: "200": description: Système opérationnel (tous les composants sont fonctionnels). content: application/json: schema: $ref: "#/components/schemas/HealthCheckResponse" "503": description: Système dégradé ou indisponible (au moins un composant est en échec). content: application/json: schema: $ref: "#/components/schemas/HealthCheckResponse" /health/oracle: get: tags: - System summary: Sonde dédiée à la connectivité Oracle description: | Vérifie exclusivement la connectivité à la base Oracle Arcadia. Cette sonde est destinée au monitoring externe (ex: UptimeRobot) et ne teste ni cache ni SMTP. operationId: checkOracleHealth security: [] responses: "200": description: Connectivité Oracle opérationnelle. content: application/json: schema: $ref: "#/components/schemas/OracleHealthCheckResponse" "503": description: Connectivité Oracle indisponible. content: application/json: schema: $ref: "#/components/schemas/OracleHealthCheckResponse" /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`), codes sites (`siteIds`), 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/SiteIds" - $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" /inco-sheets: get: tags: - IncoSheets summary: Liste paginée des fiches produits INCO (format court) description: | Retourne la liste paginée des fiches produits INCO au format court (IncoShort). Prend en charge le filtrage par marques (`brands`), la date de modification (`since`), ainsi que le tri et la pagination. operationId: listIncoSheets parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/PageSize" - $ref: "#/components/parameters/Offset" - $ref: "#/components/parameters/Limit" - $ref: "#/components/parameters/Since" - $ref: "#/components/parameters/Brands" - $ref: "#/components/parameters/IncoSortBy" - $ref: "#/components/parameters/SortDirection" responses: "200": description: Page de fiches INCO récupérée avec succès. content: application/json: schema: $ref: "#/components/schemas/IncoListResponse" "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" /brands: get: tags: - Brands summary: Liste de toutes les marques description: | Retourne la liste de toutes les marques connues du système Arcadia. Les marques non encore enregistrées localement sont automatiquement initialisées et pourvues d'un code public unique (trigramme + 2 chiffres). operationId: listBrands parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/PageSize" - $ref: "#/components/parameters/Offset" - $ref: "#/components/parameters/Limit" responses: "200": description: Liste des marques récupérée avec succès. content: application/json: schema: $ref: "#/components/schemas/BrandListResponse" "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" /brands/{brandCode}: get: tags: - Brands summary: Détail d'une marque par son code public description: | Retourne la fiche d'une marque spécifiée par son code public (ex: LGL01). operationId: getBrand parameters: - $ref: "#/components/parameters/BrandCodePath" responses: "200": description: Fiche marque trouvée. content: application/json: schema: $ref: "#/components/schemas/BrandItemResponse" "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" /inco-sheets/search: get: tags: - IncoSheets summary: Recherche de fiches INCO par identifiant (format court) description: | Recherche des fiches INCO dont l'ID correspond à un motif (`incoIdLike`) au format court (IncoShort). operationId: searchIncoSheets parameters: - $ref: "#/components/parameters/IncoIdLike" - $ref: "#/components/parameters/Brands" responses: "200": description: Résultats de recherche INCO. content: application/json: schema: $ref: "#/components/schemas/IncoListResponse" "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" /inco-sheets/{incoId}: get: tags: - IncoSheets summary: Détail d'une fiche produit INCO par son identifiant description: | Retourne la fiche produit INCO détaillée correspondant à l'identifiant spécifié. operationId: getIncoSheet parameters: - $ref: "#/components/parameters/IncoIdPath" responses: "200": description: Fiche produit INCO trouvée. content: application/json: schema: $ref: "#/components/schemas/IncoItemResponse" "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" /inco-sheets/{incoId}/composition: get: tags: - IncoComposition summary: Composition d'un produit par l'identifiant de sa fiche INCO description: | Retourne le détail de la composition nutritionnelle et des ingrédients liés à une fiche INCO. operationId: getIncoCompositionByIncoId parameters: - $ref: "#/components/parameters/IncoIdPath" responses: "200": description: Composition INCO trouvée. content: application/json: schema: $ref: "#/components/schemas/IncoCompoItemResponse" "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 RFC3339 (tolérance anti-replay +/-5 minutes). HmacNonce: type: apiKey in: header name: X-Nonce description: Identifiant unique de requête au format UUID (v4 ou v7) pour protection anti-replay. HmacSignature: type: apiKey in: header name: X-Signature description: Signature HMAC-SHA256 calculée avec la clé secrète partagée. parameters: BrandCodePath: name: brandCode in: path required: true description: Code public unique trigramme + 2 chiffres de la marque (ex. LGL01). schema: type: string pattern: '^[A-Z]{3}\d{2}$' example: "LGL01" 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). Les valeurs hors bornes sont silencieusement corrigées par l'API. schema: type: integer default: 1 example: 1 PageSize: name: pageSize in: query required: false description: Nombre d'éléments par page (max 10000). Les valeurs hors bornes sont silencieusement corrigées par l'API. schema: type: integer 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. Les valeurs négatives sont silencieusement corrigées à 0. schema: type: integer minimum: 0 example: 0 Limit: name: limit in: query required: false description: Nombre maximal d'enregistrements pour la pagination par offset. Les valeurs hors bornes sont silencieusement corrigées par l'API. schema: type: integer 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" SiteIds: name: siteIds in: query required: false description: "Filtrer par un ou plusieurs codes site (ex: siteIds[]=LDCSER&siteIds[]=SLELA)." style: form explode: true schema: type: array minItems: 1 items: type: string pattern: "^[A-Z]{2,}$" example: ["LDCSER", "SLELA"] 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 IncoIdPath: name: incoId in: path required: true description: Identifiant numérique unique de la fiche INCO. schema: type: string pattern: '^\d{1,}$' example: "12345" IncoIdLike: name: incoIdLike in: query required: true description: Motif de recherche d'ID (SQL LIKE). schema: type: string example: "123%" Brands: name: brands in: query required: false description: Filtrer par un ou plusieurs codes marque. style: form explode: true schema: type: array minItems: 1 items: type: string pattern: '^[A-Z]{3}\d{2}$' example: ["LGL01", "MCQ01"] IncoSortBy: name: sortBy in: query required: false description: Champ d'ordonnancement des fiches INCO. schema: type: string enum: - incoSheetId - createdAt - updatedAt default: incoSheetId example: incoSheetId 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: HealthCheckResponse: type: object description: Résultat de la sonde d'état et de disponibilité des services. required: - status - timestamp - checks properties: status: type: string enum: - healthy - unhealthy description: État de santé global du système. example: "healthy" timestamp: type: string format: date-time description: Horodatage de la vérification au format RFC 3339 UTC. example: "2026-08-21T14:30:00Z" checks: type: object description: Détails des vérifications par composant. additionalProperties: type: object required: - status properties: status: type: string enum: - up - down description: État du composant. example: "up" connection: type: string description: Nom de la connexion de base de données vérifiée. example: "sqlite" store: type: string description: Nom du magasin de cache vérifié. example: "database" transport: type: string description: Type de transport mail vérifié. example: "smtp" message: type: - string - "null" description: Message d'erreur éventuel en cas d'échec. OracleHealthCheckResponse: type: object description: Résultat de la sonde de connectivité Oracle. required: - status - timestamp - oracle properties: status: type: string enum: - healthy - unhealthy description: État de santé global de la connectivité Oracle. example: "healthy" timestamp: type: string format: date-time description: Horodatage de la vérification au format RFC 3339 UTC. example: "2026-08-21T14:30:00Z" oracle: type: object required: - status - connection properties: status: type: string enum: - up - down description: État de la connectivité Oracle. example: "up" connection: type: string description: Nom de la connexion Oracle vérifiée. example: "arcadia" Brand: type: object description: Représentation canonique d'une marque dans Arcadia API. required: - code - name - arcadiaId - createdAt properties: code: type: string pattern: '^[A-Z]{3}\d{2}$' description: Code public unique trigramme + 2 chiffres. example: "LGL01" name: type: string description: Nom / libellé de la marque. example: "Le Gaulois" arcadiaId: type: string pattern: '^[1-9]\d{0,}$' description: Identifiant numérique amont Arcadia. example: "1" createdAt: type: string format: date-time description: Date et heure de création (ISO 8601). example: "2024-01-15T08:00:00Z" BrandListResponse: type: object description: Enveloppe de réponse pour la liste paginée des marques. required: - brands - pagination properties: brands: type: array description: Collection des marques de la page. items: $ref: "#/components/schemas/Brand" pagination: $ref: "#/components/schemas/PaginationMeta" BrandItemResponse: type: object description: Enveloppe de réponse pour le détail d'une marque. required: - brand properties: brand: $ref: "#/components/schemas/Brand" Employee: type: object description: Représentation canonique d'un employé dans le métamodèle Arcadia. required: - matricule - firstName - lastName - establishment - site - service - startDate properties: matricule: type: string pattern: '^\d{7,8}$' description: Matricule public unique de l'employé (SIRH). 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" IncoBrand: type: object description: Marque associée à la fiche produit INCO. required: [code, label] properties: code: type: string pattern: '^[A-Z]{3}\d{2}$' example: "LGL01" label: type: string example: "Le Gaulois" Inco: type: object description: Fiche produit INCO complète. required: - incoId - name - label - description - allegations - sellArguments - preparationAdvices - ingredients - allergens - brand - isSeasonal - additives properties: incoId: type: string pattern: '^\d{1,}$' example: "12345" name: type: string example: Poulet Rôti 1kg label: type: string example: Poulet Rôti Classe A description: type: string example: Poulet prêt à cuire élevé en France allegations: $ref: "#/components/schemas/IncoAllegations" sellArguments: type: string preparationAdvices: type: string tips: type: - string - "null" example: Servir chaud sellFamilly: type: - string - "null" example: Volaille ingredients: $ref: "#/components/schemas/IncoIngredients" portions: oneOf: - $ref: "#/components/schemas/IncoPortionAmount" - type: "null" allergens: type: array items: type: string example: ["Gluten", "Lait"] brand: $ref: "#/components/schemas/IncoBrand" isSeasonal: type: boolean weight: oneOf: - $ref: "#/components/schemas/IncoWeight" - type: "null" nutriscore: oneOf: - $ref: "#/components/schemas/IncoNutriscore" - type: "null" storageCondition: oneOf: - $ref: "#/components/schemas/IncoStorageCondition" - type: "null" additives: type: array items: $ref: "#/components/schemas/IncoAdditive" incoCompoId: type: - string - "null" pattern: '^\d{1,}$' createdAt: type: - string - "null" format: date-time updatedAt: type: - string - "null" format: date-time IncoWeight: type: object description: Poids du produit en grammes. required: - netWeight - grossWeight - theoreticalAverage properties: netWeight: type: integer description: Poids net UVC (g). example: 100 grossWeight: type: integer description: Poids brut UVC (g). example: 120 theoreticalAverage: type: integer description: Moyenne théorique du poids (g). example: 110 IncoAllegations: type: object description: Allégations associées au produit (santé, nutrition, etc.). required: - allegations - health - nutrition - other properties: allegations: type: array items: type: string example: ["Volaille française"] health: type: array items: type: string example: ["Riche en protéines"] nutrition: type: array items: type: string example: ["Faible en matière grasse"] other: type: array items: type: string example: [] IncoIngredients: type: object description: Liste structurée des ingrédients groupés par section. additionalProperties: type: array items: type: string example: Ingrédients: ["Viande de dinde (66%)", "Gras de dinde", "Persil", "Sel"] Traces: ["Aucun allergène"] IncoPortionAmount: type: object description: Informations de quantité par portion. required: - lowPart - highPart - approximative properties: lowPart: type: integer description: Valeur minimale ou exacte (en centièmes ou grammes). example: 150 highPart: type: integer description: Valeur maximale. example: 150 approximative: type: boolean description: Indique si la portion est approximative. example: false IncoNutriscore: type: object description: Note Nutri-Score affichée sur l'emballage. required: - grade properties: grade: type: string enum: [A, B, C, D, E] example: D IncoStorageCondition: type: object description: Conditions de conservation du produit. required: - instructions properties: instructions: type: string example: A conserver entre 0°C et +4°C IncoAdditive: type: object description: Additif alimentaire (code E-number et libellé). required: - code - label properties: code: type: string example: E300 label: type: string example: Acide ascorbique IncoShort: type: object description: Fiche produit INCO projetée en format court. required: - incoId - name - label - description properties: incoId: type: string pattern: '^\d{1,}$' example: "12345" name: type: string example: Poulet Rôti 1kg label: type: string example: Poulet Rôti Classe A description: type: string example: Poulet prêt à cuire élevé en France createdAt: type: - string - "null" format: date-time updatedAt: type: - string - "null" format: date-time IncoCompo: type: object description: Composition nutritionnelle détaillée d'une fiche INCO. required: - incoCompoId - incoId - identification - energy - referenceMacronutrients - portionMacronutrients - freshProduceAndNuts - referenceIntakes - nutriScore - nutriScorePoints - minerals - vitamins - carbohydratesDetail - fattyAcids - aminoAcids - specialCompounds properties: incoCompoId: type: string pattern: '^\d{1,}$' example: "67890" incoId: type: string pattern: '^\d{1,}$' example: "12345" identification: $ref: "#/components/schemas/IncoCompositionIdentification" energy: $ref: "#/components/schemas/IncoCompoEnergy" referenceMacronutrients: $ref: "#/components/schemas/IncoCompoReferenceMacronutrients" portionMacronutrients: $ref: "#/components/schemas/IncoCompoPortionMacronutrients" freshProduceAndNuts: $ref: "#/components/schemas/IncoCompoFreshProduceAndNuts" referenceIntakes: $ref: "#/components/schemas/IncoCompoReferenceIntakes" nutriScore: $ref: "#/components/schemas/IncoCompoNutriScore" nutriScorePoints: $ref: "#/components/schemas/IncoCompoNutriScorePoints" minerals: $ref: "#/components/schemas/IncoCompoMinerals" vitamins: $ref: "#/components/schemas/IncoCompoVitamins" carbohydratesDetail: $ref: "#/components/schemas/IncoCompoCarbohydratesDetail" fattyAcids: $ref: "#/components/schemas/IncoCompoFattyAcids" aminoAcids: $ref: "#/components/schemas/IncoCompoAminoAcids" specialCompounds: $ref: "#/components/schemas/IncoCompoSpecialCompounds" NutrientValue: type: object description: Valeur d'un nutriment avec quantité et précision facultative. properties: amount: type: string example: "12.5" precision: type: - string - "null" example: "=" PercentageValue: type: object description: Valeur sous forme de pourcentage (0-100%). properties: value: type: string example: "45.5" EnergyValues: type: object description: Quantités d'énergie (portion ou référence). properties: size: type: string example: "100" energyKj: type: string example: "850" energyKcal: type: string example: "203" FruitAndNutAmount: type: object description: Quantités de fruits, noix et FNL. properties: fruits: type: string example: "0" nuts: type: string example: "0" freshFnl: type: string example: "0" IncoCompositionIdentification: type: object description: Informations d'identification de la composition INCO. properties: name: type: string example: Poulet Rôti 1kg number: type: string example: "12345" source: type: string example: LDC IncoCompoEnergy: type: object description: Valeurs énergétiques. properties: reference: $ref: "#/components/schemas/EnergyValues" portion: $ref: "#/components/schemas/EnergyValues" IncoCompoReferenceMacronutrients: type: object description: Macronutriments de référence pour 100g/ml. properties: fat: $ref: "#/components/schemas/NutrientValue" saturatedFat: $ref: "#/components/schemas/NutrientValue" carbohydrates: $ref: "#/components/schemas/NutrientValue" sugars: $ref: "#/components/schemas/NutrientValue" fiber: $ref: "#/components/schemas/NutrientValue" protein: $ref: "#/components/schemas/NutrientValue" salt: $ref: "#/components/schemas/NutrientValue" sodium: type: string example: "480" IncoCompoPortionMacronutrients: type: object description: Macronutriments par portion. properties: fat: $ref: "#/components/schemas/NutrientValue" saturatedFat: $ref: "#/components/schemas/NutrientValue" carbohydrates: $ref: "#/components/schemas/NutrientValue" sugars: $ref: "#/components/schemas/NutrientValue" fiber: $ref: "#/components/schemas/NutrientValue" protein: $ref: "#/components/schemas/NutrientValue" salt: $ref: "#/components/schemas/NutrientValue" sodium: type: string example: "720" IncoCompoFreshProduceAndNuts: type: object description: Teneur en fruits, légumes et noix (FNL). properties: reference: $ref: "#/components/schemas/FruitAndNutAmount" portion: $ref: "#/components/schemas/FruitAndNutAmount" freshFnlPercentage: $ref: "#/components/schemas/PercentageValue" fruitsPercentage: $ref: "#/components/schemas/PercentageValue" IncoCompoReferenceIntakes: type: object description: Pourcentages des apports de référence (AR / ARIC). properties: energyE14: $ref: "#/components/schemas/PercentageValue" energyKj: $ref: "#/components/schemas/PercentageValue" fat: $ref: "#/components/schemas/PercentageValue" saturatedFat: $ref: "#/components/schemas/PercentageValue" carbohydrates: $ref: "#/components/schemas/PercentageValue" sugars: $ref: "#/components/schemas/PercentageValue" protein: $ref: "#/components/schemas/PercentageValue" salt: $ref: "#/components/schemas/PercentageValue" portionAmount: type: string example: "150" proteinToLipidRatio: type: - string - "null" example: "1.76" IncoCompoNutriScore: type: object description: Détail des composantes et classement Nutri-Score. properties: negativeComponent: type: string example: "3" negativeComponent2022: type: string example: "3" positiveComponent: type: string example: "5" positiveComponent2022: type: string example: "5" score: type: string example: "-2" score2022: type: string example: "-2" grade: type: string example: A grade2022: type: string example: A isGradeAArticle: type: string example: "1" isRedMeat: type: string example: "0" IncoCompoNutriScorePoints: type: object description: Points élémentaires du calcul Nutri-Score. properties: energyPoints: type: string example: "2" saturatedFatPoints: type: string example: "3" sugarsPoints: type: string example: "0" saltPoints: type: string example: "2" fiberPoints: type: string example: "0" proteinPoints: type: string example: "5" freshFnlPoints: type: string example: "0" IncoCompoMinerals: type: object description: Teneur détaillée en minéraux et oligo-éléments. properties: calcium: type: string example: "12.0" magnesium: type: string example: "24.0" potassium: type: string example: "350.0" phosphorus: type: string example: "210.0" chloride: type: string example: "0.0" iron: type: string example: "1.1" zinc: type: string example: "1.8" copper: type: string example: "0.08" manganese: type: string example: "0.02" selenium: type: string example: "18.5" iodine: type: string example: "4.2" chromium: type: string example: "0.0" molybdenum: type: string example: "0.0" sulfur: type: string example: "0.0" nitrates: type: string example: "0.0" IncoCompoVitamins: type: object description: Teneur détaillée en vitamines. properties: vitaminA: type: string example: "30.0" vitaminB6: type: string example: "0.4" vitaminB12: type: string example: "0.3" vitaminC: type: string example: "0.0" vitaminD: type: string example: "0.1" vitaminE: type: string example: "0.3" vitaminK: type: string example: "1.2" cholecalciferol: type: string example: "0.1" niacin: type: string example: "8.5" IncoCompoCarbohydratesDetail: type: object description: Composition détaillée des glucides et fibres. properties: starch: type: string example: "0.0" maltodextrin: type: string example: "0.0" sucrose: type: string example: "0.2" glucose: type: string example: "0.0" lactose: type: string example: "0.0" maltose: type: string example: "0.0" galactose: type: string example: "0.0" carbohydrateHydrates: type: string example: "0.5" boundFructose: type: string example: "0.0" freeFructose: type: string example: "0.0" oligosaccharides: type: string example: "0.0" polyols: type: string example: "0.0" solubleFiber: type: string example: "0.0" inositol: type: string example: "0.0" IncoCompoFattyAcids: type: object description: Teneur détaillée en acides gras (AGS, AGMI, AGPI). properties: nutFd: type: string description: Lipides totaux (g/100g). example: "12.5" nutChol: type: string description: Cholestérol (mg/100g). example: "75.0" nutAgt: type: string description: Acides gras trans (g/100g). example: "0.1" nutFformiq: type: string description: Acide formique (C1:0). example: "0.0" nutFacetiq: type: string description: Acide acétique (C2:0). example: "0.0" nutFpropioniq: type: string description: Acide propionique (C3:0). example: "0.0" nutFbutyriq: type: string description: Acide butyrique (C4:0). example: "0.0" nutFvaleriq: type: string description: Acide valérique (C5:0). example: "0.0" nutFcaproiq: type: string description: Acide caproïque (C6:0). example: "0.0" nutFenatiq: type: string description: Acide énanthique (C7:0). example: "0.0" nutFcapryliq: type: string description: Acide caprylique (C8:0). example: "0.0" nutFpelargoniq: type: string description: Acide pélargonique (C9:0). example: "0.0" nutFcapriq: type: string description: Acide caprique (C10:0). example: "0.0" nutFundecyliq: type: string description: Acide undécylique (C11:0). example: "0.0" nutFlauriq: type: string description: Acide laurique (C12:0). example: "0.0" nutFtridecyliq: type: string description: Acide tridécylique (C13:0). example: "0.0" nutFmyristiq: type: string description: Acide myristique (C14:0). example: "0.1" nutFpentadecyliq: type: string description: Acide pentadécylique (C15:0). example: "0.0" nutF16d0: type: string description: Acide palmitique (C16:0). example: "2.5" nutFmargariq: type: string description: Acide margarique (C17:0). example: "0.0" nutFsteariq: type: string description: Acide stéarique (C18:0). example: "0.6" nutFarachidiq: type: string description: Acide arachidique (C20:0). example: "0.0" nutFheneicosyliq: type: string description: Acide héneicosylique (C21:0). example: "0.0" nutFbeheniq: type: string description: Acide béhénique (C22:0). example: "0.0" nutFtricosiliq: type: string description: Acide tétracosanoïque (C23:0). example: "0.0" nutFlignoceriq: type: string description: Acide lignocérique (C24:0). example: "0.0" nutFcarboceriq: type: string description: Acide carbocérique (C26:0). example: "0.0" nutFcerotiq: type: string description: Acide cérotique (C26:0 alt.). example: "0.0" nutFceroplastiq: type: string description: Acide céroplastique. example: "0.0" nutFmontaniq: type: string description: Acide montanique (C28:0). example: "0.0" nutFnonacosyliq: type: string description: Acide nonacosylique (C29:0). example: "0.0" nutFmelissiq: type: string description: Acide mélissique (C30:0). example: "0.0" nutFlaceroiq: type: string description: Acide lacéroïque (C32:0). example: "0.0" nutFhentriacontyliq: type: string description: Acide hentriacontylique (C31:0). example: "0.0" nutFhextriacontyliq: type: string description: Acide hexatriacontylique (C36:0). example: "0.0" nutFheptatriacontyliq: type: string description: Acide heptatriacontylique (C37:0). example: "0.0" nutFoctatriacontyliq: type: string description: Acide octariacontylique (C38:0). example: "0.0" nutFnonadylique: type: string description: Acide nonadylique. example: "0.0" nutFpsylliq: type: string description: Acide psyllique. example: "0.0" nutFpalm: type: string description: Acide palmitoléique (C16:1). example: "0.8" nutFoleiq: type: string description: Acide oléique (C18:1 ω-9). example: "4.5" nutF18d: type: string description: C18 insaturé (générique). example: "0.0" nutF19d: type: string description: C19 insaturé. example: "0.0" nutF11eico: type: string description: Acide gondoïque (C20:1). example: "0.1" nutFgeddiq: type: string description: Acide geddique (C20:1 alt.). example: "0.0" nutFeruciq: type: string description: Acide érucique (C22:1). example: "0.0" nutFnervoniq: type: string description: Acide nervonique (C24:1). example: "0.0" nutFhyeniq: type: string description: Acide hyénique. example: "0.0" nutFamscis: type: string description: AG monoinsaturés cis (total). example: "5.4" nutF18d2cn6: type: string description: Acide linoléique (C18:2 ω-6). example: "2.1" nutF18d3n3: type: string description: Acide α-linolénique (C18:3 ω-3). example: "0.3" nutF20d4: type: string description: Acide arachidonique (C20:4). example: "0.1" nutF20d5n3: type: string description: EPA (C20:5 ω-3). example: "0.0" nutF22d6n3: type: string description: DHA (C22:6 ω-3). example: "0.0" nutFapun3: type: string description: AGPI ω-3 (total). example: "0.3" nutFapun6: type: string description: AGPI ω-6 (total). example: "2.2" nutFapun9: type: string description: AGPI ω-9 (total). example: "0.0" nutFapucis: type: string description: AGPI cis (total). example: "2.5" nutFapulc: type: string description: AGPI longue chaîne (total). example: "0.1" IncoCompoAminoAcids: type: object description: Teneur en acides aminés et protéines de lait. properties: essentialAminoAcids: type: string description: Acides aminés essentiels (total g/100g). example: "8.5" caseins: type: string description: Caséines (g/100g). example: "0.0" wheyProtein: type: string description: Protéines de lactosérum (g/100g). example: "0.0" IncoCompoSpecialCompounds: type: object description: Composés spéciaux (Choline, Carnitine, Taurine, Nucléotides). properties: choline: type: string description: Choline (mg/100g). example: "65.0" carnitine: type: string description: Carnitine (mg/100g). example: "8.2" taurine: type: string description: Taurine (mg/100g). example: "12.0" nucleotides: type: string description: Nucléotides (mg/100g). example: "0.0" IncoListResponse: type: object description: Enveloppe de réponse pour la liste des fiches INCO (format court). required: - incoSheets - pagination properties: incoSheets: type: array description: Collection des fiches INCO au format court. items: $ref: "#/components/schemas/IncoShort" pagination: $ref: "#/components/schemas/PaginationMeta" IncoItemResponse: type: object description: Enveloppe de réponse pour le détail d'une fiche INCO. required: - incoSheet properties: incoSheet: $ref: "#/components/schemas/Inco" IncoCompoItemResponse: type: object description: Enveloppe de réponse pour le détail d'une composition INCO. required: - composition properties: composition: $ref: "#/components/schemas/IncoCompo" 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"