feat: add network_diagrams table

Create NetworkDiagram SQLAlchemy model with JSONB nodes/edges, team-scoped with client/asset metadata, and Alembic migration 074.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-04-04 07:41:13 +00:00
parent 9c042c750e
commit 068baec179
3 changed files with 96 additions and 0 deletions

View File

@@ -55,6 +55,7 @@ from .fork_point import ForkPoint
from .session_handoff import SessionHandoff
from .session_resolution_output import SessionResolutionOutput
from .device_type import DeviceType
from .network_diagram import NetworkDiagram
__all__ = [
"User",
@@ -124,4 +125,5 @@ __all__ = [
"SessionHandoff",
"SessionResolutionOutput",
"DeviceType",
"NetworkDiagram",
]

View File

@@ -0,0 +1,53 @@
"""Network diagram model."""
import uuid
from datetime import datetime, timezone
from typing import Optional, TYPE_CHECKING
from sqlalchemy import String, Text, Boolean, DateTime, ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.dialects.postgresql import UUID, JSONB
from app.core.database import Base
if TYPE_CHECKING:
from app.models.user import User
class NetworkDiagram(Base):
"""A network topology diagram, team-scoped."""
__tablename__ = "network_diagrams"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
)
team_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("teams.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
name: Mapped[str] = mapped_column(String(255), nullable=False)
client_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
asset_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
nodes: Mapped[list] = mapped_column(JSONB, nullable=False, server_default="'[]'")
edges: Mapped[list] = mapped_column(JSONB, nullable=False, server_default="'[]'")
thumbnail_url: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
is_archived: Mapped[bool] = mapped_column(
Boolean, nullable=False, default=False,
)
created_by: Mapped[Optional[uuid.UUID]] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id"),
nullable=True,
)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
onupdate=lambda: datetime.now(timezone.utc),
)
creator: Mapped[Optional["User"]] = relationship("User", foreign_keys=[created_by])