""" SQLAlchemy Models for Numidium """ from sqlalchemy import Column, String, Text, DateTime, Float, JSON, ForeignKey, Table from sqlalchemy.orm import relationship from datetime import datetime import uuid from app.core.database import Base def generate_uuid(): return str(uuid.uuid4()) class Entity(Base): """ Entidade - qualquer coisa rastreável no sistema Pode ser: pessoa, organização, local, veículo, evento, documento, etc. """ __tablename__ = "entities" id = Column(String(36), primary_key=True, default=generate_uuid) type = Column(String(50), nullable=False, index=True) # person, organization, location, etc name = Column(String(255), nullable=False, index=True) description = Column(Text, nullable=True) properties = Column(JSON, default=dict) # Dados flexíveis # Geolocalização (opcional) latitude = Column(Float, nullable=True) longitude = Column(Float, nullable=True) # Fonte do dado source = Column(String(100), nullable=True) # wikipedia, newsapi, manual, etc source_url = Column(Text, nullable=True) # Timestamps created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Relacionamentos outgoing_relationships = relationship( "Relationship", foreign_keys="Relationship.source_id", back_populates="source_entity" ) incoming_relationships = relationship( "Relationship", foreign_keys="Relationship.target_id", back_populates="target_entity" ) class Relationship(Base): """ Relacionamento entre duas entidades Exemplos: works_for, knows, owns, located_at, participated_in """ __tablename__ = "relationships" id = Column(String(36), primary_key=True, default=generate_uuid) source_id = Column(String(36), ForeignKey("entities.id"), nullable=False) target_id = Column(String(36), ForeignKey("entities.id"), nullable=False) type = Column(String(50), nullable=False, index=True) # works_for, knows, owns, etc properties = Column(JSON, default=dict) confidence = Column(Float, default=1.0) # 0-1, quão certo estamos dessa conexão # Fonte source = Column(String(100), nullable=True) # Timestamps created_at = Column(DateTime, default=datetime.utcnow) # Relacionamentos source_entity = relationship("Entity", foreign_keys=[source_id], back_populates="outgoing_relationships") target_entity = relationship("Entity", foreign_keys=[target_id], back_populates="incoming_relationships") class Event(Base): """ Evento - algo que aconteceu envolvendo entidades """ __tablename__ = "events" id = Column(String(36), primary_key=True, default=generate_uuid) type = Column(String(50), nullable=False, index=True) title = Column(String(255), nullable=False) description = Column(Text, nullable=True) # Quando aconteceu event_date = Column(DateTime, nullable=True) # Onde aconteceu location_name = Column(String(255), nullable=True) latitude = Column(Float, nullable=True) longitude = Column(Float, nullable=True) # Entidades envolvidas (armazenado como JSON array de IDs) entity_ids = Column(JSON, default=list) # Fonte source = Column(String(100), nullable=True) source_url = Column(Text, nullable=True) # Metadados properties = Column(JSON, default=dict) # Timestamps created_at = Column(DateTime, default=datetime.utcnow) class Document(Base): """ Documento - texto/arquivo para análise """ __tablename__ = "documents" id = Column(String(36), primary_key=True, default=generate_uuid) title = Column(String(255), nullable=False) content = Column(Text, nullable=True) summary = Column(Text, nullable=True) # Resumo gerado por IA # Tipo de documento doc_type = Column(String(50), default="text") # text, news, report, etc # Entidades mencionadas (extraídas por NLP) mentioned_entities = Column(JSON, default=list) # Fonte source = Column(String(100), nullable=True) source_url = Column(Text, nullable=True) # Timestamps published_at = Column(DateTime, nullable=True) created_at = Column(DateTime, default=datetime.utcnow)