| | from sqlalchemy import Column, Integer, String, Float, DateTime, Text, ForeignKey, Boolean
|
| | from sqlalchemy.orm import relationship
|
| | from sqlalchemy.sql import func
|
| |
|
| | from .db import Base
|
| |
|
| |
|
| | class User(Base):
|
| | """
|
| | Stores user information from Firebase or OTP authentication.
|
| | """
|
| | __tablename__ = "users"
|
| |
|
| | id = Column(Integer, primary_key=True, index=True)
|
| | email = Column(String, unique=True, index=True, nullable=False)
|
| | name = Column(String, nullable=True)
|
| | picture = Column(String, nullable=True)
|
| |
|
| |
|
| | auth_method = Column(String, default='firebase')
|
| |
|
| |
|
| | firebase_uid = Column(String, unique=True, index=True, nullable=True)
|
| |
|
| |
|
| | email_verified = Column(Boolean, default=False)
|
| |
|
| | created_at = Column(
|
| | DateTime(timezone=True),
|
| | server_default=func.now(),
|
| | )
|
| |
|
| |
|
| |
|
| | extractions = relationship(
|
| | "ExtractionRecord",
|
| | back_populates="user",
|
| | primaryjoin="User.id == ExtractionRecord.user_id"
|
| | )
|
| |
|
| |
|
| | api_keys = relationship(
|
| | "APIKey",
|
| | back_populates="user",
|
| | cascade="all, delete-orphan"
|
| | )
|
| |
|
| |
|
| | class ExtractionRecord(Base):
|
| | """
|
| | Stores one extraction run so the History page can show past jobs.
|
| | We'll fill it from the /api/extract endpoint later.
|
| | """
|
| |
|
| | __tablename__ = "extractions"
|
| |
|
| | id = Column(Integer, primary_key=True, index=True)
|
| | user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
|
| |
|
| | file_name = Column(String, index=True)
|
| | file_type = Column(String)
|
| | file_size = Column(String)
|
| |
|
| | status = Column(String)
|
| | confidence = Column(Float)
|
| | fields_extracted = Column(Integer)
|
| | total_time_ms = Column(Integer)
|
| |
|
| | raw_output = Column(Text)
|
| | file_base64 = Column(Text, nullable=True)
|
| | error_message = Column(Text, nullable=True)
|
| |
|
| | created_at = Column(
|
| | DateTime(timezone=True),
|
| | server_default=func.now(),
|
| | )
|
| |
|
| |
|
| |
|
| | user = relationship(
|
| | "User",
|
| | back_populates="extractions",
|
| | primaryjoin="ExtractionRecord.user_id == User.id"
|
| | )
|
| |
|
| |
|
| | shared_from_extraction_id = Column(Integer, ForeignKey("extractions.id"), nullable=True, index=True)
|
| | shared_by_user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True)
|
| |
|
| |
|
| | class ShareToken(Base):
|
| | """
|
| | Stores share tokens for sharing extractions with other users.
|
| | """
|
| | __tablename__ = "share_tokens"
|
| |
|
| | id = Column(Integer, primary_key=True, index=True)
|
| | token = Column(String, unique=True, index=True, nullable=False)
|
| | extraction_id = Column(Integer, ForeignKey("extractions.id"), nullable=False, index=True)
|
| | sender_user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
|
| | recipient_email = Column(String, nullable=True, index=True)
|
| | expires_at = Column(DateTime(timezone=True), nullable=True)
|
| | accessed = Column(Boolean, default=False)
|
| | accessed_at = Column(DateTime(timezone=True), nullable=True)
|
| | accessed_by_user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
|
| |
|
| | created_at = Column(
|
| | DateTime(timezone=True),
|
| | server_default=func.now(),
|
| | )
|
| |
|
| |
|
| | class APIKey(Base):
|
| | """
|
| | Stores API keys for external application authentication.
|
| | API keys are hashed before storage for security.
|
| | """
|
| | __tablename__ = "api_keys"
|
| |
|
| | id = Column(Integer, primary_key=True, index=True)
|
| | user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
|
| | name = Column(String, nullable=False)
|
| | key_hash = Column(String, unique=True, index=True, nullable=False)
|
| | key_prefix = Column(String, nullable=False)
|
| | is_active = Column(Boolean, default=True, nullable=False)
|
| | last_used_at = Column(DateTime(timezone=True), nullable=True)
|
| | created_at = Column(
|
| | DateTime(timezone=True),
|
| | server_default=func.now(),
|
| | )
|
| |
|
| |
|
| | user = relationship(
|
| | "User",
|
| | back_populates="api_keys"
|
| | )
|
| |
|