{
  "openapi": "3.1.0",
  "info": {
    "title": "Flownco 간편분석 API",
    "version": "1.0.0",
    "description": "이메일 승인형 서버 간 API. 키 원문은 발급 메일로만 전달합니다."
  },
  "servers": [
    {
      "url": "https://www.flownco.co.kr/api/quick-analysis/v1"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "File": {
        "type": "object",
        "required": [
          "id",
          "name",
          "expiresAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^qfile_[a-f0-9]{24}$"
          },
          "name": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Analysis": {
        "type": "object",
        "required": [
          "id",
          "status",
          "reportType",
          "reportReady"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^analysis_[a-f0-9]{24}$"
          },
          "status": {
            "type": "string"
          },
          "reportType": {
            "type": "string",
            "enum": [
              "simple",
              "detailed"
            ]
          },
          "reportReady": {
            "type": "boolean"
          },
          "elapsedSeconds": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0
          },
          "progress": {
            "type": [
              "object",
              "null"
            ]
          },
          "statusUrl": {
            "type": "string"
          },
          "downloadUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "errorCode": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "ok",
          "errorCode",
          "message"
        ],
        "properties": {
          "ok": {
            "const": false
          },
          "errorCode": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "paths": {
    "/status": {
      "get": {
        "summary": "발급 서비스 준비 상태와 이용 한도",
        "security": [],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          }
        }
      }
    },
    "/key-requests": {
      "post": {
        "summary": "이메일로 API 키 요청",
        "security": [],
        "responses": {
          "202": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          },
          "503": {
            "description": "발급 메일 준비 안 됨·발송 실패"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 254
                  },
                  "consent": {
                    "type": "boolean",
                    "const": true
                  }
                },
                "required": [
                  "email",
                  "consent"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/key": {
      "get": {
        "summary": "현재 키 정보 조회",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          },
          "401": {
            "description": "키 없음·만료·폐기"
          },
          "404": {
            "description": "대상 없음·권한 없음"
          }
        }
      },
      "delete": {
        "summary": "현재 키 폐기",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          },
          "401": {
            "description": "키 없음·만료·폐기"
          },
          "404": {
            "description": "대상 없음·권한 없음"
          }
        }
      }
    },
    "/files": {
      "post": {
        "summary": "원본 시험지 파일 전송",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "전송된 파일",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "file"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "file": {
                      "$ref": "#/components/schemas/File"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          },
          "401": {
            "description": "키 없음·만료·폐기"
          },
          "404": {
            "description": "대상 없음·권한 없음"
          },
          "413": {
            "description": "40MB 초과"
          }
        },
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 150
            },
            "example": "exam.pdf"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/pdf": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/png": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/jpeg": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "application/octet-stream": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        }
      }
    },
    "/analyses": {
      "post": {
        "summary": "간편분석 비동기 접수",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "분석 작업",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "analysis"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "analysis": {
                      "$ref": "#/components/schemas/Analysis"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          },
          "401": {
            "description": "키 없음·만료·폐기"
          },
          "404": {
            "description": "대상 없음·권한 없음"
          },
          "200": {
            "description": "중복 요청의 기존 작업",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "analysis"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "analysis": {
                      "$ref": "#/components/schemas/Analysis"
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fileId": {
                    "type": "string",
                    "pattern": "^qfile_[a-f0-9]{24}$"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[!-~]{1,100}$"
                  },
                  "reportType": {
                    "type": "string",
                    "enum": [
                      "simple",
                      "detailed"
                    ],
                    "default": "simple"
                  },
                  "explanationLevel": {
                    "type": "string",
                    "enum": [
                      "neutral",
                      "elementary_lower",
                      "elementary_upper",
                      "middle",
                      "high"
                    ],
                    "default": "neutral"
                  }
                },
                "required": [
                  "fileId",
                  "idempotencyKey"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/analyses/{id}": {
      "get": {
        "summary": "자신의 작업 상태·진행·시간 조회",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "분석 작업",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "analysis"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "analysis": {
                      "$ref": "#/components/schemas/Analysis"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          },
          "401": {
            "description": "키 없음·만료·폐기"
          },
          "404": {
            "description": "대상 없음·권한 없음"
          }
        }
      },
      "delete": {
        "summary": "해당 업로드 파일과 그 파생 분석·보고서 삭제",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "성공",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          },
          "401": {
            "description": "키 없음·만료·폐기"
          },
          "404": {
            "description": "대상 없음·권한 없음"
          }
        },
        "description": "같은 이메일·같은 업로드 파일의 다른 분석과 보고서도 함께 삭제됩니다."
      },
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^analysis_[a-f0-9]{24}$"
          },
          "example": "analysis_000000000000000000000000"
        }
      ]
    },
    "/analyses/{id}/report": {
      "get": {
        "summary": "자신의 준비된 첨삭 PDF 다운로드",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "첨삭 PDF",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "입력 오류"
          },
          "429": {
            "description": "한도 초과"
          },
          "401": {
            "description": "키 없음·만료·폐기"
          },
          "404": {
            "description": "대상 없음·권한 없음"
          },
          "409": {
            "description": "현재 PDF가 아직 준비되지 않음"
          }
        }
      },
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^analysis_[a-f0-9]{24}$"
          },
          "example": "analysis_000000000000000000000000"
        }
      ]
    }
  }
}
