Skip to content

Modelo de Domínio

Este documento descreve as entidades centrais do Neemias, seus atributos e relacionamentos, conforme implementado no backend (Cloudflare Workers + D1) e consumido pelo frontend (React SPA).

Glossário (Português → Inglês)

Termo em portuguêsEntidade / ConceitoUso no código
Presença / ChamadaAttendance — marcar aluno como presente ou ausenteAttendanceEvent.actionType: MARK_PRESENT, MARK_ABSENT
Aluno / EstudanteStudent — criança registrada no sistemaStudent entity, students table
TurmaClass — faixa etária (ex: Berçário, Juniores)Class entity, classes table
AulaClassSlot (recorrente) + ClassSession (ocorrência concreta)ClassSlot (dia+horário), ClassSession (data específica)
Núcleo / CélulaNucleus — pequeno grupo por regiãoNucleus entity, nuclei table
RegiãoNucleusRegion — 7 cores fixasAzul Celeste, Azul, Amarela, Branca, Vermelha, Laranja, Verde
ResponsávelGuardian — pai/mãe/responsável pelo alunoguardianName, guardianNameAlt
FrequênciaReport — presença semanal, mensal, por alunoReportsPage — Frequência Semanal, por Aula, por Aluno
MembresiaFamily membership statusMEMBRO, NAO_MEMBRO, DESCONHECIDO

Entidades

Student (Aluno)

Tabela: students (D1 SQLite) / SQLite WASM table: students (local)

AtributoTipoDescrição
student_idTEXT PKIdentificador único
display_nameTEXTNome de exibição do aluno
photo_refTEXTReferência da foto
statusTEXTACTIVE ou DELETED
deleted_justificationTEXTJustificativa obrigatória (10-500 chars) ao excluir
guardian_nameTEXTNome do responsável principal
guardian_name_altTEXTNome do responsável alternativo
birth_dateTEXTData de nascimento
phonesJSON arrayLista de telefones (mín. 1, máx. 3)
family_membership_statusTEXTStatus de membresia familiar
address_streetTEXTLogradouro
address_numberTEXTNúmero
address_complementTEXTComplemento
address_neighborhoodTEXTBairro
address_cityTEXTCidade
address_stateTEXTEstado
address_zipTEXTCEP
class_idTEXT FKReferência para classes
nucleus_participatesINTEGER0 ou 1
nucleus_regionTEXTRegião do núcleo
nucleus_nameTEXTNome do núcleo
allergiesTEXTAlergias
special_needsTEXTNecessidades especiais

Regras: Soft-delete com justificativa obrigatória (10-500 chars). Histórico de presença preservado após exclusão. Índice: (status, updated_at DESC).

Class (Turma)

Tabela: classes (D1 SQLite) / Dexie table: classes (IndexedDB)

AtributoTipoDescrição
class_idTEXT PKIdentificador único
nameTEXT UNIQUENome da turma
age_minINTEGERIdade mínima
age_maxINTEGERIdade máxima
statusTEXTACTIVE ou DELETED

Seed padrão: Berçário, Maternal Infantil, Jardim de Infância, Infantil, Juniores 1, Juniores 2, Pré-Adolescentes.

Regras: Soft-delete via status = 'DELETED'. Apenas ADMIN pode criar/editar.

ClassSlot (Aula recorrente)

Tabela Dexie: classSlots (IndexedDB, frontend apenas)

AtributoTipoDescrição
slot_idTEXT PKIdentificador único
day_of_weekINTEGER0=Dom, 1=Seg, ..., 6=Sáb
start_timeTEXTHorário de início (HH:MM)
labelTEXTRótulo descritivo
session_dateTEXT?Data de aula avulsa (YYYY-MM-DD), undefined para recorrente semanal

ClassSession (Ocorrência concreta de aula)

Tabela Dexie: classSessions (IndexedDB, frontend apenas)

AtributoTipoDescrição
session_idTEXT PKIdentificador único
slot_idTEXT FKReferência para ClassSlot
session_dateTEXTData da sessão (YYYY-MM-DD)

AttendanceEvent (Evento de Presença)

Tabela: attendance_events (D1 SQLite) / Dexie table: attendanceEvents (IndexedDB)

AtributoTipoDescrição
event_idTEXT PKIdentificador único
student_idTEXT FKReferência para students
class_session_idTEXT FKReferência para ClassSession (frontend)
action_typeTEXTMARK_PRESENT ou MARK_ABSENT
happened_atTEXTTimestamp do evento
actor_user_idTEXT FKUsuário que executou a ação
actor_roleTEXTPapel do ator no momento
server_timestampTEXTTimestamp do servidor
is_conflict_loserINTEGER0 ou 1 — perdedor de resolução de conflito
conflict_superseded_byTEXT?Ponteiro para evento vencedor (frontend)

Regras: Event-sourced — toda presença é um evento imutável. Projeção deriva estado atual. Índice: (student_id, server_timestamp DESC).

Nucleus (Núcleo)

Tabela: nuclei (D1 SQLite)

AtributoTipoDescrição
nucleus_idTEXT PKIdentificador único
regionTEXTUma das 7 regiões fixas
nameTEXTNome do núcleo
statusTEXTACTIVE ou DELETED

Regiões fixas: Azul Celeste, Azul, Amarela, Branca, Vermelha, Laranja, Verde.

Regras: Soft-delete via status = 'DELETED'. Apenas ADMIN pode criar/editar.

User (Usuário)

Tabela: users (D1 SQLite). Desde v0.56.0, papéis são armazenados em tabela separada user_roles.

UserRole (v0.56.0+)

Tabela: user_roles — tabela de junção para suporte multi-papel.

AtributoTipoDescrição
user_idTEXT FKReferência para users(user_id)
roleTEXTNome do papel (ex: CHAMADOR)
created_atTEXTISO 8601

PK: (user_id, role)

EventRegistration (Inscrição em Evento)

Tabela: event_registrations (v0.46.0+).

AtributoTipoDescrição
registration_idTEXT PKIdentificador único
event_idTEXT FKReferência para events
student_idTEXT FKReferência para students
statusTEXTREGISTERED, CONFIRMED, CANCELLED
created_atTEXTISO 8601

Tabela: users (D1 SQLite) / Dexie table: users (IndexedDB)

AtributoTipoDescrição
user_idTEXT PKIdentificador único
emailTEXT UNIQUEE-mail do usuário
display_nameTEXTNome de exibição
roleTEXTADMIN, CHAMADOR, RELATORIOS ou CADASTRO
statusTEXTACTIVE ou DELETED
password_hashTEXTHash PBKDF2 no formato pbkdf2:<hexSalt>:<hexHash>

Role (Papel / Perfil)

Definido em packages/permissions/index.ts — fonte única da verdade.

PapelCódigoPermissões principais
AdminADMINAcesso total: CRUD alunos/turmas/núcleos, chamada, relatórios, seed
ChamadorCHAMADORMarcar presença, buscar alunos
RelatóriosRELATORIOSVisualizar relatórios de frequência
CadastroCADASTROCriar e editar alunos e aulas

Relacionamentos

User ──┐
       │ actor_user_id

AttendanceEvent ◄──── Student ──────── Class
       │                  │
       │                  │ class_id
       │                  ▼
       │                Class

       │                  ┌── Nucleus (nucleus_participates)
       │                  │
       └──────────────────┘
  • Student → Class: N:1 via class_id FK.
  • Student → Nucleus: Participação opcional (nucleus_participates 0/1).
  • AttendanceEvent → Student: N:1 via student_id FK.
  • AttendanceEvent → User: N:1 via actor_user_id — todo evento registra quem o gerou.
  • ClassSlot → ClassSession: 1:N — um slot recorrente gera múltiplas sessões concretas.
  • ClassSession → AttendanceEvent: 1:N — cada sessão tem múltiplos eventos de presença.

Event Sourcing e Soft-Delete

  • Event Sourcing: Toda mutação de entidade principal (students, attendance) gera um evento imutável. O estado atual é uma projeção derivada desses eventos. Tabelas auxiliares: student_events, user_events.
  • Soft-delete: Nenhuma entidade principal é fisicamente removida. O campo status transita para DELETED. Justificativa obrigatória para exclusão de alunos.

Fontes: workers/CONTEXT.md, app/CONTEXT.md

Distribuído sob licença MIT.