Feat(Fix): Multi-Tenant Zerotier Org Setups

Imports Network From Zerotier
Async Emails
Migration guardrails
Admin to see all approvals states
This commit is contained in:
2026-03-29 23:14:20 +05:45
parent 05eb092228
commit 2b6f7e15af
21 changed files with 974 additions and 239 deletions
@@ -17,6 +17,10 @@ class Organization(BaseModel):
# Settings (stored as JSON)
settings = db.Column(db.JSON, nullable=True, default=dict)
zt_api_token = db.Column(db.String(512), nullable=True)
zt_api_url = db.Column(db.String(512), nullable=True)
zt_api_mode = db.Column(db.String(32), nullable=True) # "central" | "controller"
# Relationships
members = db.relationship(
"OrganizationMember", back_populates="organization", cascade="all, delete-orphan"
@@ -54,7 +54,7 @@ class ActivationSession(BaseModel):
)
ended_at = db.Column(db.DateTime, nullable=True)
end_reason = db.Column(
db.Enum(ActivationEndReason, name="activation_end_reason"),
db.Enum(ActivationEndReason, name="activation_end_reason", values_callable=lambda x: [e.value for e in x]),
nullable=True,
)
created_by = db.Column(
+1 -1
View File
@@ -47,7 +47,7 @@ class Device(BaseModel):
asset_tag = db.Column(db.String(255), nullable=True)
serial_number = db.Column(db.String(255), nullable=True)
status = db.Column(
db.Enum(DeviceStatus, name="device_status"),
db.Enum(DeviceStatus, name="device_status", values_callable=lambda x: [e.value for e in x]),
default=DeviceStatus.ACTIVE,
nullable=False,
)
@@ -58,7 +58,7 @@ class DeviceNetworkMembership(BaseModel):
index=True,
)
state = db.Column(
db.Enum(MembershipState, name="membership_state"),
db.Enum(MembershipState, name="membership_state", values_callable=lambda x: [e.value for e in x]),
default=MembershipState.PENDING_DEVICE_REGISTRATION,
nullable=False,
index=True,
@@ -35,7 +35,7 @@ class KillSwitchEvent(BaseModel):
index=True,
)
scope = db.Column(
db.Enum(KillSwitchScope, name="kill_switch_scope"),
db.Enum(KillSwitchScope, name="kill_switch_scope", values_callable=lambda x: [e.value for e in x]),
default=KillSwitchScope.ORGANIZATION,
nullable=False,
)
@@ -45,12 +45,12 @@ class PortalNetwork(BaseModel):
index=True,
)
environment = db.Column(
db.Enum(NetworkEnvironment, name="network_environment"),
db.Enum(NetworkEnvironment, name="network_environment", values_callable=lambda x: [e.value for e in x]),
default=NetworkEnvironment.DEVELOPMENT,
nullable=False,
)
request_mode = db.Column(
db.Enum(NetworkRequestMode, name="network_request_mode"),
db.Enum(NetworkRequestMode, name="network_request_mode", values_callable=lambda x: [e.value for e in x]),
default=NetworkRequestMode.APPROVAL_REQUIRED,
nullable=False,
)
@@ -48,12 +48,12 @@ class UserNetworkApproval(BaseModel):
nullable=True,
)
grant_type = db.Column(
db.Enum(ApprovalGrantType, name="approval_grant_type"),
db.Enum(ApprovalGrantType, name="approval_grant_type", values_callable=lambda x: [e.value for e in x]),
default=ApprovalGrantType.REQUESTED,
nullable=False,
)
state = db.Column(
db.Enum(ApprovalState, name="approval_state"),
db.Enum(ApprovalState, name="approval_state", values_callable=lambda x: [e.value for e in x]),
default=ApprovalState.PENDING,
nullable=False,
index=True,