Add upsert behaviour to attach_child (revive soft-deleted relations)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
giles
2026-02-14 17:30:55 +00:00
parent f57c765cac
commit 0a1c58d6c4

View File

@@ -18,7 +18,44 @@ async def attach_child(
) -> ContainerRelation:
"""
Create a ContainerRelation and emit container.child_attached event.
Upsert behaviour: if a relation already exists (including soft-deleted),
revive it instead of inserting a duplicate.
"""
# Check for existing (including soft-deleted)
existing = await session.scalar(
select(ContainerRelation).where(
ContainerRelation.parent_type == parent_type,
ContainerRelation.parent_id == parent_id,
ContainerRelation.child_type == child_type,
ContainerRelation.child_id == child_id,
)
)
if existing:
if existing.deleted_at is not None:
# Revive soft-deleted relation
existing.deleted_at = None
if sort_order is not None:
existing.sort_order = sort_order
if label is not None:
existing.label = label
await session.flush()
await emit_event(
session,
event_type="container.child_attached",
aggregate_type="container_relation",
aggregate_id=existing.id,
payload={
"parent_type": parent_type,
"parent_id": parent_id,
"child_type": child_type,
"child_id": child_id,
},
)
return existing
# Already attached and active — no-op
return existing
if sort_order is None:
max_order = await session.scalar(
select(func.max(ContainerRelation.sort_order)).where(