Files
Wiring-Designer/backend/app/schemas.py
T
Kyle f32203b630 Initial commit — wiring diagram maker with full feature set
- FastAPI + SQLite backend with routers for diagrams, devices, wires,
  bundles, connectors, export, and Octopart/Nexar search
- Konva.js canvas: ortho/direct/curved routing, wire crossings, harness
  mode, snap-to-grid, multi-select, drag, resize, undo
- Wire features: color/stripe, twisted pair helix, shielded glow,
  gauge size label, multi-core bundle grouping, length/unit tracking
- Device library: connector, terminal block, cable, splice, label, group,
  relay, fuse, switch, component with custom connector support
- Exports: BOM CSV, assembly TXT, JSON, formboard layout, PNG image
- Auto-migration for schema changes via ALTER TABLE at startup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 12:51:21 -04:00

181 lines
4.5 KiB
Python

from pydantic import BaseModel, field_validator
from typing import Optional, List, Any, Dict
from datetime import datetime
class DeviceBase(BaseModel):
device_type: str
label: str = ""
reference: str = ""
x: float = 100
y: float = 100
width: float = 120
height: float = 60
properties: Dict[str, Any] = {}
pins: List[Dict[str, Any]] = []
class DeviceCreate(DeviceBase):
diagram_id: int
class DeviceUpdate(BaseModel):
label: Optional[str] = None
reference: Optional[str] = None
x: Optional[float] = None
y: Optional[float] = None
width: Optional[float] = None
height: Optional[float] = None
properties: Optional[Dict[str, Any]] = None
pins: Optional[List[Dict[str, Any]]] = None
class Device(DeviceBase):
id: int
diagram_id: int
model_config = {"from_attributes": True}
class WireBase(BaseModel):
label: str = ""
from_device_id: Optional[int] = None
from_pin: str = ""
to_device_id: Optional[int] = None
to_pin: str = ""
color_primary: str = "#FF0000"
color_stripe: Optional[str] = None
gauge: str = "18 AWG"
length: Optional[float] = None
length_unit: str = "in"
notes: str = ""
waypoints: List[Dict[str, Any]] = []
twisted_pair: bool = False
twist_pitch: float = 16.0
shielded: bool = False
bundle_id: Optional[int] = None
show_size_label: bool = False
@field_validator("waypoints", mode="before")
@classmethod
def _coerce_waypoints(cls, v):
return v if v is not None else []
class WireCreate(WireBase):
diagram_id: int
class WireUpdate(BaseModel):
label: Optional[str] = None
from_device_id: Optional[int] = None
from_pin: Optional[str] = None
to_device_id: Optional[int] = None
to_pin: Optional[str] = None
color_primary: Optional[str] = None
color_stripe: Optional[str] = None
gauge: Optional[str] = None
length: Optional[float] = None
length_unit: Optional[str] = None
notes: Optional[str] = None
waypoints: Optional[List[Dict[str, Any]]] = None
twisted_pair: Optional[bool] = None
twist_pitch: Optional[float] = None
shielded: Optional[bool] = None
bundle_id: Optional[int] = None
show_size_label: Optional[bool] = None
class Wire(WireBase):
id: int
diagram_id: int
model_config = {"from_attributes": True}
# ── WireBundle ────────────────────────────────────────────────────────────────
class WireBundleBase(BaseModel):
label: str = ""
jacket_color: str = "#2a2a2a"
class WireBundleCreate(WireBundleBase):
diagram_id: int
class WireBundleUpdate(BaseModel):
label: Optional[str] = None
jacket_color: Optional[str] = None
class WireBundleOut(WireBundleBase):
id: int
diagram_id: int
model_config = {"from_attributes": True}
# ── Diagram ───────────────────────────────────────────────────────────────────
class DiagramBase(BaseModel):
name: str = "Untitled Diagram"
description: str = ""
class DiagramCreate(DiagramBase):
pass
class DiagramUpdate(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
class DiagramSummary(DiagramBase):
id: int
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
class DiagramFull(DiagramSummary):
devices: List[Device] = []
wires: List[Wire] = []
wire_bundles: List[WireBundleOut] = []
# ── CustomConnector ───────────────────────────────────────────────────────────
class CustomConnectorBase(BaseModel):
name: str
manufacturer: str = ""
part_number: str = ""
category: str = "Custom"
description: str = ""
pin_count: int
pin_labels: List[str] = []
class CustomConnectorCreate(CustomConnectorBase):
pass
class CustomConnectorUpdate(BaseModel):
name: Optional[str] = None
manufacturer: Optional[str] = None
part_number: Optional[str] = None
category: Optional[str] = None
description: Optional[str] = None
pin_count: Optional[int] = None
pin_labels: Optional[List[str]] = None
class CustomConnector(CustomConnectorBase):
id: int
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}