Design Hub developer guide - storage plugins

    Design Hub storage plugins automatically save compounds to external databases. These plugins are NodeJS modules, stored in a folder set by Design Hub's configuration file.

    Prerequisites

    • an instance of Design Hub available for development purposes, i.e.: the ability to stop and start it, to try different configuration options
    • familiarity with JavaScript, NodeJS and its module system

    {info} NodeJS introduction material: https://www.youtube.com/watch?v=_l96hPlqzcI (78m), https://www.youtube.com/watch?v=hKQr2DGJjUQ (19m), https://www.youtube.com/watch?v=cJVXP1bU68Y (48m) NodeJS module description: http://nodejs.org/api/modules.html

    Storage plugins

    This plugin type is intended to save important information from a design set, to a shared idea database.

    Life-cycle

    Design Hub scans the services directory to find all storage plugins and loads them on start.

    storage plugin life cycle

    Specification

    Export plugins are NodeJS modules, denoted by their filename: *.storage.js and the location in the services directory as configured during installation.

    An export plugin exports the following required properties:

    Name Type Description
    name string Unique identifier of the plugin, used by Design Hub for identification and internal communication. If multiple plugins use the same identifier, the last one to be loaded overrides the others.
    initialize async function An initialization function that the plugin may use to signal to Design Hub that it needs to refresh its database contents. When signaled, Design Hub will start calling insert with batches of records.

    Arguments: none
    this includes domain

    Return value:
    Promise<true> if the plugin needs access to the entire Design Hub contents again.
    Promise<false> if the plugin has up to date information.

    Required: yes
    insert async function Called when chemists create a compound with a batch of created compounds.

    Arguments:
    compound[] list of data structures containing chemical structure and metadata. See specification below.
    this includes domain

    Required: yes
    update async function Called when chemists change the metadata of a compound with a batch of changed compounds. The function should have a void return type.

    Arguments:
    compound[] list of data structures containing chemical structure and metadata. See specification below.
    this includes domain

    Required: yes
    domains array of strings List of domains where this plugin may be used. Use * to allow any domain. To query the configured domains, send a GET request to /domains or open /domains in your browser.
    onConfigurationChanged function A callback function that Design Hub calls during initialization and whenever an administrator updates the Secrets of the system.

    Arguments:
    config (Object) An object with secrets attribute containing the key-value pairs of secrets from the Admin interface

    Compound record specification

    name type (max length) description example
    project_key string (200) key of the project where this record belongs to 1
    project_label string (200) label of the project where this record belongs to CXN-1
    hypothesis_title string (500) label of the hypothesis attached to this record improve selectivity with ARG173
    hypothesis_content_id string (60) internal identifier of the hypothesis 389dff34922bb2e689df6b93c191cf9e4ba67b64
    designset_title string (500) label of the design set attached to this record route #1
    designset_content_id string (60) internal identifier of the design set e346597dbd0951bc44cf90b04fe7455adcf35fc0
    compound_id string (500) ID of the compound.
    Deprecated
    VXN00001
    compound_virtual_id string (500) Virtual ID of the compound VXN00001
    compound_substance_id string (500) Substance ID of the compound once obtained from registry. CXN001
    compound_content_id string (60) internal identifier of the compound d94b689b6296a3175dabe0b0ff75675e1ae847c5
    compound_structure string (16M) chemical structure of the compound in Marvin Document format <cml>...</cml>
    compound_author string (500) user name of the compound author as obtained from the identity provider user@pharmatx.com
    compound_create_date Date timestamp of the compound creation 2019-09-30T09:10:03.441Z
    compound_modify_date Date timestamp of the last modification of the compound 2019-09-30T09:10:03.441Z
    compound_deleted boolean flag of compound deletion true
    compound_status string (100) human friendly label of the compound's status Ready for review
    compound_priority string (100) human friendly label of the compound's priority Medium
    compound_assignee string (500) user name of the current assignee of the compound, as obtained from the identity provider user@pharmatx.com
    compound_fields Object JSON key-value pairs of custom compound fields. Optional. {"cst": "Isomer 1"}
    compound_source_system string (255) label of the source of the compound. If configured by an import plugin, then the specified value, otherwise Design Hub AI
    compound_source_id string (255) ID of the compound in the source system if imported, otherwise its value equals compound_virtual_id VXN0001

    Plugin skeleton

    skeleton.storage.js

    //@ts-check
    "use strict";
    
    const dhutils = require("@chemaxon/dh-utils");
    
    /**
     * @typedef Compound
     * @prop {string} project_key
     * @prop {string} hypothesis_title
     * @prop {string} hypothesis_content_id
     * @prop {string} designset_title
     * @prop {string} designset_content_id
     * @prop {string} compound_virtual_id
     * @prop {string} compound_substance_id
     * @prop {string} compound_content_id
     * @prop {string} compound_structure
     * @prop {string} compound_author
     * @prop {Date} compound_create_date
     * @prop {Date} compound_modify_date
     * @prop {boolean} compound_deleted
     * @prop {string} compound_status
     * @prop {string} compound_priority
     * @prop {string} compound_assignee
     * @prop {Object} [compound_fields]
     * @prop {string} compound_source_system
     * @prop {string} compound_source_id
     * 
     * @typedef ConfigurationValues
     * @prop {{[key: string]: string}} secrets
     */
    
    /**
     * determine if the database needs full resynchronization from Design Hub. Warning: this only runs on start and is extremely resource intensive
     * @returns {Promise<boolean>}
     */
    async function initialize() {
      return false;
    }
    
    /**
     * Update values in database
     * @param {Compound[]} compounds
     * @returns {Promise<void>}
     */
    async function updateCompounds(compounds) {
      for (const record of compounds) {
        //update compound
      }
    }
    
    /**
     * Insert values into database
     * @param {Compound[]} compounds
     */
    async function insertCompounds(compounds) {
      for (const record of compounds) {
        //insert compound
      }
    }
    
    /**
     * Store and use values provided by Admin interface's Secret manager
     * @param {ConfigurationValues} config
     */
    function onConfigurationChanged(config) {
      console.log("plugin-name configuration", config.secrets);
    }
    
    //export the necessary plugin properties
    module.exports = {
      name: "skeleton-db",
      domains: ["*"],
      insert: insertCompounds,
      update: updateCompounds,
      initialize: initialize,
      onConfigurationChanged: onConfigurationChanged
    };