# 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: ```bash 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_censo` referencia `AnoCenso`. - `curso` referencia `Curso.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: ```text GET /vinculo/?ano=&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//` - `/cadastros//novo/` - `/cadastros///` - `/cadastros///editar/` - `/cadastros///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 `BRA` e UF de nascimento. - Brasileira naturalizada ou estrangeira nao pode ter pais `BRA` nem 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 `01AAAA` ou `02AAAA`. - 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_ingresso` deve ser atualizado a partir do registro mais antigo do grupo de vinculos, considerando ano e semestre. O formato gravado e `AAYYYY`, por exemplo `012026` para 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.csv` e `cursos_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 1. Conferir e atualizar cadastros de cursos. 2. Exportar `aluno_exportacao.txt` no sistema Censup. 3. Importar o Arquivo Aluno no Autocensup. 4. Importar pessoas e vinculos da API Gennera quando necessario. 5. Revisar dashboard e pendencias. 6. Processar ajustes de situacao por matricula, se aplicavel. 7. Corrigir cadastros pendentes via CRUD. ## Testes Executar a suite: ```bash UV_CACHE_DIR=/tmp/uv-cache uv run python manage.py test ``` Verificar migracoes pendentes: ```bash 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.