""" Site model for client physical locations. Sites represent physical locations for clients including network configuration, VPN settings, and gateway information. """ from typing import Optional from sqlalchemy import Boolean, CHAR, ForeignKey, Index, String, Text from sqlalchemy.orm import Mapped, mapped_column from .base import Base, TimestampMixin, UUIDMixin class Site(Base, UUIDMixin, TimestampMixin): """ Site model representing client physical locations. Tracks physical sites for clients with network configuration including subnets, VPN settings, gateway IPs, and DNS servers. Attributes: client_id: Reference to the client this site belongs to name: Site name (e.g., "Main Office", "SLC - Salt Lake City") network_subnet: Network subnet for the site (e.g., "172.16.9.0/24") vpn_required: Whether VPN is required to access this site vpn_subnet: VPN subnet if applicable (e.g., "192.168.1.0/24") gateway_ip: Gateway IP address (IPv4 or IPv6) dns_servers: JSON array of DNS server addresses notes: Additional notes about the site """ __tablename__ = "sites" # Foreign keys client_id: Mapped[str] = mapped_column( CHAR(36), ForeignKey("clients.id", ondelete="CASCADE"), nullable=False, doc="Reference to the client this site belongs to" ) # Site identification name: Mapped[str] = mapped_column( String(255), nullable=False, doc="Site name (e.g., 'Main Office', 'SLC - Salt Lake City')" ) # Network configuration network_subnet: Mapped[Optional[str]] = mapped_column( String(100), doc="Network subnet for the site (e.g., '172.16.9.0/24')" ) # VPN configuration vpn_required: Mapped[bool] = mapped_column( Boolean, default=False, server_default="0", nullable=False, doc="Whether VPN is required to access this site" ) vpn_subnet: Mapped[Optional[str]] = mapped_column( String(100), doc="VPN subnet if applicable (e.g., '192.168.1.0/24')" ) # Gateway and DNS gateway_ip: Mapped[Optional[str]] = mapped_column( String(45), doc="Gateway IP address (IPv4 or IPv6)" ) dns_servers: Mapped[Optional[str]] = mapped_column( Text, doc="JSON array of DNS server addresses" ) # Notes notes: Mapped[Optional[str]] = mapped_column( Text, doc="Additional notes about the site" ) # Indexes __table_args__ = ( Index("idx_sites_client", "client_id"), ) def __repr__(self) -> str: """String representation of the site.""" return f""