--- name: Módulo de Feriados + Cron de aulas description: Sistema que pausa lembretes/cobranças em feriados e marca aulas como concluídas via cron diário. Tela em /direcao/feriados. type: project originSessionId: 86576285-fa7a-44f0-8ed3-9a88bcd27a8e --- ## Módulo de Feriados (2026-05-05) ### Banco - **Tabela `feriados`**: id, data (DATE — ano 2000 quando recorrente), descricao, tipo ENUM(nacional|estadual|municipal|recesso|facultativo), recorrente TINYINT, ativo TINYINT - **Pré-populada com 21 feriados** em produção: 11 nacionais recorrentes (Ano Novo, Tiradentes, Trabalho, Independência, Aparecida, Finados, República, Consciência Negra, Natal + Vésperas) e 10 móveis para 2026 e 2027 (Carnaval seg/ter, Cinzas, Sexta Santa, Corpus Christi) - **Config `pausar_em_feriados`** em `configuracoes_lembrete` (chave/valor) — default ON ### Código - **`FeriadoModel`** com `isFeriado($data)`, `getFeriadoNaData($data)`, `listarPorAno($ano)` (expande recorrentes), e **`static deveBloquearAutomacoesHoje()`** que combina config + check de hoje - **Bloqueio integrado** em: - `LembreteService::processarLembretesPendentes()` — return early com flag `bloqueado_feriado` - `CobrancaService::processarCobrancas()` — idem com `motivo='feriado'` - **`FeriadoController`** + view `direcao/feriados.php` — CRUD com modal, toggle global, status do dia - **Item "Feriados" no menu lateral** (com check de permissão) ### Cron diário — `CronController::marcarAulasFeriado` - Endpoint público protegido por token: `/cron/marcar-aulas-feriado?token=agm-cron-7Hk29Lqp2Mz5RtVx` - Endpoint dry-run: `/cron/teste-feriado?token=...` - **Cron ativo no servidor**: `0 11 * * * curl ...` (11h UTC = 8h BRT) - Lógica: se config ON + hoje feriado → pega aulas `agendada`/`em_andamento` do dia → marca `concluida` com `presenca_aluno=presente` (computa comissão integral 100%) e adiciona `[FERIADO]` na observação - **Idempotente**: pula aulas que já têm `[FERIADO]` na observação **Why:** Escola fechada em feriado (carnaval, semana santa, etc) — clientes não recebem cobranças, professores recebem comissão sem precisar dar a aula, sistema não envia spam. **How to apply:** Para adicionar bloqueio em outro disparador automático, importar `\App\Models\FeriadoModel` e checar `FeriadoModel::deveBloquearAutomacoesHoje()` no início. Para reuso do cron token, está hardcoded em `CronController::TOKEN`.