Pular para o conteúdo principal

Modelo de dados funcional

Introdução ao documento

Este documento descreve o modelo de dados observável localmente neste repositório. O escopo não é um schema relacional de banco, porque o projeto não expõe migrations, diretório schema ou ORM local; o que existe no código são:

  • tipos de domínio em src/types/*;
  • modelos utilitários em src/models/*;
  • projeções e composições de runtime nos handlers BFF e hooks.

Por isso, o conteúdo abaixo representa um modelo contratual/runtime do frontend+BFF, não um DDL persistente do backend externo.

Evidências:

  • src/types/IClass.ts:42-86
  • src/types/ITurma.ts:4-38
  • src/types/IAppointment.ts:4-55
  • src/types/ISubmission.ts:1-106
  • src/models/MeetingRecover.ts:1-234
  • src/models/ReasonOption.ts:1-5

Versionamento

Baseline derivado do estado atual do repositório em 2026-03-20. Este documento deve ser revisado quando houver mudança material em:

  • tipos de domínio em src/types/*;
  • composição de payloads nos handlers de src/app/api/*;
  • mapeamentos de runtime em hooks e serviços BFF.

Evidências:

  • src/app/api/submissions/[id]/route.ts:4-84
  • src/app/api/schedule/appointment/create/route.ts:10-77
  • src/hooks/useSubmissions.ts:34-175
  • src/app/services/bff/SubmissionService.ts:17-197

Referencial teórico

O documento usa três referências principais:

  • modelagem contratual por tipos TypeScript;
  • projeções de runtime consumidas pelas telas e hooks;
  • notação Mermaid ERD para visualizar cardinalidade e chaves observadas.

Evidências:

  • src/types/IApiResponse.ts:1-6
  • src/types/IParticipants.ts:1-25
  • src/utils/mapSubmissionStatus.ts:3-15
  • src/utils/createMissingActivities.ts:13-25

Escopo e fontes usadas

Fontes primárias efetivamente usadas

FontePapel no modeloEvidência
src/types/IClass.tsProjeção resumida de turma/curso/ciclo usada no app protegidosrc/types/IClass.ts:42-86
src/types/ITurma.tsDetalhe de turma com lista de estudantes e consultoriassrc/types/ITurma.ts:4-38
src/types/IStudent.tsParticipante no fluxo de presençasrc/types/IStudent.ts:1-18
src/types/IParticipants.tsProjeção de participante no fluxo de gestão de atividadessrc/types/IParticipants.ts:1-25
src/types/ISubmission.tsEntidades de submissão, arquivo e notificaçãosrc/types/ISubmission.ts:1-106
src/types/IAppointment.tsEntidades de agenda/agendamentosrc/types/IAppointment.ts:4-55
src/types/ICycles.tsProjeções de ciclo e turma por ciclosrc/types/ICycles.ts:1-27
src/types/IUser.tsProjeção mínima de usuário retornado por backendsrc/types/IUser.ts:1-10
src/types/next-auth.d.tsShape enriquecido de sessão no runtimesrc/types/next-auth.d.ts:3-14
src/mocks/e2e-fixtures.tsExemplos concretos de payloads em execução E2Esrc/mocks/e2e-fixtures.ts:221-560

Limitação de fonte

Não há schema relacional localmente formalizado; por isso, “PK”, “FK”, “unique” e cardinalidade abaixo significam papel observado no contrato e não constraint física comprovada em banco.

Evidências:

  • src/app/services/api.ts:115-244
  • src/utils/consts.ts:1-11

Entidades/tabelas principais

EntidadeTipo localPapel observadoCampos centrais observadosEvidência
ClassDataagregação de turmavisão resumida de turma carregada no app protegidoid, title, slug, courses, ciclos, facilitator, facilitator_name, enable_calendar, enable_room, strategic_activities_numbersrc/types/IClass.ts:42-82
Coursedetalhe de turmavisão detalhada de turma com alunos e consultoriasid, title, students, facilitator, start_date, end_date, first_consultancy, second_consultancysrc/types/ITurma.ts:4-25
Cycleciclociclo retornado em listagensid, name, slug, course_id, start_date, end_date, activitiessrc/types/ICycles.ts:1-16
ClassByClycleResponseturma por cicloprojeção simplificada de turma em listagens por cicloid, name, slug, cycle_id, turnosrc/types/ICycles.ts:18-27
Studentparticipante de presençaaluno usado em presença e recuperaçãoid, name, cpf, activities, phone, enrollment_id, is_enroll_canceled, is_cancel_requestedsrc/types/IStudent.ts:1-18
Participantparticipante de gestão de atividadesprojeção usada no hook useSubmissionsid, name, cpf, email, activities[], is_enroll_canceled, is_cancel_requestedsrc/types/IParticipants.ts:1-25
SubmissionResponsesubmissãoentrega/avaliação de atividade estratégicaid, participant_id, activity_id, class_id, course_id, cycle_id, facilitator_id, status, score, files[]src/types/ISubmission.ts:11-27
SubmissionFilearquivo de submissãoanexo vinculado a uma submissãoid, deliverable_submission_id, file_path, original_name, file_typesrc/types/ISubmission.ts:1-9
Appointmentagendamentoslot/agendamento individual, grupo ou bloqueioid, start_time, finish_time, class_id, type_id, client_id, employee_id, deleted_atsrc/types/IAppointment.ts:4-28
Appointment.clientparticipante de agendaparticipante associado ao agendamentoid, name, cpf, email, phone_numbersrc/types/IAppointment.ts:17-27
Appointment.employeefacilitador de agendafacilitador associado ao agendamentoid, name, cpf, email, phone_numbersrc/types/IAppointment.ts:18-27
UserLoginusuário mínimousuário retornado por consultas BFF específicasID, user_login, user_email, display_namesrc/types/IUser.ts:1-10
RecoveryStatusResponse.datastatus de recuperaçãopayload funcional de recuperação por encontrouser_id, class_id, cycle_id, collective_meeting_index, has_presence, recovery_deadline, recovery_videosrc/models/MeetingRecover.ts:7-33

Relacionamentos e cardinalidade

As cardinalidades abaixo foram extraídas de chaves e coleções observadas no contrato. Quando o vínculo completo depende de backend externo, isso aparece na observação.

OrigemDestinoCardinalidade observadaBaseEvidência
ClassDataCourseInfo embutido em coursesN:1 inferência operacionalcada ClassData contém um único courses, identificado por courses.idsrc/types/IClass.ts:12-26, src/types/IClass.ts:42-56
ClassDataCycleInfo embutido em ciclosN:1 inferência operacionalcada ClassData contém um único ciclos, identificado por ciclos.idsrc/types/IClass.ts:28-35, src/types/IClass.ts:42-56
CourseStudent[]1:N fato observadoo detalhe de turma expõe students: Student[]src/types/ITurma.ts:4-10
ClassDataStudent[]1:N fato observadoa rota de presença é indexada por class_id e retorna lista de alunossrc/app/services/external/ClassService.ts:223-234, src/app/api/presence/[id]/route.ts:19-24
ClassDataParticipant[]1:N projeção de runtimeuseSubmissions carrega participantes por turma e os enriquece com submissõessrc/hooks/useSubmissions.ts:51-127
SubmissionResponseSubmissionFile[]1:N fato observadoa submissão contém files: SubmissionFile[]src/types/ISubmission.ts:11-27
SubmissionResponseParticipantN:1 fato observadoparticipant_id vincula a submissão a um participantesrc/types/ISubmission.ts:11-27, src/hooks/useSubmissions.ts:81-103
SubmissionResponseClassDataN:1 fato observadoclass_id vincula a submissão à turmasrc/types/ISubmission.ts:11-27
SubmissionResponseCourseInfoN:1 fato observadocourse_id vincula a submissão ao cursosrc/types/ISubmission.ts:11-27
SubmissionResponseCycleInfo/CycleN:1 fato observadocycle_id vincula a submissão ao ciclosrc/types/ISubmission.ts:11-27, src/types/ICycles.ts:1-16
SubmissionResponseFacilitatorN:1 fato observadofacilitator_id é propagado na criação e no contrato de submissãosrc/types/ISubmission.ts:11-27, src/components/EnvioDeAtividades/components/Upload.component.tsx:165-176
AppointmentClassDataN:1 fato observadoclass_id identifica a turma do agendamentosrc/types/IAppointment.ts:4-16
AppointmentAppointment.clientN:0..1 fato observadoclient pode ser null em bloqueios/grupossrc/types/IAppointment.ts:13-18, src/mocks/e2e-fixtures.ts:405-417
AppointmentAppointment.employeeN:1 fato observadotodo agendamento tem employeesrc/types/IAppointment.ts:18-27
RecoveryStatusResponse.dataClassDataN:1 fato observadoclass_id liga o status de recuperação à turmasrc/models/MeetingRecover.ts:7-26
RecoveryStatusResponse.dataCycleN:1 fato observadocycle_id liga o status de recuperação ao ciclosrc/models/MeetingRecover.ts:7-26

Campos críticos

Identificadores e chaves observadas

EntidadeCampoPapel observadoEvidência
ClassDataidPK observada no contrato de turmasrc/types/IClass.ts:50-53
CourseidPK observada no detalhe de turmasrc/types/ITurma.ts:4-7
CycleidPK observada no contrato de ciclosrc/types/ICycles.ts:1-5
ClassByClycleResponseidPK observada em listagem por ciclosrc/types/ICycles.ts:18-22
StudentidPK observada do aluno em presençasrc/types/IStudent.ts:6-8
ParticipantidPK observada da projeção de gestão de atividadessrc/types/IParticipants.ts:4-8
SubmissionResponseidPK observada da submissãosrc/types/ISubmission.ts:11-14
SubmissionFileidPK observada do arquivosrc/types/ISubmission.ts:1-4
SubmissionFiledeliverable_submission_idFK observada para submissãosrc/types/ISubmission.ts:1-9
AppointmentidPK observada do agendamentosrc/types/IAppointment.ts:4-16
Appointmentclass_idFK observada para turmasrc/types/IAppointment.ts:9-12
Appointmentclient_idFK observada para cliente/participantesrc/types/IAppointment.ts:11-16
Appointmentemployee_idFK observada para facilitadorsrc/types/IAppointment.ts:12-16

Status, flags e timestamps

EntidadeCampoSemântica observadaEvidência
SubmissionResponsestatusestado de entrega/avaliaçãosrc/types/ISubmission.ts:25-27
SubmissionResponsescorenota da avaliaçãosrc/types/ISubmission.ts:20-21
SubmissionResponseevaluated_attimestamp de avaliaçãosrc/types/ISubmission.ts:20-24
SubmissionResponsecreated_at, updated_attimestamps de criação/atualizaçãosrc/types/ISubmission.ts:22-24
SubmissionFilecreated_at, updated_attimestamps do anexosrc/types/ISubmission.ts:6-9
Appointmentcreated_at, updated_at, deleted_attimestamps de ciclo de vida; deleted_at sugere soft deletesrc/types/IAppointment.ts:14-16
Studentis_enroll_canceled, is_cancel_requestedflags de cancelamentosrc/types/IStudent.ts:12-15
ClassDataenable_calendar, enable_room, enable_strategic_activities, is_recovery_enabledflags de feature de turmasrc/types/IClass.ts:43-44, src/types/IClass.ts:66-82
RecoveryStatusResponse.datahas_presence, recovery_needed, recovery_expiredestado funcional de recuperaçãosrc/models/MeetingRecover.ts:16-26

Unique

Constraint unique não foi comprovada localmente em nenhuma entidade por ausência de migrations/schema físico. Há apenas chaves observadas no contrato.

Evidências:

  • src/types/ISubmission.ts:11-27
  • src/types/IAppointment.ts:4-28
  • src/types/IClass.ts:42-82

Constraints e enums

DomínioCampoValores observadosEvidência
SubmissionResponsestatuspending, submitted, evaluated, submitted_externalsrc/types/ISubmission.ts:25-27, src/types/ISubmission.ts:44-55
Participant.activities[]statusavaliada, recebida, não recebida, recebida em outro canalsrc/types/IParticipants.ts:9-25
Mapeamento runtimeSubmission.status -> ActivityStatusevaluated -> avaliada, submitted -> recebida, pending -> não recebida, submitted_external -> recebida em outro canalsrc/utils/mapSubmissionStatus.ts:3-15
Appointmenttype_id`12
Appointment mocktype_id semântica observada1 = bloqueio, 3 = individual, 4 = gruposrc/mocks/e2e-fixtures.ts:367-367, src/mocks/e2e-fixtures.ts:405-405, src/mocks/e2e-fixtures.ts:1069-1071
Turnovaluediurno, noturno, vespertino, unicasrc/types/IClass.ts:37-40, src/types/ITurma.ts:14-17, src/types/ICycles.ts:23-26
MeetingStatusstatusavailable, progress, donesrc/models/MeetingRecover.ts:1-5

Divergências entre modelo e código de runtime

DivergênciaTipo/ModeloRuntime observadoImpactoEvidência
Projeção de participante muda de shape entre presença e gestão de atividadesStudent.activities é Record<string, boolean>Participant.activities é lista com status, id?, activity_id; useSubmissions junta participantes com submissões para construir essa visãomesmo conceito funcional aparece em dois formatos distintossrc/types/IStudent.ts:1-18, src/types/IParticipants.ts:1-25, src/hooks/useSubmissions.ts:81-127
BFF de participantes retorna fonte de presença, mas o consumidor tipa Participant[]rota usa getPresenceByClassIdgetParticipants() promete Participant[]possível descompasso entre contrato do endpoint e shape consumidosrc/app/api/submissions/class/[id]/route.ts:22-27, src/app/services/bff/SubmissionService.ts:151-155
CreateAppointment.employee_id é numérico no tipoo handler injeta facilitador.cpf em employee_idcampo sai como string/CPF ao montar o payload do upstreamincompatibilidade entre tipo local e payload efetivo enviadosrc/types/IAppointment.ts:43-50, src/app/api/schedule/appointment/create/route.ts:54-60
Facilitador muda de shape entre resumo e detalhe de turmaClassData.facilitator é id numérico, com facilitator_name e facilitator_email separadosCourse.facilitator é objeto completo Facilitatora entidade “facilitador” não é uniforme entre projeçõessrc/types/IClass.ts:69-73, src/types/ITurma.ts:4-10, src/types/IFacilitador.ts:2-10
Ciclo muda de tipo no campo activitiesCycle.activities é stringClassData.ciclos.activities é number; fixture também usa númerodivergência de tipagem entre projeções do mesmo domíniosrc/types/ICycles.ts:1-10, src/types/IClass.ts:28-35, src/mocks/e2e-fixtures.ts:466-473
Usuário consultado e sessão autenticada não compartilham o mesmo contratoUserLogin é mínimoSession.user e payload de login carregam token, role, user_display_name, user_first_name, user_last_name, possivelmente enroll_idso modelo de usuário de runtime é mais rico que o tipo de consulta BFFsrc/types/IUser.ts:1-10, src/types/next-auth.d.ts:3-14, src/utils/authOptions.ts:69-87

Pendências

  • Não há migrations, DDL, schema Prisma/Sequelize/TypeORM ou modelos persistentes locais; portanto não foi possível comprovar constraints físicas de banco, unique reais, on delete, índices ou nomes de tabelas.
  • ClassData, Course e Cycle são projeções de API externa e não um modelo relacional único; o acoplamento exato entre essas estruturas depende do backend WordPress.
  • A rota GET /api/submissions/{id} é consumida por serviço BFF, mas não está implementada no handler local; isso impede validar um modelo canônico de “submissão unitária”. Evidência: src/app/services/bff/SubmissionService.ts:43-47, src/app/api/submissions/[id]/route.ts:4-84.
  • O payload de recuperação depende de backend externo e ainda contém a divergência class_idd no proxy local. Evidência: src/app/api/cycles/recovery-status/route.ts:38-46.

ERD Mermaid

Evidências do ERD:

  • src/types/IClass.ts:42-82
  • src/types/ITurma.ts:4-25
  • src/types/IStudent.ts:6-18
  • src/types/IParticipants.ts:1-25
  • src/types/ISubmission.ts:1-106
  • src/types/IAppointment.ts:4-55
  • src/models/MeetingRecover.ts:7-33