apigateway / core /models.py
jebin2's picture
google sign in
1bd7131
raw
history blame
4.93 kB
"""
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})>"