Pular para o conteúdo principal

Endpoints

Esta lista foi montada a partir dos controllers do backend.

Formato comum de erros​

Todos os erros são retornados em JSON no formato abaixo (conforme ApiError):

{
"timestamp": "2026-01-10T14:45:01.123Z",
"status": 400,
"code": "VALIDATION_ERROR",
"message": "Falha de validação dos dados enviados.",
"path": "/api/modules",
"details": [
{
"field": "title",
"message": "Título é obrigatório",
"rejectedValue": ""
}
]
}

Campos:

  • timestamp: instante UTC da falha.
  • status: status HTTP.
  • code: código estável de erro.
  • message: mensagem humana.
  • path: endpoint chamado.
  • details: lista de erros detalhados (validação/parse/constraint). Pode vir vazia.

Códigos de erro possíveis no backend:

  • 400: VALIDATION_ERROR, INVALID_JSON, BUSINESS_VALIDATION, BAD_REQUEST.
  • 401: UNAUTHORIZED.
  • 403: FORBIDDEN.
  • 404: RESOURCE_NOT_FOUND.
  • 409: CONFLICT.
  • 429: LOGIN_RATE_LIMIT_EXCEEDED.
  • 500: INTERNAL_ERROR.

AuthController​

Base path: /api/auth

POST /api/auth/login (login)​

Corpo (JSON)

CampoTipoObrigatórioDescrição
usernamestringSimUsuário para autenticação.
passwordstringSimSenha do usuário.

Respostas

StatusDescriçãoPayload
200Login efetuado com sucesso.{ "token": "<jwt>" }
400Erro de validação/JSON inválido.Formato de erro comum.
401Credenciais inválidas.Formato de erro comum.
429Muitas tentativas de login.Formato de erro comum.
500Falha inesperada.Formato de erro comum.

ContestController​

Base path: /api/contests

GET /api/contests (list)​

ParâmetroLocalTipoObrigatórioDescrição
pagequeryintegerNãoPágina (default 0, mínimo 0).
sizequeryintegerNãoTamanho (default 20, 1..100).

Respostas

StatusDescriçãoPayload
200Página de contests.Page de ContestResponse.
400Query params inválidos.Formato de erro comum.
500Falha inesperada.Formato de erro comum.

GET /api/contests/{id} (get)​

ParâmetroLocalTipoObrigatórioDescrição
idpathintegerSimID do contest.

Respostas: 200, 404, 500.

POST /api/contests (create)​

Corpo (JSON)

CampoTipoObrigatórioDescrição
namestringSimNome do contest.
durationMinutesintegerSimDuração (>0).
startDateTimedatetimeSimData/hora de início.
teamBasedbooleanNãoSe é por equipes.
codeforcesMirrorUrlstringNãoURL HTTP/HTTPS opcional.

Respostas: 201, 400, 500.

PUT /api/contests/{id} (update)​

Mesma estrutura do create.

Respostas: 200, 400, 404, 500.

DELETE /api/contests/{id} (delete)​

Respostas: 200, 404, 500.

GET /api/contests/{contestId}/teams (list teams)​

Respostas: 200, 404, 500.

POST /api/contests/{contestId}/teams (register team)​

Corpo (JSON)

CampoTipoObrigatórioDescrição
teamNamestringCondicionalObrigatório se teamBased=true.
coachNamestringNãoNome do coach.
institutionstringNãoInstituição.
competitor1NamestringSimCompetidor 1.
competitor2NamestringCondicionalObrigatório se teamBased=true.
competitor3NamestringCondicionalObrigatório se teamBased=true.
reserveNamestringNãoReserva.
cafeComLeitebooleanNãoTime café com leite.

Respostas: 201, 400 (VALIDATION_ERROR/BUSINESS_VALIDATION), 404, 409, 500.

ModuleController​

Base path: /api/modules

GET /api/modules (list)​

ParâmetroLocalTipoObrigatórioDescrição
pagequeryintegerNãoPágina (default 0, mínimo 0).
sizequeryintegerNãoTamanho (default 20, 1..100).

Respostas: 200, 400, 500.

GET /api/modules/full (list full)​

Respostas: 200, 500.

GET /api/modules/{id} (get)​

Respostas: 200, 404, 500.

POST /api/modules (create legacy)​

CampoTipoObrigatórioDescrição
titlestringSimNome do módulo.
notesstringNãoAnotações.
publishedbooleanNãoPublicado (default true).

Respostas: 201, 400, 500.

POST /api/modules/full (create full)​

Corpo ModuleAggregateRequest:

  • title, notes, published
  • lessons[] (title, videoUrl, orderIndex)
  • exercises[] (title, ojUrl, difficulty, tags[])
  • extraMaterials[] (title, url)

Respostas: 201, 400, 500.

PUT /api/modules/full/{id} (update full)​

PUT /api/modules/full?id={id} (update full por query)​

Mesmo corpo do create full.

Respostas: 200, 400, 404, 500.

PUT /api/modules/{id} (update)​

Mesmo corpo do create legacy.

Respostas: 200, 400, 404, 500.

DELETE /api/modules/{id} (delete)​

Respostas: 200, 404, 409, 500.

LessonController​

Base path: /api/modules/{moduleId}/lessons

GET /api/modules/{moduleId}/lessons (list)​

Respostas: 200, 404, 500.

POST /api/modules/{moduleId}/lessons (create)​

CampoTipoObrigatórioDescrição
titlestringSimTítulo da lição.
videoUrlstringSimURL do vídeo (http/https).
orderIndexintegerSimOrdem da lição.

Respostas: 201, 400, 404, 500.

PUT /api/modules/{moduleId}/lessons/{lessonId} (update)​

Mesmo corpo do create.

Respostas: 200, 400, 404, 500.

DELETE /api/modules/{moduleId}/lessons/{lessonId} (delete)​

Respostas: 200, 400 (BUSINESS_VALIDATION quando lição não pertence ao módulo), 404, 500.

ExerciseController​

Base path: /api/modules/{moduleId}/exercises

GET /api/modules/{moduleId}/exercises (list)​

Respostas: 200, 404, 500.

POST /api/modules/{moduleId}/exercises (create)​

CampoTipoObrigatórioDescrição
titlestringSimTítulo do exercício.
ojUrlstringSimURL do juiz online (http/https).
difficultyExerciseDifficultySimDificuldade (enum).
tagsstring[]NãoTags do exercício.

Respostas: 201, 400, 404, 500.

PUT /api/modules/{moduleId}/exercises/{exerciseId} (update)​

Mesmo corpo do create.

Respostas: 200, 400, 404, 500.

DELETE /api/modules/{moduleId}/exercises/{exerciseId} (delete)​

Respostas: 200, 400 (BUSINESS_VALIDATION quando exercício não pertence ao módulo), 404, 500.

ExtraMaterialController​

Base path: /api/modules/{moduleId}/materials

GET /api/modules/{moduleId}/materials (list)​

Respostas: 200, 404, 500.

POST /api/modules/{moduleId}/materials (create)​

CampoTipoObrigatórioDescrição
titlestringSimTítulo do material.
urlstringSimURL do material (http/https).

Respostas: 201, 400, 404, 500.

PUT /api/modules/{moduleId}/materials/{materialId} (update)​

Mesmo corpo do create.

Respostas: 200, 400, 404, 500.

DELETE /api/modules/{moduleId}/materials/{materialId} (delete)​

Respostas: 200, 400 (BUSINESS_VALIDATION quando material não pertence ao módulo), 404, 500.

PostController​

Base path: /api/posts

GET /api/posts (list)​

ParâmetroLocalTipoObrigatórioDescrição
pagequeryintegerNãoPágina (default 0, mínimo 0).
sizequeryintegerNãoTamanho (default 20, 1..100).

Respostas: 200, 400, 500.

GET /api/posts/{id} (get)​

Respostas: 200, 404, 500.

POST /api/posts (create)​

CampoTipoObrigatórioDescrição
titlestringSimTítulo do post.
tagstringNãoTag/categoria.
slugstringSimSlug (^[a-z0-9]+(?:-[a-z0-9]+)*$).
summarystringNãoResumo.
coverImageUrlstringNãoURL da capa.
authorNamestringSimNome do autor.
statusstringSimStatus do post.
mainTextstringNãoTexto principal.
sectionsarrayNãoSeções do post.

Respostas: 201, 400, 409, 500.

PUT /api/posts/{id} (update)​

Mesmo corpo do create.

Respostas: 200, 400, 404, 409, 500.

DELETE /api/posts/{id} (delete)​

Respostas: 200, 404, 500.

RegistrationController​

Base path: /api/registrations

GET /api/registrations (list)​

ParâmetroLocalTipoObrigatórioDescrição
pagequeryintegerNãoPágina (default 0, mínimo 0).
sizequeryintegerNãoTamanho (default 20, 1..100).

Respostas: 200, 400, 500.

GET /api/registrations/{id} (get)​

Respostas: 200, 404, 500.

POST /api/registrations (create)​

CampoTipoObrigatórioDescrição
namestringSimNome completo.
emailstringSimEmail.
whatsappstringNãoWhatsApp.
institutionstringNãoInstituição.
campusstringSimCampus.
coursestringSimCurso.
semesterstringSimSemestre.
howDidYouHearstringSimComo conheceu.
previousExperiencestringNãoExperiência prévia.
messagestringNãoMensagem adicional.

Respostas: 201, 400, 409, 500.

PUT /api/registrations/{id} (update)​

Mesmo corpo do create.

Respostas: 200, 400, 404, 409, 500.

DELETE /api/registrations/{id} (delete)​

Respostas: 200, 404, 500.