fix: keep mesh/cluster links so edges resolve onto a second canvas

Approving the same zigbee/zwave/proxmox devices onto a second design
placed the nodes but drew no edges. _resolve_pending_links_for_ieee
deleted each pending_device_link after materializing its edge, so the
first approve consumed the whole topology and later approves had nothing
to resolve.

Links are topology, not one-shot: every importer wipes+reinserts its
link set on each import, so they can safely persist across approvals.

- keep the link rows (drop both db.delete(link) calls)
- scope resolution to the target design (Node.ieee_address + design_id)
  so a re-approve links that canvas's nodes, not another's
- thread design_id through all three approve call sites

Existing links deleted by the old code do not come back on their own;
a re-import repopulates them.

ha-relevant: maybe
This commit is contained in:
Pouzor
2026-07-07 10:32:47 +02:00
parent 601f731135
commit 5b5eabf5db
3 changed files with 69 additions and 22 deletions
+4 -2
View File
@@ -1375,7 +1375,9 @@ async def test_approve_zigbee_skips_when_other_endpoint_still_pending(
async def test_approve_zigbee_resolves_link_after_second_approval(
client: AsyncClient, headers, db_session
):
"""First approval keeps link; second approval creates the edge."""
"""First approval keeps link (other endpoint pending); second approval
creates the edge. The link row is retained afterwards so the same pair can
be re-approved onto another canvas — it's topology, wiped only on reimport."""
from sqlalchemy import select
from app.db.models import Edge, PendingDevice, PendingDeviceLink
@@ -1408,7 +1410,7 @@ async def test_approve_zigbee_resolves_link_after_second_approval(
edges = (await db_session.execute(select(Edge))).scalars().all()
assert len(edges) == 1
links = (await db_session.execute(select(PendingDeviceLink))).scalars().all()
assert links == [] # consumed
assert len(links) == 1 # retained for re-approval onto other canvases
# --- Deep scan: trigger overrides + config persistence ---