import uuid from datetime import datetime from sqlalchemy import Boolean, DateTime, Float, ForeignKey, Integer, String, Text, UniqueConstraint from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from api.models.base import Base, TimestampMixin, new_uuid class FabricGraphImport(Base, TimestampMixin): __tablename__ = "fabric_graph_imports" __table_args__ = ( UniqueConstraint( "source_repo_slug", "content_hash", name="uq_fabric_graph_imports_source_hash", ), ) id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=new_uuid ) source_repo_slug: Mapped[str] = mapped_column(String(100), nullable=False, index=True) source_url: Mapped[str | None] = mapped_column(Text, nullable=True) source_commit: Mapped[str | None] = mapped_column(String(80), nullable=True, index=True) source_path: Mapped[str | None] = mapped_column(Text, nullable=True) api_version: Mapped[str | None] = mapped_column(String(100), nullable=True) schema_version: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True) export_kind: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True) exported_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True) netkingdom_id: Mapped[str | None] = mapped_column(Text, nullable=True) king_actor_id: Mapped[str | None] = mapped_column(Text, nullable=True) actor_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0") fabric_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0") unresolved_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0") compatibility: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}") content_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True) node_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0") edge_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0") validation_status: Mapped[str] = mapped_column(String(20), nullable=False, default="valid", server_default="valid", index=True) error_details: Mapped[dict | None] = mapped_column(JSONB, nullable=True) graph_json: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}") is_latest: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false", index=True) last_seen_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) nodes: Mapped[list["FabricGraphNode"]] = relationship( "FabricGraphNode", back_populates="import_run", cascade="all, delete-orphan", lazy="select" ) edges: Mapped[list["FabricGraphEdge"]] = relationship( "FabricGraphEdge", back_populates="import_run", cascade="all, delete-orphan", lazy="select" ) class FabricGraphNode(Base): __tablename__ = "fabric_graph_nodes" __table_args__ = ( UniqueConstraint("import_id", "graph_id", name="uq_fabric_graph_nodes_import_graph_id"), ) id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=new_uuid ) import_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("fabric_graph_imports.id", ondelete="CASCADE"), nullable=False, index=True, ) source_repo_slug: Mapped[str] = mapped_column(String(100), nullable=False, index=True) graph_id: Mapped[str] = mapped_column(Text, nullable=False) kind: Mapped[str] = mapped_column(String(100), nullable=False, index=True) name: Mapped[str] = mapped_column(Text, nullable=False) repo_slug: Mapped[str] = mapped_column(String(100), nullable=False, index=True) domain_slug: Mapped[str] = mapped_column(String(100), nullable=False, index=True) lifecycle: Mapped[str] = mapped_column(String(50), nullable=False, index=True) canonical_type: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True) canon_category: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True) canon_anchor: Mapped[str | None] = mapped_column(Text, nullable=True) mapping_fit: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True) evidence_state: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True) evidence_review_state: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True) evidence_confidence: Mapped[float | None] = mapped_column(Float, nullable=True) netkingdom_id: Mapped[str | None] = mapped_column(Text, nullable=True) fabric_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) subfabric_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) environment: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True) deployment_scenario_id: Mapped[str | None] = mapped_column(Text, nullable=True) owner_actor_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) owner_role: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True) ownership_resolution: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True) cost_center_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) profit_center_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) display_only: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false", index=True) attributes: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}") raw_json: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}") import_run: Mapped["FabricGraphImport"] = relationship("FabricGraphImport", back_populates="nodes") class FabricGraphEdge(Base): __tablename__ = "fabric_graph_edges" __table_args__ = ( UniqueConstraint("import_id", "edge_key", name="uq_fabric_graph_edges_import_edge_key"), ) id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=new_uuid ) import_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("fabric_graph_imports.id", ondelete="CASCADE"), nullable=False, index=True, ) source_repo_slug: Mapped[str] = mapped_column(String(100), nullable=False, index=True) edge_key: Mapped[str] = mapped_column(String(64), nullable=False, index=True) from_graph_id: Mapped[str] = mapped_column(Text, nullable=False) to_graph_id: Mapped[str] = mapped_column(Text, nullable=False) edge_type: Mapped[str] = mapped_column(String(100), nullable=False, index=True) canonical_type: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True) canon_anchor: Mapped[str | None] = mapped_column(Text, nullable=True) mapping_fit: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True) evidence_state: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True) evidence_review_state: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True) evidence_confidence: Mapped[float | None] = mapped_column(Float, nullable=True) relationship_category: Mapped[str | None] = mapped_column(String(30), nullable=True, index=True) provider_owner_actor_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) provider_fabric_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) provider_subfabric_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) consumer_owner_actor_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) consumer_fabric_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) consumer_subfabric_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) crosses_fabric_boundary: Mapped[bool | None] = mapped_column(Boolean, nullable=True, index=True) crosses_subfabric_boundary: Mapped[bool | None] = mapped_column(Boolean, nullable=True, index=True) utility_type: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True) utility_contract_id: Mapped[str | None] = mapped_column(Text, nullable=True) utility_payment_schema_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) utility_metering_basis: Mapped[str | None] = mapped_column(String(100), nullable=True) utility_business_model: Mapped[str | None] = mapped_column(String(100), nullable=True, index=True) cost_center_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) profit_center_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) provider_profit_center_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) consumer_cost_center_id: Mapped[str | None] = mapped_column(Text, nullable=True, index=True) display_only: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false", index=True) attributes: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}") raw_json: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}") import_run: Mapped["FabricGraphImport"] = relationship("FabricGraphImport", back_populates="edges")