from typing import Any import uuid from datetime import datetime, timezone from sqlalchemy import DateTime, JSON, func from sqlalchemy.ext.asyncio import AsyncSession from sqlmodel import Field, SQLModel, select def _now() -> datetime: return datetime.now(timezone.utc) class OrgSettings(SQLModel, table=True): __tablename__ = "org_settings" id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) setting_key: str = Field(unique=True, index=True) setting_value: Any = Field(sa_type=JSON) category: str updated_by: uuid.UUID | None = Field(default=None, foreign_key="users.id") created_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True)) updated_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True)) @staticmethod def _as_uuid(record_id) -> uuid.UUID | None: if record_id in (None, ""): return None try: return uuid.UUID(str(record_id)) except ValueError: return None @classmethod async def fetch_settings(cls, session: AsyncSession, *, category: str | None = None): statement = select(cls) if category: statement = statement.where(cls.category == category) statement = statement.order_by(cls.setting_key.asc()) result = await session.execute(statement) rows = list(result.scalars().all()) return rows, len(rows) @classmethod async def get_by_key(cls, session: AsyncSession, setting_key: str): result = await session.execute(select(cls).where(cls.setting_key == setting_key)) return result.scalars().first() @classmethod async def upsert_settings(cls, session: AsyncSession, items: list[dict], updated_by): rows = [] now = _now() for item in items: key = item["setting_key"] row = await cls.get_by_key(session, key) if row is None: row = cls( setting_key=key, setting_value=item.get("setting_value"), category=item["category"], updated_by=updated_by, created_at=now, updated_at=now, ) else: row.setting_value = item.get("setting_value") row.category = item["category"] row.updated_by = updated_by row.updated_at = now session.add(row) rows.append(row) await session.commit() for row in rows: await session.refresh(row) return rows class ExcludeUniversity(SQLModel, table=True): __tablename__ = "exclude_university" id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) name: str = Field(index=True) created_by: uuid.UUID | None = Field(default=None, foreign_key="users.id") created_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True)) updated_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True)) is_deleted: bool = Field(default=False) @staticmethod def _as_uuid(record_id) -> uuid.UUID | None: if record_id in (None, ""): return None try: return uuid.UUID(str(record_id)) except ValueError: return None @classmethod async def get_by_id(cls, session: AsyncSession, record_id): uid = cls._as_uuid(record_id) if uid is None: return None result = await session.execute( select(cls).where(cls.id == uid, cls.is_deleted == False) # noqa: E712 ) return result.scalars().first() @classmethod async def get_by_name(cls, session: AsyncSession, name: str, *, exclude_id=None): cleaned = (name or "").strip() if not cleaned: return None statement = select(cls).where( func.lower(cls.name) == cleaned.lower(), cls.is_deleted == False, # noqa: E712 ) if exclude_id is not None: uid = cls._as_uuid(exclude_id) if uid is not None: statement = statement.where(cls.id != uid) result = await session.execute(statement) return result.scalars().first() @classmethod async def fetch_rows(cls, session: AsyncSession): statement = select(cls).where(cls.is_deleted == False).order_by(cls.name.asc()) # noqa: E712 result = await session.execute(statement) rows = list(result.scalars().all()) return rows, len(rows) @classmethod async def fetch_names(cls, session: AsyncSession) -> list[str]: rows, _ = await cls.fetch_rows(session) return [r.name for r in rows if r.name] @classmethod async def insert_row(cls, session: AsyncSession, fields: dict): row = cls(**fields) session.add(row) await session.commit() return await cls.get_by_id(session, row.id) @classmethod async def update_row(cls, session: AsyncSession, record_id, fields: dict): row = await cls.get_by_id(session, record_id) if not row: return None for key, value in fields.items(): setattr(row, key, value) row.updated_at = _now() session.add(row) await session.commit() await session.refresh(row) return row @classmethod async def soft_delete_row(cls, session: AsyncSession, record_id): row = await cls.get_by_id(session, record_id) if not row: return None row.is_deleted = True row.updated_at = _now() session.add(row) await session.commit() return row class ExcludeCompany(SQLModel, table=True): __tablename__ = "exclude_company" id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) name: str = Field(index=True) linkedin_url: str | None = Field(default=None) created_by: uuid.UUID | None = Field(default=None, foreign_key="users.id") created_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True)) updated_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True)) is_deleted: bool = Field(default=False) @staticmethod def _as_uuid(record_id) -> uuid.UUID | None: if record_id in (None, ""): return None try: return uuid.UUID(str(record_id)) except ValueError: return None @classmethod async def get_by_id(cls, session: AsyncSession, record_id): uid = cls._as_uuid(record_id) if uid is None: return None result = await session.execute( select(cls).where(cls.id == uid, cls.is_deleted == False) # noqa: E712 ) return result.scalars().first() @classmethod async def get_by_name(cls, session: AsyncSession, name: str, *, exclude_id=None): cleaned = (name or "").strip() if not cleaned: return None statement = select(cls).where( func.lower(cls.name) == cleaned.lower(), cls.is_deleted == False, # noqa: E712 ) if exclude_id is not None: uid = cls._as_uuid(exclude_id) if uid is not None: statement = statement.where(cls.id != uid) result = await session.execute(statement) return result.scalars().first() @classmethod async def fetch_rows(cls, session: AsyncSession): statement = select(cls).where(cls.is_deleted == False).order_by(cls.name.asc()) # noqa: E712 result = await session.execute(statement) rows = list(result.scalars().all()) return rows, len(rows) @classmethod async def fetch_names(cls, session: AsyncSession) -> list[str]: rows, _ = await cls.fetch_rows(session) return [r.name for r in rows if r.name] @classmethod async def fetch_linkedin_urls(cls, session: AsyncSession) -> list[str]: rows, _ = await cls.fetch_rows(session) return [r.linkedin_url for r in rows if r.linkedin_url] @classmethod async def insert_row(cls, session: AsyncSession, fields: dict): row = cls(**fields) session.add(row) await session.commit() return await cls.get_by_id(session, row.id) @classmethod async def update_row(cls, session: AsyncSession, record_id, fields: dict): row = await cls.get_by_id(session, record_id) if not row: return None for key, value in fields.items(): setattr(row, key, value) row.updated_at = _now() session.add(row) await session.commit() await session.refresh(row) return row @classmethod async def soft_delete_row(cls, session: AsyncSession, record_id): row = await cls.get_by_id(session, record_id) if not row: return None row.is_deleted = True row.updated_at = _now() session.add(row) await session.commit() return row import users.models as _users_models # noqa: E402, F401