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