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.
- 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.
| 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. |
| 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 |
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
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 |
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"
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
- 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
partialem vez desuccess. - Rastreabilidade. Cada
sync_runguarda 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,sieouadmin), e a sincronização nunca rebaixa um papel definido pela administração.
| 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. |
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 |
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 --buildO 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.
python -m pytestA 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.
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.
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
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.