Story: Fix the has_parent_id feature namespace so profile bindings take effect
Table of Contents
This page documents a story in Sprint 25. It captures the goal, current status, acceptance criteria, and the tasks that compose it.
1. Goal
A model must state only what it decides for itself. The binding
program exists so the bound profile supplies the rest. has_parent_id
was the one feature where that did not hold. The profile merge filed
the feature under the entity's sql namespace. Every reader looked at
the entity root instead. So a profile's assignment never arrived, and
each model that needed the feature repeated the line by hand.
The silence hid a second fault. Fifteen entities bound the
self-referencing-hierarchy profile, whose contract requires a
parent_id_column and a hierarchy_name_field. Only four carried
both. The defect alone protected the other eleven. Had the profile
assignment ever reached the reader, those eleven would have generated
a hierarchy function naming empty columns.
This story moves the feature to the root namespace and repairs what the defect masked. A profile becomes the single source of truth for the hierarchy block, and no model can bind that profile without meeting its contract.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent sprint | Sprint 25 |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-09-17 |
3. Acceptance
_FEATURE_NAMESPACErouteshas_parent_idto the entity root, so a profile assignment reaches the readers.- The four hierarchy models (
business_unit,counterparty,party,folder) drop their explicithas_parent_idline and still generate their hierarchy function, repository method, service and handler. - Every model that turns the feature on names both
parent_id_columnandhierarchy_name_field. - No model binds
self-referencing-hierarchywithout those two column properties. - The eleven flat entities that bound it move to a profile that describes them, and generate no hierarchy code.
- Regeneration over the nine known-drift-free components produces no diff.
4. Tasks
| Task | State | Start | End | Description |
|---|---|---|---|---|
| Route has_parent_id to the entity root and rebind the entities the defect masked | DONE | 2026-09-17 | 2026-09-17 | Move has_parent_id out of the sql namespace so a profile assignment reaches the readers, remove the four explicit workaround lines, and rebind the eleven flat entities that bound the hierarchy profile while the defect hid their missing parent columns. |
5. Decisions
- 2026-09-17 (task E2929BA0): fix the namespace, not the readers. Every
reader looks at the entity root, so nothing read
sql.has_parent_id. Moving the feature to the root is the smaller change, and it matcheshas_tenant_idandhas_workspace_id, which already live there.doc_generate.pycorroborated the choice independently: itshierarchical-compositeshape preset already groupedhas_parent_idwith the two tenancy features at the root. - 2026-09-17 (task E2929BA0): rebind the eleven to
uuid-identified-lookup, notuuid-surrogate-lookup. The tiebreaker is the physical-space table. The profile they left anduuid-identified-lookupboth enableores.cpp.eventing-integration-test, and eleven generated integration tests exist for those entities.uuid-surrogate-lookuphas no physical-space table at all, so that binding would have deleted them. On feature assignments the two profiles are interchangeable here, becauseuuid-surrogate-lookup's two extra rows pin flags that already default to false. The fit holds on the descriptive axis too. The reference entity is UUID-keyed, tenant-scoped, parentless and natural-keyed, and ten of the eleven declare a natural key of their own. Onlycalendar_rulehas none, so it alone stretches the profile. - 2026-09-17 (task E2929BA0): keep
parent_id_columnandhierarchy_name_fieldin the root* Flagsdrawer. They are structural, so no profile can carry them, and the readers already look for them there. Two SQL-facet templates are the only readers, so a later change could move them into* SQL, but that move must change the reader paths too. - 2026-09-17 (task E2929BA0):
has_parent_idbelongs to the Keys and columns bundle, not toores.sql.schema. The templates that read it reach beyond SQL into the C++, protocol and NATS facets. Its narrative home stays on the SQL page, beside the hierarchy block it gates. The feature index, the feature catalogue and the UVL models now file it with the other structural features.
6. Out of scope
parent_id_columnandhierarchy_name_fieldstay in the root* Flagsdrawer while only the SQL facet reads them. The task's Notes record the tidy-up and the change it needs.- The scaffolder's
--entity-<knob>vocabulary. A model authored withcompass add entity_orgstill cannot express the hierarchy block. - A loader guard that fails when the feature is on without both column properties. It would have caught the eleven at the point of regeneration instead of at the point of audit. Filed as a capture rather than built here.