-
Notifications
You must be signed in to change notification settings - Fork 12
Open
Milestone
Description
Parent Epic
Part of #71 (Network Interface Visualization and Connectivity)
Supersedes: #261 / PR #355 (cable data model) - refactors to graph-based architecture
Summary
Refactor the cable/connection model from PR #355 to use a proper graph-based architecture with first-class ports. This enables power path traversal, capacity planning, failure impact analysis, and multi-rack support.
Problem
The current Cable model (PR #355) uses an edge-list approach with string-based interface references:
// Current: fragile string references
interface Cable {
a_device_id: string;
a_interface: string; // String name - breaks if renamed
b_device_id: string;
b_interface: string;
}Issues with current approach:
- No stable port identity (renaming interface breaks connections)
- Port metadata has nowhere to live (link state, power draw)
- Traversal requires O(n) string matching at every hop
- Termination union type violates Open/Closed Principle
- PDU circuit model is a special-case hack, not generalizable
- Infrastructure nodes are second-class citizens vs devices
Child Issues
Data Model (v0.7.0)
| Issue | Title | Size | Priority |
|---|---|---|---|
| #363 | PlacedPort schema and port instantiation | M | high |
| #364 | Rack.id and Layout.racks array | S | medium |
| #365 | Connection model refactor (port-ID based) | M | high |
| #369 | Connection store with validation | M | high |
| #370 | Port lookup indexes | S | medium |
Extended Model (v0.8.0)
| Issue | Title | Size | Priority |
|---|---|---|---|
| #366 | InfrastructureNode with ports | M | medium |
| #367 | InternalConnection generalization | M | medium |
| #368 | Power interface types and InterfaceRole | S | low |
| #371 | Migration from Cable to Connection | S | low |
Port Rendering (v0.7.0)
| Issue | Title | Size |
|---|---|---|
| #356 | Port layout algorithm with multi-row support | M |
| #357 | Port render modes (individual and grouped) | M |
| #358 | Zoom-aware port rendering thresholds | S |
| #359 | Touch-accessible port overlays | M |
| #360 | 10-inch rack port layout optimizations | S |
Dependency Graph
Data Model Layer:
#363 PlacedPort ──────┬──► #365 Connection ──► #369 Store ──► #371 Migration
#364 Rack.id │
#368 Power types ─────┤
├──► #366 InfrastructureNode
└──► #367 InternalConnection
#370 Port indexes ◄───┘
Port Rendering Layer:
#356 Port layout ──► #357 Render modes ──► #358 Zoom
#359 Touch overlays └──► #360 10"
Cable UI (under #71, depends on this epic):
#262, #263, #264, #265, #266
Proposed Solution
1. First-Class Ports with Stable Identity
When placing a device, instantiate ports with UUIDs:
interface PlacedPort {
id: string; // UUID - stable identity
template_name: string; // Reference to InterfaceTemplate.name
label?: string; // User override
}
interface PlacedDevice {
// ...existing fields...
ports: PlacedPort[]; // Instantiated from DeviceType.interfaces
}2. Unified Connection Model
Connections reference port IDs, not device+interface strings:
interface Connection {
id: string;
connection_class: ConnectionClass;
a_port_id: string; // PlacedPort.id - works for devices AND infra
b_port_id: string;
cable?: CableProperties;
status?: ConnectionStatus;
role?: ConnectionRole;
redundancy_group?: string;
}3. Infrastructure Nodes with Same Port Model
interface InfrastructureNode {
id: string;
node_type: InfraNodeType;
name: string;
scope: InfraScope;
ports: PlacedPort[]; // Same structure as device ports!
}4. Generalized Internal Connections
interface InternalConnection {
from_interface: string;
to_interfaces: string[];
connection_type: 'power-distribution' | 'passthrough' | 'fabric' | 'stacking';
circuit_name?: string;
breaker_amps?: number;
}Acceptance Criteria
Schema Changes
- PlacedPort interface with id, template_name, label
- PlacedDevice.ports: PlacedPort[] field
- Connection uses a_port_id/b_port_id (UUIDs)
- InfrastructureNode with ports: PlacedPort[]
- InternalConnection on DeviceType
- InterfaceTemplate.role and electrical fields
- Power interface types in InterfaceType enum
- Rack.id field for multi-rack support
- Layout.racks is array
- Connection.role and redundancy_group fields
Store/Logic Changes
- Port instantiation when placing device
- Connection validation uses port IDs
- Port lookup indexes (O(1) queries)
- Validation: port can only have one connection
- Validation: incompatible port types
- Zod schemas for all new types
Migration
- Existing Cable data migrates to Connection format
Architecture Decision Record
This refactor was driven by analysis of graph-based infrastructure modeling:
- Everything with ports should be uniform - devices and infrastructure both have ports
- Ports need stable identity - UUIDs, not string names
- Connections are edges between ports - simple a_port_id → b_port_id
- Internal topology is generalizable - not just PDUs, also patch panels, chassis
- Multi-rack ready - rack IDs and infrastructure scoping for future expansion