> For the complete documentation index, see [llms.txt](https://t1t.gitbook.io/t1c-js-guide-v3/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://t1t.gitbook.io/t1c-js-guide-v3/file/custom/vdds.md).

# VDDS

## 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.&#x20;

The \`file-exchange\` module exposes an API for abstract file management. For more information see: [File Exchange](/t1c-js-guide-v3/file/file-exchange.md#introduction). 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:

<figure><img src="/files/xNYRERmdSbH0donnR9tG" alt=""><figcaption><p>Overview of VDDS-media</p></figcaption></figure>

### Security Considerations

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

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).&#x20;

```rust
/// 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:

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

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

```rust
#[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
    #[serde(rename = "argFilePathQuotesDisable")]
    pub arg_file_path_quotes_disable: Option<bool>,
}
```

### Prerequisites

The execution endpoint assumes a proper file management handled by the requesting web application.&#x20;

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

### Interface (T1C-SDK-js)

```typescript
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>
    argFilePathQuotesDisable?: boolean,
}

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

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

### Remarks

* the ExecDescriptor contains a field 'argFilePathQuatesDisable', that field basically resolves the file path parameter to a list of strings (split on whitespaces) to simulate passing the argument on a shell, without the double quotes ' " '. Shell execution wraps a file path argument in a C-like string, but some bat or exe files who are not complying to this, can thread the whitespaces in a path as a concatentation of arguments.&#x20;

### Get the VDDS module object

Initialize a Trust1Connector client:

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

Get the module using the client

```javascript
var vdds = client.vdds();
```

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

#### Import

```typescript
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

```typescript
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

```typescript
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:

```json
# 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) \[<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\*.

```sh
# 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):

````sh
```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:

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

#### Example 1 - VDDS Import

```sh
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

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

#### Example 3 - VDDS Viewer

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://t1t.gitbook.io/t1c-js-guide-v3/file/custom/vdds.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
