Make virtual org departments filter-aware + tighten the model#307
Open
etiennechabert wants to merge 1 commit into
Open
Conversation
The cost table already showed virtual departments as rolled-up rows when grouping by owner (applyOrgTreeRollup post-processing), but clicking a department to filter by it sent WHERE owner='Engineering' literally and returned zero rows. Filter and display layers disagreed on what a virtual node meant. This change closes that asymmetry and tightens the model: - Validator enforces a single virtual root. Multi-root configs are wrapped under a synthetic "Organization" on load; empty trees get the same synthetic root. Non-virtual nodes with children are auto-promoted to virtual (eliminating the confusing "leaf-and-parent at the same time" edge case). The editor surfaces all three migrations as a dismissible banner. - New expandOrgFilters core helper expands virtual-department filter values to their descendant leaves. Wired through setupQuery (covers query:costs, query:trends, query:daily-costs, query:missing-tags, query:entity-detail) and the explorer + filter-values handlers so a picked department becomes WHERE owner IN (descendants...) before SQL builds. - query:filter-values synthesizes one entry per virtual node, summing its descendant leaf costs from the same SQL it already runs. The owner-dim LIMIT 100 is dropped (cardinality is bounded by team count). When the user has a virtual department picked, the dropdown shows only the picked node + its immediate children. - Entity-detail handles virtual entities by expanding to descendant leaves before applying the entity filter. - Filter bar renders virtual entries with a Folder icon and "department" badge, sharing the visual language used in the cost table. - applyOrgTreeRollup now rolls up at the children of the synthetic root (departments) rather than at the root itself, so the cost table shows per-department rows instead of one big "Organization" row. - rollupRealNode and the dead orgNodeValues query param are deleted — the children-implies-virtual invariant makes them redundant. - Cost-scope autocomplete strips virtual entries (exclusion rules apply to literal CUR values, so virtual names would be misleading). - The org-tree editor's "Unassigned" panel filters out the synthesized virtual entries it now receives from getFilterValues. 20 new tests on the rollup, validator migrations, and filter expansion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stacks on top of #282. The cost table already showed virtual departments as rolled-up rows when grouping by owner, but clicking a department to filter by it sent
WHERE owner='Engineering'literally and returned zero rows — display and filter layers disagreed on what a virtual node meant. This closes the asymmetry and tightens the model.What changes
expandOrgFilterscore helper expands virtual-department filter values to their descendant leaves. Wired throughsetupQueryso every query handler (costs, trends, daily-costs, missing-tags, entity-detail) plus the explorer and filter-values handlers get it.query:filter-valuessynthesizes virtual entries with rolled-up costs (isVirtual: true). The owner-dimLIMIT 100is dropped since cardinality is bounded by team count. When a virtual department is picked, the dropdown shows only that node + its immediate children for drill-down.applyOrgTreeRolluprolls up at the root's children (departments) rather than at the root itself, so the cost table shows per-department rows instead of one big "Organization" row.rollupRealNodeand the deadorgNodeValuesquery param are deleted.ownerDimension.tagName(rawuser_sb_team) instead of the column ID (tag_user_sb_team) togetFilterValues, which made the SQL reference a non-existent column. Now using the canonicalgetDimensionIdhelper.20 new tests on the rollup, validator migrations, and filter expansion. All existing tests still pass.