Skip to main content

Schema Builder — Developer Reference

Technical reference for engineers working on the Schema Builder codebase. Covers architecture, data flow, plugin integration points, and key subsystems.


Application Bootstrap (main.ts)​

The app is bootstrapped in src/main.ts. Key registration sequence:

app.use(createPinia());           // 1. Pinia reactive store
app.use(useAppRouter()); // 2. Vue Router (hash-based)
app.use(PrimeVue, { ... }); // 3. PrimeVue (SureCentric Lara preset)
registerIcons(); // 4. FontAwesome icon library
registerDefaultDataFormats(); // 5. JSON, YAML, JSON-LD format handlers
registerDefaultPanelTypes(); // 6. Panel registry (GUI, Table, Mapper, Diagram...)
registerBuiltins(); // 7. Built-in plugins (PostgreSQL DDL, DuckDB DDL)
initApiKey(); // 8. AI API key
app.mount('#app');

Data Formats (src/dataformats/)​

The format registry maps file types to parse/serialize handlers and validators.

FormatHandlerValidator
jsonJSON.parse / stringifyAJV (JSON Schema Draft 2020-12) — off-thread worker
yamljs-yamlAJV via worker
jsonldJSON.parse / stringifyCustom jsonLdValidator.ts — synchronous, main thread

JSON-LD Validator (src/dataformats/jsonld/jsonLdValidator.ts)​

A custom synchronous recursive linter that:

  • Bypasses the AJV worker entirely for .jsonld files (prevents structural crashes)
  • Collects up to 10 errors per scan (multi-error, not fail-fast)
  • Outputs ErrorObject[] with instancePath JSON Pointers compatible with the existing AceEditor annotation pipeline
  • Validates: illegal @ keywords, @context type, @id must be string, mixed-type node values

Panel System (src/components/panels/)​

Panels are registered in defaultPanelTypes.ts and rendered in the main split-pane layout. Each panel type defines:

{
name: string; // e.g. 'mapperView'
label: string; // Toolbar tooltip
icon: string; // FontAwesome class
supportedModes: SessionMode[];
component: Component;
}

Registered Panels (Schema Mode)​

PanelKeyDescription
Text ViewtextEditorAceEditor with gutter annotations
GUI ViewguiEditorVisual property editor
Table ViewtableViewTabular node browser
Mapper ViewmapperViewNode → DDL/JSON translator (plugin-powered)
Diagram ViewschemaDiagramVue Flow interactive diagram
DocumentationdocumentationAuto-generated schema docs

Mapper View (src/components/panels/mapper/)​

The Mapper View loads all JSON-LD nodes from the active schema, lets the user select and configure them, then translates to an output format via the plugin registry.

Data Flow​

Schema data (Pinia store)
↓ auto-load on mount
MapperPanel.vue — MappingRow[] table
↓ user selects rows + target format
translators/index.ts → pluginRegistry.getTranslator(format)
↓ plugin.translate(selectedRows, sourceUri)
Output string (Preview panel)
↓ user clicks Export
File download

MappingRow Interface​

interface MappingRow {
id: string; // UUID row key
nodeId: string; // Full @id URI
nodeType: string; // owl:Class | owl:DatatypeProperty | ...
nodeLabel: string; // rdfs:label → skos:prefLabel → @id fragment
selected: boolean;
mapTo: string; // Target identifier (SQL table/column name)
targetType: string; // TABLE | TEXT | INTEGER | DATE | ...
notes: string;
}

Translator Routing (src/components/panels/mapper/translators/index.ts)​

export function translate(format, rows, sourceFile): string {
// 1. Check plugin registry — registered translator wins
const plugin = pluginRegistry.getTranslator(format);
if (plugin?.translate) return plugin.translate(rows, sourceFile);

// 2. Fall back to Phase A stub
return stubs[format](rows, sourceFile);
}

// Async variant for plugins that call the OWL sidecar
export async function translateAsync(format, rows, sourceFile): Promise<string>

Plugin System (src/plugins/)​

See the Plugin Authoring Guide for the full plugin contract and build instructions.

Registry API (pluginRegistry.ts)​

pluginRegistry.register(plugin)          // Register (calls onActivate)
pluginRegistry.unregister(id) // Remove (calls onDeactivate)
pluginRegistry.getAll // computed<SchemaBuilderPlugin[]> — reactive
pluginRegistry.getByType(type) // SchemaBuilderPlugin[] snapshot
pluginRegistry.getTranslator(formatId) // First translator for formatId
pluginRegistry.hasTranslator(formatId) // boolean — used to enable Export button
pluginRegistry.size // number of registered plugins

Built-in Plugins​

IDFormatFile
com.sureclinical.sql-postgresqlsql-postgresqlsrc/plugins/builtin/sqlPostgresqlPlugin.ts
com.sureclinical.sql-duckdbsql-duckdbsrc/plugins/builtin/sqlDuckDbPlugin.ts

DDL Generation Algorithm​

Both SQL plugins share the same table-grouping algorithm:

  1. Filter rows to selected === true
  2. Rows with targetType === 'TABLE' (or nodeType === 'owl:Class') begin a new CREATE TABLE block
  3. Subsequent non-TABLE rows become columns of the most recent table
  4. Each table auto-receives an iri primary key column derived from @id
  5. Identifiers are sanitized: camelCase → snake_case, special chars → _, lowercased

Type maps:

SourcePostgreSQLDuckDB
TEXT / STRINGTEXTVARCHAR
INTEGER / INTINTEGERINTEGER
FLOAT / DOUBLE / NUMBERDOUBLE PRECISIONDOUBLE
BOOLEANBOOLEANBOOLEAN
DATEDATEDATE
DATETIME / TIMESTAMPTIMESTAMP WITH TIME ZONETIMESTAMP
JSON / JSONBJSONBJSON
UUIDUUIDVARCHAR(36)
URI / IRITEXTVARCHAR

Toolbar (src/components/toolbar/)​

Three-dot Overflow Menu (TopToolbar.vue)​

⋮  Settings          → SessionMode.Settings
View Plugins → showPluginManagerDialog.value = true
──────────────
SureCentric Docs → https://docs.surecentric.net
──────────────
About Schema Builder
──────────────
Restore default settings

Adding a New Menu Item​

  1. Add the item to overflowMenuItems ref in TopToolbar.vue
  2. If it opens a dialog, add a ref<boolean> and mount the dialog component in the template
  3. If the icon is FontAwesome, register it in src/fontawesome.ts

Session Modes (src/store/sessionMode.ts)​

ModeDescription
SchemaEditorJSON-LD / JSON Schema authoring
DataEditorData document editing
SettingsApplication settings

Known Extension Points​

ExtensionHow
New output formatImplement SchemaBuilderPlugin with pluginType: 'translator'
New panelImplement SchemaBuilderPlugin with pluginType: 'panel' (P3: auto-registered into panel registry)
New import sourceImplement SchemaBuilderPlugin with pluginType: 'importer'
New validatorImplement SchemaBuilderPlugin with pluginType: 'validator'
New toolbar menu itemEdit overflowMenuItems in TopToolbar.vue
New data formatRegister in src/dataformats/defaultFormats.ts