feat: show table renders relationships as compact diagrams (ADR-0044)

show table <T> and add/drop relationship echoes now render the focal
structure box plus a Relationships section of compact stacked
connector diagrams (child-left/parent-right, n…1, actions); incidental
DDL echoes keep the prose References:/Referenced by: form. Selected by
command in handle_dsl_success via the "relationship-relevant" reach.

- output_render.rs: render_structure refactored into section helpers
  (box/prose/index/constraint), byte-identical output; new
  render_structure_with_diagrams + compact-box rendering
- app.rs: handle_dsl_success routes ShowTable/Add/DropRelationship to
  the diagram path, others to prose
- fixes: eager widths[1] index on compact (1-col) boxes; body-cell
  padding under title-widening (name wider than columns)

Tests: unit + snapshot + integration; add-relationship echo test
updated to the diagram form. Full suite 2203 pass / 0 fail / 1 ignored;
clippy clean. V1 still [/] (compound routing + self-ref remain).
This commit is contained in:
claude@clouddev1
2026-06-10 06:56:35 +00:00
parent cad90ec4a5
commit a0ee32393f
5 changed files with 258 additions and 32 deletions
+35
View File
@@ -454,3 +454,38 @@ fn app_show_relationship_not_found_shows_friendly_line() {
"friendly not-found line",
);
}
#[test]
fn app_show_table_renders_relationships_as_compact_diagrams() {
let (_p, db, _dir) = open_project_db();
let rt = rt();
rt.block_on(seed_schema(&db));
// Orders holds the FK to Customers — an outbound relationship.
let desc = rt
.block_on(db.describe_table("Orders".to_string(), None))
.expect("describe Orders");
let mut app = App::new();
app.output.push_back(rdbms_playground::app::OutputLine::echo(
"show table Orders",
Mode::Simple,
));
app.update(AppEvent::DslSucceeded {
command: Command::ShowTable {
name: "Orders".to_string(),
},
description: Some(desc),
echo: None,
});
let text: String = app
.output
.iter()
.map(|l| l.text.as_str())
.collect::<Vec<_>>()
.join("\n");
// The focal structure box, then a diagram (not the prose block).
assert!(text.contains("Relationships"), "diagram heading: {text}");
assert!(!text.contains("References:"), "prose suppressed: {text}");
assert!(text.contains("Customers"), "neighbour box: {text}");
assert!(text.contains('▶'), "connector arrow: {text}");
}