misakovhearst
Initial deploy
48c7fed
from sqlalchemy import create_engine, Column, String, Float, DateTime, Integer, JSON, Text, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
import json
import os
Base = declarative_base()
class AnalysisResult(Base):
"""Database model for storing analysis results"""
__tablename__ = "analysis_results"
id = Column(Integer, primary_key=True)
# File information
file_id = Column(String(50), unique=True, nullable=False, index=True)
filename = Column(String(255), nullable=False)
file_format = Column(String(10), nullable=False) # pdf, docx, txt, raw
file_size = Column(Integer, nullable=True) # in bytes
# Upload information
upload_timestamp = Column(DateTime, nullable=False, default=datetime.utcnow, index=True)
user_id = Column(String(100), nullable=True) # For future auth integration
# Text analysis
text_preview = Column(String(500), nullable=True) # First 500 chars
text_length = Column(Integer, nullable=False) # Total character count
word_count = Column(Integer, nullable=False)
# Overall detection results
overall_ai_score = Column(Float, nullable=False) # 0-1
overall_confidence = Column(String(20), nullable=False) # very_low, low, medium, high, very_high
# Detector results (JSON)
detector_results = Column(JSON, nullable=False) # Full detector results
# Status
analysis_status = Column(String(20), default="completed") # completed, failed, pending
error_message = Column(Text, nullable=True)
# Report storage
report_html_path = Column(String(500), nullable=True)
# Metadata
notes = Column(Text, nullable=True)
is_flagged = Column(Boolean, default=False) # For manual flagging
def to_dict(self):
"""Convert to dictionary"""
return {
"id": self.id,
"file_id": self.file_id,
"filename": self.filename,
"file_format": self.file_format,
"file_size": self.file_size,
"upload_timestamp": self.upload_timestamp.isoformat() if self.upload_timestamp else None,
"text_length": self.text_length,
"word_count": self.word_count,
"overall_ai_score": self.overall_ai_score,
"overall_ai_score_percentage": f"{self.overall_ai_score * 100:.1f}%",
"overall_confidence": self.overall_confidence,
"detector_results": self.detector_results,
"analysis_status": self.analysis_status,
"error_message": self.error_message,
"is_flagged": self.is_flagged,
"notes": self.notes,
}
@staticmethod
def get_status_label(score: float) -> str:
"""Get human-readable status based on AI score"""
if score < 0.3:
return "Likely Human"
elif score < 0.6:
return "Suspicious"
else:
return "Likely AI"
class Session:
"""Database session manager"""
_engine = None
_SessionLocal = None
@classmethod
def init(cls):
"""Initialize database connection"""
# Get DATABASE_URL from environment or use SQLite default
database_url = os.getenv('DATABASE_URL', 'sqlite:///./analysis_results.db')
cls._engine = create_engine(
database_url,
connect_args={"check_same_thread": False} if "sqlite" in database_url else {}
)
# Create tables
Base.metadata.create_all(cls._engine)
cls._SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=cls._engine)
@classmethod
def get_session(cls):
"""Get a new database session"""
if cls._SessionLocal is None:
cls.init()
return cls._SessionLocal()
@classmethod
def close(cls):
"""Close database connection"""
if cls._engine:
cls._engine.dispose()