Ir para o conteúdo

03 — Modelagem de Entidades — Dito e Feito

Esboço do modelo relacional do sistema, com as principais entidades, seus atributos e relacionamentos.


Entidades principais

1. parlamentar

Representa um deputado federal com seus dados cadastrais.

CREATE TABLE parlamentar (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    id_externo BIGINT UNIQUE, -- ID da API da Câmara
    nome_civil TEXT NOT NULL,
    nome_urna TEXT,
    sigla_partido VARCHAR(15),
    sigla_uf VARCHAR(2),
    foto_url TEXT,
    email TEXT,
    situacao TEXT, -- ex: "Exercício", "Afastado"
    dados_api JSONB, -- resposta bruta da API (opcional)
    criado_em TIMESTAMPTZ DEFAULT now(),
    atualizado_em TIMESTAMPTZ DEFAULT now()
);

2. discurso

Pronunciamentos feitos pelo parlamentar em plenário ou comissões.

CREATE TYPE fase_discurso AS ENUM (
    'Plenário', 'Comissão', 'CPI', 'Outro'
);

CREATE TABLE discurso (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    id_externo BIGINT UNIQUE,
    parlamentar_id UUID NOT NULL REFERENCES parlamentar(id) ON DELETE CASCADE,
    data_hora TIMESTAMPTZ NOT NULL,
    fase fase_discurso,
    sumario TEXT,
    transcricao TEXT, -- texto completo, se disponível
    palavras_chave TEXT[], -- extraídas por NLP
    dados_api JSONB,
    criado_em TIMESTAMPTZ DEFAULT now()
);

3. proposicao

Uma proposta legislativa (PL, PEC, MPV, etc.) que vai a votação.

CREATE TABLE proposicao (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    id_externo BIGINT UNIQUE,
    sigla_tipo VARCHAR(10), -- ex: "PL", "PEC", "MPV"
    numero INTEGER,
    ano INTEGER,
    ementa TEXT,
    keywords TEXT[],
    dados_api JSONB,
    criado_em TIMESTAMPTZ DEFAULT now()
);

4. votacao

Evento de votação em plenário sobre uma proposição.

CREATE TABLE votacao (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    id_externo TEXT UNIQUE, -- ID da API (pode ser string)
    proposicao_id UUID REFERENCES proposicao(id) ON DELETE SET NULL,
    data_hora TIMESTAMPTZ NOT NULL,
    descricao TEXT,
    aprovada BOOLEAN,
    dados_api JSONB,
    criado_em TIMESTAMPTZ DEFAULT now()
);

5. voto

O voto individual de um parlamentar em uma votação específica.

CREATE TYPE resultado_voto AS ENUM (
    'Sim', 'Não', 'Abstenção', 'Obstrução', 'Art. 17', 'Ausente'
);

CREATE TABLE voto (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    parlamentar_id UUID NOT NULL REFERENCES parlamentar(id) ON DELETE CASCADE,
    votacao_id UUID NOT NULL REFERENCES votacao(id) ON DELETE CASCADE,
    resultado resultado_voto NOT NULL,
    criado_em TIMESTAMPTZ DEFAULT now(),
    UNIQUE (parlamentar_id, votacao_id) -- um parlamentar vota uma vez por votação
);

6. score_coerencia

Score calculado pela IA comparando os discursos e votos de um parlamentar.

CREATE TABLE score_coerencia (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    parlamentar_id UUID NOT NULL REFERENCES parlamentar(id) ON DELETE CASCADE,
    discurso_id UUID REFERENCES discurso(id) ON DELETE SET NULL,
    votacao_id UUID REFERENCES votacao(id) ON DELETE SET NULL,
    score NUMERIC(5, 2) CHECK (score >= 0 AND score <= 100),
    similaridade_coseno FLOAT, -- métrica do modelo NLP
    modelo_usado TEXT, -- ex: "sentence-transformers/..."
    justificativa TEXT, -- explicação gerada pela IA
    calculado_em TIMESTAMPTZ DEFAULT now()
);

Diagrama de relacionamentos (texto)

parlamentar
    │
    ├──< discurso (1 parlamentar → N discursos)
    │
    ├──< voto (1 parlamentar → N votos)
    │ │
    │ └──> votacao (N votos → 1 votação)
    │ │
    │ └──> proposicao (N votações → 1 proposição)
    │
    └──< score_coerencia (1 parlamentar → N scores)
             ├──> discurso
             └──> votacao

Diagrama ER (Mermaid)

Cole este código em mermaid.live para visualizar o diagrama.

erDiagram
    PARLAMENTAR {
        uuid id PK
        bigint id_externo
        text nome_civil
        text nome_urna
        varchar sigla_partido
        varchar sigla_uf
    }

    DISCURSO {
        uuid id PK
        uuid parlamentar_id FK
        timestamptz data_hora
        text sumario
        text transcricao
        text[] palavras_chave
    }

    PROPOSICAO {
        uuid id PK
        bigint id_externo
        varchar sigla_tipo
        integer numero
        integer ano
        text ementa
    }

    VOTACAO {
        uuid id PK
        uuid proposicao_id FK
        timestamptz data_hora
        text descricao
        boolean aprovada
    }

    VOTO {
        uuid id PK
        uuid parlamentar_id FK
        uuid votacao_id FK
        resultado_voto resultado
    }

    SCORE_COERENCIA {
        uuid id PK
        uuid parlamentar_id FK
        uuid discurso_id FK
        uuid votacao_id FK
        numeric score
        float similaridade_coseno
        text modelo_usado
    }

    PARLAMENTAR ||--o{ DISCURSO : "faz"
    PARLAMENTAR ||--o{ VOTO : "realiza"
    VOTACAO ||--o{ VOTO : "contém"
    PROPOSICAO ||--o{ VOTACAO : "origina"
    PARLAMENTAR ||--o{ SCORE_COERENCIA : "recebe"
    DISCURSO ||--o{ SCORE_COERENCIA : "alimenta"
    VOTACAO ||--o{ SCORE_COERENCIA : "alimenta"

Decisões de modelagem

Decisão Justificativa
UUID como PK Evita exposição de sequência, facilita integração entre serviços
id_externo separado Preserva o ID da API sem depender dele como PK
dados_api JSONB Permite armazenar a resposta bruta para reprocessamento futuro
ENUM para resultado_voto Garante integridade sem depender da aplicação
UNIQUE (parlamentar_id, votacao_id) em voto Impede duplicidade de votos
score_coerencia como tabela separada O cálculo pode ser refeito com modelos diferentes