VDDS

Verband Deutscher Dental Software (VDDS-media 1.4)

Introduction

VDDS-media 1.4 defines an interface for the exchange of multimedia data between practice management software and the X-ray/camera software

The Trust1Connector has a custom `vdds` module which can be used in combination with the `file-exchange` module.

The `file-exchange` module exposes an API for abstract file management. For more information see: File Exchange. In summary, the `file-exchange` module allows you to define `scoped` abstractions for folders and files, in a web context (based on the origin of the requesting web applciation).

The additional functionality exposed by the `vdds` module, is mainly:

  • open the Image viewer with a pre-defined image ID

  • import/export data to/from an IPS (Image Processing System)

The typical client application is a web PMS (Practice Management System).

Integration

The following communication diagram depicts the information exchange defined in the specification:

Overview of VDDS-media

Security Considerations

The executable names are hard-coded and statically extended to the abstract file descriptor on the T1C-API.

The HTTP/REST API is used by the T1C-SDK-js (javascript client).

A file descriptor is defined in terms of the entity and entity type, the absolute path can be used to build a relative folder path starting from the folder mapping (linked to the entity type).

/// Filepath abstraction for VDDS
#[derive(Debug, Deserialize, Clone)]
pub struct FileDescriptor {
    pub entity: String,
    #[serde(rename = "type")]
    pub entity_type: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(rename = "relPath")]
    pub rel_path: Option<Vec<String>>,
    #[serde(rename = "fileName")]
    pub file_name: String,
}

The supported commands available are denoted in the following enumeration:

#[derive(Debug, Clone, Deserialize)]
pub enum VddsCmd {
    import,
    export,
    view,
}

The `vdds` execution endpoint has a single, multi-purpose struct:

#[derive(Debug, Serialize, Deserialize, Clone, Validate)]
pub struct VddsExecutable {
    #[validate(length(min = 1, max = 256))]
    #[serde(rename = "entity")]
    pub entity: String,
    #[validate(length(min = 1, max = 256))]
    #[serde(rename = "type")]
    pub entity_type: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(rename = "relPath")]
    pub rel_path: Option<Vec<String>>,
    #[serde(rename = "cmd")]
    pub cmd: String, //import, export, view
}

Prerequisites

The execution endpoint assumes a proper file management handled by the requesting web application.

The file-exchange entity, entity-type and thus type-mapping MUST exist prior to the command execution request.

Interface (T1C-SDK-js)

export interface AbstractVdds {
    import(body: VddsImportRequest): Promise<VddsResponse>;
    export(body: VddsExportRequest): Promise<VddsResponse>;
    view(body: VddsViewRequest): Promise<VddsResponse>;
}

// Models
export interface VddsImportRequest {
    exec: ExecDescriptor,
    file: FileDescriptor 
}

export interface VddsExportRequest {
    exec: ExecDescriptor,
    file: FileDescriptor 
}

export interface VddsViewRequest {
    exec: ExecDescriptor,
    args: Array<String> 
}

export interface ExecDescriptor {
    entity: String,
    type: String,
    relPath?: Array<String>
}

export interface FileDescriptor {
    entity: String,
    type: String,
    relPath?: Array<String>
    fileName: String
}

export class VddsResponse extends T1CResponse {
    constructor(public success: boolean){
        super(success, null);
    }
} 

Get the VDDS module object

Initialize a Trust1Connector client:

T1CSdk.T1CClient.initialize(config).then(res => {
    client = res;
}, err => {
    console.error(error)
});

Get the module using the client

var vdds = client.vdds();

Now you can use the vdds client to call its functionality.

Import

let body = {
    exec: {
        entity: "Crossuite",
        type: "vdds",
        relPath: ["build"],
    },
    file: {
        entity: "Crossuite",
        type: "vdds",
        relPath: ["files"],
        fileName: "somefile.txt"
    }
};

vdds.import(body).then(res => {
// handle response
}).catch(error => {
// handle error
});

Export

let body = {
    exec: {
        entity: "Crossuite",
        type: "vdds",
        relPath: ["build"],
    },
    file: {
        entity: "Crossuite",
        type: "vdds",
        relPath: ["files"],
        fileName: "somefile.txt"
    }
};

vdds.export(body).then(res => {
// handle response
}).catch(error => {
// handle error
});

View

let body = {
    exec: {
        entity: "Crossuite",
        type: "vdds",
        relPath: ["build"],
    },
    args: ["rnd_image_id"]
};

vdds.view(body).then(res => {
// handle response
}).catch(error => {
// handle error
});

Error Handling

The following responses are returned when an exception is thrown:

# InvalidInput
{
    "success": false,
    "code": 106997,
    "description": "Invalid Input"
}

# ConfigurationError
{
    "success": false,
    "code": 505126,
    "description": "Configuration Error"
}

# FileNotFoundException
{
    "success": false,
    "code": 505126,
    "description": "File not found"
}

InvalidInput

  • wrong or missing arguments in request body defined by (entity, entity-type, file-name or args)

  • wrong or missing executable path reference defined by (entity, entity-type, command)

ConfigurationError

  • file-exchange has not been initialized prior to the documented use case

FileNotFoundException

  • referencing file is not found on the local device file system, this is typically the case when a wrong entity-type of relative folder has been provided in the request

Testing

To test the VDDS module execution, you can use a bunch of stubbed executables which are available on github [https://github.com/Trust1Team/vdds-test-exec].

This is nothing fancy, just a cpp repo, which generates 3 executables and dumps the arguments on std::out.

The testing track described here follow the T1C-API, and does NOT use the T1C-SDK-js !

If you are using the javascript SDK, you can skip or continue reading to have more insights on how it works *under the hood*.

# checkout
git clone https://github.com/Trust1Team/vdds-test-exec

# build
mkdir build
cd build
cmake ..
cmake --build .

Use an REST client of curl to create an entity and entity type -> this will pop-up a file-chooser, where you need to select the folder (where you want the entity-type to link to):

```powershell
curl --location 'https://t1c.t1t.io:55000/v3/modules/fileexchange/apps/file/create-type' \
--header 'X-CSRF-Token: t1c-js' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{
	"entity": "MyCompany",
	"type": "vdds",
	"modal": true
}'
```

Response example:

{
    "success": true,
    "data": {
        "entity": "MyComp",
        "type": "vdds",
        "absPath": "/Users/michallispashidis/_git/vdds-test-exec",
        "accessMode": "d",
        "total": 0,
        "appId": "unknown"
    }
}

Example 1 - VDDS Import

curl --location 'https://t1c.t1t.io:55000/v3/modules/vdds/cmd/exec' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{
    "exec": {
        "entity": "MyComp",
        "type": "vdds",
        "relPath": ["build"],
        "cmd": "import"
    },
    "file": {
        "entity": "Crossuite",
        "type": "vdds",
        "relPath": ["files"],
        "fileName": "somefile.txt"
    }
}
'

Example 2 - VDDS Export

{
    "exec": {
        "entity": "MyComp",
        "type": "vdds",
        "relPath": ["build"],
        "cmd": "export"
    },
    "file": {
        "entity": "Crossuite",
        "type": "vdds",
        "relPath": ["files"],
        "fileName": "somefile.txt"
    }
}

Example 3 - VDDS Viewer

{
    "exec": {
        "entity": "Crossuite",
        "type": "vdds",
        "relPath": ["build"],
        "cmd": "view"
    },
    "args": ["rnd_image_id"]
}

Last updated

Was this helpful?