from __future__ import annotations from datetime import datetime from typing import TYPE_CHECKING, Optional from sqlalchemy import FetchedValue, ForeignKey, Index, String, text from sqlalchemy.orm import Mapped, mapped_column, relationship from src.core.models.base import Base from src.core.models.utils import BooleanBit, IntEnum from src.enums import MusicService, ServiceType if TYPE_CHECKING: from src.core.models import ApplicationInstance from src.playlist_sync.models import PlaylistSynchronization __all__ = ["ServiceAccount", "SpotifyApiKey"] class ServiceAccount(Base): __tablename__ = "tblServiceAccount" id: Mapped[int] = mapped_column("Id", primary_key=True) service_type: Mapped[Optional[ServiceType]] = mapped_column("ServiceType", IntEnum(ServiceType)) music_service: Mapped[Optional[MusicService]] = mapped_column("MusicServiceId", IntEnum(MusicService)) display_name: Mapped[Optional[str]] = mapped_column("DisplayName", String(255)) user_identifier: Mapped[Optional[str]] = mapped_column("UserIdentifier", String(255)) access_token: Mapped[Optional[str]] = mapped_column("AccessToken", String(1024)) refresh_token: Mapped[Optional[str]] = mapped_column("RefreshToken", String(1024)) expires_in: Mapped[Optional[int]] = mapped_column("AccessTokenExpiry") updated_at: Mapped[datetime] = mapped_column( "UpdatedDate", server_default=text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"), server_onupdate=FetchedValue(), ) application_id: Mapped[Optional[int]] = mapped_column( "ApplicationId", ForeignKey("tblApplicationInstance.intApplicationInstanceID") ) channel_name: Mapped[Optional[str]] = mapped_column("ChannelName", String(255)) spotify_api_key_id: Mapped[Optional[int]] = mapped_column("SpotifyClientIdKey", ForeignKey("tblSpotifyApiKeys.Id")) redirect_uri: Mapped[Optional[str]] = mapped_column("RedirectUri", String(1024)) playlist_synchronizations: Mapped[list["PlaylistSynchronization"]] = relationship( back_populates="service_account", lazy="raise" ) application: Mapped["ApplicationInstance"] = relationship(back_populates="service_accounts", lazy="raise") spotify_api_key: Mapped["SpotifyApiKey"] = relationship( back_populates="service_accounts", lazy="raise", foreign_keys="[ServiceAccount.spotify_api_key_id]" ) class SpotifyApiKey(Base): __tablename__ = "tblSpotifyApiKeys" id: Mapped[int] = mapped_column("Id", primary_key=True) client_id: Mapped[str] = mapped_column("ClientId", String(255)) client_secret: Mapped[str] = mapped_column("SecretId", String(255)) is_main: Mapped[bool] = mapped_column("IsMain", BooleanBit) created_at: Mapped[datetime] = mapped_column("CreateDate") service_accounts: Mapped[list["ServiceAccount"]] = relationship(back_populates="spotify_api_key", lazy="raise") __table_args__ = (Index("UQ_Client_Secret", "ClientId", "SecretId", unique=True),)