| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | import enum | 
					
						
							| 
									
										
										
										
											2024-01-12 12:34:01 +08:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  | from typing import Optional, cast | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  | from flask_login import UserMixin  # type: ignore | 
					
						
							| 
									
										
										
										
											2024-12-21 23:13:58 +08:00
										 |  |  | from sqlalchemy import func | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  | from sqlalchemy.orm import Mapped, mapped_column, reconstructor | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from models.base import Base | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-20 14:12:29 +08:00
										 |  |  | from .engine import db | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  | from .types import StringUUID | 
					
						
							| 
									
										
										
										
											2024-02-06 13:21:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  | class TenantAccountRole(enum.StrEnum): | 
					
						
							|  |  |  |     OWNER = "owner" | 
					
						
							|  |  |  |     ADMIN = "admin" | 
					
						
							|  |  |  |     EDITOR = "editor" | 
					
						
							|  |  |  |     NORMAL = "normal" | 
					
						
							|  |  |  |     DATASET_OPERATOR = "dataset_operator" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def is_valid_role(role: str) -> bool: | 
					
						
							|  |  |  |         if not role: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         return role in { | 
					
						
							|  |  |  |             TenantAccountRole.OWNER, | 
					
						
							|  |  |  |             TenantAccountRole.ADMIN, | 
					
						
							|  |  |  |             TenantAccountRole.EDITOR, | 
					
						
							|  |  |  |             TenantAccountRole.NORMAL, | 
					
						
							|  |  |  |             TenantAccountRole.DATASET_OPERATOR, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def is_privileged_role(role: Optional["TenantAccountRole"]) -> bool: | 
					
						
							|  |  |  |         if not role: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         return role in {TenantAccountRole.OWNER, TenantAccountRole.ADMIN} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def is_admin_role(role: Optional["TenantAccountRole"]) -> bool: | 
					
						
							|  |  |  |         if not role: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         return role == TenantAccountRole.ADMIN | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def is_non_owner_role(role: Optional["TenantAccountRole"]) -> bool: | 
					
						
							|  |  |  |         if not role: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         return role in { | 
					
						
							|  |  |  |             TenantAccountRole.ADMIN, | 
					
						
							|  |  |  |             TenantAccountRole.EDITOR, | 
					
						
							|  |  |  |             TenantAccountRole.NORMAL, | 
					
						
							|  |  |  |             TenantAccountRole.DATASET_OPERATOR, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def is_editing_role(role: Optional["TenantAccountRole"]) -> bool: | 
					
						
							|  |  |  |         if not role: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         return role in {TenantAccountRole.OWNER, TenantAccountRole.ADMIN, TenantAccountRole.EDITOR} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def is_dataset_edit_role(role: Optional["TenantAccountRole"]) -> bool: | 
					
						
							|  |  |  |         if not role: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         return role in { | 
					
						
							|  |  |  |             TenantAccountRole.OWNER, | 
					
						
							|  |  |  |             TenantAccountRole.ADMIN, | 
					
						
							|  |  |  |             TenantAccountRole.EDITOR, | 
					
						
							|  |  |  |             TenantAccountRole.DATASET_OPERATOR, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-24 13:28:46 +08:00
										 |  |  | class AccountStatus(enum.StrEnum): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     PENDING = "pending" | 
					
						
							|  |  |  |     UNINITIALIZED = "uninitialized" | 
					
						
							|  |  |  |     ACTIVE = "active" | 
					
						
							|  |  |  |     BANNED = "banned" | 
					
						
							|  |  |  |     CLOSED = "closed" | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | class Account(UserMixin, Base): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     __tablename__ = "accounts" | 
					
						
							|  |  |  |     __table_args__ = (db.PrimaryKeyConstraint("id", name="account_pkey"), db.Index("account_email_idx", "email")) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-25 16:24:52 +08:00
										 |  |  |     id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()")) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     name = db.Column(db.String(255), nullable=False) | 
					
						
							|  |  |  |     email = db.Column(db.String(255), nullable=False) | 
					
						
							|  |  |  |     password = db.Column(db.String(255), nullable=True) | 
					
						
							|  |  |  |     password_salt = db.Column(db.String(255), nullable=True) | 
					
						
							|  |  |  |     avatar = db.Column(db.String(255)) | 
					
						
							|  |  |  |     interface_language = db.Column(db.String(255)) | 
					
						
							|  |  |  |     interface_theme = db.Column(db.String(255)) | 
					
						
							|  |  |  |     timezone = db.Column(db.String(255)) | 
					
						
							|  |  |  |     last_login_at = db.Column(db.DateTime) | 
					
						
							|  |  |  |     last_login_ip = db.Column(db.String(255)) | 
					
						
							| 
									
										
										
										
											2024-12-21 23:13:58 +08:00
										 |  |  |     last_active_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     status = db.Column(db.String(16), nullable=False, server_default=db.text("'active'::character varying")) | 
					
						
							|  |  |  |     initialized_at = db.Column(db.DateTime) | 
					
						
							| 
									
										
										
										
											2024-12-21 23:13:58 +08:00
										 |  |  |     created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							|  |  |  |     updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |     @reconstructor | 
					
						
							|  |  |  |     def init_on_load(self): | 
					
						
							|  |  |  |         self.role: Optional[TenantAccountRole] = None | 
					
						
							|  |  |  |         self._current_tenant: Optional[Tenant] = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-14 11:19:26 +08:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def is_password_set(self): | 
					
						
							|  |  |  |         return self.password is not None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def current_tenant(self): | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |         return self._current_tenant | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @current_tenant.setter | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |     def current_tenant(self, tenant: "Tenant"): | 
					
						
							| 
									
										
										
										
											2025-05-10 19:43:56 +08:00
										 |  |  |         ta = db.session.query(TenantAccountJoin).filter_by(tenant_id=tenant.id, account_id=self.id).first() | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         if ta: | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |             self.role = TenantAccountRole(ta.role) | 
					
						
							|  |  |  |             self._current_tenant = tenant | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         self._current_tenant = None | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							| 
									
										
										
										
											2024-11-26 13:43:38 +08:00
										 |  |  |     def current_tenant_id(self) -> str | None: | 
					
						
							|  |  |  |         return self._current_tenant.id if self._current_tenant else None | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  |     def set_tenant_id(self, tenant_id: str): | 
					
						
							|  |  |  |         tenant_account_join = cast( | 
					
						
							|  |  |  |             tuple[Tenant, TenantAccountJoin], | 
					
						
							|  |  |  |             ( | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |                 db.session.query(Tenant, TenantAccountJoin) | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  |                 .filter(Tenant.id == tenant_id) | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |                 .filter(TenantAccountJoin.tenant_id == Tenant.id) | 
					
						
							|  |  |  |                 .filter(TenantAccountJoin.account_id == self.id) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |                 .one_or_none() | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  |             ), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  |         if not tenant_account_join: | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  |         tenant, join = tenant_account_join | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |         self.role = join.role | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         self._current_tenant = tenant | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-09 17:47:54 +08:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def current_role(self): | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |         return self.role | 
					
						
							| 
									
										
										
										
											2024-07-09 17:47:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     def get_status(self) -> AccountStatus: | 
					
						
							|  |  |  |         status_str = self.status | 
					
						
							|  |  |  |         return AccountStatus(status_str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |     def get_by_openid(cls, provider: str, open_id: str): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |         account_integrate = ( | 
					
						
							|  |  |  |             db.session.query(AccountIntegrate) | 
					
						
							|  |  |  |             .filter(AccountIntegrate.provider == provider, AccountIntegrate.open_id == open_id) | 
					
						
							|  |  |  |             .one_or_none() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         if account_integrate: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |             return db.session.query(Account).filter(Account.id == account_integrate.account_id).one_or_none() | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     # check current_user.current_tenant.current_role in ['admin', 'owner'] | 
					
						
							| 
									
										
										
										
											2024-01-26 12:47:42 +08:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def is_admin_or_owner(self): | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |         return TenantAccountRole.is_privileged_role(self.role) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-25 12:11:00 +09:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def is_admin(self): | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |         return TenantAccountRole.is_admin_role(self.role) | 
					
						
							| 
									
										
										
										
											2024-11-25 12:11:00 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-14 07:34:25 -05:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def is_editor(self): | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |         return TenantAccountRole.is_editing_role(self.role) | 
					
						
							| 
									
										
										
										
											2024-04-18 17:33:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-09 17:47:54 +08:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def is_dataset_editor(self): | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |         return TenantAccountRole.is_dataset_edit_role(self.role) | 
					
						
							| 
									
										
										
										
											2024-07-09 17:47:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def is_dataset_operator(self): | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |         return self.role == TenantAccountRole.DATASET_OPERATOR | 
					
						
							| 
									
										
										
										
											2024-07-09 17:47:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-24 13:28:46 +08:00
										 |  |  | class TenantStatus(enum.StrEnum): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     NORMAL = "normal" | 
					
						
							|  |  |  |     ARCHIVE = "archive" | 
					
						
							| 
									
										
										
										
											2024-04-18 17:33:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  | class Tenant(Base): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     __tablename__ = "tenants" | 
					
						
							|  |  |  |     __table_args__ = (db.PrimaryKeyConstraint("id", name="tenant_pkey"),) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     id = db.Column(StringUUID, server_default=db.text("uuid_generate_v4()")) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     name = db.Column(db.String(255), nullable=False) | 
					
						
							|  |  |  |     encrypt_public_key = db.Column(db.Text) | 
					
						
							|  |  |  |     plan = db.Column(db.String(255), nullable=False, server_default=db.text("'basic'::character varying")) | 
					
						
							|  |  |  |     status = db.Column(db.String(255), nullable=False, server_default=db.text("'normal'::character varying")) | 
					
						
							| 
									
										
										
										
											2023-12-18 16:25:37 +08:00
										 |  |  |     custom_config = db.Column(db.Text) | 
					
						
							| 
									
										
										
										
											2024-12-21 23:13:58 +08:00
										 |  |  |     created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							|  |  |  |     updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-28 20:20:23 +08:00
										 |  |  |     def get_accounts(self) -> list[Account]: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |         return ( | 
					
						
							|  |  |  |             db.session.query(Account) | 
					
						
							|  |  |  |             .filter(Account.id == TenantAccountJoin.account_id, TenantAccountJoin.tenant_id == self.id) | 
					
						
							|  |  |  |             .all() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-04-25 18:20:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 16:25:37 +08:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def custom_config_dict(self) -> dict: | 
					
						
							| 
									
										
										
										
											2023-12-19 11:45:16 +08:00
										 |  |  |         return json.loads(self.custom_config) if self.custom_config else {} | 
					
						
							| 
									
										
										
										
											2024-04-25 18:20:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 16:25:37 +08:00
										 |  |  |     @custom_config_dict.setter | 
					
						
							|  |  |  |     def custom_config_dict(self, value: dict): | 
					
						
							|  |  |  |         self.custom_config = json.dumps(value) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  | class TenantAccountJoin(Base): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     __tablename__ = "tenant_account_joins" | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     __table_args__ = ( | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |         db.PrimaryKeyConstraint("id", name="tenant_account_join_pkey"), | 
					
						
							|  |  |  |         db.Index("tenant_account_join_account_id_idx", "account_id"), | 
					
						
							|  |  |  |         db.Index("tenant_account_join_tenant_id_idx", "tenant_id"), | 
					
						
							|  |  |  |         db.UniqueConstraint("tenant_id", "account_id", name="unique_tenant_account_join"), | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     id = db.Column(StringUUID, server_default=db.text("uuid_generate_v4()")) | 
					
						
							| 
									
										
										
										
											2024-04-29 11:58:17 +08:00
										 |  |  |     tenant_id = db.Column(StringUUID, nullable=False) | 
					
						
							|  |  |  |     account_id = db.Column(StringUUID, nullable=False) | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     current = db.Column(db.Boolean, nullable=False, server_default=db.text("false")) | 
					
						
							|  |  |  |     role = db.Column(db.String(16), nullable=False, server_default="normal") | 
					
						
							| 
									
										
										
										
											2024-04-29 11:58:17 +08:00
										 |  |  |     invited_by = db.Column(StringUUID, nullable=True) | 
					
						
							| 
									
										
										
										
											2024-12-21 23:13:58 +08:00
										 |  |  |     created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							|  |  |  |     updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  | class AccountIntegrate(Base): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     __tablename__ = "account_integrates" | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     __table_args__ = ( | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |         db.PrimaryKeyConstraint("id", name="account_integrate_pkey"), | 
					
						
							|  |  |  |         db.UniqueConstraint("account_id", "provider", name="unique_account_provider"), | 
					
						
							|  |  |  |         db.UniqueConstraint("provider", "open_id", name="unique_provider_open_id"), | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     id = db.Column(StringUUID, server_default=db.text("uuid_generate_v4()")) | 
					
						
							| 
									
										
										
										
											2024-04-29 11:58:17 +08:00
										 |  |  |     account_id = db.Column(StringUUID, nullable=False) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     provider = db.Column(db.String(16), nullable=False) | 
					
						
							|  |  |  |     open_id = db.Column(db.String(255), nullable=False) | 
					
						
							|  |  |  |     encrypted_token = db.Column(db.String(255), nullable=False) | 
					
						
							| 
									
										
										
										
											2024-12-21 23:13:58 +08:00
										 |  |  |     created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							|  |  |  |     updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-09 13:52:05 +08:00
										 |  |  | class InvitationCode(Base): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |     __tablename__ = "invitation_codes" | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     __table_args__ = ( | 
					
						
							| 
									
										
										
										
											2024-09-10 17:08:06 +08:00
										 |  |  |         db.PrimaryKeyConstraint("id", name="invitation_code_pkey"), | 
					
						
							|  |  |  |         db.Index("invitation_codes_batch_idx", "batch"), | 
					
						
							|  |  |  |         db.Index("invitation_codes_code_idx", "code", "status"), | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     id = db.Column(db.Integer, nullable=False) | 
					
						
							|  |  |  |     batch = db.Column(db.String(255), nullable=False) | 
					
						
							|  |  |  |     code = db.Column(db.String(32), nullable=False) | 
					
						
							|  |  |  |     status = db.Column(db.String(16), nullable=False, server_default=db.text("'unused'::character varying")) | 
					
						
							|  |  |  |     used_at = db.Column(db.DateTime) | 
					
						
							| 
									
										
										
										
											2024-04-29 11:58:17 +08:00
										 |  |  |     used_by_tenant_id = db.Column(StringUUID) | 
					
						
							|  |  |  |     used_by_account_id = db.Column(StringUUID) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     deprecated_at = db.Column(db.DateTime) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TenantPluginPermission(Base): | 
					
						
							|  |  |  |     class InstallPermission(enum.StrEnum): | 
					
						
							|  |  |  |         EVERYONE = "everyone" | 
					
						
							|  |  |  |         ADMINS = "admins" | 
					
						
							|  |  |  |         NOBODY = "noone" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class DebugPermission(enum.StrEnum): | 
					
						
							|  |  |  |         EVERYONE = "everyone" | 
					
						
							|  |  |  |         ADMINS = "admins" | 
					
						
							|  |  |  |         NOBODY = "noone" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __tablename__ = "account_plugin_permissions" | 
					
						
							|  |  |  |     __table_args__ = ( | 
					
						
							|  |  |  |         db.PrimaryKeyConstraint("id", name="account_plugin_permission_pkey"), | 
					
						
							|  |  |  |         db.UniqueConstraint("tenant_id", name="unique_tenant_plugin"), | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()")) | 
					
						
							|  |  |  |     tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) | 
					
						
							|  |  |  |     install_permission: Mapped[InstallPermission] = mapped_column( | 
					
						
							|  |  |  |         db.String(16), nullable=False, server_default="everyone" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     debug_permission: Mapped[DebugPermission] = mapped_column(db.String(16), nullable=False, server_default="noone") |