Skip to content

feat(voyager): add Hide Reverse Relationships toggle for ER diagram#99

Merged
allmonday merged 1 commit into
masterfrom
feat/007-hide-reverse-relationships
Jul 3, 2026
Merged

feat(voyager): add Hide Reverse Relationships toggle for ER diagram#99
allmonday merged 1 commit into
masterfrom
feat/007-hide-reverse-relationships

Conversation

@allmonday

Copy link
Copy Markdown
Collaborator

Summary

Adds a new display toggle "Hide Reverse Relationships" to the Voyager ER diagram. When enabled, ONETOMANY reverse-mirror edges are hidden; only MANYTOONE (FK-holder side) and MANYTOMANY edges remain. Eliminates the visual duplication produced by SQLModel back_populates bidirectional relationships (each entity pair drops from 2 edges to 1).

  • Backend: ErDiagramDotBuilder early-returns on direction == 'ONETOMANY' when the flag is on; RelationshipInfo.direction (already populated by SQLAlchemy inspect()) drives the filter, no new reflection needed
  • Frontend: new q-toggle in the ER-diagram display options panel; state persisted to localStorage (key hide_reverse_relationships); both /er-diagram and /er-diagram-subgraph payloads carry the field
  • Subgraph (spec 005) follows the filter automatically — filter_to_neighborhood consumes the already-filtered self.links
  • Toggle orthogonal to all existing display options (cluster display / brief mode / show methods / etc.)

Naming note

Originally specced as "Pure Foreign Key" — feature was renamed mid-spec after discovering the original premise (independent FK-column edges) doesn't match the current implementation (all ER edges today come from Relationship(...) fields, not FK column constraints). Directory specs/007-voyager-er-pure-fk/ kept as a filesystem identifier, decoupled from the UI label. See spec.md Q4/Q5 for the full clarification trail.

Implementation notes

  • Backend filter lives in _add_relationship_link (entrance early-return), so self.rel_name_set still records all relationships — Fields tab content is unaffected (FR-007 invariant verified by test_fields_table_unchanged)
  • Link anchor / label generation is untouched — surviving edges look identical to the unfiltered version, just fewer
  • Pydantic payload field defaults to False → old clients unaffected, response shape unchanged

Test plan

  • tests/test_voyager_hide_reverse.py — 10 new pytest cases (filter off/on, M2M preservation, unirectional MANYTOONE/ONETOMANY, SchemaNode.fields invariance, endpoint contract + backward compat, subgraph follow-through, self-referential back_populates)
  • Full voyager regression: uv run pytest tests/ -k voyager41 passed, 0 regressions
  • Manual browser verification still pending (T016/T019/T022/T023 in tasks.md):
    • Run uv run uvicorn demo.enterprise_voyager.voyager_demo:app --port 8010
    • Follow specs/007-voyager-er-pure-fk/quickstart.md §2.2–2.10
    • Confirm: toggle on → 1 edge per entity pair; toggle off → 2 edges; M2M both sides preserved; Fields/Source/About tabs unaffected; Related Entities subgraph follows filter; refresh preserves preference; Tab/Space keyboard-accessible; cross-toggle orthogonality with cluster display + brief mode
  • T024 CHANGELOG / version bump (optional, project discretion)

Spec kit artifacts

Full spec-kit trail under specs/007-voyager-er-pure-fk/:

  • spec.md (5 clarify Q&As)
  • plan.md + research.md (5 implementation decisions)
  • data-model.md + contracts/ (3 contract documents)
  • quickstart.md (10 pytest cases + 10 manual verification procedures)
  • tasks.md (27 tasks, 21 auto-completed, 6 pending manual)

🤖 Generated with Claude Code

Add a new display toggle that hides ONETOMANY reverse-mirror edges in the
ER diagram, keeping only MANYTOONE (FK-holder side) and MANYTOMANY edges.
Eliminates the visual duplication produced by SQLModel `back_populates`
bidirectional relationships (each entity pair went from 2 edges to 1).

Backend:
- `ErDiagramDotBuilder.__init__` accepts `hide_reverse_relationships: bool`
- `_add_relationship_link` early-returns on `direction == 'ONETOMANY'` when
  the flag is on; MANYTOONE and MANYTOMANY are preserved unchanged
- `ErDiagramPayload` and `ErDiagramSubgraphPayload` get the new field
  (default `False`, backward compatible)
- `VoyagerContext` transparently passes the field through to the builder

Frontend:
- `store.js` adds `state.filter.hideReverseRelationships` field,
  `toggleHideReverseRelationships(val, onGenerate)` action, and threads
  the field into both payload builders (`buildErDiagramPayload` and
  `buildErDiagramSubgraphPayload`)
- `vue-main.js` reads the persisted state from `localStorage` on init and
  registers the toggle action
- `index.html` renders a `<q-toggle>` in the ER-diagram display options
  panel (keyboard-accessible by default; only shown in ER-diagram mode)
- Subgraph (spec 005) follows the filter automatically because
  `filter_to_neighborhood` consumes the already-filtered `self.links`

Spec kit artifacts under `specs/007-voyager-er-pure-fk/` (spec, plan,
research, data-model, contracts, quickstart, tasks) — feature was renamed
from "Pure Foreign Key" to "Hide Reverse Relationships" mid-spec after
discovering the original premise (independent FK-column edges) doesn't
match the current implementation; directory name retained as a filesystem
identifier, decoupled from the UI label.

Tests: 10 new pytest cases cover filter off/on, M2M preservation,
unirectional MANYTOONE/ONETOMANY, SchemaNode.fields invariance (FR-007),
endpoint contract + backward compat, subgraph follow-through, and
self-referential back_populates. Full suite: 41 passed, 0 regressions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@allmonday allmonday merged commit 3f7d78d into master Jul 3, 2026
6 checks passed
allmonday added a commit that referenced this pull request Jul 3, 2026
Version bump for PR #99 (Voyager ER diagram Hide Reverse Relationships
display toggle). Updates CHANGELOG, pyproject.toml, uv.lock.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant