Spaces:
Sleeping
Sleeping
| """ | |
| SQLAlchemy models for the APIGateway application. | |
| """ | |
| from sqlalchemy import Column, Integer, String, Text, DateTime, JSON, Boolean | |
| from sqlalchemy.sql import func | |
| from core.database import Base | |
| class BlinkData(Base): | |
| """ | |
| Model for storing decrypted blink data. | |
| Attributes: | |
| id: Primary key | |
| user_id: User identifier (first 20 chars from URL param) | |
| refer_url: Referer URL from request header | |
| json_data: Decrypted JSON data | |
| created_at: Timestamp of record creation | |
| """ | |
| __tablename__ = "blink_data" | |
| id = Column(Integer, primary_key=True, autoincrement=True, index=True) | |
| user_id = Column(String(20), index=True, nullable=False) | |
| refer_url = Column(Text, nullable=True) | |
| ip_address = Column(String(45), nullable=True) # IPv6 can be up to 45 chars | |
| ipv4_address = Column(String(15), nullable=True) | |
| ipv6_address = Column(String(45), nullable=True) | |
| country = Column(String(100), nullable=True) # Country from IP geolocation | |
| region = Column(String(100), nullable=True) # Region/State from IP geolocation | |
| json_data = Column(JSON, nullable=True) | |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) | |
| def __repr__(self): | |
| return f"<BlinkData(id={self.id}, user_id={self.user_id})>" | |
| class User(Base): | |
| """ | |
| User model for credit system. | |
| Supports both legacy secret key and Google OAuth authentication. | |
| """ | |
| __tablename__ = "users" | |
| id = Column(Integer, primary_key=True, autoincrement=True, index=True) | |
| user_id = Column(String(50), unique=True, index=True, nullable=False) # Backend generated UUID | |
| temp_user_id = Column(String(50), index=True, nullable=True) # From frontend | |
| email = Column(String(255), unique=True, index=True, nullable=False) | |
| # Google OAuth fields | |
| google_id = Column(String(255), unique=True, index=True, nullable=True) # Google sub claim | |
| name = Column(String(255), nullable=True) # Display name from Google | |
| profile_picture = Column(Text, nullable=True) # Google profile picture URL | |
| # Legacy field (kept for migration, nullable now) | |
| secret_key_hash = Column(String(255), nullable=True) | |
| # Credits and status | |
| credits = Column(Integer, default=100) | |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) | |
| updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) | |
| last_used_at = Column(DateTime(timezone=True), nullable=True) | |
| is_active = Column(Boolean, default=True) | |
| def __repr__(self): | |
| return f"<User(id={self.id}, email={self.email})>" | |
| class RateLimit(Base): | |
| """ | |
| Rate limit tracking table. | |
| """ | |
| __tablename__ = "rate_limits" | |
| id = Column(Integer, primary_key=True, autoincrement=True, index=True) | |
| identifier = Column(String(255), index=True, nullable=False) # IP or email | |
| endpoint = Column(String(255), index=True, nullable=False) | |
| attempts = Column(Integer, default=0) | |
| window_start = Column(DateTime(timezone=True), nullable=False) | |
| expires_at = Column(DateTime(timezone=True), nullable=False) | |
| class AuditLog(Base): | |
| """ | |
| Audit log for security events. | |
| """ | |
| __tablename__ = "audit_logs" | |
| id = Column(Integer, primary_key=True, autoincrement=True, index=True) | |
| user_id = Column(String(50), nullable=True) | |
| action = Column(String(50), nullable=False) | |
| ip_address = Column(String(45), nullable=False) | |
| user_agent = Column(String(255), nullable=True) | |
| status = Column(String(20), nullable=False) | |
| error_message = Column(Text, nullable=True) | |
| timestamp = Column(DateTime(timezone=True), server_default=func.now()) | |
| class GeminiJob(Base): | |
| """ | |
| Generic job queue for Gemini operations (video, image, text). | |
| """ | |
| __tablename__ = "gemini_jobs" | |
| id = Column(Integer, primary_key=True, autoincrement=True, index=True) | |
| job_id = Column(String(100), unique=True, index=True, nullable=False) # Our ID for client | |
| user_id = Column(String(50), index=True, nullable=False) # User who requested | |
| job_type = Column(String(20), index=True, nullable=False) # video, image, text, analyze | |
| third_party_id = Column(String(255), nullable=True) # Gemini operation name (for video) | |
| status = Column(String(20), default="queued", index=True) # queued, processing, completed, failed | |
| input_data = Column(JSON, nullable=True) # Request details (prompt, settings, etc.) | |
| output_data = Column(JSON, nullable=True) # Result (filename, text, etc.) | |
| error_message = Column(Text, nullable=True) | |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) | |
| started_at = Column(DateTime(timezone=True), nullable=True) | |
| completed_at = Column(DateTime(timezone=True), nullable=True) | |
| def __repr__(self): | |
| return f"<GeminiJob(job_id={self.job_id}, type={self.job_type}, status={self.status})>" | |