ARCHIVISE / app /models.py
UNI12345's picture
fix: resolution of critical blockers (P0/P1/P2 fixes) - async Redis, atomic credit updates, schema compatibility, task event loop safety, rate limits, timezone datetimes
5019340
Raw
History Blame Contribute Delete
7.47 kB
import uuid
from datetime import datetime, timezone
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, Float, JSON
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import relationship
from app.database import Base
# Timezone-aware UTC timestamp factory — avoids naive/aware comparison TypeError
def utcnow():
return datetime.now(timezone.utc)
class User(Base):
__tablename__ = "users"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
firebase_uid = Column(String, unique=True, index=True, nullable=False)
email = Column(String, unique=True, index=True, nullable=False)
name = Column(String, nullable=True)
avatar_url = Column(String, nullable=True)
plan = Column(String, default="free") # 'free', 'starter', 'pro'
display_mode = Column(String, default="founder") # 'founder', 'engineer'
credits_remaining = Column(Integer, default=2)
credits_reset_at = Column(DateTime(timezone=True), default=utcnow)
stripe_customer_id = Column(String, nullable=True)
github_connected = Column(Boolean, default=False)
total_audits = Column(Integer, default=0)
total_designs = Column(Integer, default=0)
is_active = Column(Boolean, default=True)
created_at = Column(DateTime(timezone=True), default=utcnow)
updated_at = Column(DateTime(timezone=True), default=utcnow, onupdate=utcnow)
projects = relationship("Project", back_populates="user", cascade="all, delete-orphan")
github_connection = relationship("GitHubConnection", back_populates="user", uselist=False, cascade="all, delete-orphan")
class Project(Base):
__tablename__ = "projects"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), index=True, nullable=False)
name = Column(String(100), nullable=False)
type = Column(String, nullable=False) # 'audit', 'system_design'
source = Column(String, nullable=False) # 'upload', 'github'
status = Column(String, index=True, default="queued") # 'queued', 'processing', 'complete', 'failed'
job_id = Column(String, index=True, nullable=True)
error_msg = Column(Text, nullable=True)
github_repo = Column(String, nullable=True)
github_branch = Column(String, nullable=True)
created_at = Column(DateTime(timezone=True), default=utcnow)
updated_at = Column(DateTime(timezone=True), default=utcnow, onupdate=utcnow)
user = relationship("User", back_populates="projects")
audit_report = relationship("AuditReport", back_populates="project", uselist=False, cascade="all, delete-orphan")
system_design = relationship("SystemDesign", back_populates="project", uselist=False, cascade="all, delete-orphan")
class AuditReport(Base):
__tablename__ = "audit_reports"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
project_id = Column(UUID(as_uuid=True), ForeignKey("projects.id", ondelete="CASCADE"), index=True, unique=True, nullable=False)
overall_score = Column(Integer, nullable=False)
confidence = Column(JSONB, nullable=False) # JSON: level, score, label, based_on, limitations, to_increase_confidence
capacity_estimate = Column(JSONB, nullable=False) # JSON: safe_range, peak_range, description, reasoning, confidence
agents = Column(JSONB, nullable=False) # JSON: SRE, backend, infrastructure, cloud_architect reports
top_critical_issues = Column(JSONB, nullable=False) # Array of issues
quick_wins = Column(JSONB, nullable=False) # Array of quick wins
benchmark_percentile = Column(Float, nullable=True)
score_disclaimer = Column(Text, nullable=False)
files_analyzed = Column(Integer, default=0)
files_skipped = Column(Integer, default=0)
was_truncated = Column(Boolean, default=False)
created_at = Column(DateTime(timezone=True), default=utcnow)
project = relationship("Project", back_populates="audit_report")
class SystemDesign(Base):
__tablename__ = "system_designs"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
project_id = Column(UUID(as_uuid=True), ForeignKey("projects.id", ondelete="CASCADE"), index=True, unique=True, nullable=False)
idea_prompt = Column(Text, nullable=False)
title = Column(String, nullable=False)
founder_summary = Column(Text, nullable=False)
engineer_summary = Column(Text, nullable=False)
architecture_type = Column(String, nullable=False) # 'Monolith', 'Microservices', 'Hybrid'
reasoning = Column(Text, nullable=False)
stack = Column(JSONB, nullable=False) # JSON: Frontend, Backend, Database, Infrastructure chips with reasons
database_design = Column(JSONB, nullable=False) # JSON: primary_db, cache, key_tables
api_design = Column(JSONB, nullable=False) # JSON: style, auth_strategy, core_endpoints
infrastructure = Column(JSONB, nullable=False) # JSON: cloud_provider, components, scaling_strategy
reliability = Column(JSONB, nullable=False) # JSON: uptime_target, strategies, backup_dr
cost_estimates = Column(JSONB, nullable=False) # JSON: 1k, 100k, 1m tier costs and drivers
diagram = Column(JSONB, nullable=False) # JSON: nodes, edges
created_at = Column(DateTime(timezone=True), default=utcnow)
project = relationship("Project", back_populates="system_design")
shared_link = relationship("SharedLink", back_populates="design", uselist=False, cascade="all, delete-orphan")
class SharedLink(Base):
__tablename__ = "shared_links"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
design_id = Column(UUID(as_uuid=True), ForeignKey("system_designs.id", ondelete="CASCADE"), unique=True, nullable=False)
slug = Column(String, unique=True, index=True, nullable=False)
view_count = Column(Integer, default=0)
created_at = Column(DateTime(timezone=True), default=utcnow)
design = relationship("SystemDesign", back_populates="shared_link")
class GitHubConnection(Base):
__tablename__ = "github_connections"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), unique=True, index=True, nullable=False)
github_username = Column(String, nullable=False)
access_token = Column(String, nullable=False) # Encrypted text
token_expires_at = Column(DateTime(timezone=True), nullable=True)
connected_at = Column(DateTime(timezone=True), default=utcnow)
last_used_at = Column(DateTime(timezone=True), default=utcnow, onupdate=utcnow)
user = relationship("User", back_populates="github_connection")
class BenchmarkData(Base):
__tablename__ = "benchmark_data"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
score_range = Column(String, nullable=False) # e.g., '80-89'
industry_tag = Column(String, nullable=False) # e.g., 'E-Commerce'
arch_type = Column(String, nullable=False) # e.g., 'Serverless'
created_at = Column(DateTime(timezone=True), default=utcnow)
class WebhookEvent(Base):
__tablename__ = "webhook_events"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
event_id = Column(String, unique=True, index=True, nullable=False)
event_type = Column(String, nullable=False)
processed_at = Column(DateTime(timezone=True), default=utcnow)