{
  "openapi": "3.1.0",
  "info": {
    "title": "DILAIG Agent API",
    "version": "1.0.0",
    "description": "API permettant à un agent IA (Claude Code, GPT, ou tout client HTTP) de remplir un brouillon de questionnaire d'audit AI Act DILAIG pour le compte d'une organisation.\n\nPérimètre volontairement restreint : l'agent crée un brouillon, y enregistre des réponses validées et le marque « prêt pour revue ». Il ne peut ni soumettre l'audit, ni lancer l'analyse, ni générer de documents, ni lire un score ou un niveau de risque. Ces actions restent humaines, dans DILAIG, selon le plan de l'organisation.\n\nInstructions détaillées : /agent/SKILL.md. Serveur MCP équivalent : /api/v1/agent/mcp."
  },
  "servers": [
    {
      "url": "https://dilaig.com"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/api/v1/agent": {
      "get": {
        "operationId": "discover",
        "summary": "Découverte (sans authentification)",
        "security": [],
        "responses": {
          "200": {
            "description": "Version, URLs utiles et règles d'usage."
          }
        }
      }
    },
    "/api/v1/agent/me": {
      "get": {
        "operationId": "getContext",
        "summary": "Contexte de la clé : organisation, client géré, plan, capacités humaines",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Contexte",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Context"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/agent/questionnaire": {
      "get": {
        "operationId": "getQuestionnaire",
        "summary": "Questionnaire visible pour ce contexte, localisé, sans information de scoring",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "locale",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "fr",
                "en"
              ],
              "default": "fr"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Questionnaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Questionnaire"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/agent/audits": {
      "post": {
        "operationId": "createDraft",
        "summary": "Crée un brouillon vide rattaché à la clé",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "agent"
                ],
                "properties": {
                  "agent": {
                    "type": "string",
                    "maxLength": 60,
                    "description": "Nom de l'agent (ex. claude-code), affiché à l'humain lors de la revue."
                  },
                  "locale": {
                    "type": "string",
                    "enum": [
                      "fr",
                      "en"
                    ],
                    "default": "fr"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Brouillon créé",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Draft"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/agent/audits/{id}": {
      "get": {
        "operationId": "getDraft",
        "summary": "État du brouillon : réponses, justifications, complétude",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "locale",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "fr",
                "en"
              ],
              "default": "fr"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Brouillon",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Draft"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/agent/audits/{id}/answers": {
      "patch": {
        "operationId": "saveAnswers",
        "summary": "Enregistre des réponses (fusion partielle, validation tout ou rien)",
        "description": "Les clés absentes sont conservées ; `null` supprime une réponse. Une seule erreur de validation ⇒ rien n'est écrit et toutes les erreurs sont renvoyées. Refusé (409 handed_off) une fois le brouillon remis à l'humain par /ready. 409 conflict si le brouillon a été modifié en parallèle : relire puis renvoyer.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnswerPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Brouillon mis à jour",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Draft"
                }
              }
            }
          },
          "400": {
            "description": "Validation échouée",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationFailed"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "handed_off : brouillon remis à l'humain, plus modifiable ; conflict : modification concurrente, relire puis renvoyer",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/agent/audits/{id}/ready": {
      "post": {
        "operationId": "markReady",
        "summary": "Marque le brouillon prêt pour revue humaine (idempotent)",
        "description": "Exige que toutes les questions obligatoires visibles aient une réponse. Remet le brouillon à l'humain : l'agent ne peut plus le modifier ensuite (409 handed_off). Notifie par e-mail le créateur de la clé (une seule fois). Renvoie les prochaines étapes que l'agent doit relayer au client : relecture, soumission, puis génération des documents dans DILAIG selon le plan.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "locale": {
                    "type": "string",
                    "enum": [
                      "fr",
                      "en"
                    ],
                    "default": "fr"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Prêt pour revue",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadyResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Questions obligatoires manquantes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "const": "incomplete"
                    },
                    "details": {
                      "type": "object",
                      "properties": {
                        "completeness": {
                          "$ref": "#/components/schemas/Completeness"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Clé API dlg_live_… créée dans DILAIG → Paramètres → Accès agent IA."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Clé API absente, invalide ou révoquée",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Brouillon introuvable, déjà soumis, ou créé par une autre clé",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Corps de requête invalide",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "invalid_key",
              "rate_limited",
              "client_forbidden",
              "invalid_body",
              "not_found",
              "validation_failed",
              "incomplete",
              "handed_off",
              "conflict",
              "internal_error"
            ]
          },
          "details": {}
        }
      },
      "Context": {
        "type": "object",
        "properties": {
          "organisation": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              }
            }
          },
          "client": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "auditorMode": {
            "type": "string",
            "enum": [
              "self",
              "client"
            ]
          },
          "plan": {
            "type": "string",
            "enum": [
              "free",
              "pro",
              "enterprise",
              "npo"
            ]
          },
          "capabilities": {
            "type": "object",
            "description": "Informatif : ce que l'HUMAIN pourra faire dans DILAIG après la revue. Aucune de ces actions n'est accessible à l'agent.",
            "properties": {
              "richQuestions": {
                "type": "boolean"
              },
              "humanCanRunAiNarrative": {
                "type": "boolean"
              },
              "humanCanGenerateDocuments": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/DocType"
                }
              }
            }
          },
          "agentCan": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "agentCannot": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "DocType": {
        "type": "string",
        "enum": [
          "fria",
          "declaration_conformite",
          "notice_transparence",
          "documentation_technique",
          "gouvernance_donnees",
          "plan_surveillance"
        ]
      },
      "Questionnaire": {
        "type": "object",
        "properties": {
          "version": {
            "const": "1"
          },
          "locale": {
            "type": "string",
            "enum": [
              "fr",
              "en"
            ]
          },
          "answerFormat": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "sections": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "questions": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Question"
                  }
                }
              }
            }
          }
        }
      },
      "Question": {
        "type": "object",
        "required": [
          "id",
          "type",
          "required",
          "allowOther",
          "question"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "textarea",
              "radio",
              "select",
              "multi_select"
            ]
          },
          "required": {
            "type": "boolean"
          },
          "allowOther": {
            "type": "boolean",
            "description": "true ⇒ { value: \"__other__\", freeText } accepté"
          },
          "question": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "placeholder": {
            "type": "string"
          },
          "options": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "value": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "AnswerValue": {
        "oneOf": [
          {
            "type": "string"
          },
          {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "$ref": "#/components/schemas/OtherValue"
                }
              ]
            }
          },
          {
            "$ref": "#/components/schemas/OtherValue"
          },
          {
            "type": "null",
            "description": "Supprime la réponse"
          }
        ]
      },
      "OtherValue": {
        "type": "object",
        "required": [
          "value",
          "freeText"
        ],
        "properties": {
          "value": {
            "const": "__other__"
          },
          "freeText": {
            "type": "string",
            "maxLength": 2000
          }
        }
      },
      "Justification": {
        "type": "object",
        "required": [
          "note"
        ],
        "properties": {
          "note": {
            "type": "string",
            "maxLength": 500
          },
          "source": {
            "type": "string",
            "maxLength": 200
          }
        }
      },
      "AnswerPatch": {
        "type": "object",
        "properties": {
          "answers": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/AnswerValue"
            }
          },
          "justifications": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Justification"
            }
          },
          "locale": {
            "type": "string",
            "enum": [
              "fr",
              "en"
            ],
            "default": "fr"
          }
        }
      },
      "Completeness": {
        "type": "object",
        "properties": {
          "requiredTotal": {
            "type": "integer"
          },
          "requiredAnswered": {
            "type": "integer"
          },
          "missing": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "sectionId": {
                  "type": "string"
                },
                "questionIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "Draft": {
        "type": "object",
        "properties": {
          "auditId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "const": "draft"
          },
          "agent": {
            "type": "string"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "readyForReview": {
            "type": "boolean"
          },
          "readyAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "answers": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/AnswerValue"
            }
          },
          "justifications": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Justification"
            }
          },
          "completeness": {
            "$ref": "#/components/schemas/Completeness"
          },
          "reviewUrl": {
            "type": "string",
            "format": "uri",
            "description": "Lien de relecture à transmettre à l'humain."
          }
        }
      },
      "ValidationError": {
        "type": "object",
        "properties": {
          "questionId": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "unknown_question",
              "invalid_option",
              "other_not_allowed",
              "other_requires_text",
              "invalid_text",
              "filtered_text",
              "reserved_key",
              "invalid_justification"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ValidationFailed": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "const": "validation_failed"
          },
          "details": {
            "type": "object",
            "properties": {
              "errors": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          }
        }
      },
      "NextSteps": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "string"
          },
          "humanActions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "agentMustNot": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "documentsAvailableToHuman": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocType"
            }
          }
        }
      },
      "ReadyResult": {
        "type": "object",
        "properties": {
          "readyForReview": {
            "const": true
          },
          "reviewUrl": {
            "type": "string",
            "format": "uri"
          },
          "humanNotified": {
            "type": "boolean"
          },
          "nextSteps": {
            "$ref": "#/components/schemas/NextSteps"
          },
          "draft": {
            "$ref": "#/components/schemas/Draft"
          }
        }
      }
    }
  }
}
