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.
| Format | Handler | Validator |
|---|---|---|
json | JSON.parse / stringify | AJV (JSON Schema Draft 2020-12) — off-thread worker |
yaml | js-yaml | AJV via worker |
jsonld | JSON.parse / stringify | Custom 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
.jsonldfiles (prevents structural crashes) - Collects up to 10 errors per scan (multi-error, not fail-fast)
- Outputs
ErrorObject[]withinstancePathJSON Pointers compatible with the existing AceEditor annotation pipeline - Validates: illegal
@keywords,@contexttype,@idmust 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)
| Panel | Key | Description |
|---|---|---|
| Text View | textEditor | AceEditor with gutter annotations |
| GUI View | guiEditor | Visual property editor |
| Table View | tableView | Tabular node browser |
| Mapper View | mapperView | Node → DDL/JSON translator (plugin-powered) |
| Diagram View | schemaDiagram | Vue Flow interactive diagram |
| Documentation | documentation | Auto-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
| ID | Format | File |
|---|---|---|
com.sureclinical.sql-postgresql | sql-postgresql | src/plugins/builtin/sqlPostgresqlPlugin.ts |
com.sureclinical.sql-duckdb | sql-duckdb | src/plugins/builtin/sqlDuckDbPlugin.ts |
DDL Generation Algorithm
Both SQL plugins share the same table-grouping algorithm:
- Filter rows to
selected === true - Rows with
targetType === 'TABLE'(ornodeType === 'owl:Class') begin a newCREATE TABLEblock - Subsequent non-TABLE rows become columns of the most recent table
- Each table auto-receives an
iriprimary key column derived from@id - Identifiers are sanitized:
camelCase → snake_case, special chars →_, lowercased
Type maps:
| Source | PostgreSQL | DuckDB |
|---|---|---|
| TEXT / STRING | TEXT | VARCHAR |
| INTEGER / INT | INTEGER | INTEGER |
| FLOAT / DOUBLE / NUMBER | DOUBLE PRECISION | DOUBLE |
| BOOLEAN | BOOLEAN | BOOLEAN |
| DATE | DATE | DATE |
| DATETIME / TIMESTAMP | TIMESTAMP WITH TIME ZONE | TIMESTAMP |
| JSON / JSONB | JSONB | JSON |
| UUID | UUID | VARCHAR(36) |
| URI / IRI | TEXT | VARCHAR |
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
- Add the item to
overflowMenuItemsref inTopToolbar.vue - If it opens a dialog, add a
ref<boolean>and mount the dialog component in the template - If the icon is FontAwesome, register it in
src/fontawesome.ts
Session Modes (src/store/sessionMode.ts)
| Mode | Description |
|---|---|
SchemaEditor | JSON-LD / JSON Schema authoring |
DataEditor | Data document editing |
Settings | Application settings |
Known Extension Points
| Extension | How |
|---|---|
| New output format | Implement SchemaBuilderPlugin with pluginType: 'translator' |
| New panel | Implement SchemaBuilderPlugin with pluginType: 'panel' (P3: auto-registered into panel registry) |
| New import source | Implement SchemaBuilderPlugin with pluginType: 'importer' |
| New validator | Implement SchemaBuilderPlugin with pluginType: 'validator' |
| New toolbar menu item | Edit overflowMenuItems in TopToolbar.vue |
| New data format | Register in src/dataformats/defaultFormats.ts |