gmail-agentic / backend /app /database /postgres.py
Kushal14680
Add files via upload
e280b6e unverified
Raw
History Blame Contribute Delete
3.72 kB
import uuid
from datetime import datetime
from typing import AsyncGenerator
from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, Text, select
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import DeclarativeBase
from app.config import settings
# Create async engine
engine = create_async_engine(settings.DATABASE_URL, echo=False)
# Create session factory
SessionLocal = async_sessionmaker(
bind=engine,
class_=AsyncSession,
expire_on_commit=False,
autocommit=False,
autoflush=False
)
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
email = Column(String, unique=True, index=True, nullable=False)
name = Column(String, nullable=True)
oauth_token_encrypted = Column(Text, nullable=True)
hashed_password = Column(String, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
class Email(Base):
__tablename__ = "emails"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
gmail_message_id = Column(String, unique=True, index=True, nullable=True)
subject = Column(String, nullable=True)
sender = Column(String, nullable=False)
received_at = Column(DateTime, default=datetime.utcnow, nullable=False)
category = Column(String, default="personal", nullable=False) # urgent, personal, invoice, newsletter
is_read = Column(Boolean, default=False, nullable=False)
is_starred = Column(Boolean, default=False, nullable=False)
thread_id = Column(String, nullable=True)
has_attachment = Column(Boolean, default=False, nullable=False)
class AgentRun(Base):
__tablename__ = "agent_runs"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
email_id = Column(UUID(as_uuid=True), ForeignKey("emails.id", ondelete="CASCADE"), nullable=True, index=True)
action_type = Column(String, nullable=False) # TRIAGE | SUMMARIZE | DRAFT | TASK_EXTRACTION
status = Column(String, default="PENDING", nullable=False) # PENDING | RUNNING | COMPLETED | FAILED
started_at = Column(DateTime, default=datetime.utcnow, nullable=False)
completed_at = Column(DateTime, nullable=True)
celery_task_id = Column(String, nullable=True)
class Followup(Base):
__tablename__ = "followups"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
email_id = Column(UUID(as_uuid=True), ForeignKey("emails.id", ondelete="CASCADE"), nullable=False, index=True)
due_at = Column(DateTime, nullable=False)
message = Column(Text, nullable=False)
status = Column(String, default="PENDING", nullable=False) # PENDING | COMPLETED
async def init_db() -> None:
"""Initialize tables in the database."""
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
async def get_db() -> AsyncGenerator[AsyncSession, None]:
"""Dependency for getting async db sessions in routes."""
async with SessionLocal() as session:
try:
yield session
await session.commit()
except Exception:
await session.rollback()
raise
finally:
await session.close()