Pular para o conteúdo principal

Exemplos de API

Introdução ao documento

Este documento consolida exemplos de request/response observados no repositório para as rotas em src/app/api/**/route.ts. Cada exemplo informa se o payload vem de:

  • Fato observado: o shape esta explicitamente no handler, tipo local, fixture E2E ou consumidor do endpoint.
  • Inferência: o shape foi deduzido do consumidor local, mas o handler apenas faz proxy e nao valida/serializa esse contrato.

Quando nao houver resposta local suficiente para fechar o schema, o exemplo e parcial e a lacuna fica em Pendências.

Versionamento

Baseline derivado do estado atual do repositório. Atualizar este arquivo sempre que algum handler mudar metodo, path, autenticacao, parametros ou payloads.

Referencial teórico

  • OpenAPI 3.1 como referencia de contrato HTTP.
  • Implementacoes locais em src/app/api, src/app/services, src/hooks, src/components e src/mocks/e2e-fixtures.ts.
  • Tipos locais em src/types/**.

Matriz de rastreabilidade

EndpointExemplo de requestExemplo de responseTipo da evidência
GET /api/healthHandlerHandlerFato observado
GET /api/livenessHandlerHandlerFato observado
GET /api/readinessHandlerHandlerFato observado
GET /api/envsHandlerHandlerFato observado
GET /api/jitsi/configHandlerHandlerFato observado
GET /api/project-name/configHandlerHandlerFato observado
GET /api/blip/configHandlerHandlerFato observado
GET /api/reasonsHandlerHandlerFato observado
GET /api/classRota + tipo localFixture E2EFato observado
GET /api/classesRota + tipo localFixture E2E parcialFato observado
GET /api/class/{id}Rota + tipo localTipo local CourseFato observado
GET /api/courses/{id}RotaFixture E2EFato observado
GET /api/cycles/{id}RotaFixture E2EFato observado
GET /api/cycles/by-year/{year}RotaFixture E2EFato observado
GET /api/cycles/recovery-statusServiço + rotaFixture E2EFato observado
GET /api/room/{id}RotaFixture E2EFato observado
GET /api/user/{id}RotaFixture E2EFato observado
GET /api/presence/{id}RotaFixture E2EFato observado
POST /api/presenceServiço BFFFixture E2EFato observado
POST /api/presence/autoServiço BFFFixture E2EFato observado
POST /api/presence/recoveryServiço BFFFixture E2EFato observado
POST /api/logsServiço BFFHandlerFato observado
POST /api/participant-mode-logServiço BFFFixture E2EFato observado
POST /api/enrollment/{id}/request-cancellationServiço BFFFixture E2EFato observado
POST /api/enroll/cancel/{id}RotaFixture E2EFato observado
GET /api/status/{client-id}HandlerHandlerFato observado
PUT /api/status/{client-id}Serviço + handlerHandlerFato observado
GET /api/activity-templateHookHook + tipo localInferência parcial
POST /api/activity-templateComponentesProxy opacoFato observado no request; response parcial
DELETE /api/activity-templateHookHookInferência parcial
GET /api/submissionsServiço BFFTipos + fixture E2EFato observado
POST /api/submissionsComponentesTipos + fixture E2EFato observado
PUT /api/submissions/{id}Serviço BFFTipos + fixture E2EFato observado
DELETE /api/submissions/{id}Serviço BFFFixture E2EFato observado
GET /api/submissions/class/{id}Serviço BFFTipos + fixture E2EFato observado
GET /api/submissions/status-sumaryServiço BFFTipos + fixture E2EFato observado
GET /api/submissions/api-tokenServiço BFFFixture E2EFato observado
GET /api/submissions/downloadServiço BFFHandler + fixture E2E parcialFato observado
GET /api/submissions/files/{path}Uso em utilitarioHandlerFato observado
GET /api/downloadUso em componenteHandlerFato observado
GET /api/schedule/calendar/{id}Serviço BFFTipos + fixture E2EFato observado
GET /api/schedule/calendar/{id}/class/{slug}Serviço BFFTipos + fixture E2EFato observado
GET /api/schedule/slot/{slug}/class/{id}Serviço BFFTipos + fixture E2EFato observado
POST /api/schedule/slotServiço BFFTipos + fixture E2EFato observado
GET /api/schedule/appointment/class/{id}Serviço BFFTipos + fixture E2EFato observado
POST /api/schedule/appointment/createComponente + tipo localFixture E2EFato observado
POST /api/schedule/appointment/delete/{id}Serviço BFFFixture E2EFato observado
POST /api/schedule/block/{id}Serviço BFFFixture E2EFato observado
POST /api/schedule/unblock/{id}Serviço BFFFixture E2EFato observado

Exemplos

GET /api/health

Fato observado

Request:

curl -s http://localhost:3000/api/health

Response:

{
"status": "healthy",
"timestamp": "2026-03-20T12:00:00.000Z",
"uptime": 123.45,
"version": "0.1.0",
"node_version": "v22.0.0",
"memory": {
"used": 120,
"total": 180
},
"env": "production"
}

Evidências:

  • src/app/api/health/route.ts:3-31

GET /api/envs

Fato observado

Request:

curl -s http://localhost:3000/api/envs

Response:

{
"appVersion": "0.1.0",
"privacyPolicyUrl": "https://example.com/privacy",
"datadog": {
"clientId": "client-id",
"clientToken": "client-token",
"serviceName": "dhedalos-app-frontend-nextjs",
"env": "staging",
"sessionSampleRate": 100,
"sessionReplaySampleRate": 20
},
"apis": {
"quizApiUrl": "https://quiz-api.example.com"
}
}

Evidências:

  • src/app/api/envs/route.ts:6-27
  • src/types/AppEnvs.d.ts:1-15

GET /api/reasons

Fato observado

Request:

curl -s http://localhost:3000/api/reasons

Response:

[
{ "value": "schedule_conflict", "label": "Conflito de agenda" },
{ "value": "forgot_time", "label": "Esqueci do horário" },
{ "value": "connection_issue", "label": "Problema de conexão" },
{ "value": "unexpected_event", "label": "Imprevisto pessoal" },
{ "value": "lack_of_interest", "label": "Falta de interesse" },
{ "value": "other", "label": "Outro" }
]

Evidências:

  • src/app/api/reasons/route.ts:5-21
  • src/models/ReasonOption.ts:1-5

GET /api/cycles/recovery-status

Fato observado

Request:

curl -s 'http://localhost:3000/api/cycles/recovery-status?class_id=1'

Response:

{
"status": 200,
"message": "Success",
"code": "recovery_status",
"data": {
"user_id": 3,
"class_id": 1,
"cycle_id": 1,
"cycle_name": "Ciclo 1 - 2026",
"class_turno": "diurno",
"collective_meeting_index": 3,
"collective_meeting_name": "Encontro Coletivo 3",
"collective_meeting_date": "10/01/2026 14:00:00",
"has_presence": false,
"recovery_needed": true,
"recovery_hours_configured": 48,
"collective_meeting_time": "10/01/2026 14:00:00",
"recovery_deadline": "12/01/2027 15:00:00",
"recovery_expired": false,
"time_remaining": 172800,
"recovery_video": "a4nOgmxGWg6gULfcBbAa00gXyfcwPnAFldF8RdsNyk8M",
"enable_strategic_activities": true,
"now": "12/02/2026 10:00:00"
}
}

Evidências:

  • src/app/api/cycles/recovery-status/route.ts:22-72
  • src/services/StatusService.ts:46-90
  • src/mocks/e2e-fixtures.ts:554-577

Pendência:

  • O proxy envia class_idd para o upstream, não class_id. Isso foi documentado como fato observado, mas o comportamento real do backend externo precisa ser verificado em ambiente integrado.

GET /api/presence/{id}

Fato observado

Request:

curl -s http://localhost:3000/api/presence/1

Response:

[
{
"id": 1,
"name": "João da Silva",
"cpf": "11111111111",
"phone": "(11) 99999-1111",
"activities": {
"1": true,
"2": false,
"3": true
},
"is_enroll_canceled": false,
"is_cancel_requested": false,
"enrollment_id": 100
}
]

Evidências:

  • src/app/api/presence/[id]/route.ts:7-35
  • src/types/IStudent.ts:6-18
  • src/mocks/e2e-fixtures.ts:711-714

POST /api/presence

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/presence \
-H 'Content-Type: application/json' \
-d '{
"class_id": "1",
"student_id": "2",
"activity_id": "1"
}'

Response:

{
"status": 200,
"message": "Presença registrada com sucesso",
"data": {
"id": 2,
"name": "Maria Santos",
"cpf": "22222222222",
"phone": "(11) 99999-2222",
"activities": {
"1": true,
"2": false,
"3": false
}
}
}

Evidências:

  • src/app/api/presence/route.ts:6-29
  • src/app/services/bff/ClassService.ts:61-71
  • src/mocks/e2e-fixtures.ts:914-932

POST /api/logs

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/logs \
-H 'Content-Type: application/json' \
-d '{
"subscriber_id": "100",
"action": "Enviou: ATIVIDADE ESTRATEGICA 1"
}'

Response:

{
"message": "Ação registrada com sucesso.",
"status": 201
}

Evidências:

  • src/app/api/logs/route.ts:20-40
  • src/app/services/bff/LogsService.ts:3-10
  • src/utils/sendLog.ts:3-13

Pendência:

  • O body devolve status: 201, mas o handler nao seta explicitamente o status HTTP na resposta de sucesso.

POST /api/participant-mode-log

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/participant-mode-log \
-H 'Content-Type: application/json' \
-d '{
"supervisor_id": "10",
"supervisor_cpf": "99999999999",
"participant_id": "3",
"participant_cpf": "33333333333",
"action": "Entrou no modo participante"
}'

Response:

{
"status": 200,
"message": "Log registrado com sucesso",
"data": {
"id": 1710000000000,
"supervisor_id": "10",
"supervisor_cpf": "99999999999",
"participant_id": "3",
"participant_cpf": "33333333333",
"action": "Entrou no modo participante",
"created_at": "2026-03-20T12:00:00.000Z"
}
}

Evidências:

  • src/app/api/participant-mode-log/route.ts:20-40
  • src/app/services/bff/ParticipantModeLogs.ts:3-17
  • src/mocks/e2e-fixtures.ts:1186-1205

POST /api/enrollment/{enrollment_id}/request-cancellation

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/enrollment/101/request-cancellation

Response:

{
"status": 200,
"message": "Solicitação de cancelamento enviada com sucesso",
"data": {
"enrollment_id": 101,
"is_cancel_requested": true
}
}

Evidências:

  • src/app/api/enrollment/[enrollment_id]/request-cancellation/route.ts:26-54
  • src/app/services/bff/ClassService.ts:123-130
  • src/mocks/e2e-fixtures.ts:936-961

POST /api/enroll/cancel/{enroll_id}

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/enroll/cancel/101 \
-H 'Content-Type: application/json' \
-d '{ "reason": "schedule_conflict" }'

Response:

{
"status": "cancelled",
"message": "Matrícula cancelada com sucesso",
"data": {
"enrollment_id": 101,
"is_enroll_canceled": true,
"reason": "schedule_conflict"
}
}

Evidências:

  • src/app/api/enroll/cancel/[enroll_id]/route.ts:27-54
  • src/mocks/e2e-fixtures.ts:1154-1184

GET /api/status/{client-id}

Fato observado

Request:

curl -s http://localhost:3000/api/status/meeting-recover-01

Response:

{
"id": "meeting-recover-01",
"title": "Encontro 01",
"status": "available",
"when": "2026-03-20T12:00:00.000Z",
"activityIncluded": true,
"activityAvailable": false,
"activityCompleted": false,
"videoPlaybackId": "a4nOgmxGWg6gULfcBbAa00gXyfcwPnAFldF8RdsNyk8M",
"expiresIn": 24,
"videoMetadata": {
"video_id": "video-id-12345",
"video_title": "Test video title",
"viewer_user_id": "user-id-007"
}
}

Evidências:

  • src/app/api/status/[client-id]/route.ts:13-31
  • src/models/MeetingRecover.ts:64-83

GET /api/activity-template

Inferência parcial

Request:

curl -s 'http://localhost:3000/api/activity-template?class_id=1&course_id=1&cycle_id=1'

Response esperada pelo consumidor:

{
"data": {
"1": {
"id": 10,
"activity_id": 1,
"course_id": 1,
"cycle_id": 1,
"class_id": 1,
"original_name": "template-atividade-1.pdf",
"file_path": "templates/atividade-1.pdf",
"file_type": "application/pdf",
"description": "Template da atividade 1",
"created_at": "2026-01-02T10:00:00Z",
"updated_at": "2026-01-02T10:00:00Z"
}
}
}

Evidências:

  • src/app/api/activity-template/route.ts:59-126
  • src/hooks/useActivityTemplates.ts:3-58

Pendência:

  • O handler nao tipa nem valida o response do upstream; o exemplo acima reflete o shape esperado pelo hook consumidor.

POST /api/activity-template

Fato observado no request; response parcial

Request:

curl -s -X POST http://localhost:3000/api/activity-template \
-F 'course_id=1' \
-F 'activity_id=1' \
-F 'cycle_id=1' \
-F 'class_id=1' \
-F 'description=Template de atividade 1 - Turma 1' \
-F 'file=@./template.pdf'

Response:

{
"...": "payload retornado pelo upstream /activity-template-files"
}

Evidências:

  • src/app/api/activity-template/route.ts:3-57
  • src/components/ActivityManagement/ActivityManagement.component.tsx:255-265
  • src/components/ActivityManagement/components/ActivitiesSlider/ActivitiesSlider.component.tsx:166-178

Pendência:

  • Nao existe fixture local nem DTO interno para a resposta do upstream.

GET /api/submissions

Fato observado

Request:

curl -s 'http://localhost:3000/api/submissions?class_id=1&status=submitted'

Response:

[
{
"id": 2,
"participant_id": 2,
"activity_id": 1,
"title": "Atividade Estratégica 1",
"class_id": 1,
"course_id": 1,
"cycle_id": 1,
"facilitator_id": 1,
"score": null,
"facilitator_comment": null,
"evaluated_at": null,
"created_at": "2026-01-03T11:00:00Z",
"updated_at": "2026-01-03T11:00:00Z",
"status": "submitted",
"files": [
{
"id": 2,
"deliverable_submission_id": 2,
"file_path": "/uploads/maria-atividade-1.pdf",
"original_name": "atividade-1-maria.pdf",
"file_type": "application/pdf",
"created_at": "2026-01-03T11:00:00Z",
"updated_at": "2026-01-03T11:00:00Z"
}
]
}
]

Evidências:

  • src/app/api/submissions/route.ts:41-83
  • src/types/ISubmission.ts:11-59
  • src/mocks/e2e-fixtures.ts:222-289

POST /api/submissions

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/submissions \
-H 'Authorization: Bearer mock_submission_api_token_12345' \
-F 'participant_email=joao.silva@example.com' \
-F 'participant_name=João da Silva' \
-F 'course_name=Curso Teste' \
-F 'class_id=1' \
-F 'participant_id=1' \
-F 'activity_id=1' \
-F 'title=João da Silva_ATIVIDADE ESTRATEGICA 1_20-03-2026' \
-F 'course_id=1' \
-F 'cycle_id=1' \
-F 'facilitator_id=1' \
-F 'status=submitted' \
-F 'files[0]=@./atividade.pdf'

Response:

{
"id": 4,
"participant_id": 1,
"activity_id": 1,
"title": "João da Silva_ATIVIDADE ESTRATEGICA 1_20-03-2026",
"class_id": 1,
"course_id": 1,
"cycle_id": 1,
"facilitator_id": 1,
"score": null,
"facilitator_comment": null,
"evaluated_at": null,
"created_at": "2026-03-20T12:00:00.000Z",
"updated_at": "2026-03-20T12:00:00.000Z",
"status": "submitted",
"files": []
}

Evidências:

  • src/app/api/submissions/route.ts:4-31
  • src/app/services/bff/SubmissionService.ts:54-99
  • src/components/EnvioDeAtividades/components/Upload.component.tsx:146-191
  • src/mocks/e2e-fixtures.ts:964-1019

PUT /api/submissions/{id}

Fato observado

Request:

curl -s -X PUT http://localhost:3000/api/submissions/1 \
-F 'id=1' \
-F 'status=evaluated' \
-F 'score=5' \
-F 'facilitator_comment=Muito bom' \
-F 'participant_email=joao.silva@example.com' \
-F 'participant_name=João da Silva' \
-F 'course_name=Curso Teste'

Response:

{
"id": 1,
"participant_id": 1,
"activity_id": 1,
"title": "Atividade Estratégica 1",
"class_id": 1,
"course_id": 1,
"cycle_id": 1,
"facilitator_id": 1,
"score": 5,
"facilitator_comment": "Muito bom",
"evaluated_at": "2026-03-20T12:00:00.000Z",
"created_at": "2026-01-02T10:00:00Z",
"updated_at": "2026-03-20T12:00:00.000Z",
"status": "evaluated",
"files": [
{
"id": 1,
"deliverable_submission_id": 1,
"file_path": "/uploads/joao-atividade-1.pdf",
"original_name": "atividade-1-joao.pdf",
"file_type": "application/pdf",
"created_at": "2026-01-02T10:00:00Z",
"updated_at": "2026-01-02T10:00:00Z"
}
]
}

Evidências:

  • src/app/api/submissions/[id]/route.ts:4-40
  • src/app/services/bff/SubmissionService.ts:107-132
  • src/mocks/e2e-fixtures.ts:1217-1267

Pendência:

  • O handler usa formData.id para montar o upstream e nao o id do path.

DELETE /api/submissions/{id}

Fato observado

Request:

curl -s -X DELETE http://localhost:3000/api/submissions/1 \
-H 'Content-Type: application/json' \
-d '{
"participant_name": "João da Silva",
"participant_email": "joao.silva@example.com",
"action": "resend",
"course_name": "Curso Teste"
}'

Response:

{
"status": 200,
"message": "Submission deletada com sucesso"
}

Evidências:

  • src/app/api/submissions/[id]/route.ts:46-80
  • src/app/services/bff/SubmissionService.ts:139-149
  • src/components/ActivityEvaluation/ ActivityEvaluation.component.tsx:212-226
  • src/mocks/e2e-fixtures.ts:1288-1311

GET /api/submissions/class/{id}

Fato observado

Request:

curl -s http://localhost:3000/api/submissions/class/1

Response:

[
{
"id": "1",
"name": "João da Silva",
"cpf": "11111111111",
"phone": "(11) 99999-1111",
"email": "joao.silva@example.com",
"is_enroll_canceled": false,
"is_cancel_requested": false,
"activities": [
{ "status": "avaliada", "id": "1", "activity_id": "1" },
{ "status": "não recebida", "activity_id": "2" },
{ "status": "não recebida", "activity_id": "3" }
]
}
]

Evidências:

  • src/app/api/submissions/class/[id]/route.ts:6-38
  • src/types/IParticipants.ts:1-25
  • src/mocks/e2e-fixtures.ts:757-761

GET /api/submissions/status-sumary

Fato observado

Request:

curl -s 'http://localhost:3000/api/submissions/status-sumary?facilitator_id=1&class_id=1&cycle_id=1'

Response:

{
"1": {
"cycle_id": 1,
"hasSubmittedActivities": true,
"classes": {
"1": {
"class_id": 1,
"hasSubmittedActivities": true
}
}
}
}

Evidências:

  • src/app/api/submissions/status-sumary/route.ts:6-41
  • src/types/ISubmission.ts:93-106
  • src/mocks/e2e-fixtures.ts:763-778

GET /api/submissions/api-token

Fato observado

Request:

curl -s http://localhost:3000/api/submissions/api-token

Response:

{
"token": "mock_submission_api_token_12345"
}

Evidências:

  • src/app/api/submissions/api-token/route.ts:6-29
  • src/mocks/e2e-fixtures.ts:780-785

GET /api/submissions/download

Fato observado

Request:

curl -L 'http://localhost:3000/api/submissions/download?class_id=1&participant_id=1&activity_id=1' \
-o submissoes.zip

Response:

HTTP 200
Content-Type: application/zip
Content-Disposition: attachment; filename="submissoes.zip"
<binary zip stream>

Evidências:

  • src/app/api/submissions/download/route.ts:6-53
  • src/app/services/bff/SubmissionService.ts:175-197

Pendência:

  • A fixture E2E registra apenas um Blob genérico; o conteudo real do ZIP depende do upstream.

GET /api/submissions/files/{path}

Fato observado

Request:

curl -L http://localhost:3000/api/submissions/files/uploads/joao-atividade-1.pdf -o atividade.pdf

Response:

HTTP 200
Cache-Control: public, max-age=3600
Content-Type: application/pdf
<binary stream>

Evidências:

  • src/app/api/submissions/files/[...path]/route.ts:3-60
  • src/utils/renderFile.tsx:41-41

GET /api/download

Fato observado

Request:

curl -L 'http://localhost:3000/api/download?url=%2Fuploads%2Fjoao-atividade-1.pdf&name=atividade-1-joao.pdf' \
-o atividade-1-joao.pdf

Response:

HTTP 200
Content-Disposition: attachment; filename="atividade-1-joao.pdf"
Content-Type: application/pdf
<binary stream>

Evidências:

  • src/app/api/download/route.ts:6-51
  • src/components/ActivityEvaluation/ ActivityEvaluation.component.tsx:311-313

GET /api/schedule/appointment/class/{id}

Fato observado

Request:

curl -s http://localhost:3000/api/schedule/appointment/class/1

Response:

{
"status": 200,
"message": "Success",
"data": [
{
"id": 1,
"start_time": "2026-03-20 09:00:00",
"finish_time": "2026-03-20 10:00:00",
"comments": "Consultoria individual sobre empreendedorismo",
"additional_fields": "{\"main_topic\":\"Marketing Digital\",\"social_network\":\"@joaodasilva\",\"specific_questions\":\"Como criar campanhas eficientes?\"}",
"class_id": "1",
"type_id": 3,
"client_id": 1,
"employee_id": 1,
"deleted_at": null
}
]
}

Evidências:

  • src/app/api/schedule/appointment/class/[id]/route.ts:24-39
  • src/types/IAppointment.ts:4-41
  • src/mocks/e2e-fixtures.ts:803-841

POST /api/schedule/appointment/create

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/schedule/appointment/create \
-H 'Content-Type: application/json' \
-d '{
"start_time": "2026-03-20 14:00:00",
"finish_time": "2026-03-20 15:00:00",
"class_id": "1",
"course_name": "Curso Teste",
"employee_id": 1,
"type_id": 3,
"additional_fields": {
"social_network": "@joaodasilva",
"main_topic": "Marketing Digital",
"specific_questions": "Como criar campanhas eficientes?"
}
}'

Response:

{
"status": 201,
"message": "Agendamento criado com sucesso",
"data": {
"id": 4,
"start_time": "2026-03-20 14:00:00",
"finish_time": "2026-03-20 15:00:00",
"comments": "{\"social_network\":\"@joaodasilva\",\"main_topic\":\"Marketing Digital\",\"specific_questions\":\"Como criar campanhas eficientes?\"}",
"additional_fields": "{\"social_network\":\"@joaodasilva\",\"main_topic\":\"Marketing Digital\",\"specific_questions\":\"Como criar campanhas eficientes?\"}",
"class_id": "1",
"type_id": 3
}
}

Evidências:

  • src/app/api/schedule/appointment/create/route.ts:24-66
  • src/components/Consultorias/Consultorias.component.tsx:230-243
  • src/types/IAppointment.ts:43-51
  • src/mocks/e2e-fixtures.ts:1021-1063

POST /api/schedule/appointment/delete/{id}

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/schedule/appointment/delete/1

Response:

{
"status": 200,
"message": "Agendamento deletado com sucesso",
"data": {
"id": 1,
"deleted_at": "2026-03-20T12:00:00.000Z"
}
}

Evidências:

  • src/app/api/schedule/appointment/delete/[id]/route.ts:20-26
  • src/mocks/e2e-fixtures.ts:1326-1344

GET /api/schedule/slot/{date}/class/{class_id}

Fato observado

Request:

curl -s http://localhost:3000/api/schedule/slot/2026-03-20/class/1

Response:

{
"status": 200,
"message": "Success",
"data": [
{ "id": "1", "date": "2026-03-20", "time": "09:00:00" },
{ "id": "2", "date": "2026-03-20", "time": "10:00:00" },
{ "id": "3", "date": "2026-03-20", "time": "11:00:00" }
]
}

Evidências:

  • src/app/api/schedule/slot/[slug]/class/[id]/route.ts:21-45
  • src/types/ISlots.ts:3-12
  • src/mocks/e2e-fixtures.ts:842-860

POST /api/schedule/slot

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/schedule/slot \
-H 'Content-Type: application/json' \
-d '{
"class_id": "1",
"date": "2026-03-20"
}'

Response:

{
"status": 200,
"message": "Success",
"data": [
{ "id": "1", "date": "2026-03-20", "time": "14:00:00", "appointment_count": 3 },
{ "id": "2", "date": "2026-03-20", "time": "15:00:00", "appointment_count": 0 },
{ "id": "3", "date": "2026-03-20", "time": "16:00:00", "appointment_count": 0 }
]
}

Evidências:

  • src/app/api/schedule/slot/route.ts:21-53
  • src/app/services/bff/ScheduleService.ts:72-80
  • src/mocks/e2e-fixtures.ts:1140-1151

POST /api/schedule/block/{id}

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/schedule/block/1 \
-H 'Content-Type: application/json' \
-d '{
"start_time": "2026-03-20 17:00:00",
"finish_time": "2026-03-20 18:00:00"
}'

Response:

{
"status": 201,
"message": "Horário bloqueado com sucesso",
"data": {
"id": 5,
"class_id": "1",
"type_id": 1,
"comments": "Horário bloqueado"
}
}

Evidências:

  • src/app/api/schedule/block/[id]/route.ts:21-36
  • src/mocks/e2e-fixtures.ts:1066-1107

POST /api/schedule/unblock/{id}

Fato observado

Request:

curl -s -X POST http://localhost:3000/api/schedule/unblock/5

Response:

{
"status": 200,
"message": "Horário desbloqueado com sucesso",
"data": {
"id": 5,
"deleted_at": "2026-03-20T12:00:00.000Z"
}
}

Evidências:

  • src/app/api/schedule/unblock/[id]/route.ts:20-26
  • src/mocks/e2e-fixtures.ts:1110-1137

Pendências

  • GET /api/activity-template e DELETE /api/activity-template dependem de um upstream sem DTO/fixture local; o exemplo de response foi mantido parcial.
  • POST /api/activity-template nao possui exemplo de response local; o handler apenas retransmite o payload do upstream.
  • GET /api/submissions/download e GET /api/submissions/files/{path} entregam binario; o conteudo real depende de storage/upstream externo.
  • POST /api/logs devolve body com status: 201, mas o status HTTP de sucesso nao e explicitamente definido no handler.
  • GET /api/cycles/recovery-status envia class_idd ao upstream; isso parece divergencia de implementacao, nao regra de negocio documentada.

Endpoints sem cobertura funcional observada

  • GET /api/submissions/{id}: existe consumidor local em src/app/services/bff/SubmissionService.ts:43-47, mas o handler src/app/api/submissions/[id]/route.ts:4-84 implementa apenas PUT e DELETE.
  • GET /api/activity-template-files/{...}: existe uso de URL com prefixo /api/activity-template-files/ em src/components/ActivityManagement/ActivityManagement.component.tsx:620-620, mas nenhum route.ts correspondente foi localizado em src/app/api.