from sqlalchemy import Column, String, Integer, DateTime, Float, Boolean, Text, ForeignKey, Index, UniqueConstraint, CheckConstraint from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from datetime import datetime import uuid Base = declarative_base() class Tribunal(Base): """Tabela de Tribunais.""" __tablename__ = 'tribunais' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) nome = Column(String(255), nullable=False, unique=True, index=True) sigla = Column(String(10), nullable=False, unique=True) uf = Column(String(2), nullable=False) tipo = Column(String(50), nullable=False) url_base = Column(String(500)) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) acordaos = relationship('Acordao', back_populates='tribunal', cascade='all, delete-orphan') __table_args__ = ( Index('idx_tribunal_sigla_uf', 'sigla', 'uf'), ) class Acordao(Base): """Tabela de Acórdãos.""" __tablename__ = 'acordaos' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) tribunal_id = Column(String(36), ForeignKey('tribunais.id'), nullable=False, index=True) numero = Column(String(50), nullable=False) ano = Column(Integer, nullable=False, index=True) data_julgamento = Column(DateTime, nullable=False, index=True) ementa = Column(Text, nullable=False) relator = Column(String(255)) orgao_julgador = Column(String(255)) url_original = Column(String(500), unique=True) hash_conteudo = Column(String(64), nullable=False, unique=True, index=True) status_processamento = Column(String(20), default='pendente', index=True) created_at = Column(DateTime, default=datetime.utcnow, index=True) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) tribunal = relationship('Tribunal', back_populates='acordaos') decisoes = relationship('Decisao', back_populates='acordao', cascade='all, delete-orphan') palavras_chave = relationship('PalavraChave', secondary='acordao_palavras_chave', back_populates='acordaos') embeddings = relationship('Embedding', back_populates='acordao', cascade='all, delete-orphan') __table_args__ = ( UniqueConstraint('tribunal_id', 'numero', 'ano', name='uq_acordao_tribunal_numero_ano'), Index('idx_acordao_data_tribunal', 'data_julgamento', 'tribunal_id'), Index('idx_acordao_status', 'status_processamento'), ) class Decisao(Base): """Tabela de Decisões extraídas dos acórdãos.""" __tablename__ = 'decisoes' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) acordao_id = Column(String(36), ForeignKey('acordaos.id'), nullable=False, index=True) tipo = Column(String(50), nullable=False) texto = Column(Text, nullable=False) confianca = Column(Float, default=0.0) created_at = Column(DateTime, default=datetime.utcnow) acordao = relationship('Acordao', back_populates='decisoes') __table_args__ = ( Index('idx_decisao_acordo_tipo', 'acordao_id', 'tipo'), ) class PalavraChave(Base): """Tabela de Palavras-chave para classificação.""" __tablename__ = 'palavras_chave' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) termo = Column(String(255), nullable=False, unique=True, index=True) categoria = Column(String(100), nullable=False, index=True) frequencia = Column(Integer, default=0) ativo = Column(Boolean, default=True) created_at = Column(DateTime, default=datetime.utcnow) acordaos = relationship('Acordao', secondary='acordao_palavras_chave', back_populates='palavras_chave') class AcordaoPalavraChave(Base): """Tabela de associação Acórdão-PalavraChave.""" __tablename__ = 'acordao_palavras_chave' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) acordao_id = Column(String(36), ForeignKey('acordaos.id'), nullable=False, index=True) palavra_chave_id = Column(String(36), ForeignKey('palavras_chave.id'), nullable=False, index=True) relevancia = Column(Float, default=0.0) created_at = Column(DateTime, default=datetime.utcnow) __table_args__ = ( UniqueConstraint('acordao_id', 'palavra_chave_id', name='uq_acordao_palavra'), ) class Embedding(Base): """Tabela de Embeddings (representação vetorial).""" __tablename__ = 'embeddings' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) acordao_id = Column(String(36), ForeignKey('acordaos.id'), nullable=False, index=True) modelo = Column(String(100), nullable=False) tipo = Column(String(50), nullable=False) vetor = Column(Text, nullable=False) dimensoes = Column(Integer) created_at = Column(DateTime, default=datetime.utcnow) acordao = relationship('Acordao', back_populates='embeddings') __table_args__ = ( Index('idx_embedding_acordo_modelo', 'acordao_id', 'modelo'), ) class Usuario(Base): """Tabela de Usuários do sistema.""" __tablename__ = 'usuarios' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) email = Column(String(255), nullable=False, unique=True, index=True) nome = Column(String(255), nullable=False) senha_hash = Column(String(255), nullable=False) ativo = Column(Boolean, default=True) role = Column(String(50), default='user') created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) buscas = relationship('Busca', back_populates='usuario', cascade='all, delete-orphan') class Busca(Base): """Tabela de Buscas realizadas pelos usuários.""" __tablename__ = 'buscas' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) usuario_id = Column(String(36), ForeignKey('usuarios.id'), nullable=False, index=True) termo = Column(String(500), nullable=False) filtros = Column(Text) resultado_count = Column(Integer, default=0) tempo_execucao = Column(Float) created_at = Column(DateTime, default=datetime.utcnow, index=True) usuario = relationship('Usuario', back_populates='buscas') __table_args__ = ( Index('idx_busca_usuario_data', 'usuario_id', 'created_at'), ) class ProcessoJudicial(Base): """Tabela de Processos Judiciais relacionados.""" __tablename__ = 'processos_judiciais' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) numero_processo = Column(String(50), nullable=False, unique=True, index=True) tribunal_id = Column(String(36), ForeignKey('tribunais.id'), nullable=False) data_distribuicao = Column(DateTime, nullable=False) status = Column(String(50), default='ativo') parte_ativa = Column(String(255)) parte_passiva = Column(String(255)) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class AuditoriaAcesso(Base): """Tabela de auditoria de acessos.""" __tablename__ = 'auditoria_acessos' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) usuario_id = Column(String(36), ForeignKey('usuarios.id'), nullable=True) acao = Column(String(100), nullable=False) recurso = Column(String(255)) ip_address = Column(String(45)) status = Column(String(20)) created_at = Column(DateTime, default=datetime.utcnow, index=True) __table_args__ = ( Index('idx_auditoria_usuario_data', 'usuario_id', 'created_at'), )