Parent-Child Assets: When A Docking Station Belongs To The Laptop
The relationship model, the three relation types and the cycle-guard — for the day a docking station shipped with the laptop and you don’t want to lose track.
A docking station shipped with the laptop. Two SFP transceivers came with the switch. Eight RAM modules came out of one server. None of those things are independent assets — they belong to a parent, and treating them as standalone rows loses the relationship the moment somebody picks up the parent without remembering the children.
The relation
Every asset can point to a parent asset. The relation is asset-to-asset (not asset-to-product or asset-to-pallet) and it carries a type: harvested from for a component pulled out of a device, mounted in for a part that sits inside one, and bundled with for an accessory that travels alongside. A laptop with a dock has the laptop as the parent and the dock as a child, bundled with. A switch with two SFPs has the switch as the parent and each SFP as a child, mounted in. Parent and relation type are set together or not at all — the database refuses a parent without a type and a type without a parent.
The cycle-guard
The platform refuses to create a parent-child relation that would form a loop. When you choose a parent, the picker already leaves out the asset itself and everything below it; the server then does the authoritative check by walking up the proposed parent’s chain and rejecting the choice if the child appears anywhere in it (A→B, B→C, C→A is rejected). If an existing chain is already corrupt, the platform refuses to build on it rather than pretending it is fine. There is no depth limit — a chain is either a tree or it is not.
What the detail page shows
From a child you see its parent’s asset tag and can jump to it. From a parent you see its children and their statuses. Every change to a relation writes an Activity row with the previous and the new parent, so “when did this SSD stop belonging to that server” has an answer with a timestamp.
Why model it explicitly
Because the alternative is encoding the relation in a notes field, and the notes field doesn’t survive a sort, a filter, or an export. Modeling the relation explicitly means it survives — and the dock travels with the laptop as a tracked asset of its own instead of hiding inside a description. A tree is a data structure. A note is a hope.