| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- """
- Organization model - represents a client company.
- """
- from sqlalchemy import Boolean, String
- from sqlalchemy.orm import Mapped, mapped_column, relationship
- from app.core.encryption import decrypt_password, encrypt_password
- from app.models.base import Base
- class Organization(Base):
- """
- Organization (client company) model.
- Each organization can have multiple users and devices.
- Products (WiFi, BLE) are enabled/disabled per organization.
- """
- __tablename__ = "organizations"
- id: Mapped[int] = mapped_column(primary_key=True)
- name: Mapped[str] = mapped_column(String(255), nullable=False)
- contact_name: Mapped[str | None] = mapped_column(String(255))
- contact_email: Mapped[str] = mapped_column(String(255), nullable=False)
- contact_phone: Mapped[str | None] = mapped_column(String(50))
- # Product access (modular)
- wifi_enabled: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
- ble_enabled: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
- android_enabled: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
- # WiFi credentials (encrypted)
- wifi_ssid: Mapped[str | None] = mapped_column(String(100))
- _wifi_password_encrypted: Mapped[str | None] = mapped_column(
- "wifi_password_encrypted", String(500)
- )
- # Status: pending, active, suspended, deleted
- status: Mapped[str] = mapped_column(
- String(20), default="pending", nullable=False
- )
- # Admin notes
- notes: Mapped[str | None] = mapped_column(String)
- # Relationships
- users: Mapped[list["User"]] = relationship(
- "User", back_populates="organization", cascade="all, delete-orphan"
- )
- devices: Mapped[list["Device"]] = relationship(
- "Device", back_populates="organization"
- )
- @property
- def wifi_password(self) -> str | None:
- """Decrypt WiFi password for viewing by admin."""
- if not self._wifi_password_encrypted:
- return None
- return decrypt_password(self._wifi_password_encrypted)
- @wifi_password.setter
- def wifi_password(self, plain_password: str | None) -> None:
- """Encrypt WiFi password before storing."""
- if plain_password is None:
- self._wifi_password_encrypted = None
- else:
- self._wifi_password_encrypted = encrypt_password(plain_password)
- def __repr__(self) -> str:
- return f"<Organization {self.id}: {self.name}>"
|