| 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_id = Column(String(50), unique=True, nullable=False, index=True) |
| filename = Column(String(255), nullable=False) |
| file_format = Column(String(10), nullable=False) |
| file_size = Column(Integer, nullable=True) |
| |
| |
| upload_timestamp = Column(DateTime, nullable=False, default=datetime.utcnow, index=True) |
| user_id = Column(String(100), nullable=True) |
| |
| |
| text_preview = Column(String(500), nullable=True) |
| text_length = Column(Integer, nullable=False) |
| word_count = Column(Integer, nullable=False) |
| |
| |
| overall_ai_score = Column(Float, nullable=False) |
| overall_confidence = Column(String(20), nullable=False) |
| |
| |
| detector_results = Column(JSON, nullable=False) |
| |
| |
| analysis_status = Column(String(20), default="completed") |
| error_message = Column(Text, nullable=True) |
| |
| |
| report_html_path = Column(String(500), nullable=True) |
| |
| |
| notes = Column(Text, nullable=True) |
| is_flagged = Column(Boolean, default=False) |
| |
| 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""" |
| |
| 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 {} |
| ) |
| |
| |
| 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() |
|
|