2.3 KiB
ADR 0001: Universal node tree
Status: accepted
Date: 2026-08-25
Context
The physical world does not provide a clean structural boundary between a location, a container, and an item. A room contains a shelf, a box contains a pen, and a toolbox can both be owned and contain tools. Encoding those words as exclusive system types would impose rules that the hierarchy itself does not need.
The project has no users or persisted data requiring compatibility.
Decision
Represent the hierarchy as one rooted tree of universal nodes. Every node can have children. The system assigns no structural type or role to a node.
The initial persistent model is deliberately small:
Node
- id
- lookup_code
- parent_id
- name
- quantity?
idis stable and opaque.lookup_codeis a stable human-enterable key for labels and search; it is not the internal identity.parent_idpoints to exactly one parent, except for the root.nameis required and non-empty.quantityis an optional non-negative integer. Missing and zero are distinct.- Sibling names may be duplicated; identity and paths never depend on names.
The server creates two protected nodes:
Rootis the sole node without a parent.Unsortedis a direct child of Root and acts as the inbox for nodes whose placement has not been decided.
Root and Unsorted cannot be deleted or moved. Their displayed names are fixed for now.
Moving a node requires one child-handling mode:
WITH_SUBTREE: move the node with all descendants. This is the default.PROMOTE_CHILDREN: move the node, reparenting its direct children to the node's former parent.CHILDREN_TO_UNSORTED: move the node, reparenting its direct children to Unsorted.
All changes made by one move are atomic. A move that would create a cycle is rejected. A node may be deleted only when it is empty; recursive deletion is not supported.
Consequences
- All clients can render the complete core model as a simple tree.
- The UI may use familiar words such as room, shelf, or box without making them database types.
- A node can be both something the user owns and something that contains other nodes.
- Stable IDs remain necessary because names can change and repeat.
- Additional metadata can be introduced without changing the tree abstraction.