rails-schema 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75eb165fa4db98c3ef82f825eccb9288fa94c2d74426ae8116546fa95305dc17
4
- data.tar.gz: aaf4af95cbc0b22f345d17fd897b8890b82702d601268f2a227055f44c84c764
3
+ metadata.gz: d97a36c459cf91334bda4a6feb1bb99222432a71d75cf8fa368215facf465012
4
+ data.tar.gz: 5851a6d08e91c981fc15801a4cb805bb107079e8ede44c6ea5dc6da033302253
5
5
  SHA512:
6
- metadata.gz: 0dbd41660049021c934ffa405ddff95e0b5a6f1e587dc67bd1b1da7e69c0a7aebdfb0684fe8d1a1ccfa78fa06adb2f8f7d0dd02ed21fca9c34131296621acc83
7
- data.tar.gz: fb06c1f8dbcd7aa07e67a92f759abe9f48299da55e7d9d726cf05cfa8fd185db61677e1f82eb813b0c1214f57ae58091f6629f82df8e6361932c623f09a7b2d5
6
+ metadata.gz: 968db5097006071930a3972b96d7aa6b0a616133999aee055e45466612f6141dff125f6e38adb426c60dbf4dfc4ab31e1171613637577164a825e4db2be0684e
7
+ data.tar.gz: 735d4895a9e7b80ade035acfeab3439b810b572e5ff4835dfe1e0c2160d727aa59f9616910eecd72316813c448e429f40f50546ea33096b78f7b6ac1d3f4bd0e
data/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [0.1.8] - 2026-06-14
8
+
9
+ ### Added
10
+
11
+ - SQL view support — models backed by a SQL view (`CREATE VIEW`, e.g. `self.table_name = "some_view"`) now appear on the diagram instead of being silently dropped. `StructureSqlParser` parses `CREATE VIEW` statements (column names from the SQLite hint comment or the `SELECT` list); columns are read from live DB introspection when a connection is available (accurate types) and fall back to the parsed names offline. View nodes are visually distinguished with a "VIEW" badge and a dashed border, plus a "VIEW" tag in the detail panel.
12
+
13
+ ### Fixed
14
+
15
+ - SQLite `structure.sql` parsing — `StructureSqlParser` now correctly extracts all columns from SQLite-format dumps, which place the entire `CREATE TABLE` on a single line. Previously only the primary key was read (every model rendered with just its `id`). Column splitting is now parenthesis- and quote-aware, so commas inside type modifiers (`decimal(5,4)`), `FOREIGN KEY` clauses, and string literals no longer break parsing; inline C-style comments (`/* ... */`) are stripped. PostgreSQL `pg_dump` output continues to parse as before.
16
+
17
+ ## [0.1.7] - 2026-04-25
18
+
19
+ ### Added
20
+
21
+ - Manual Positioning toggle — toolbar checkbox that removes all simulation forces when enabled; nodes stay wherever they are dropped and drag-and-drop continues to work normally; unchecking re-enables automatic force-directed layout (#33)
22
+ - Layout persistence — node positions, visibility, zoom, and toggle states are auto-saved to `localStorage` and restored on page reload; layouts are scoped per schema via a fingerprint hash so different projects don't collide (#33)
23
+ - Save/Load Layout — export the current layout as a portable `.json` file to share with teammates or check into git; import a saved layout file to restore it (#33)
24
+ - File menu dropdown — toolbar "File" menu groups Export Mermaid, Save Layout, and Load Layout actions (#33)
25
+
7
26
  ## [0.1.6] - 2026-03-28
8
27
 
9
28
  ### Added
data/CLAUDE.md CHANGED
@@ -47,9 +47,10 @@ end
47
47
  ### Data Extraction Strategy
48
48
 
49
49
  1. **`db/schema.rb`** — `SchemaFileParser` parses with regex (table names, columns, types, nullable, defaults, PKs)
50
- 2. **`db/structure.sql`** — `StructureSqlParser` parses SQL `CREATE TABLE` statements, maps SQL types to Rails types
50
+ 2. **`db/structure.sql`** — `StructureSqlParser` parses SQL `CREATE TABLE` statements, maps SQL types to Rails types. Column splitting is parenthesis/quote-aware (a top-level-comma splitter), so it handles both PostgreSQL `pg_dump` (one column per line) and SQLite (whole table on one line) dumps. Also parses `CREATE VIEW` statements — view names go into `#views` (a Set), and view column names come from the SQLite hint comment (`/* viewname(col,...) */`) or the `SELECT` list
51
51
  3. **ActiveRecord reflection API** — `AssociationReader` uses `reflect_on_all_associations` for associations
52
52
  4. **`Model.columns`** — `ColumnReader` falls back to this when table not found in schema_data
53
+ 5. **SQL views** — `parse_schema` returns `[columns, view_names]`. `ColumnReader.new(view_tables:)` reads view columns from live DB introspection first (accurate types), falling back to the parsed names offline. `GraphBuilder.new(view_tables:)` sets `Node#view`, which the frontend renders with a "VIEW" badge + dashed border. Views are always included (no config flag); the model just needs `self.table_name` pointing at the view
53
54
 
54
55
  ### Model Discovery
55
56
 
@@ -102,8 +103,11 @@ Single self-contained HTML file — no CDN, no network requests. D3 is vendored/
102
103
 
103
104
  - **Vanilla JS + d3-force** for graph rendering
104
105
  - **CSS custom properties** for dark/light theming
105
- - Features: searchable sidebar, click-to-focus, double-click to isolate neighborhood, detail panel (clicking a relation link auto-selects the related model, adding it to the diagram if hidden), zoom/pan, keyboard shortcuts (`/` search, `Esc` deselect, `+/-` zoom, `F` fit), Mermaid ER diagram export (`.mmd`) filtered by sidebar visibility
106
+ - Features: searchable sidebar, click-to-focus, double-click to isolate neighborhood, detail panel (clicking a relation link auto-selects the related model, adding it to the diagram if hidden), zoom/pan, keyboard shortcuts (`/` search, `Esc` deselect, `+/-` zoom, `F` fit)
106
107
  - **Through edges toggle** — legend checkbox to show/hide `:through` edges on the diagram at runtime; `config.show_through_edges` (default `true`) sets the initial checkbox state; through associations always remain visible in the detail panel regardless of toggle state; filtering happens in `setupSimulation()` on the frontend (edges stay in `data.edges` for the detail panel)
108
+ - **Manual Positioning toggle** — toolbar checkbox that removes all simulation forces when enabled; nodes stay wherever they are dropped since nothing pushes or pulls them; drag-and-drop continues to work normally via the standard `fx/fy` mechanism; unchecking calls `render()` to restore all forces and resume automatic layout; in manual mode, `ticked()` skips `layoutOrphans()`/`layoutSelfRefNodes()` to preserve manually-placed positions; `dragEnded` keeps `fx/fy` set so nodes stay pinned where dropped
109
+ - **Layout persistence** — node positions, visibility, zoom, collapsed groups, and toggle states are auto-saved to `localStorage` on every state change; on page load, saved layout is restored via `applyLayout()`, which honors the saved `manualPositioning` flag: when true, nodes are pinned via `fx/fy` and forces are removed so the restored layout is frozen; when false, positions seed `x/y` only and forces keep running so automatic layout resumes; `localStorage` key is `"rails-schema-layout:" + fingerprint` where fingerprint is a djb2 hash of sorted node IDs, so different schemas get separate saved layouts
110
+ - **File menu dropdown** — toolbar dropdown ("File ▼") groups export/import actions: "Export Mermaid" (`.mmd` filtered by sidebar visibility), "Save Layout" (downloads a `.json` file with positions, visibility, zoom, and toggle state), "Load Layout" (reads a `.json` file via file picker and applies it); the JSON format uses a `version: 1` field and `schemaFingerprint` for forward compatibility; layout files are portable and can be shared with teammates or checked into git
107
111
  - **Select All smart toggle** — when all models are already selected and a search filter is active, "Select All" narrows to only filtered models (acts as "select only these"); otherwise it adds filtered models to the current selection
108
112
  - **Model grouping** — when `config.model_schema_group` is set, models are organized under collapsible group headers in the sidebar with color-coded dots; each group's models get a distinct node header color in the SVG; a custom d3 force (`strength 0.15`) pulls same-group nodes toward their centroid, and a separation force pushes overlapping group bounding boxes apart; double-click a group header to select/deselect (uses delayed click timer to avoid triggering collapse); search also matches group names
109
113
 
@@ -115,4 +119,5 @@ Single self-contained HTML file — no CDN, no network requests. D3 is vendored/
115
119
  - **Force-directed layout** — handles unknown schemas gracefully without pre-defined positions
116
120
  - **Node layout categories** — three-way partition in `app.js`: connected nodes use force simulation, self-ref-only models (all edges point to themselves) are placed in a vertical left column via `layoutSelfRefNodes()`, true orphans (zero edges) are placed in rows above the diagram via `layoutOrphans()`
117
121
  - **Edge deduplication** — `GraphBuilder.deduplicate_edges` chains two passes: (1) HABTM dedup merges symmetric `has_and_belongs_to_many` pairs into one edge with `reverse_label`, (2) has_many/belongs_to dedup merges matching pairs (same foreign_key, reversed endpoints) into one edge where the has_many/has_one side is kept and the belongs_to label becomes `reverse_label` with its own `reverse_association_type`. The frontend uses `reverse_association_type` to color each label by its own association type.
122
+ - **Layout persistence** — dual storage: `localStorage` for automatic save/restore (zero friction), plus JSON file export/import for portability and sharing. Restoring a layout honors the saved `manualPositioning` flag: manual-mode layouts are pinned and frozen (forces removed) so they survive exactly; auto-mode layouts seed initial positions but let forces keep running so the user can return to automatic layout by unchecking the toggle and reloading. The `schemaFingerprint` (djb2 hash of sorted node IDs) scopes `localStorage` keys so different schemas don't collide and schema changes get a clean slate.
118
123
  - **Model grouping config** — `config.model_schema_group` accepts `nil` (default, no grouping), `:namespaces` (splits `model.name` on `::`, drops the model name, keeps namespace parts), or a custom `Proc` that receives a model and returns an array (e.g., `["Admin", "Reports"]`). `Configuration#resolved_group_proc` normalizes all forms into a callable proc. `GraphBuilder` calls it per model and attaches the result as `Node#group`. The `group` field is omitted from JSON when empty to keep output compact when grouping is off.
data/README.md CHANGED
@@ -169,11 +169,15 @@ If the targeted loading doesn't find any models, the gem falls back to a full ea
169
169
  - **Click-to-focus** — click a model to highlight its neighborhood, fading unrelated models
170
170
  - **Double-click to isolate** — double-click a model to filter the view to only that model and its direct neighbors
171
171
  - **Through edges toggle** — checkbox in the legend to show/hide `:through` association edges on the diagram; through associations always remain visible in the detail panel regardless of toggle state
172
+ - **Manual Positioning** — toolbar checkbox that removes all simulation forces; nodes stay exactly where you drop them and drag-and-drop continues to work normally; uncheck to re-enable automatic force-directed layout
173
+ - **Layout persistence** — node positions, visibility, zoom, and toggle states are automatically saved to `localStorage` and restored on page reload; scoped per schema so different projects don't collide
172
174
  - **Detail panel** — full column list and associations for the selected model; clicking a relation link auto-selects the related model (adding it to the diagram if hidden)
173
175
  - **Dark/light theme** — toggle or auto-detect from system preference
174
176
  - **Zoom & pan** — scroll wheel, pinch, or buttons
175
177
  - **Keyboard shortcuts** — `/` search, `Esc` deselect, `+/-` zoom, `F` fit to screen
176
- - **Export to Mermaid** — download the diagram as a `.mmd` file for use in Markdown, GitHub, or other tools that render Mermaid ER diagrams; respects sidebar visibility filters so you can export a subset of models
178
+ - **File menu** — toolbar dropdown grouping export/import actions: Export Mermaid (`.mmd`), Save Layout (`.json`), and Load Layout
179
+ - **Save/Load Layout** — export the current layout as a portable `.json` file to share with teammates or check into version control; import a saved layout to restore it on any machine or browser
180
+ - **Export to Mermaid** — download the diagram as a `.mmd` file for use in Markdown, GitHub, or other tools that render Mermaid ER diagrams; respects sidebar visibility filters so you can export a subset of models
177
181
  - **Deduplicated edges** — reciprocal associations (e.g. `has_many :posts` / `belongs_to :user`, or symmetric HABTM) are merged into a single edge with dual labels, each colored by its own association type
178
182
  - **Self-contained** — single HTML file with all CSS, JS, and data inlined
179
183