Import-API hardening: network device IP endpoint + communicationtypes seeder

The legacy-import surface (docs/IMPORT-API.md) is the schema-agnostic contract
every adopting site targets; these close two gaps found while mapping the WJ
classic import.

Network device IP: POST/PUT /api/network now accept an `ipaddress` and
materialize a primary Communication (mirroring the printer route), and GET
(list + detail + create/update result) surface it. Previously a network
device's IP - which lives in the communications table, not on the extension -
had no HTTP import path at all.

communicationtypes seed: `flask seed reference-data` now seeds the eight
canonical communication types (IP/Serial/Network_Interface/USB/Parallel/VNC/
FTP/DNC), which IMPORT-API.md already documents as a prerequisite. The IP type
must exist before any asset import so printer/network routes can attach an IP.
There is no CRUD endpoint for these, so seeding is the only path.

Tests: network create/update IP upsert + GET surfacing + seed creates IP type.
204 targeted tests pass; naming + pyflakes green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-13 11:11:01 -04:00
parent 1c6c7ba14b
commit be1ea29403
3 changed files with 128 additions and 2 deletions

View File

@@ -127,7 +127,8 @@ def seed_cli():
def seed_reference_data():
"""Seed reference data (model types, statuses, etc.)."""
from shopdb.extensions import db
from shopdb.core.models import ModelType, OperatingSystem, AssetStatus, LocationType
from shopdb.core.models import (ModelType, OperatingSystem, AssetStatus,
LocationType, CommunicationType)
from shopdb.core.models.relationship import RelationshipType
# Model types (type the vendor models catalog)
@@ -178,6 +179,23 @@ def seed_reference_data():
if not LocationType.query.filter_by(locationtype=lt).first():
db.session.add(LocationType(locationtype=lt, isactive=True))
# Communication types (how an asset is reached / its interfaces). The IP
# type is what the printer + network create routes attach an ipaddress to,
# so it must exist before any asset import.
comm_types = [
('IP', 'IP address / network reachable'),
('Serial', 'Serial (RS-232) connection'),
('Network_Interface', 'Physical network interface (MAC/port)'),
('USB', 'USB connection'),
('Parallel', 'Parallel port connection'),
('VNC', 'VNC remote access'),
('FTP', 'FTP file transfer'),
('DNC', 'Direct numerical control link'),
]
for comtype, description in comm_types:
if not CommunicationType.query.filter_by(comtype=comtype).first():
db.session.add(CommunicationType(comtype=comtype, description=description))
# Operating systems
os_list = [
{'osname': 'Windows 10', 'osversion': '10.0'},