Skip to content
pablozrPublic

About

Academic projects platform for UNIRIO: a public catalog synced from the SIE, with institutional Google sign-in, editorial tools for professors and admin control over publication and sync history. FastAPI, PostgreSQL, Redis.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

152 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PRISMA: Plataforma de Referência e Integração de Saberes e Mediação Acadêmica. Catálogo público de projetos acadêmicos da UNIRIO, sincronizado com o SIE.

CI Python 3.13 FastAPI PostgreSQL 16 Redis 7 Docker Compose

Visão geral · Arquitetura · Sincronização · Segurança · API · Execução · Deploy


Resumo. O PRISMA é o backend da plataforma da Universidade Federal do Estado do Rio de Janeiro (UNIRIO) que centraliza, divulga e administra os projetos acadêmicos registrados no Sistema de Informações para o Ensino (SIE). Um worker importa periodicamente os projetos e seus participantes; a API expõe um catálogo público, permite que professores e técnicos complementem o conteúdo dos projetos sob sua responsabilidade e oferece à administração o controle de usuários, publicação e histórico das sincronizações. O SIE continua sendo a fonte oficial: o PRISMA nunca o substitui nem escreve nele.

Visão geral

Escopo atual

  • Catálogo público de projetos, com detalhes, filtros e catálogos auxiliares.
  • Autenticação institucional via Google para a comunidade acadêmica.
  • Autenticação local para administradores.
  • Sessões com access token, refresh token e Redis.
  • Área de professor/técnico para consultar e complementar projetos sob sua responsabilidade.
  • Edição de descrição, imagem de capa e oportunidades vinculadas aos projetos.
  • Administração de usuários, visibilidade/publicação de projetos, métricas e execuções de sincronização.
  • Sincronização periódica de dados institucionais com a API do SIE.

Fora do escopo do projeto-base

Não faz parte Observação
Notificações internas e envio automático de e-mails O e-mail institucional é usado só como identificador de acesso, vínculo de pessoas e contato público dos responsáveis.
Recuperação de senha por e-mail e filas de mensageria para e-mail RabbitMQ não faz parte da arquitetura atual.
Inscrição e seleção completa de candidatos As oportunidades são divulgadas, não geridas.
Gestão de bolsas ou pagamentos —
Substituição do SIE ou de outros sistemas oficiais O SIE permanece como fonte de verdade institucional.

Perfis de acesso

Perfil Acesso Capacidades principais
Visitante Sem autenticação Consultar o catálogo e os detalhes públicos
Aluno Google institucional Acessar o sistema como membro da comunidade acadêmica
Professor/técnico Google institucional e vínculo importado do SIE Gerenciar o conteúdo editorial de seus projetos
Administrador E-mail e senha locais Administrar usuários e projetos e acompanhar as sincronizações

Arquitetura

flowchart LR
    subgraph clientes["Usuários"]
        V["Visitante"]
        C["Comunidade acadêmica<br/>(Google institucional)"]
        A["Administrador"]
    end

    W["prisma-web<br/>frontend + nginx"]
    API["prisma-api<br/>FastAPI · /api/v1/unirio"]
    WK["prisma-worker<br/>sincronização SIE"]
    PG[("PostgreSQL 16")]
    R[("Redis 7<br/>sessões · estado OAuth · rate limit")]
    G["Google OAuth<br/>(OpenID Connect)"]
    SIE["API do SIE<br/>(UNIRIO)"]

    V & C & A --> W --> API
    API --> PG
    API --> R
    API -. "login institucional" .-> G
    WK -- "páginas de projetos" --> SIE
    WK -- "upsert por página" --> PG
Loading

A API é um monólito modular em camadas. As rotas recebem e validam as requisições, os serviços concentram as regras de negócio e os repositórios são a única camada que fala SQL. O worker reusa o mesmo código e a mesma imagem Docker, mas roda como um processo separado.

Camada Diretório Responsabilidade
Rotas routes/ Endpoints HTTP, dependências de autenticação e limites de taxa
Contratos schemas/ Modelos Pydantic de entrada e saída
Serviços services/ Regras de negócio: autenticação, projetos, catálogo, administração, sincronização
Repositórios repositories/ Acesso ao PostgreSQL com asyncpg
Integrações integrations/ Clientes do Google OAuth e da API do SIE
Núcleo core/ Configuração, segurança, cookies, conexões e logging
Worker workers/ Laço da sincronização periódica

Modelo de dados

O schema separa o que pertence ao SIE do que pertence ao PRISMA. No mesmo registro de projeto, os campos source_* são escritos apenas pela sincronização, e os campos local_* (descrição, capa, oportunidades) apenas pelos responsáveis. Assim, uma nova importação nunca apaga o trabalho editorial feito na plataforma.

erDiagram
    direction LR
    users ||--o| people : "vincula no primeiro login"
    people ||--o{ project_participations : participa
    projects ||--o{ project_participations : tem
    people ||--o{ project_edit_permissions : "pode editar"
    projects ||--o{ project_edit_permissions : concede
    projects ||--o{ project_images : capa
    projects ||--o{ project_opportunities : divulga
    projects }o--o{ project_areas : "área temática"
    projects }o--o{ courses : "cursos relacionados"
    organizational_units ||--o{ projects : "centro e unidade"
    sync_runs ||--o{ projects : "visto pela última vez em"
Loading

Sincronização com o SIE

O worker prisma-worker executa uma sincronização completa a cada 15 dias e, em caso de falha, tenta de novo após 5 minutos. Os dois intervalos são configuráveis.

sequenceDiagram
    autonumber
    participant W as prisma-worker
    participant S as API do SIE
    participant DB as PostgreSQL

    W->>DB: cria sync_run (status = running)
    W->>S: autentica e obtém token
    loop uma página por vez (500 linhas por padrão)
        W->>S: busca a página seguinte
        S-->>W: linhas de projetos e participantes
        W->>W: normaliza cada linha
        W->>DB: upsert de projetos, pessoas e vínculos (uma transação por página)
    end
    W->>DB: fecha sync_run como success, partial ou failed
Loading
  • Uma transação por página. Cada página é gravada de forma atômica, e uma falha interrompe a execução sem deixar uma página pela metade.
  • Linhas inválidas não derrubam a execução. Elas são ignoradas, contadas e registradas; a execução termina como partial em vez de success.
  • Rastreabilidade. Cada sync_run guarda páginas processadas, linhas recebidas, projetos e participantes atualizados e um resumo do erro. A administração consulta esse histórico e as falhas de cada execução pela API.
  • Identidade sem dado sensível em claro. As pessoas importadas são identificadas por um digest SHA-256 dos identificadores do SIE; CPF e telefone não são armazenados.
  • Papéis com origem. O papel de cada usuário registra de onde veio (google_default, sie ou admin), e a sincronização nunca rebaixa um papel definido pela administração.

Segurança e privacidade

Tema Como é tratado
Login institucional Fluxo OAuth com state e nonce guardados no Redis com validade curta; o ID token do Google é verificado e o domínio do e-mail é restrito aos domínios institucionais permitidos.
Sessões Access token de 30 minutos e refresh token de 7 dias em cookies HttpOnly, SameSite=Lax e Secure em produção. Cada renovação gira o refresh token e invalida o anterior pela sessão no Redis.
Força bruta Login, OAuth e renovação de sessão limitados a 5 requisições por minuto por IP, com contadores no Redis.
Senhas Hash com bcrypt, usado só pelas contas administrativas locais.
Upload de capas Apenas JPEG, PNG e WebP, com até 5 MB, gravados num diretório próprio do backend.
CORS Somente origens explícitas; * nunca é usado com credenciais.
Banco e cache Em produção, PostgreSQL e Redis ficam numa rede interna, sem portas publicadas no host.

API

Todas as rotas usam o prefixo /api/v1/unirio. Com a aplicação em execução, a documentação OpenAPI interativa fica em http://localhost:5685/api/v1/unirio/docs.

Grupo Endpoints Acesso
Autenticação POST /auth/login · GET /auth/google/start · GET /auth/google/callback · GET /auth/me · POST /auth/refresh · POST /auth/logout Público e autenticado
Catálogo de projetos GET /projects · GET /projects/{id} Público
Projetos do responsável GET /me/projects · GET /me/projects/{id} · PATCH /projects/{id} · POST /projects/{id}/logo · POST /projects/{id}/opportunities · DELETE /opportunities/{id} Professor/técnico vinculado
Catálogos auxiliares GET /catalogues/areas-tematicas · /centros · /unidades · /cursos Público
Administração GET /admin/metrics · GET, PATCH /admin/users · GET, PATCH /admin/projects · GET /admin/sync-runs · GET /admin/sync-runs/{id}/failures Administrador

Execução local

Requisitos: Docker com Docker Compose. Para rodar os testes fora do container, Python 3.13.

cp .env.example .env        # preencha as credenciais necessárias
docker compose up --build

O Compose sobe a API, o PostgreSQL, o Redis, um passo que aplica o schema e as migrações e o worker de sincronização. A API responde em http://localhost:5685 e expõe GET /health para o healthcheck.

Variáveis de ambiente
Grupo Variáveis
Aplicação ENVIRONMENT, API_PORT, SECRET_KEY, CORS_ALLOWED_ORIGINS
PostgreSQL DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME
Redis REDIS_HOST, REDIS_PORT, REDIS_PASSWORD
Sessão ACCESS_TOKEN_EXPIRE_MINUTES, REFRESH_TOKEN_EXPIRE_MINUTES
Google OAuth GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REDIRECT_URI, ALLOWED_GOOGLE_DOMAINS, ALLOWED_EMAIL_DOMAIN, GOOGLE_OAUTH_STATE_TTL_SECONDS, GOOGLE_OAUTH_CLOCK_SKEW_SECONDS, FRONTEND_AUTH_SUCCESS_URL, FRONTEND_AUTH_ERROR_URL
SIE SIE_API_BASE_URL, SIE_EMAIL, SIE_PASSWORD, SIE_SYNC_PAGE_SIZE, SIE_SYNC_INTERVAL_DAYS, SIE_SYNC_RETRY_SECONDS
Cliente HTTP HTTP_CLIENT_TIMEOUT_SECONDS, HTTP_CLIENT_MAX_CONNECTIONS, HTTP_CLIENT_MAX_KEEPALIVE_CONNECTIONS
Capas PROJECT_COVER_UPLOAD_DIR, PROJECT_COVER_PUBLIC_PATH

Os valores de exemplo estão em .env.example. Nunca versione o .env.

Testes

python -m pytest

A suíte cobre autenticação e perfis, fluxos de segurança, validação de schemas, contratos dos repositórios, rotas e serviços de projetos e catálogo, o cliente e o normalizador do SIE, a sincronização e a prontidão para produção. A CI roda os testes em Python 3.13 a cada push e pull request.

Deploy

O runbook de produção está em DEPLOY.md. Ele cobre o layout com o frontend prisma-front, os serviços e volumes do Compose, HTTPS, migrações, deploy automático após a CI, backup, restauração e verificação pós-deploy.

Estrutura do repositório

core/               configuração, segurança, cookies, conexões e logging
integrations/       clientes do Google OAuth e da API do SIE
repositories/       acesso ao PostgreSQL
routes/             endpoints HTTP
schemas/            contratos de entrada e saída
services/           regras de negócio
workers/            sincronização periódica com o SIE
tests/              testes automatizados
deploy/, scripts/   deploy de produção e automação
.github/assets/     banner do README e o script que o gera
main.py             inicialização da API
schema.sql          modelo do banco; migration_*.sql aplicam as mudanças posteriores

Regra de documentação

Note

O código e este README representam o produto implementado. Ideias ainda não desenvolvidas devem aparecer no TCC como trabalhos futuros, limitações ou itens planejados, nunca como funcionalidades disponíveis.


Desenvolvido no curso de Bacharelado em Sistemas de Informação da UNIRIO.

About

Academic projects platform for UNIRIO: a public catalog synced from the SIE, with institutional Google sign-in, editorial tools for professors and admin control over publication and sync history. FastAPI, PostgreSQL, Redis.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages