MODULO 5.7

💾 Persistencia e Auditoria

Modelo de dados, queries de auditoria e rastreabilidade.

6
Topicos
~40
Minutos
Pratico
Nivel
Hands-on
Tipo
1

🗃️ Implementando o Modelo

# app/models/interaction.py
from sqlalchemy import Column, Integer, String, Text, Float, DateTime
from app.database import Base

class Interaction(Base):
    __tablename__ = "interactions"

    id = Column(Integer, primary_key=True, index=True)
    request_id = Column(String(36), unique=True, index=True)

    # Input
    input_text = Column(Text, nullable=False)
    prompt_sent = Column(Text, nullable=False)

    # Output
    response_received = Column(Text, nullable=False)

    # Governanca
    persona_used = Column(String(50))

    # Metricas
    tokens_input = Column(Integer)
    tokens_output = Column(Integer)
    cost_usd = Column(Float)
    latency_ms = Column(Integer)

    # Timestamp
    timestamp = Column(DateTime, index=True)
2

📊 CRUD Operations

# app/repositories/interaction.py
class InteractionRepository:
    def __init__(self, db: Session):
        self.db = db

    def create(self, data: dict) -> Interaction:
        interaction = Interaction(**data)
        self.db.add(interaction)
        self.db.commit()
        self.db.refresh(interaction)
        return interaction

    def get_by_request_id(self, request_id: str) -> Optional[Interaction]:
        return self.db.query(Interaction).filter(
            Interaction.request_id == request_id
        ).first()

    def list_recent(self, limit: int = 100) -> List[Interaction]:
        return self.db.query(Interaction).order_by(
            Interaction.timestamp.desc()
        ).limit(limit).all()

    def delete(self, request_id: str) -> bool:
        interaction = self.get_by_request_id(request_id)
        if interaction:
            self.db.delete(interaction)
            self.db.commit()
            return True
        return False
3

🔍 Queries de Auditoria

class AuditRepository:
    """Queries especializadas para auditoria GIPM"""

    def get_full_trace(self, request_id: str) -> dict:
        """Rastreia uma requisicao completa"""
        interaction = self.db.query(Interaction).filter(
            Interaction.request_id == request_id
        ).first()

        return {
            "request_id": interaction.request_id,
            "timestamp": interaction.timestamp,
            "input": interaction.input_text,
            "prompt_sent": interaction.prompt_sent,
            "response": interaction.response_received,
            "persona": interaction.persona_used,
            "tokens": interaction.tokens_input + interaction.tokens_output,
            "cost": interaction.cost_usd,
            "latency": interaction.latency_ms
        }

    def get_interactions_by_date_range(self, start: datetime, end: datetime):
        return self.db.query(Interaction).filter(
            Interaction.timestamp >= start,
            Interaction.timestamp <= end
        ).all()
4

💰 Tracking de Custos

class CostTracker:
    def get_total_cost(self, db: Session) -> float:
        return db.query(func.sum(Interaction.cost_usd)).scalar() or 0.0

    def get_daily_costs(self, db: Session, days: int = 30) -> List[dict]:
        results = db.query(
            func.date(Interaction.timestamp).label('date'),
            func.sum(Interaction.cost_usd).label('cost'),
            func.count(Interaction.id).label('requests')
        ).group_by(
            func.date(Interaction.timestamp)
        ).order_by(
            func.date(Interaction.timestamp).desc()
        ).limit(days).all()

        return [{"date": r.date, "cost": r.cost, "requests": r.requests} for r in results]

    def check_daily_limit(self, db: Session, limit_usd: float) -> bool:
        today_cost = db.query(func.sum(Interaction.cost_usd)).filter(
            func.date(Interaction.timestamp) == func.date(func.now())
        ).scalar() or 0.0
        return today_cost < limit_usd
5

📈 Dashboards

# Endpoint para dashboard de metricas
@router.get("/api/v1/dashboard")
async def get_dashboard(db: Session = Depends(get_db)):
    cost_tracker = CostTracker()
    audit_repo = AuditRepository(db)

    return {
        "summary": {
            "total_requests": db.query(func.count(Interaction.id)).scalar(),
            "total_cost": cost_tracker.get_total_cost(db),
            "total_tokens": db.query(func.sum(
                Interaction.tokens_input + Interaction.tokens_output
            )).scalar() or 0
        },
        "daily_costs": cost_tracker.get_daily_costs(db, days=7),
        "persona_usage": db.query(
            Interaction.persona_used,
            func.count(Interaction.id)
        ).group_by(Interaction.persona_used).all(),
        "avg_latency": db.query(func.avg(Interaction.latency_ms)).scalar()
    }
6

🔐 Compliance

class ComplianceService:
    """Servico para garantir conformidade GIPM"""

    def verify_complete_audit_trail(self, request_id: str, db: Session) -> bool:
        """Verifica se a interacao tem audit trail completo"""
        interaction = db.query(Interaction).filter(
            Interaction.request_id == request_id
        ).first()

        required_fields = [
            'input_text', 'prompt_sent', 'response_received',
            'persona_used', 'tokens_input', 'tokens_output',
            'cost_usd', 'timestamp'
        ]

        for field in required_fields:
            if getattr(interaction, field) is None:
                return False
        return True

    def generate_compliance_report(self, db: Session) -> dict:
        total = db.query(func.count(Interaction.id)).scalar()
        complete = 0
        for interaction in db.query(Interaction).all():
            if self.verify_complete_audit_trail(interaction.request_id, db):
                complete += 1

        return {
            "total_interactions": total,
            "complete_audit_trail": complete,
            "compliance_rate": complete / total if total > 0 else 1.0,
            "gipm_compliant": complete == total
        }

📝 Resumo do Modulo

Modelo - Interaction com todos os campos
Auditoria - Queries para rastrear tudo
Custos - Tracking e limites diarios
Compliance - Verificacao de conformidade