📄 Documento de Execução — Card 13: [M3] Chamada Digital (4 status)
| Campo | Valor |
|---|---|
| Card Trello | [13] [M3] Chamada Digital (4 status) |
| URL Trello | https://trello.com/c/dnVTE9R7 |
| Marco | M3 — Painel do Professor (PROFESSOR) |
| Data execução | 04/08/2026 |
| Responsável | Wellington Santiago (via ZCode) |
| Doc anterior | Card 12: Diário de Classe (M3) |
| Próximo card | Card 14: Tarefas & Avaliações (M3) |
| Commits | 6dab52b |
🎯 1. O que foi implementado
Substituído o protótipo mock da página /professor/chamada (que usava students de @/data/mock, inicializava todos como PRESENTE, e tinha o botão "Marcar todos presentes" que o cliente proibiu) por uma implementação real e completa da Chamada Digital, conectada ao banco via tRPC.
O professor agora registra a frequência dos alunos por turma/data/aula, com 4 status clicáveis (Presente, Atrasado, Falta, Justificada), sem botão "marcar todos" (regra explícita do cliente — cada aluno é marcado individualmente). Cada marcação é salva automaticamente (auto-save via optimistic UI), com feedback imediato.
O sistema respeita todas as regras confirmadas pelo cliente: atraso = mais de 15 minutos (registra arrivalTime), faltas geram notificação aos responsáveis (prazo de justificativa de 3 dias), justificativas aprovadas aparecem inline no registro, frequência mínima 75%, e validação de que o professor só faz chamada nas turmas onde foi formalmente vinculado (ClassTeacher).
O seletor de data (default hoje, não permite futuro) + número da aula (1-4) permite registrar chamadas de aulas passadas ou múltiplas aulas no mesmo dia. O resumo mostra presentes/atrasados/faltas/justificados + taxa de presença em tempo real.
✅ Critérios de aceite validados
| # | Critério | Status |
|---|---|---|
| 1 | Lista de alunos da turma | ✅ |
| 2 | 4 status clicáveis | ✅ |
| 3 | Observação por aluno (justificativa aprovada inline) | ✅ |
| 4 | Sincronização com frequência (Attendance) | ✅ |
| 5 | Rota tRPC attendance.listByClass | ✅ |
| 6 | Rota tRPC attendance.mark | ✅ |
| 7 | Rota tRPC attendance.batchMark | ✅ |
| 8 | Página /professor/chamada (seleção) | ✅ |
| 9 | Página /professor/chamada/[classId] | ✅ |
| 10 | Componente StudentAttendanceRow | ✅ |
| 11 | Componente StatusButton (4 variantes) | ✅ |
| 12 | Componente DatePicker (default hoje) | ✅ |
| 13 | Componente LessonNumberSelect (1-4) | ✅ |
| 14 | Componente SummaryCounter | ✅ |
| 15 | Validação: professor só em turmas atribuídas | ✅ |
| 16 | Validação: 1 chamada por aluno/aula (unique constraint) | ✅ |
| 17 | Auto-save a cada marcação | ✅ |
| 18 | Auditoria: logar CREATE/UPDATE attendance | ✅ |
| 19 | Histórico: ver chamadas anteriores (DatePicker) | ✅ |
| 20 | Editar chamada passada | ✅ |
| 21 | Indicador: aluno já justificou falta (inline) | ✅ |
| 22 | SEM botão "marcar todos presentes" (regra cliente) | ✅ |
📁 2. Arquivos criados/modificados
Criados
| Arquivo | Função |
|---|---|
src/app/(dashboard)/professor/chamada/[classId]/page.tsx |
Lista de alunos com 4 status clicáveis, auto-save, resumo, seletor data/aula |
src/components/ui/StatusButton.tsx |
Botão de status de frequência (4 variantes coloridas + STATUS_CONFIG + STATUS_ORDER) |
Modificados
| Arquivo | Mudança |
|---|---|
src/server/trpc/routers/professor.ts |
+sub-router attendance com 4 procedures (listByClass, mark, batchMark, history) |
src/app/(dashboard)/professor/chamada/page.tsx |
Reescrita total: removeu mock, agora lista turmas reais (agrupadas por turma única) |
🗄️ 3. Schema do banco (mudanças)
Nenhuma mudança de schema — reutilizado:
- Model
Attendance(com@@unique([studentId, classId, date, lessonNumber])— garante 1 chamada por aluno/aula) - Enum
AttendanceStatus { PRESENT, ABSENT, JUSTIFIED, LATE } - Model
AttendanceJustification(status PENDING → aprovada por LOCAL/Coordenação) - Model
ClassTeacher(validação de acesso pedagógico)
🔌 4. Handoff para o próximo card
Procedures tRPC disponíveis (professor.attendance.*)
listByClass({classId, date, lessonNumber})→{ classInfo, students[], records[] }mark({studentId, classId, date, lessonNumber, status})→{id, status}(auto-save, LATE registra arrivalTime, ABSENT notifica responsáveis)batchMark({classId, date, lessonNumber, entries[]})→{upserted}(lote)history({classId, from?, to?})→{ history: [{date, lessonNumber, total, counts}] }
Componentes reutilizáveis
StatusButton+STATUS_CONFIG+STATUS_ORDER— reusar em qualquer lugar que mostre frequência (relatórios, dashboard, painel do pai)resolveTeacher()(do Card 12) — autorização padrão para todos os procedures do professor
Regras de negócio aplicadas (decisões do cliente)
| # | Regra | Implementação |
|---|---|---|
| 1 | Atraso = 15 min | LATE registra arrivalTime = new Date() (UI não força o cálculo dos 15min — professor decide marcar LATE) |
| 2 | SEM "marcar todos" | Botão removido; cada aluno marcado individualmente |
| 3 | Faltas → aviso responsáveis | ABSENT cria Notification para cada StudentGuardian (WhatsApp real no Card 29, push no Card 11/18) |
| 4 | Prazo justificativa: 3 dias | Já validado no Card 9 (canJustify) — pai vê no /pais/faltas |
| 5 | Atestado facultativo | Já no Card 9 (modal de justificativa) |
| 6 | Aprovação: Coordenador/LOCAL | Já no Card 9 (reviewedBy = LOCAL) |
| 7 | Frequência mínima 75% | Mostrado na legenda (cálculo consolidado no Card 9/painel pai) |
| 8 | 1-4 aulas por dia | LessonNumberSelect (1, 2, 3, 4) |
📋 5. Checklist do Trello — status por item
Entregas (4/4)
- Lista de alunos da turma
- 4 status clicáveis
- Observação por aluno (justificativa aprovada mostrada inline)
- Sincronização com frequência
Especificação Técnica (19/24 implementados)
Não implementados nesta iteração (refinamento futuro):
markAllPresent— intencionalmente não implementado (cliente proibiu botão "marcar todos")- Job Bull
attendance-alert→ WhatsApp (Card 29, quando integrar WhatsApp Business API) - Push notification (Card 11/18, quando integrar Web Push)
- Evento Socket
attendance:updated(tempo real, quando adicionar Socket.io) - Remarcar após erro até 24h (atualmente permite editar qualquer data passada sem restrição de 24h)
🚀 6. Deploy DEV
- URL seleção: https://sistemaescolar.wellka.com.br/professor/chamada
- URL chamada: https://sistemaescolar.wellka.com.br/professor/chamada/{classId}
- Login demo:
carla.prof@genioon.com.br/Prof@2026 - Profª Carla Mendes: turma "6º A", 5 alunos ativos
- Commit:
6dab52b - PM2: genioon-dev reload ✓ (smoke test HTTP 200)
🧠 7. Contexto gerado para próximas etapas
STATUS_CONFIG+STATUS_ORDER(emStatusButton.tsx) são a fonte canônica de cores/labels de status de frequência — reusar em relatórios, dashboard, painel do pai.- Fluxo ABSENT → Notification → responsável está pronto. Quando integrar WhatsApp (Card 29), substituir/adicionar o envio do template de falta. Quando integrar Web Push (Card 11/18), disparar push também.
attendance.history(groupBy) está disponível para o dashboard da unidade (Card 17) consolidar frequência da turma.- Justificativa aprovada aparece inline no registro do professor (campo
justifiedda query). O fluxo de aprovação em si está no Card 9 (painel do pai/pais/faltas+ LOCAL aprova). - Auto-save via optimistic UI: padrão que funcionou bem aqui — aplicar nos próximos formulários do professor (Card 14 tarefas, Card 15 plano de aula).
🎯 8. Próximo card
Card 14 [M3] Tarefas & Avaliações
- Spec:
docs/execucao/14-m3-tarefas-avaliacoes.md - Foco: professor cria tarefas/avaliações (Task/Exam), define prazos, anexa materiais
- Reuso:
ProfessorShell,resolveTeacher(), validaçãoClassTeacher, modelTask/Exam - O aluno já entrega tarefas (Card 7) — este card é o painel do professor para criar/corrigir