Pular para o conteúdo principal

Data Model

Introdução ao documento

Este documento descreve o modelo de dados real que pôde ser comprovado no repositório. A fonte principal solicitada para este tipo de inventário seria migrations/schema/models, mas esse workspace não contém migrations, ORM schema, DDL ou arquivos SQL. Por isso, o conteúdo abaixo registra um modelo lógico de runtime e integração, derivado de interfaces TypeScript, contratos HTTP e validações de formulário, sem promovê-lo a modelo físico persistente.

Leitura aplicada

  • Fato observado: campos e estruturas presentes em interfaces, handlers, adapters e validações.
  • Inferência controlada: relacionamento lógico sugerido pelo uso em runtime, sem FK física comprovada.
  • Divergência: diferença entre o modelo lógico observado no runtime e a ausência de schema físico local.

Evidências:

Versionamento

Este documento deve ser atualizado quando:

  • surgirem migrations, schema files ou models físicos no repositório;
  • interfaces TypeScript e contratos HTTP alterarem o shape das entidades lógicas;
  • validações de runtime mudarem constraints relevantes de domínio.

Inferência controlada

  • Enquanto o schema físico permanecer fora deste repositório, docs/data/model.md continuará sendo uma fotografia do modelo lógico observado no código de integração e no runtime.

Evidências:

Referencial teórico

Este documento usa modelagem lógica orientada a contratos, priorizando:

  • tipagem TypeScript para shape de entidades de integração;
  • contratos HTTP para objetos trafegados em runtime;
  • validações de formulário para constraints observáveis do domínio.

Inferência controlada

  • Na ausência de schema físico, esse é o nível mais confiável de modelagem que o repositório permite hoje.

Evidências:

Entidades/tabelas principais

1. Participant (runtime/frontend + WordPress)

Fato observado

  • Campos comprovados: ID?, id, cpf, name, email, phone, birthday, gender, race.
  • Este é o shape mais completo de participante usado no runtime do frontend.

Evidências:

2. RegistrationPerson (backend de registration)

Fato observado

  • Campos comprovados no payload retornado: id, name, has_cnpj, show_name, contactInfo[].
  • O adapter converte esse payload para uma visão simplificada com id, cpf, name, email, phone.

Evidências:

3. ContactInfo (aninhado em RegistrationPerson)

Fato observado

  • Campos comprovados: id?, contact_info_type, contact_info_content.
  • Essa estrutura aparece tanto em leitura quanto em escrita no backend de registration.

Evidências:

4. CourseCustomization

Fato observado

  • Campos comprovados: course_id, slug, title, presentation, logo.url, banner.url, total_users, flow_template_id, flow_template_header_image, tracking_id?, flags e textos de manutenção.
  • Essa entidade é obtida do endpoint WordPress /course/{slug} e usada para montar a UI, o tracking e o envio de template.

Evidências:

5. CourseCycleStatus

Fato observado

  • Campos comprovados: available e um objeto cycle com ID, cicle, start_date, end_date, activities, activity_titles, collective_meeting_time_slot, collective_meetings, individual_meetings, enrollment_start_date, enrollment_end_date.

Divergência

  • O campo cicle aparece assim no contrato observado, e não cycle. O documento mantém a grafia real do código.

Evidências:

6. EnrollmentSnapshot

Fato observado

  • Campos comprovados: enrollment_id, class_id, course_name, enrolled_in, cycle_id.
  • Essa estrutura aparece dentro de enrolls[] no retorno do status de matrícula.

Evidências:

7. ConcurrentEnrollmentDetail

Fato observado

  • Campos comprovados: class_id, start_date, end_date, course_name, block.
  • Essa estrutura aparece dentro de enrolled_in_concurrent_course_detail[].

Evidências:

8. SessionUser

Fato observado

  • Campos comprovados: id?, cpf, name?, email?, birthday?, gender?, race?, phone?, course_slug?, canceledEnrolls?.
  • A sessão é o principal snapshot local de identidade usado pelos handlers e componentes autenticados.

Evidências:

Fato observado

  • Campos comprovados: ok, enroll_id?, group_link?.
  • O frontend usa group_link para redirecionamento e enroll_id como identificador de entrada.

Evidências:

10. MaintenanceMode

Fato observado

  • Campos comprovados: active, fields.title?, fields.message?, fields.description?.
  • Essa estrutura governa o desvio de fluxo no middleware e na página de manutenção.

Evidências:

Relacionamentos e cardinalidade

RegistrationPerson 1:N ContactInfo

Fato observado

  • O contrato do backend de registration expõe contactInfo[] dentro da pessoa.

Evidências:

Participant 1:1 SessionUser

Inferência controlada

  • A sessão armazena um snapshot do participante, enriquecido com course_slug e canceledEnrolls.

Evidências:

Participant 1:N EnrollmentSnapshot

Inferência controlada

  • O status de matrícula é buscado por (course_slug, id) do usuário e retorna enrolls[], o que sugere múltiplas matrículas históricas ou relacionadas ao participante.

Evidências:

CourseCycleStatus 1:N EnrollmentSnapshot

Inferência controlada

  • EnrollmentSnapshot carrega cycle_id, enquanto CourseCycleStatus.cycle expõe ID. O vínculo é lógico por nomenclatura, não físico.

Evidências:

CourseCustomization 1:1 CourseCycleStatus

Inferência controlada

  • Ambos são buscados a partir do mesmo slug de curso em runtime.

Evidências:

Inferência controlada

  • GroupLink recebe enroll_id, enquanto a matrícula expõe enrollment_id. A proximidade semântica sugere ligação, mas há divergência de nomenclatura e nenhuma FK explícita.

Evidências:

Campos críticos (PK, FK, unique, status, timestamps)

EntidadeCampoPapel observadoLeituraEvidências
ParticipantidIdentificador principal lógicoInferência controlada como PK lógica; não há PK física comprovada../../src/features/components/SignupConfirmation/components/ProfileConfirmation/ProfileConfirmation.interface.ts#L8-L18
ParticipantcpfIdentificador de negócio e lookup principalFato observado../../pages/api/v1/participantes/[cpf].ts#L17-L24, ../../pages/api/auth/[...nextauth].ts#L41-L45
SessionUsercourse_slugChave contextual de curso na sessãoFato observado../../src/common/types/next-auth/next-auth.d.ts#L13-L14, ../../pages/api/auth/[...nextauth].ts#L102-L106
CourseCustomizationslugChave de acesso do cursoFato observado../../src/features/api/external/wp/getCustomization/getCustomization.ts#L10-L13
CourseCustomizationcourse_idIdentificador de curso do backendFato observado../../src/features/api/external/wp/getCustomization/getCustomization.ts#L9-L10
CourseCustomizationflow_template_idChave funcional para envio de template WhatsAppFato observado../../src/features/api/external/wp/getCustomization/getCustomization.ts#L13-L16, ../../pages/api/v1/otp/confirm.ts#L39-L46
CourseCycleStatusavailableStatus funcional do cursoFato observado../../src/features/api/external/wp/getCourseStatus/getCourseStatus.interface.ts#L1-L3
EnrollmentSnapshotenrollment_idIdentificador da matrículaFato observado../../src/features/api/external/wp/getUserEnrollStatus/getUserEnrollStatus.interface.ts#L3-L9
EnrollmentSnapshotcycle_idReferência lógica para cicloInferência controlada como FK lógica../../src/features/api/external/wp/getUserEnrollStatus/getUserEnrollStatus.interface.ts#L3-L9, ../../src/features/api/external/wp/getCourseStatus/getCourseStatus.interface.ts#L3-L15
GroupLinkenroll_idReferência lógica para matrículaInferência controlada como FK lógica../../src/features/api/external/wp/getGroupLink/getGroupLink.interface.ts#L1-L10
MaintenanceModeactiveStatus binário de desvio operacionalFato observado../../src/features/api/external/wp/getMaintenanceMode/getMaintenanceMode.ts#L4-L11

Timestamps e datas

Fato observado

  • Não há created_at, updated_at, deleted_at ou campos equivalentes de auditoria no modelo local observado.
  • Há campos de data e período de domínio: birthday, start_date, end_date, enrollment_start_date, enrollment_end_date, enrolled_in.

Evidências:

Unique e chaves físicas

Divergência

  • O código sugere que cpf funciona como identificador de negócio, mas o repositório não contém constraint UNIQUE física para comprovar isso no storage.
  • O mesmo vale para id, course_id, cycle.ID, enrollment_id e enroll_id: há uso como identificadores, mas não há PK/FK/UNIQUE físicos versionados aqui.

Evidências:

Constraints e enums

Constraints de runtime comprovadas

Fato observado

  • cpf é obrigatório, com mínimo e máximo de 11 dígitos, e passa por validateCpf.
  • name é obrigatório, trimado e deve parecer nome completo.
  • email é obrigatório e validado como e-mail.
  • phone é obrigatório e deve ter pelo menos 8 caracteres.
  • birthday é obrigatória, deve ter pelo menos 10 caracteres e representar data válida no passado.
  • gender e race são obrigatórios.

Evidências:

Enums/catálogos observados em runtime

Fato observado

  • gender possui opções de UI: Feminino, Masculino, Prefiro não informar.
  • race possui opções de UI: Preta, Parda, Branca, Amarela, Indigena, Prefiro não informar.
  • MaintenanceMode.active, CourseCycleStatus.available, GetUserEnrollsResponse.enrolled, enrolled_in_same_category, enrolled_in_concurrent_course são booleanos observados.

Divergência

  • Essas listas são catálogos de interface/runtime, não enums físicos comprovados em banco.

Evidências:

Divergências entre modelo e código de runtime

Ausência de schema físico local

Divergência

  • O runtime trabalha com entidades relativamente claras (Participant, CourseCustomization, EnrollmentSnapshot, SessionUser), mas não há migrations, models persistentes ou DDL que permitam afirmar o desenho físico real.

Evidências:

Divergência de nomes entre contratos

Divergência

  • GroupLink.enroll_id e EnrollmentSnapshot.enrollment_id parecem referir o mesmo conceito, mas com nomes diferentes.
  • CourseCycleStatus.cycle.cicle está grafado dessa forma no contrato observado.
  • Participant no frontend usa ID? e id, enquanto SessionUser aceita id?.

Evidências:

Pendências

  • Identificar se o modelo físico real vive em outro repositório ou serviço.
  • Confirmar se o backend canônico de pessoa/participante é WordPress, Registration backend ou ambos.
  • Confirmar a semântica exata do vínculo entre enroll_id e enrollment_id.
  • Confirmar se course_id e cycle.ID são chaves estáveis ou apenas identificadores de payload externo.
  • Confirmar se os catálogos de gender e race são realmente enums de domínio ou apenas opções atuais de UI.

Evidências:

ERD Mermaid

Evidências: