O backend canônico é backend.app:app (backend/app.py):
python -m uvicorn backend.app:app --reload --host 0.0.0.0 --port 8001
Legado: backend/app_main.py é uma variante reduzida (sem intervenções, nap-cases nem static). Não use em ambiente novo.
Routers ativos: recomendações, planos, reports, auth, e-mails, estudantes-data, nap-cases e intervenções.
Resposta:
```json
{ "status": "ok" }
```
Probe do banco (503 se indisponível).
Prefixo: /api/auth — register, login, logout, me, forgot-password, change-password, gestão de users (admin).
Prefixo: /api/estudantes-data — GET/PUT da base JSON (Bearer).
Prefixo: /api/intervencoes — POST /registrar, POST /por-estudantes.
Prefixo: /api/nap-cases — GET lista, GET/PUT por estudante.
Prefixo: /api/emails — config, check-connection, test, send-risk-summary.
Prefixo: `/api/recomendacoes`
Gera recomendações personalizadas (com fallback local conforme implementação do serviço).
Payload:
```json
{
"aluno_id": "123",
"score_risco": 0.72,
"tipo_risco": "academico",
"alerta": {
"motivoFinanceiro": false,
"motivoNota": true,
"motivoFrequencia": false,
"motivoEngajamento": true
},
"estudante": {
"nome": "Ana Silva",
"curso": "Engenharia de Software"
},
"model": "opcional"
}
```
Resposta esperada (exemplo):
```json
{
"tipo_risco": "academico",
"fonte": "ollama",
"recomendacoes": [
{
"tipo_intervencao": "reforcoAcademico",
"proxima_acao": "Agendar monitoria focada nos tópicos críticos.",
"urgencia_label": "Alta",
"urgencia_nivel": 3,
"confidence": 0.81,
"efetividade_pct": 0,
"casos_similares": 0,
"metricas_observadas": false
}
]
}
```
Query params opcionais:
Uso: recomendação rápida por aluno.
Prefixo: `/api/planos`
Retorna HTML de plano de ação.
Query params opcionais relevantes:
Observação importante:
Erro comum:
```json
{
"detail": [
{
"type": "float_parsing",
"loc": ["query", "financeiro_valor_pago"],
"msg": "Input should be a valid number, unable to parse string as a number",
"input": ""
}
]
}
```
Payload:
```json
{
"aluno_id": "123",
"periodo": "2026/1",
"curso_id": "ENG"
}
```
Resposta:
```json
{ "url": "https://..." }
```
Payload:
```json
{
"periodicidade": "semanal",
"periodo": "2026/1"
}
```
Resposta:
```json
{
"status": "ok",
"url": "https://...",
"periodo": "2026/1",
"periodicidade": "semanal"
}
```
Payload:
```json
{ "nome_responsavel": "Coordenador(a) X" }
```
Resposta:
```json
{
"status": "ok",
"plano_id": 10,
"assinado_por": "Coordenador(a) X",
"hash_documento": "sha256..."
}
```
Prefixo: `/api/reports`
Payload comum (`ReportExportPayload`):
```json
{
"title": "Relatório PESA",
"page": "centro-alertas",
"filters": {
"curso": "Engenharia de Software"
},
"columns": ["nome", "curso", "nivel"],
"rows": [
{ "nome": "Ana", "curso": "Engenharia de Software", "nivel": "alta" }
]
}
```
Resposta:
Heurística remat_v0.1 (não é ML treinado). Requer Bearer.
Spec: modelos-e-score.html (APROVADO v0.1).
Retorna o período configurado pela IES (pode estar vazio).
Somente admin. Body com semestreAlvo, inicio/fim (opcionais),
diasGracaAposFim (padrão 15), inicioLetivoS1.
Conceito separado de rematrícula. Períodos por nível (graduacao, stricto_sensu, lato_sensu)
com marcos analíticos. Escrita: função configurar_calendario
(admin todos os níveis; coordenacao→graduação; coordenacao_stricto_sensu→stricto;
coordenacao_especializacao→lato). Coordenador de curso não edita por padrão.
Marcos (ordem cronológica, datas em [inicio..fim]):
diagnostico_inicial, acompanhamento_1, acompanhamento_2, fechamento.
A fase do resolver é o último marco ≤ data_ref (ou inicio).
GET /api/config/calendario-academico — lista períodosGET /api/config/calendario-academico/resolver — resolve ativo / entre períodos (fase, marcos, fonte).
Estados: ativo | entre_periodos | sem_calendarioPOST /api/config/calendario-academico — upsert manual (409 se sobreposição no nível)POST /api/config/calendario-academico/importar — CSV/Excel do CRM (dry-run + confirmar;
mapeamento_json opcional; upsert por nível+código; origem crm_arquivo; marcos ausentes preservados; RBAC por nível)GET /api/config/calendario-academico/template.csv — templateGET /api/config/calendario-academico/importacoes — histórico / auditoriaGET/PUT /api/config/calendario-academico/crm-api — conector REST (segredos mascarados)POST /api/config/calendario-academico/crm-api/test — testa conexãoPOST /api/config/calendario-academico/crm-api/sincronizar — sync dry-run / confirmar (origem crm_api)Frontend: módulo calendario-academico.js unifica Centro de Alertas, Heatmap, Index/Atlas, Dashboard, Relatórios e Trajetória.
Ordem: calendário institucional → fallback explícito (semestre mais recente na base) → nunca mês civil.
UI admin: admin-calendario.html (admin e coordenações com a função).
Retorna score 0–100, versao_modelo, confianca, label_janela,
metodo: "heuristica". Erros: 401, 404.
{
"estudante_id": "uc:123",
"score": 72,
"versao_modelo": "remat_v0.1",
"calculado_em": "2026-07-24T12:00:00Z",
"confianca": 0.64,
"label_janela": {
"fonte": "configurado",
"semestre_alvo": "2026/2",
"periodo_inicio": "2026-07-01",
"periodo_fim": "2026-07-31",
"dias_graca": 15,
"data_limite": "2026-08-15",
"janela_aberta": true
},
"metodo": "heuristica"
}
Query: page, limit, curso, status, q.
Ordena por score (bump se SLA estourado). Respeita cursos do usuário.
Atualiza status operacional com histórico auditável
(novo | em_atendimento | aguardando | concluido | descartado).
Requer função operar_fila.
Prefixo /api/campanhas — criar/ativar/encerrar campanhas com playbook e participantes.
Prefixo /api/metricas/operacionais — SLA, contato e conclusão (fila + campanhas).
UI: campanhas.html e painel em efetividade.html.
RBAC: filtro por cursos + funções gerir_campanhas / operar_fila.
Tabela app_baseline_snapshot — captura automática e imutável em t0
(fila em_atendimento, inclusão em campanha, 1ª intervenção).
Campos: score/nível de risco, score rematrícula, curso, playbook, features mínimas.
Disponível. Método matching_heuristico_v0.1
(quasi-experimental — não é RCT).
Spec: efetividade-causal.html.
GET /api/metricas/efetividade-coorte — query:
de, ate, outcome=O1|O2|O3,
origem, playbook_key, curso,
janela_dias, k_match.
Autenticado; RBAC por curso (P2-006). Painel: efetividade.html (P2-005).
Regras: n<5 só contagens; 5≤n<10 taxa/lift sem IC;
O2 → pendente_janela; sem baseline → não inventa métricas.
GET /api/metricas/efetividade-mensal — agrega por playbook/origem,
compara 2 cortes e gera texto escalar / manter / pausar.
Escalar exige lift ≥ 0,10 estável nos dois períodos (n≥10).
Painel + export CSV/PNG em efetividade.html.
GET /api/modelos e GET /api/modelos/{id} —
versão, vigente_desde, features e owner.
Tabela app_modelo_registro (seed no startup).
Score rematrícula anexa registro.
UI: admin-modelos.html + pesa-modelos.js.
/api/drift/config|status|verificar|alertas e job
/api/drift/jobs/tick. Alerta quando lift ou calibração
(confiança/cobertura) caem abaixo do limiar.
UI: admin-drift.html.
Contrato: conectores-multi-fontes.html.
P2-009 entregue: conector LMS com dry-run/commit, log
(app_conector_run) e alerta e-mail.
GET/PUT /api/conectores/{fonte}/configPOST /api/conectores/{fonte}/testPOST /api/conectores/{fonte}/sincronizarGET /api/conectores/runsPOST /api/conectores/jobs/tick — token PESA_CONECTOR_JOB_TOKEN ou usuário autenticadoUI: admin-conectores.html. Fonte v0.1: lms.