import uuid from datetime import date, datetime from sqlalchemy import ( Boolean, CheckConstraint, Date, DateTime, ForeignKey, Integer, String, Text, func, ) from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): pass class Account(Base): __tablename__ = "users" __table_args__ = ( CheckConstraint( "account_type IN ('individual', 'company')", name="ck_users_account_type", ), ) id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) account_type: Mapped[str] = mapped_column(String(20)) email: Mapped[str] = mapped_column(String(320), unique=True, index=True) first_name: Mapped[str] = mapped_column(String(80)) last_name: Mapped[str] = mapped_column(String(80)) date_of_birth: Mapped[date] = mapped_column(Date) phone_number: Mapped[str] = mapped_column(String(24), unique=True) company_domain: Mapped[str | None] = mapped_column(String(253), nullable=True) org_role: Mapped[str] = mapped_column(String(20), default="user") member_status: Mapped[str] = mapped_column(String(20), default="active") created_by_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True, ) invitation_email: Mapped[str | None] = mapped_column(String(320), nullable=True) must_change_password: Mapped[bool] = mapped_column(Boolean, default=False) section_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("org_sections.id"), nullable=True, ) password_hash: Mapped[str] = mapped_column(String(255)) section: Mapped["OrgSection | None"] = relationship() created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), ) mail_domains: Mapped[list["MailDomain"]] = relationship(back_populates="account") class MailDomain(Base): __tablename__ = "mail_domains" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) domain_name: Mapped[str] = mapped_column(String(253), unique=True, index=True) domain_type: Mapped[str] = mapped_column(String(20)) account_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True, ) mail_host: Mapped[str] = mapped_column(String(253)) dkim_selector: Mapped[str] = mapped_column(String(63)) dkim_private_key: Mapped[str] = mapped_column(Text) dkim_public_key: Mapped[str] = mapped_column(Text) status: Mapped[str] = mapped_column(String(20), default="pending_dns") created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), ) account: Mapped[Account | None] = relationship(back_populates="mail_domains") dns_records: Mapped[list["DomainDnsRecord"]] = relationship( back_populates="domain", cascade="all, delete-orphan", ) smtp_credentials: Mapped[list["SmtpCredential"]] = relationship( back_populates="domain", cascade="all, delete-orphan", ) class DomainDnsRecord(Base): __tablename__ = "domain_dns_records" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) domain_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("mail_domains.id"), index=True, ) record_type: Mapped[str] = mapped_column(String(10)) host: Mapped[str] = mapped_column(String(253)) value: Mapped[str] = mapped_column(Text) purpose: Mapped[str] = mapped_column(String(20)) ttl: Mapped[int] = mapped_column(Integer, default=3600) domain: Mapped[MailDomain] = relationship(back_populates="dns_records") class SmtpCredential(Base): __tablename__ = "smtp_credentials" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) domain_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("mail_domains.id"), index=True, ) username: Mapped[str] = mapped_column(String(120), unique=True, index=True) password_hash: Mapped[str] = mapped_column(String(255)) label: Mapped[str] = mapped_column(String(120)) is_active: Mapped[bool] = mapped_column(Boolean, default=True) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), ) domain: Mapped[MailDomain] = relationship(back_populates="smtp_credentials") class MemberInvitation(Base): __tablename__ = "member_invitations" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) account_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), index=True, ) token_hash: Mapped[str] = mapped_column(String(64), unique=True, index=True) expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True)) used_at: Mapped[datetime | None] = mapped_column( DateTime(timezone=True), nullable=True, ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), ) account: Mapped[Account] = relationship() class OrgSection(Base): __tablename__ = "org_sections" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) company_domain: Mapped[str] = mapped_column(String(253), index=True) name: Mapped[str] = mapped_column(String(120)) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), ) class OrgSecuritySettings(Base): __tablename__ = "org_security_settings" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) company_domain: Mapped[str] = mapped_column(String(253), unique=True, index=True) require_strong_passwords: Mapped[bool] = mapped_column(Boolean, default=True) require_mfa_admins: Mapped[bool] = mapped_column(Boolean, default=True) require_mfa_all_users: Mapped[bool] = mapped_column(Boolean, default=False) session_timeout_minutes: Mapped[int] = mapped_column(Integer, default=60) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), ) class MailGroup(Base): __tablename__ = "mail_groups" __table_args__ = ( CheckConstraint( "group_type IN ('distribution', 'dynamic')", name="ck_mail_groups_group_type", ), ) id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) company_domain: Mapped[str] = mapped_column(String(253), index=True) name: Mapped[str] = mapped_column(String(120)) email: Mapped[str] = mapped_column(String(320), unique=True, index=True) group_type: Mapped[str] = mapped_column(String(20), default="distribution") owner_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True, ) send_permission: Mapped[str] = mapped_column(String(30), default="org_members") description: Mapped[str | None] = mapped_column(Text, nullable=True) created_by_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True, ) owner: Mapped["Account | None"] = relationship(foreign_keys=[owner_id]) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), ) members: Mapped[list["MailGroupMember"]] = relationship( back_populates="group", cascade="all, delete-orphan", ) class MailGroupMember(Base): __tablename__ = "mail_group_members" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) group_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("mail_groups.id"), index=True, ) account_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), index=True, ) group: Mapped[MailGroup] = relationship(back_populates="members") account: Mapped[Account] = relationship() class MailAlias(Base): __tablename__ = "mail_aliases" __table_args__ = ( CheckConstraint( "alias_type IN ('user', 'group')", name="ck_mail_aliases_alias_type", ), CheckConstraint( "status IN ('active', 'disabled')", name="ck_mail_aliases_status", ), ) id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) company_domain: Mapped[str] = mapped_column(String(253), index=True) alias_address: Mapped[str] = mapped_column(String(320), unique=True, index=True) forwards_to: Mapped[str] = mapped_column(String(320)) alias_type: Mapped[str] = mapped_column(String(20), default="user") is_domain_alias: Mapped[bool] = mapped_column(Boolean, default=False) status: Mapped[str] = mapped_column(String(20), default="active") created_by_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True, ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), )