- Add Pessoa/Vinculo.atualizado_manualmente flag, set automatically on web CRUD save; all Gennera/txt import paths now skip records flagged this way instead of overwriting them - Vinculo import: finalize step corrects leftover "situacao nao informada" vinculos to "Desvinculado", pulling carga horaria from censup_carga_horaria - Generic CRUD list view: click a column header to sort (asc/desc), persists through pagination; FK columns sort by their related display field - Rename GENNERA_API_BASE_URL setting to GENNERA_LOCAL_BASE_URL Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
9.7 KiB
Especificacoes do Projeto Autocensup
Visao geral
O Autocensup e uma aplicacao web Django para apoiar a preparacao, conferencia e processamento de dados do Censo da Educacao Superior. O sistema centraliza cadastros de pessoas, cursos, vinculos, instituicoes, polos e tabelas auxiliares, permitindo importar dados locais e da API Gennera, revisar pendencias e operar os registros por ano de censo.
Objetivos
- Manter uma base local de dados necessarios ao Censo Superior.
- Importar pessoas e vinculos a partir da API Gennera.
- Importar o Arquivo Aluno exportado do sistema Censup.
- Conferir vinculos por curso, situacao e pendencias cadastrais.
- Permitir ajustes cadastrais via telas CRUD autenticadas.
- Processar situacoes de vinculos em lote por matricula.
Stack tecnica
- Linguagem: Python 3.12+.
- Framework web: Django 5.2.
- Banco de dados: PostgreSQL 16.
- Driver PostgreSQL: psycopg 3.
- Gerenciador de dependencias: uv.
- Infra local: Docker Compose para o servico
db. - Templates: Django Templates com Bootstrap/Tabler.
- Autenticacao: autenticacao padrao do Django, com views protegidas por login.
Configuracao de ambiente
Variaveis principais:
DJANGO_DEBUG: habilita ou desabilita modo debug.DJANGO_SECRET_KEY: chave secreta da aplicacao.DJANGO_ALLOWED_HOSTS: hosts permitidos.POSTGRES_DB,POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_HOST,POSTGRES_PORT: conexao PostgreSQL.DATABASE_URL: alternativa para configurar o banco por URL.GENNERA_LOCAL_BASE_URL: URL base da API Gennera.API_TOKEN: token Bearer usado nas chamadas a API Gennera.
Comandos basicos:
cp .env.example .env
UV_CACHE_DIR=/tmp/uv-cache uv sync
docker compose up -d db
UV_CACHE_DIR=/tmp/uv-cache uv run python manage.py migrate
UV_CACHE_DIR=/tmp/uv-cache uv run python manage.py loaddata ufs municipios
UV_CACHE_DIR=/tmp/uv-cache uv run python manage.py runserver
Modulos principais
config/settings.py: configuracao Django e leitura de variaveis de ambiente.core/models.py: modelos de dominio.core/views.py: dashboard, selecao de ano, importacoes, processamento em lote e CRUD generico.core/importers.py: importacao de arquivos, CSVs e API Gennera.core/validation.py: validacoes de curso, pessoa e vinculo.core/year.py: ano de censo selecionado na sessao.templates/: layout e telas da aplicacao.docs/: insumos e regras de leiaute do Censo Superior.
Modelo de dados
AnoCenso
Representa o ano de referencia do censo. O campo ano e chave primaria. A propriedade ano_execucao retorna ano + 1.
UF, Pais e Municipio
Tabelas auxiliares usadas nos cadastros de pessoa. Municipio pertence a uma UF.
Curso
Cadastro de cursos identificados por codigo_mec. Campos relevantes:
- descricao.
- situacao de funcionamento.
- indicador de licenciatura.
- indicador de EaD.
- carga horaria total.
- polo vinculado, quando aplicavel.
FallbackCurso
Mapeia textos divergentes entre dados externos e cursos locais para uso cadastral/manual. A importacao de vinculos da API Gennera nao usa fallback por nome: o curso deve ser identificado exclusivamente por course_code.
Instituicao e Polo
Representam instituicoes INEP e locais de oferta. Polos podem ser vinculados a cursos EaD.
Pessoa
Cadastro do aluno/pessoa com CPF unico, dados de nascimento, nacionalidade, cor/raca, pais de origem, deficiencias, tipo de escola do ensino medio e anos de censo associados.
Vinculo
Relaciona pessoa, curso e ano de censo. Regras estruturais:
ano_censoreferenciaAnoCenso.cursoreferenciaCurso.codigo_mec.- uma pessoa pode ter apenas um vinculo para o mesmo curso no mesmo ano de censo.
- uma pessoa pode ter mais de um vinculo no mesmo ano de censo quando os cursos forem diferentes.
- a regra acima e garantida por restricao unica em pessoa, curso e ano de censo.
- vinculos sao filtrados pelo ano de trabalho selecionado em telas de consulta.
Situacoes suportadas:
- Nao informada.
- Cursando.
- Matricula trancada.
- Desvinculado do curso.
- Transferencia interna.
- Formado.
- Falecido.
Funcionalidades web
Dashboard
Rota: /
Exibe vinculos agregados por curso para o ano selecionado, com contadores por situacao e quantidade de registros pendentes.
Selecao de ano de censo
Rota: /ano-censo/
Atualiza na sessao o ano de trabalho. Esse ano e usado para filtrar vinculos em dashboard, listagens e processamento de situacao.
Importacao do Arquivo Aluno
Rota: /importar/alunos/
Recebe arquivo .txt do Censup e processa registros:
40: cabecalho.41: dados cadastrais de pessoa.42: vinculo do aluno com curso.
O resultado informa pessoas criadas/atualizadas, vinculos criados/atualizados, registros ignorados e erros.
Importacao de pessoas Gennera
Rota: /importar/pessoas-gennera/
Consulta a API Gennera por ano de referencia e cria pessoas ainda nao existentes na base local.
Importacao de vinculos Gennera
Rota: /importar/vinculos-gennera/
Consulta a API Gennera por CPF e ano selecionado, criando ou atualizando vinculos locais conforme regras de situacao.
Endpoint esperado:
GET /vinculo/?ano=<ano>&cpf=<cpf>
O curso do vinculo deve ser resolvido exclusivamente pelo campo course_code, correspondente a Curso.codigo_mec. Se course_code nao vier na resposta ou nao existir em cursos locais, o registro deve ser rejeitado com erro.
Processamento de situacao em lote
Rota: /processar/situacao/
Recebe uma lista de matriculas e uma situacao alvo. Atualiza vinculos do ano selecionado e informa matriculas nao encontradas.
Pendencias
Rota: /pendencias/
Lista registros com campos obrigatorios ou regras de consistencia pendentes, usando as validacoes de core/validation.py.
CRUD generico
Rotas:
/cadastros/<slug>//cadastros/<slug>/novo//cadastros/<slug>/<pk>//cadastros/<slug>/<pk>/editar//cadastros/<slug>/<pk>/excluir/
Cadastros disponiveis:
- anos do censo.
- UFs.
- paises.
- municipios.
- cursos.
- fallbacks de curso.
- instituicoes.
- polos.
- pessoas.
- vinculos.
Regras de validacao
Curso
- Codigo MEC e descricao sao obrigatorios.
- Situacao de funcionamento e obrigatoria.
- Carga horaria total deve ser maior que zero.
- Curso EaD deve ter polo vinculado.
Pessoa
- Nome, CPF, data de nascimento, cor/raca, nacionalidade, pais de origem, indicador de deficiencia e tipo de escola do ensino medio sao obrigatorios.
- CPF deve conter 11 digitos numericos.
- Brasileira nata deve ter pais
BRAe UF de nascimento. - Brasileira naturalizada ou estrangeira nao pode ter pais
BRAnem UF/municipio de nascimento. - Municipio de nascimento exige UF e deve pertencer a UF informada.
- Quando o indicador de deficiencia for Sim, todos os tipos de deficiencia devem estar preenchidos e ao menos um deve estar marcado.
Vinculo
- Ano do censo e situacao sao obrigatorios.
- Semestre de ingresso deve seguir o formato
01AAAAou02AAAA. - Curso presencial exige turno do aluno.
- Curso EaD exige polo no vinculo ou no curso.
- Curso de licenciatura exige informacoes de Aluno PARFOR e segunda licenciatura/formacao pedagogica.
- Carga horaria total do aluno deve vir do curso.
- Vinculo formado exige carga horaria integralizada maior ou igual a carga horaria total.
- Indicadores de financiamento, apoio social, atividade extracurricular e acao afirmativa devem ter os tipos correspondentes preenchidos conforme a opcao principal.
Regras de importacao de vinculos
- A decisao de situacao e feita por pessoa, curso e ano de censo.
- Registros retornados pela API para outro ano sao ignorados na decisao do ano selecionado.
- Se a carga horaria acumulada for maior ou igual a carga horaria total do curso, a situacao deve ser Formado.
- Vinculo ja Formado nao deve ser rebaixado por outra regra de importacao.
- Se houver registro no segundo semestre do ano selecionado, a situacao deve ser Cursando.
- Se houver registro apenas no primeiro semestre do ano selecionado, a situacao deve ser Desvinculado.
- Se nao houver vinculo retornado para pessoa que ja possui vinculo local no ano, a situacao local deve ser Desvinculado, exceto quando ja estiver Formado.
- A carga horaria acumulada retornada pela API deve atualizar a carga horaria integralizada mesmo quando a situacao Formado for preservada.
- O campo
semestre_ingressodeve ser atualizado a partir do registro mais antigo do grupo de vinculos, considerando ano e semestre. O formato gravado eAAYYYY, por exemplo012026para primeiro semestre de 2026.
Dados de apoio
Arquivos relevantes em docs/:
REGRAS_ARQUIVO_ALUNO.md: regras do leiaute do Arquivo Aluno.aluno_exportacao.txt: exemplo ou insumo de arquivo aluno.cursos.csvecursos_locais.csv: insumos de cursos.leiaute_aluno_2025.xlsx: leiaute oficial usado como referencia.tabela_municipio_2025.xlsx,tabela_paises_2025.xlsx,tabela_uf_2025.xlsx: tabelas auxiliares.
Fluxo operacional sugerido
- Conferir e atualizar cadastros de cursos.
- Exportar
aluno_exportacao.txtno sistema Censup. - Importar o Arquivo Aluno no Autocensup.
- Importar pessoas e vinculos da API Gennera quando necessario.
- Revisar dashboard e pendencias.
- Processar ajustes de situacao por matricula, se aplicavel.
- Corrigir cadastros pendentes via CRUD.
Testes
Executar a suite:
UV_CACHE_DIR=/tmp/uv-cache uv run python manage.py test
Verificar migracoes pendentes:
UV_CACHE_DIR=/tmp/uv-cache uv run python manage.py makemigrations --check --dry-run
Observacoes de schema
O campo Vinculo.ano_censo e uma ForeignKey para AnoCenso, mas usa explicitamente a coluna fisica ano_censo no banco por compatibilidade com dados existentes. Essa decisao evita perda de dados e mantem o ORM alinhado ao schema atual.