fix: enforce subject and period selection when publishing exams to ensure report card sync
This commit is contained in:
parent
94fe187998
commit
c75d27f198
|
|
@ -19,6 +19,12 @@
|
|||
> Ao realizar a migração completa dos dados do sistema legado 'schoodat' para o nosso banco de dados local Postgres, **é terminantemente proibido alterar, resetar ou re-hashear as senhas existentes.**
|
||||
> As credenciais devem ser mantidas exatamente como estão para garantir que o acesso dos usuários não seja interrompido.
|
||||
|
||||
## 🚨 Regras de Fluxo de Trabalho (CRÍTICO)
|
||||
|
||||
> [!CAUTION]
|
||||
> **Git Push Proibido Sem Demanda Explícita:**
|
||||
> NUNCA execute `git add`, `git commit` ou `git push` sem que o USUÁRIO solicite explicitamente. Alterações devem ser feitas nos arquivos, mas o envio ao repositório remoto é uma ação exclusiva do usuário. Aguarde sempre o comando direto do usuário para realizar qualquer operação de versionamento.
|
||||
|
||||
## 📜 Padrões de Desenvolvimento
|
||||
1. **Design System:** Estética Premium, Dark Mode por padrão (ou glassmorphism), micro-animações e ausência de placeholders.
|
||||
2. **Segurança:** Todas as rotas sensíveis devem validar o token JWT local (via secrets do ambiente). Proibido usar Supabase SDK para lógica de autenticação ou sincronização no frontend.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# MEMORY.md - Contexto de Desenvolvimento
|
||||
|
||||
> **🚨 REGRA ABSOLUTA:** NUNCA execute `git add/commit/push` sem que o usuário peça explicitamente. Alterações nos arquivos são livres, mas versionamento é ação EXCLUSIVA do usuário.
|
||||
|
||||
## 📅 Estado Atual (30/04/2026)
|
||||
|
||||
- [x] **Automação de Mensagens (Cron Jobs):** Implementados dois disparadores independentes (`preventivo` e `atrasado`) via `node-cron`.
|
||||
|
|
@ -10,8 +12,10 @@
|
|||
- [x] **Auto-Initialization DB:** Script de boot que garante a existência das colunas `overdue_warnings_count` e `last_overdue_warning_at` na tabela `alunos_cobrancas`.
|
||||
- [x] **Correção de Crash no Portal:** Resolvido erro de `.toFixed()` que quebrava as abas de "Avaliações" e "Notas" devido ao retorno de tipos `NUMERIC` do PostgreSQL como strings.
|
||||
- [x] **Persistência de UI (Mensagens):** Integrada chamada ao `updateData` ao salvar agendamentos, garantindo que o estado do toggle não seja perdido ao trocar de aba no Manager.
|
||||
- [x] **Sincronização de Boletim (Provas):** Adicionada validação rigorosa no Manager (`Exams.tsx`) para impedir a publicação de provas sem vínculo com `subjectId` e `periodId`. Inserido alerta visual para provas legadas desconectadas, garantindo que as notas feitas no Portal sejam corretamente injetadas no Boletim.
|
||||
- [ ] Próximo Passo: Monitorar o log de disparos automáticos (`[Cron]`) e validar a taxa de entrega via Evolution API.
|
||||
|
||||
|
||||
## 📅 Histórico Anterior (22/04/2026)
|
||||
|
||||
- [x] Correção do "Bug da Tela Preta" na câmera ao alternar para câmera traseira no celular.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState, useRef } from 'react';
|
||||
import { SchoolData, Exam, Question } from '../types';
|
||||
import { FileText, Plus, Search, BookOpen, Upload, Trash2, ArrowLeft, Save, CheckCircle, Image as ImageIcon, X, RefreshCw, Lock, Unlock } from 'lucide-react';
|
||||
import { FileText, Plus, Search, BookOpen, Upload, Trash2, ArrowLeft, Save, CheckCircle, Image as ImageIcon, X, RefreshCw, Lock, Unlock, AlertTriangle } from 'lucide-react';
|
||||
import { uploadExamImage } from '../services/supabase';
|
||||
import { useDialog } from '../DialogContext';
|
||||
import { dbService } from '../services/dbService';
|
||||
|
|
@ -165,7 +165,16 @@ const Exams: React.FC<ExamsProps> = ({ data, updateData }) => {
|
|||
if (!editingExam) return;
|
||||
|
||||
if (!editingExam.title || !editingExam.classId) {
|
||||
alert('Preencha o título e a turma antes de salvar.');
|
||||
showAlert('Atenção', 'Preencha o título e a turma antes de salvar.', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
if (status === 'published' && (!editingExam.subjectId || !editingExam.periodId)) {
|
||||
showAlert(
|
||||
'Vínculo Obrigatório',
|
||||
'Para PUBLICAR a avaliação e permitir que as notas entrem no Boletim Escolar, você precisa vincular uma Disciplina e um Período.',
|
||||
'warning'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -266,7 +275,9 @@ const Exams: React.FC<ExamsProps> = ({ data, updateData }) => {
|
|||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-bold text-slate-700 mb-2">Disciplina (Boletim)</label>
|
||||
<label className="block text-sm font-bold text-slate-700 mb-2">
|
||||
Disciplina (Boletim) <span className="text-amber-500" title="Obrigatório para publicar">*</span>
|
||||
</label>
|
||||
<select
|
||||
value={editingExam.subjectId || ''}
|
||||
onChange={e => setEditingExam({ ...editingExam, subjectId: e.target.value || undefined })}
|
||||
|
|
@ -277,10 +288,12 @@ const Exams: React.FC<ExamsProps> = ({ data, updateData }) => {
|
|||
<option key={s.id} value={s.id}>{s.name}</option>
|
||||
))}
|
||||
</select>
|
||||
<p className="text-[11px] text-slate-400 mt-1.5">Vincule a uma disciplina do Boletim Escolar para lançar notas automaticamente.</p>
|
||||
<p className="text-[11px] text-amber-600 mt-1.5 font-semibold">Obrigatório para Publicar. A nota irá automaticamente para o boletim.</p>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-bold text-slate-700 mb-2">Período (Boletim)</label>
|
||||
<label className="block text-sm font-bold text-slate-700 mb-2">
|
||||
Período (Boletim) <span className="text-amber-500" title="Obrigatório para publicar">*</span>
|
||||
</label>
|
||||
<select
|
||||
value={editingExam.periodId || ''}
|
||||
onChange={e => setEditingExam({ ...editingExam, periodId: e.target.value || undefined })}
|
||||
|
|
@ -291,7 +304,7 @@ const Exams: React.FC<ExamsProps> = ({ data, updateData }) => {
|
|||
<option key={p.id} value={p.id}>{p.name}</option>
|
||||
))}
|
||||
</select>
|
||||
<p className="text-[11px] text-slate-400 mt-1.5">Vincule a um período para que a nota apareça no campo correto do boletim.</p>
|
||||
<p className="text-[11px] text-amber-600 mt-1.5 font-semibold">Obrigatório para Publicar. Define em qual coluna do boletim a nota entra.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -536,6 +549,17 @@ const Exams: React.FC<ExamsProps> = ({ data, updateData }) => {
|
|||
{(data.periods || []).find(p => p.id === exam.periodId)?.name || '—'}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* ALERTA DE BOLETIM */}
|
||||
{exam.status === 'published' && (!exam.subjectId || !exam.periodId) && (
|
||||
<div className="flex items-start gap-2 bg-amber-50 p-3 rounded-xl border border-amber-200 mt-3">
|
||||
<AlertTriangle size={16} className="text-amber-500 shrink-0 mt-0.5" />
|
||||
<p className="text-[11px] font-medium text-amber-700 leading-tight">
|
||||
<strong>Boletim Desconectado!</strong><br />
|
||||
As notas desta avaliação não aparecerão no boletim do aluno porque faltou vincular a Disciplina ou o Período. Edite a prova para corrigir.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="border-t border-slate-100 pt-4 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
|
|
|
|||
Loading…
Reference in New Issue