Database Model Viewer

This page demonstrates rendering relational database schemas in PaperScape using Giraffe.js. The example below loads and visualizes the `example-database-model.json` file.
PaperScape Integration

Drag the link onto the PaperScape canvas to embed this viewer as a reusable scene component.

Database Model View PaperScape App (.giraffe.js) undefined

Within PaperScape, click a table card to explore its columns, constraints, and indexes. Foreign key arrows are rendered automatically from the JSON model and are clickable for editing.

Drop `.dbmv.json` files or URLs directly onto the PaperScape canvas to load models; choose _Import_ to merge or _Replace_ to swap the active scene.

PaperScape Controls

PaperScape Editing Roadmap

Goal: evolve the Database Model viewer into a schema design studio that complements PaperScape's spatial layout tooling.

✅ Recently Completed 🚧 In Progress - Enhanced constraint management (check constraints, exclusion constraints). 🗺️ Upcoming - Schema diffing utilities with SQL migration export. - Seed data attachments and quick prototyping helpers. - Collaborative enhancements (comments, change history, keyboard shortcuts, theming).

Roadmap Additions

MCP Collaboration Plan

The canvas renders database tables as cards showing columns, constraints, and indexes. Foreign key relationships draw clickable labels between tables. Update the JSON file and refresh the page to see changes—no manual markup edits required.

Interactive Features

  • Automatic Layout: Tables are arranged in dependency tiers derived from foreign keys
  • Constraint Awareness: Column badges reflect PK, uniqueness, nullability, and FK targets
  • Unique Constraints: Define multi-column unique constraints in the table editor
  • FK Validation: Foreign keys are validated against existing tables and columns
  • Clickable Relationships: Click FK arrow labels to view details or delete relationships
  • Index Summary: Index definitions render with names, uniqueness, and filter clauses
  • Color-Coded Tables: Choose from 6 header color schemes to visually organize your schema
  • Responsive Canvas: Scene resizes to fit the generated layout, including large schemas
  • Error Handling: Friendly messaging when the JSON payload cannot be parsed

Schema Definition

The visualization above renders the following schema structure from `example-database-model.json`: { "tables": [ { "id": "users", "name": "users", "columns": [ { "name": "id", "type": "uuid", "primaryKey": true, "nullable": false, "default": "uuid_generate_v4()" }, { "name": "email", "type": "text", "nullable": false, "unique": true }, { "name": "display_name", "type": "text", "nullable": false }, { "name": "created_at", "type": "timestamptz", "nullable": false, "default": "now()" }, { "name": "status", "type": "user_status", "nullable": false, "default": "'active'::user_status" } ], "indexes": [ { "name": "users_email_idx", "unique": true, "columns": ["email"] }, { "name": "users_status_created_at_idx", "columns": ["status", "created_at"], "method": "btree" } ], "extensions": { "description": "Registered platform members with authentication credentials and profile metadata.", "datasource": "PostgreSQL", "color": "teal" } }, { "id": "products", "name": "products", "columns": [ { "name": "id", "type": "uuid", "primaryKey": true, "nullable": false, "default": "uuid_generate_v4()" }, { "name": "sku", "type": "text", "nullable": false, "unique": true }, { "name": "name", "type": "text", "nullable": false }, { "name": "price_cents", "type": "integer", "nullable": false }, { "name": "active", "type": "boolean", "nullable": false, "default": "true" } ], "indexes": [ { "name": "products_active_idx", "columns": ["active"], "method": "btree" } ], "extensions": { "description": "Catalog entries that can appear on customer orders.", "datasource": "PostgreSQL", "color": "emerald" } }, { "id": "orders", "name": "orders", "columns": [ { "name": "id", "type": "uuid", "primaryKey": true, "nullable": false, "default": "uuid_generate_v4()" }, { "name": "user_id", "type": "uuid", "nullable": false, "foreignKey": { "targetTable": "users", "targetColumn": "id" } }, { "name": "ordered_at", "type": "timestamptz", "nullable": false, "default": "now()" }, { "name": "status", "type": "order_status", "nullable": false, "default": "'pending'::order_status" }, { "name": "total_cents", "type": "integer", "nullable": false } ], "indexes": [ { "name": "orders_user_id_idx", "columns": ["user_id"], "method": "btree" }, { "name": "orders_status_idx", "columns": ["status"], "method": "btree" } ], "extensions": { "description": "Order headers capturing who placed the order and its fulfilment status.", "datasource": "PostgreSQL", "color": "blue" } }, { "id": "order_items", "name": "order_items", "columns": [ { "name": "id", "type": "uuid", "primaryKey": true, "nullable": false, "default": "uuid_generate_v4()" }, { "name": "order_id", "type": "uuid", "nullable": false, "foreignKey": { "targetTable": "orders", "targetColumn": "id" } }, { "name": "product_id", "type": "uuid", "nullable": false, "foreignKey": { "targetTable": "products", "targetColumn": "id" } }, { "name": "quantity", "type": "integer", "nullable": false, "default": 1 }, { "name": "unit_price_cents", "type": "integer", "nullable": false } ], "indexes": [ { "name": "order_items_order_id_idx", "columns": ["order_id"], "method": "btree" }, { "name": "order_items_product_id_idx", "columns": ["product_id"], "method": "btree" } ], "extensions": { "description": "Line items associated with an order, connecting products and quantities.", "datasource": "PostgreSQL", "color": "violet" } } ], "relationships": [ { "type": "foreignKey", "sourceTable": "orders", "targetTable": "users" }, { "type": "foreignKey", "sourceTable": "order_items", "targetTable": "orders" }, { "type": "foreignKey", "sourceTable": "order_items", "targetTable": "products" } ] }

Database Model Schema

JSON Schema Specification

DBModelView uses a canonical JSON Schema (Draft 2020-12) that defines the structure and validation rules for database models. The schema focuses purely on database structure elements (tables, columns, indexes, constraints, relationships) and uses an extensions model for metadata, similar to Object Model Viewer.

database-model-schema.json

The schema provides:

Schema Properties

Tables

Table Extensions

The `extensions` object can contain tool-specific metadata that is not part of the core database schema:

Columns

Indexes

Constraints

Foreign Keys

Relationships

Note: The schema structure follows the Object Model Viewer pattern, using an extensions object for tool-specific metadata separate from core database structure. This ensures portability between tools while supporting rich metadata for documentation and visualization.

Application Architecture

The Database Model Viewer uses a modular component-based architecture assembled via ServiceBuilder:

Build Configuration

The application is built from multiple source files using `script.build.json`: { "version": "0.0.3", "targetFile": "/OpenForum/AddOn/PaperScape/DBModelView/db-model-view.giraffe.js", "versionFile": "/OpenForum/AddOn/PaperScape/DBModelView/Version/db-model-view.giraffe.js", "steps": [ { "action": "append", "file": "/OpenForum/AddOn/PaperScape/DBModelView/db-model-view-core.giraffe.js" }, { "action": "insert", "searchFor": "// insert TableBox", "file": "/OpenForum/AddOn/PaperScape/DBModelView/TableBox.js" }, { "action": "insert", "searchFor": "// insert RelationshipArrow", "file": "/OpenForum/AddOn/PaperScape/DBModelView/RelationshipArrow.js" } ] }

Component Files

Core Application (`db-model-view-core.giraffe.js`) Table Rendering (`TableBox.js`) Relationship Rendering (`RelationshipArrow.js`)

Standalone Component Pattern

Components use defensive programming to work in multiple contexts: // Color constants defined with guards in db-model-view-core.giraffe.js var TABLE_COLOR_OPTIONS = [ { id: "teal", headerFill: "#0f766e", headerBorder: "#0d9488", titleColor: "#ecfeff" }, { id: "blue", headerFill: "#2563eb", headerBorder: "#1d4ed8", titleColor: "#f8fafc" }, // ... more colors ]; var DEFAULT_TABLE_COLOR = "teal"; // Components receive colorTokens as options var colorTokens = getTableColorTokens(table.extensions.color || DEFAULT_TABLE_COLOR); var box = new TableBox(table, metrics, position, { colorTokens: colorTokens }); This design enables:

Building the Application

To rebuild after modifying source files: http://localhost:8888/OpenForum/AddOn/ServiceBuilder?action=buildJavascript&pageName=/OpenForum/AddOn/PaperScape/DBModelView&fileName=script.build.json The build process: 1. **Appends** the core file as the base (includes Integration module, color system) 2. **Inserts** TableBox at `// insert TableBox` marker 3. **Inserts** RelationshipArrow at `// insert RelationshipArrow` marker 4. **Outputs** the complete `.giraffe.js` file ready for PaperScape

Drag-and-Drop Integration

The Integration module handles `.dbmv.json` file drops:

Extending the Viewer

Custom Styling

Adjust `TableBox.js` colours and fonts to match your product design system or highlight regulated data sets.

Additional Relationship Types

Add support for replication or materialized view dependencies with alternate arrow styling and legends.

Interactive Features

Introduce click handlers or overlays to edit columns, constraints, and indexes directly within PaperScape.

Export Capabilities

Integrate export buttons that emit DBML, Mermaid, or SQL migration scripts using the PaperScape scene data.

Schema Validation

Use the JSON Schema file with validation tools: # Using AJV (Node.js) npm install ajv const Ajv = require('ajv'); const ajv = new Ajv(); const validate = ajv.compile(schemaJson); const valid = validate(modelJson); # Using online validators https://www.jsonschemavalidator.net/

Child Pages


Attachments