# AG-Music - Projeto de Escola de Música ## Stack - CodeIgniter 4.6.1, PHP, MySQL (ag_music_banco) - Views com Tailwind CSS + SweetAlert2 ## Sistema de Comissões (atualizado 2026-03-20) - **Modelo atual**: Comissão por ANO DE MATRÍCULA do aluno (tabela `comissao_anual`) - **Override por matrícula**: campos `comissao_override_tipo/valor/motivo` → ver `memory/comissao_override.md` - Resolução: override > comissao_anual > fallback professor - Model: `ComissaoAnualModel::resolverComissao()` - método central - Limite: 4 aulas pagas por aluno/mês - Ver `memory/comissoes.md` para detalhes ## Deploy - Servidor: `server.whmservidor.com` **porta 1907** (user: root, pw: QVxdH6beewndm7Vj8nTvKTokr6eFJNvFy — atualizada 2026-05-06) - DB produção: `agmusiccom_agmusic` (user: `agmusiccom_agmusic`, pw: `&i?Vjpcf2jIU`) - Caminho no servidor: `/home/agmusiccom/public_html/sistema.agmusic/` - Ferramentas: PuTTY (`plink` e `pscp`) em `C:\Program Files\PuTTY\` - **IMPORTANTE**: Sempre sincronizar `financeiro/index.php` → `financeiro.php` (cp + chown) - Após upload, corrigir ownership: `chown -R agmusiccom:agmusiccom` ## Financeiro (atualizado 2026-03-20) - Cards, abas, contas, transferências → ver `memory/financeiro_cards_e_contas.md` - Views: `direcao/financeiro/index.php` E `direcao/financeiro.php` (ambos devem ser iguais) ## WhatsApp (atualizado 2026-03-20) - Bloqueio matrículas inativas, resposta automática, opção inválida → ver `memory/whatsapp_melhorias.md` ## Taxa de Matrícula (2026-03-10) - Campos: `matriculas.valor_matricula` (decimal) + `valor_matricula_status` (pendente/pago/isento) - Gera lançamento financeiro tipo 'taxa_matricula' (se valor > 0 e não isento) ## Estrutura Principal - Controllers: `FinanceiroController`, `MatriculaController`, `ProfessorController` - Models: `ComissaoAnualModel`, `ProfessorModel`, `MatriculaModel`, `AulaModel`, `ContaFinanceiraModel` - Views: `direcao/financeiro/index.php`, `direcao/professores.php` ## App Professor e Assinatura (2026-03) - App mobile, API REST, assinatura digital → ver `memory/app_professor_assinatura.md` ## Deploy - Procedimento Completo - Passo a passo detalhado com cuidados → ver `memory/deploy_procedimento.md` ## Edição de Aulas (2026-04-14) - **NUNCA usar `$this->aulaModel->update()`** para updates parciais — validação required rejeita silenciosamente - Usar `$this->db->table('aulas')->update()` direto - Verificações de conflito também usam `$db->table()` direto (Model corrompe estado) - Conflito professor: só em sala diferente. Sala: respeita capacidade - Ver `memory/aula_edicao_conflitos.md` para detalhes ## Cancelar/Trancar Matrícula (2026-04-20) - Mesmo padrão: **NUNCA usar `$this->matriculaModel->update()`** para updates parciais - MatriculaModel exige aluno_id/curso_id/professor_id/sala_id como required - Campos `data_trancamento/motivo_trancamento/data_destrancamento/dias_trancados` não estão em allowedFields - Usar `$db->table('matriculas')->where('id', $id)->update($data)` direto - Ver `memory/matricula_cancelar_trancar.md` ## Dashboard Calendário (2026-04-14) - Sem Domingo (6 dias), grid 48px + repeat(6, 1fr) - Painel filtros/stats colapsável, busca no header - Ver `memory/dashboard_calendario.md` ## Permissões RBAC (2026-05-05) - Tipo direção tem `is_superuser` + tabela `usuario_permissoes` com 15 módulos - Helper `PermissaoModel::pode($modulo)` + AuthFilter aceita `modulo=alunos` - Menu lateral esconde itens sem permissão. Tela `/direcao/usuarios-direcao` (só superuser) gerencia - Ver `memory/permissoes_rbac.md` ## Feriados + Cron (2026-05-05) - Tabela `feriados` (21 nacionais + móveis), config `pausar_em_feriados` - LembreteService e CobrancaService bloqueiam em feriado - Cron diário 08h BRT marca aulas como concluídas (comissão 100%) - Endpoint: `/cron/marcar-aulas-feriado?token=agm-cron-7Hk29Lqp2Mz5RtVx` - Ver `memory/feriados_automacoes.md` ## Analytics (2026-05-05) - `/direcao/analytics` com Chart.js — KPIs com delta% vs ano anterior, tabela mensal - Ver `memory/analytics_modulo.md` ## Bugs de Produção CRÍTICOS (2026-05-05) - **PHP servidor está em UTC** — usar `timestampBrasilia()`/`formatarBrasilia()`/`dataBrasilia()` nos controllers. Ver `memory/timezone_php_servidor.md` - **OPcache cheio impede deploys** — sempre rodar `opcache_reset()` após pscp. Ver `memory/opcache_env_pitfalls.md` - **`.env` quebra com valor não-quoteado contendo espaços** — derrubou site. Sempre `cp .env .env.bak.*` antes de mexer - **AutoMigrate quebra com migration aplicada manualmente** — registrar entrada na tabela `migrations` - **CI4 `$allowedFields` filtra silenciosamente** — coluna não listada some do INSERT/UPDATE sem erro. Ver `memory/codeigniter_allowedfields_pitfall.md` - **WhatsApp `@lid` esconde número real** — não usar `payload['jid']` (é o receptor!). Captura `lid_destino` ao enviar + fallback pushName. Ver `memory/whatsapp_lid_privacy.md` ## Arquivos de Memória - [Comissões](comissoes.md) — modelo de comissão por ano de matrícula - [Override de Comissão](comissao_override.md) — override por matrícula individual - [Financeiro](financeiro_cards_e_contas.md) — cards, abas, contas, transferências - [Cartão/Faturas](financeiro_cartao_faturas.md) — faturas por mês, data compra/vencimento, recibo PDF - [Edição de Aulas](aula_edicao_conflitos.md) — update parcial, conflitos, comparação de horários - [Dashboard Calendário](dashboard_calendario.md) — sem domingo, grid customizado, painel colapsável + feriados marcados - [WhatsApp](whatsapp_melhorias.md) — bloqueio, resposta automática, anti-spam - [Deploy](deploy_procedimento.md) — procedimento completo de deploy com pscp/plink - [App Professor](app_professor_assinatura.md) — app mobile, API, assinatura digital - [Cancelar/Trancar Matrícula](matricula_cancelar_trancar.md) — $db->table() direto, bugs de update parcial - [Feedback: Deploy sem perguntar](feedback_deploy_sem_perguntar.md) — bug em produção → corrigir + deploy direto - [Recibo Pagamento Aluno](recibo_pagamento_aluno.md) — baixa + PDF + WhatsApp do recibo de mensalidade - [Boleto Bradesco](bradesco_boleto.md) — mTLS Portal Developers OK, contrato sem cidtfdProdCobr cadastrado - [Feedback: Salvar memória automaticamente](feedback_salvar_memoria_automatico.md) — salvar proativamente, não esperar usuário pedir - [App Timezone API](app_timezone_api.md) — API manda em Brasília sem `Z`, app NÃO usar `toLocal()` - [Chat Atendimento](chat_atendimento.md) — chat aluno↔direção (chat_conversas/mensagens, polling, badge) - [Ferramentas Estudo App](ferramentas_estudo_app.md) — metrônomo + afinador no app aluno - [Avaliações Professor](avaliacoes_professor.md) — estrelas + comentário, exibido na ficha do professor - [Permissões RBAC](permissoes_rbac.md) — superuser + módulos por usuário direção, AuthFilter, menu condicional - [Feriados + Cron](feriados_automacoes.md) — tabela feriados, bloqueio em LembreteService/CobrancaService, cron diário marca aulas concluídas - [Analytics](analytics_modulo.md) — /direcao/analytics, KPIs, Chart.js, comparativo ano anterior - [Monitoramento v2](monitoramento_aulas_v2.md) — abas, timeline de eventos do app, refresh 10s - [PHP UTC pitfall](timezone_php_servidor.md) — helpers timestampBrasilia/formatarBrasilia/dataBrasilia - [OPcache + .env pitfalls](opcache_env_pitfalls.md) — três armadilhas críticas que tomaram o site fora do ar - [CI4 allowedFields pitfall](codeigniter_allowedfields_pitfall.md) — coluna não listada some do INSERT silenciosamente - [App Aluno Play Store](app_aluno_playstore.md) — package com.agmusic.aluno, keystore, build/sign, URL política privacidade - [Envio Play Store 2026-05-12](playstore_envio_2026-05-12.md) — teste fechado v1.0.0 em revisão, requer 12 testadores/14 dias antes de produção/aberto - [Deploy PHP-CLI path](deploy_php_cli_path.md) — `php` no servidor é php-cgi, usar `/opt/cpanel/ea-php83/root/usr/bin/php` pra spark - [App Professor Play Store + App Store](app_professor_playstore.md) — package com.agmusic.professor, iOS pendente (sem pasta ios/, precisa Apple Dev + macOS) - [GitHub repos](github_repos.md) — URLs dos repos privados dos apps (jesieltelles), HTTPS only (sem SSH), backup keystore crítico - [WhatsApp LID privacy](whatsapp_lid_privacy.md) — capturar lid_destino no envio + fallback pushName - [Feriados save silencioso](feriados_save_silencioso.md) — fetch sem .catch() comia erro 500/401, controller agora tem try/catch + validação tipo/data