{"openapi":"3.0.3","info":{"title":"QuestBoard API","version":"0.1.0","description":"Documentacao OpenAPI para as rotas existentes do Next.js e contratos planejados para perfil, dashboard e progresso do usuario."},"servers":[{"url":"http://localhost:3002","description":"Aplicacao Next.js"},{"url":"https://backend.studentpractices.com","description":"Backend/API externa configurada no frontend"}],"tags":[{"name":"System","description":"Documentacao e saude da API"},{"name":"Checkout","description":"Fluxo de pagamento Mercado Pago"},{"name":"Images","description":"Upload e listagem de imagens do blog"},{"name":"User","description":"Perfil e preferencias do usuario"},{"name":"Dashboard","description":"Metricas, historico e progresso do usuario"},{"name":"Questions","description":"Contratos futuros para respostas de questoes"}],"paths":{"/api/openapi.json":{"get":{"tags":["System"],"summary":"Retorna a documentacao OpenAPI","responses":{"200":{"description":"Documento OpenAPI","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/checkout":{"post":{"tags":["Checkout"],"summary":"Cria uma preferencia de pagamento no Mercado Pago","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutPreferenceRequest"}}}},"responses":{"200":{"description":"Preferencia criada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutPreferenceResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/list-blog-images":{"get":{"tags":["Images"],"summary":"Lista imagens publicas do blog","responses":{"200":{"description":"URLs das imagens","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","format":"uri"}}}}},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/upload-blog-image":{"post":{"tags":["Images"],"summary":"Faz upload de uma imagem para o blog","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Imagem enviada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageUploadResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/api/user/profile":{"get":{"tags":["User"],"summary":"Retorna o perfil do usuario autenticado","description":"Contrato planejado para substituir o mock userProfile.json.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Perfil do usuario","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"put":{"tags":["User"],"summary":"Atualiza perfil e preferencias do usuario","description":"Contrato pronto para o submit da tela /user. A foto pode ser enviada em rota separada ou junto em multipart, conforme decisao do backend.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileUpdateRequest"}}}},"responses":{"200":{"description":"Perfil atualizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/user/profile/avatar":{"post":{"tags":["User"],"summary":"Atualiza foto de perfil do usuario","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["avatar"],"properties":{"avatar":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Avatar atualizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarUploadResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/user/dashboard":{"get":{"tags":["Dashboard"],"summary":"Retorna metricas consolidadas da dashboard do usuario","description":"Contrato planejado para substituir dashboard.json e userQuestionHistory.json.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Dados da dashboard","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDashboard"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/user/question-history":{"get":{"tags":["Dashboard"],"summary":"Lista historico de respostas do usuario","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/Limit"},{"name":"source","in":"query","schema":{"type":"string","example":"enem"}},{"name":"subject","in":"query","schema":{"type":"string","example":"ciencias-natureza"}},{"name":"difficulty","in":"query","schema":{"$ref":"#/components/schemas/QuestionDifficulty"}}],"responses":{"200":{"description":"Historico paginado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserQuestionHistoryList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Questions"],"summary":"Registra uma resposta de questao do usuario","description":"Usado pelo auto save do progresso. Por padrao a preferencia autoSaveProgress fica ativa no perfil.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserQuestionAnswerCreateRequest"}}}},"responses":{"201":{"description":"Resposta registrada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserQuestionHistoryItem"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"parameters":{"Page":{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}},"responses":{"BadRequest":{"description":"Requisicao invalida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Nao autenticado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"MethodNotAllowed":{"description":"Metodo nao permitido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalError":{"description":"Erro interno","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"schemas":{"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"details":{}}},"CheckoutItem":{"type":"object","required":["title","quantity","price"],"properties":{"title":{"type":"string","example":"Plano Premium"},"quantity":{"type":"integer","minimum":1,"example":1},"price":{"type":"number","minimum":0,"example":29.9}}},"CheckoutPreferenceRequest":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CheckoutItem"}}}},"CheckoutPreferenceResponse":{"type":"object","required":["id"],"properties":{"id":{"type":"string","example":"123456789-abcdef"}}},"ImageUploadResponse":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},"AvatarUploadResponse":{"type":"object","required":["avatarUrl"],"properties":{"avatarUrl":{"type":"string","format":"uri"}}},"QuestionDifficulty":{"type":"string","enum":["easy","medium","hard"]},"UserPreferences":{"type":"object","required":["dailyQuestionGoal","targetAccuracy","weeklyStudyHours","favoriteSubjects","autoSaveProgress","manualSubmit"],"properties":{"dailyQuestionGoal":{"type":"integer","example":25},"targetAccuracy":{"type":"integer","minimum":1,"maximum":100,"example":75},"weeklyStudyHours":{"type":"integer","example":12},"favoriteSubjects":{"type":"array","items":{"type":"string"},"example":["matematica","linguagens","ciencias-natureza"]},"autoSaveProgress":{"type":"boolean","default":true},"manualSubmit":{"type":"boolean","default":false},"emailNotifications":{"type":"boolean","default":true},"publicRanking":{"type":"boolean","default":false}}},"UserProfile":{"type":"object","required":["id","name","email","role","plan","preferences"],"properties":{"id":{"type":"string","example":"user_mock_001"},"name":{"type":"string","example":"Bianca Souza"},"email":{"type":"string","format":"email","example":"bianca.souza@example.com"},"phone":{"type":"string","example":"+55 11 99999-0000"},"city":{"type":"string","example":"Sao Paulo"},"state":{"type":"string","example":"SP"},"bio":{"type":"string"},"avatarInitials":{"type":"string","example":"BS"},"avatarUrl":{"type":"string","format":"uri"},"role":{"type":"string","example":"student"},"plan":{"type":"string","example":"premium"},"studyGoal":{"type":"string","example":"enem"},"educationLevel":{"type":"string","example":"ensino-medio"},"createdAt":{"type":"string","format":"date-time"},"preferences":{"$ref":"#/components/schemas/UserPreferences"}}},"UserProfileUpdateRequest":{"type":"object","required":["name","email","preferences"],"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"bio":{"type":"string"},"studyGoal":{"type":"string"},"educationLevel":{"type":"string"},"preferences":{"$ref":"#/components/schemas/UserPreferences"}}},"UserQuestionHistoryItem":{"type":"object","required":["userId","questionId","answeredAt","isCorrect","selectedOption","timeSpent","subject","difficulty","examCode","source","year"],"properties":{"userId":{"type":"string","example":"user_mock_001"},"questionId":{"type":"integer","example":2023001},"answeredAt":{"type":"string","format":"date-time"},"isCorrect":{"type":"boolean"},"selectedOption":{"type":"string","example":"A"},"timeSpent":{"type":"integer","description":"Tempo em segundos","example":95},"subject":{"type":"string","example":"linguagens"},"difficulty":{"$ref":"#/components/schemas/QuestionDifficulty"},"examCode":{"type":"string","example":"enem-2023"},"examName":{"type":"string","example":"ENEM 2023"},"source":{"type":"string","example":"enem"},"year":{"type":"integer","example":2023},"tags":{"type":"array","items":{"type":"string"}}}},"UserQuestionAnswerCreateRequest":{"type":"object","required":["questionId","selectedOption","timeSpent","subject","difficulty","examCode"],"properties":{"questionId":{"type":"integer","example":2023001},"selectedOption":{"type":"string","example":"A"},"timeSpent":{"type":"integer","example":95},"subject":{"type":"string","example":"linguagens"},"difficulty":{"$ref":"#/components/schemas/QuestionDifficulty"},"examCode":{"type":"string","example":"enem-2023"},"examName":{"type":"string","example":"ENEM 2023"},"source":{"type":"string","example":"enem"},"year":{"type":"integer","example":2023},"tags":{"type":"array","items":{"type":"string"}}}},"UserQuestionHistoryList":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserQuestionHistoryItem"}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}}}},"DashboardGoal":{"type":"object","properties":{"title":{"type":"string"},"current":{"type":"number"},"target":{"type":"number"},"unit":{"type":"string"}}},"ExamProgress":{"type":"object","properties":{"examName":{"type":"string"},"source":{"type":"string"},"year":{"type":"integer"},"progress":{"type":"integer"},"questionsAnswered":{"type":"integer"},"totalQuestions":{"type":"integer"}}},"UserDashboard":{"type":"object","required":["userId","header","goals","examProgress","dailyActivity","accuracyTrend"],"properties":{"userId":{"type":"string"},"header":{"type":"object","properties":{"title":{"type":"string"},"subtitle":{"type":"string"}}},"goals":{"type":"array","items":{"$ref":"#/components/schemas/DashboardGoal"}},"examProgress":{"type":"array","items":{"$ref":"#/components/schemas/ExamProgress"}},"dailyActivity":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"count":{"type":"integer"}}}},"accuracyTrend":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"accuracy":{"type":"integer"}}}}}}}}}