diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fbe963e2..0814d9518 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added +### Changed + +### Deprecated + +### Fixed + +## [FDC3 Standard 2.1](https://github.com/finos/FDC3/compare/v2.0..v2.1) - 2023-09-13 + +### Added + * Added `CreateInteraction` intent. To be used when a user wants to record an interaction into a system. New context `Interaction` also introduced. An interaction might be a call, IM, email, a meeting (physical or virtual) or the preparation of some specialist data. ([#747](https://github.com/finos/FDC3/pull/747)) * Added `TransactionResult` context. A context type representing the result of a transaction initiated via FDC3. Its purpose is to provide a status and message (where needed) for the transaction and MAY wrap a returned context object. ([#761] (https://github.com/finos/FDC3/pull/761)) * Added a `MalformedContext` error to the `OpenError`, `ChannelError` and `ResolveError` enumerations, to be used when `broadcast`, `open`, `findIntents`, `raiseIntents`, and other related functions are passed an invalid context Object. ([#972](https://github.com/finos/FDC3/pull/972)) diff --git a/docs/agent-bridging/ref/PrivateChannel.broadcast.md b/docs/agent-bridging/ref/PrivateChannel.broadcast.md index 51695afcf..19b2b849e 100644 --- a/docs/agent-bridging/ref/PrivateChannel.broadcast.md +++ b/docs/agent-bridging/ref/PrivateChannel.broadcast.md @@ -69,7 +69,7 @@ Hence, the broadcast message should be repeated once for each subscriber, and mo { "type": "PrivateChannel.broadcast", //modified type for PrivateChannel broadcasts "payload": { - "channelId": "private-channel-ABC123", + "channel": "private-channel-ABC123", "context": { /*contextObj*/} }, "meta": { diff --git a/docs/fdc3-intro.md b/docs/fdc3-intro.md index 5a321b102..061d8059f 100644 --- a/docs/fdc3-intro.md +++ b/docs/fdc3-intro.md @@ -1,6 +1,6 @@ --- id: fdc3-intro -title: Welcome to FDC3 2.1 (pre-draft) +title: Welcome to FDC3 2.2 (pre-draft) sidebar_label: Introduction --- diff --git a/docs/fdc3-standard.md b/docs/fdc3-standard.md index 39cf8e2a6..4042abf09 100644 --- a/docs/fdc3-standard.md +++ b/docs/fdc3-standard.md @@ -1,6 +1,6 @@ --- id: fdc3-standard -title: FDC3 2.1 (pre-draft) +title: FDC3 2.2 (pre-draft) sidebar_label: Abstract --- diff --git a/package.json b/package.json index d6c1e88eb..c2f35ca14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@finos/fdc3", - "version": "2.0.3", + "version": "2.1.0-beta.1", "author": "Fintech Open Source Foundation (FINOS)", "homepage": "https://fdc3.finos.org", "repository": { diff --git a/schemas/bridging/privateChannelBroadcastAgentRequest.schema.json b/schemas/bridging/privateChannelBroadcastAgentRequest.schema.json index 16c4ca25e..e5f070306 100644 --- a/schemas/bridging/privateChannelBroadcastAgentRequest.schema.json +++ b/schemas/bridging/privateChannelBroadcastAgentRequest.schema.json @@ -25,7 +25,7 @@ "title": "PrivateChannelBroadcast Request Payload", "type": "object", "properties": { - "channelId": { + "channel": { "type": "string", "title": "Channel Id", "description": "The Id of the PrivateChannel that the broadcast was sent on" diff --git a/website/README.md b/website/README.md new file mode 100644 index 000000000..c8526afce --- /dev/null +++ b/website/README.md @@ -0,0 +1,62 @@ +# FDC3 website readme + +## Releasing new versions of the Standard + +To create a new version of the website, a number of NPM scripts need to be run that will create the version and update certain content within it (as automatically as possible). There are then a number of additional manual steps to run. + +1. Enter the website directory and make sure the site has been built: + + ```bash + cd website + npm run build + ``` + +2. Then run the versioning script - this should work cross-platform, but can be brittle... + - edit *website/package.json* and replace the version number in the `version` script to the version number you wish to create: + `version": "cross-env-shell VERSION=2.1 ...` + - Run it: + + ```bash + npm run version + ``` + + - Check the reported version number is as expected and that the scripts ran without errors. + +3. Check that the version script has done what it needs to: + - The new website version should exist in _website/versioned_docs_ + - Links to schema files should have been updated to the versioned links, e.g. check *website/versioned_docs/version-2.1/context/ref/Context.md* has a link like (where '2.1' would be 'next' in the pre-draft) + - The overview docs (often called spec.md) should have had '(next)' in their titles replaced with the version, e.g. '(2.1)', e.g. check *website/versioned_docs/version-2.1/api/spec.md* + - A new set of schemas should exist in *website/static/schemas* + - Check all schema files/folders got copied, including *api/*, *context/*, *bridging/*, *bridgingAsyncAPI/* and the *appd* files. + - Check that their `$id` fields were updated to match their new URLs, e.g. *website/static/schemas/2.1/context/context.schema.json* should have an `$id` that looks like: `"$id": "https://fdc3.finos.org/schemas/2.1/context/context.schema.json"` (where '2.1' would be 'next' in the pre-draft) + - Check that the appD schema's `version` field has been updated, i.e. *website/static/schemas/2.1/appd.schema.json* should have `"version": "2.1",` (where '2.1' would be 'next' in the pre-draft) + +4. Make a number of additional manual changes: + - Edit the titles of *website/versioned_docs/version-2.1/fdc3-intro.md* and *website/versioned_docs/version-2.1/fdc3-standard.md* to remove '(pre-draft') + - Edit the titles of *docs/fdc3-intro.md* and *docs/fdc3-standard.md* to use the next planned version number + - Edit the last Standard version's abstract to update its status and dates, e.g. *website/versioned_docs/version-2.0/fdc3-standard.md* + - Edit the new Standard version's abstract to update its status and dates, e.g. *website/versioned_docs/version-2.1/fdc3-standard.md* + - Edit the `Version` element of `themeConfig.navbar.items` in *website/docusaurus.config.js* to include the new version as the first element. + +5. Edit CHANGELOG.md to mark the unreleased changes as teh new version and create a new unreleased section for the next version. + - Note that the title of the release section usually includes a compare link for the previous version. These are based on tags - the tag needed will not exist yet, but is created in a later step. It should be fine to set it to what the tag name will be. + +6. If creating a new NPM module version at the same time, then + - Return to the root of the repository (i.e. parent dir of the *website* dir) and edit *package.json*, + - Set the `version` filed to the new standard version - but consider appending a beta label, e.g.: `"version": "2.1.0-beta.1",` + - The new NPM module will be built and submitted to NPM via a Github action automatically when this PR is merged. + +7. Test you changes locally by running the site: + + ```bash + cd website + npm run build + npm run start + ``` + +8. Create a PR and send out details for other maintainers to review and test. + +9. Merge the PR - website and NPM module will be deployed automatically. + +10. Goto and create a new release and tag for the new version. + - Copy the change log into the release description. \ No newline at end of file diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 5c9c65414..51e4d4553 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -91,10 +91,14 @@ module.exports={ "position": "right", "items": [ { - "label": "2.0", + "label": "2.1", "to": "/docs/fdc3-intro", "activeBaseRegex": "docs/(?!1.0|1.1|1.2|2.0|next)" }, + { + "label": "2.0", + "to": "/docs/2.0/fdc3-intro", + }, { "label": "1.2", "to": "/docs/1.2/fdc3-intro" diff --git a/website/package.json b/website/package.json index f2f50cacd..42c839605 100644 --- a/website/package.json +++ b/website/package.json @@ -9,32 +9,30 @@ "build-workbench": "cd ../toolbox/fdc3-workbench && npm install && npm run build", "copy-workbench": "del-cli static/toolbox/fdc3-workbench && npm run build-workbench && cpy \"../toolbox/fdc3-workbench/build/**\" static/toolbox/fdc3-workbench", "copy-explained": "del-cli static/toolbox/fdc3-explained && cpy \"../toolbox/fdc3-explained\" ../website/static/toolbox/", - "version": "npm run version:docs && npm run version:schemas && npm run version:appd", - "version:docs": "docusaurus-version ${VERSION}", - "version:schemas": "cpy static/schemas/next/*.schema.json static/schemas/${VERSION} && replace-in-files --string=/schemas/next --replacement=/schemas/${VERSION} static/schemas/${VERSION}/*.schema.json", - "version:appd": "cpy static/schemas/next/appd.schema.json static/schemas/${VERSION} && cpy pages/schemas/next/app-directory.html pages/schemas/${VERSION}", - "version:delete": "docusaurus-delete-version ${VERSION}", - "postversion:docs": "replace-in-files --string=/schemas/next --replacement=/schemas/${VERSION} versioned_docs/version-${VERSION}/'**/*.md'", - "postversion:schemas": "replace-in-files --string=/schemas/next --replacement=/schemas/${VERSION} static/schemas/${VERSION}/*.schema.json", - "postversion:appd": "replace-in-files --string='\"version\": \"next\"' --replacement='\"version\": \"${VERSION}\"' static/schemas/${VERSION}/appd.schema.json", - "postversion:delete": "rimraf static/schemas/${VERSION} && rimraf pages/schemas/${VERSION}", + "version": "cross-env-shell VERSION=2.1 \"echo \\\"Creating version: $VERSION...\\\" && npm run version:docs && npm run version:docs-schema && npm run version:docs-replace && npm run version:schemas && npm run version:schemas-replace && npm run version:appd-replace", + "version:docs": "cross-env-shell \"docusaurus docs:version $VERSION\"", + "version:docs-schema": "cross-env-shell replace-in-files --string=/schemas/next --replacement=/schemas/$VERSION versioned_docs/version-$VERSION/**/*.md", + "version:docs-replace": "cross-env-shell replace-in-files --string=(next) --replacement=($VERSION) versioned_docs/version-$VERSION/*/*.md", + "version:schemas": "cross-env-shell cpy static/schemas/next/** static/schemas/$VERSION", + "version:schemas-replace": "cross-env-shell replace-in-files --string=/schemas/next --replacement=/schemas/$VERSION static/schemas/$VERSION/*/*.schema.json", + "version:appd-replace": "cross-env-shell replace-in-files --string=\"\"next\"\" --replacement=\"\"$VERSION\"\" static/schemas/$VERSION/appd.schema.json", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "docusaurus": "docusaurus" }, "devDependencies": { - "cpy-cli": "4.2.0", - "del-cli": "5.0.0", - "docusaurus-delete-version": "0.1.1", - "replace-in-files-cli": "2.0.0", - "replace-json-property": "1.8.0", - "rimraf": "5.0.0", "@docusaurus/core": "~2.4.1", "@docusaurus/preset-classic": "~2.4.1", "@docusaurus/theme-mermaid": "~2.4.1", "clsx": "^1.2.1", + "cpy-cli": "4.2.0", + "cross-env": "^7.0.3", + "del-cli": "5.0.0", "react": "^17.0.2", - "react-dom": "^17.0.2" + "react-dom": "^17.0.2", + "replace-in-files-cli": "2.0.0", + "replace-json-property": "1.8.0", + "rimraf": "5.0.0" }, "resolutions": { "got": "^11.8.5", diff --git a/website/static/schemas/2.1/api/README.md b/website/static/schemas/2.1/api/README.md new file mode 100644 index 000000000..c782f2e7a --- /dev/null +++ b/website/static/schemas/2.1/api/README.md @@ -0,0 +1,10 @@ +# Intro + +Quicktype, the chosen generation tool currently has some limitations that prevent fully automatic schema generation from the existing TS types. For example it can not handle interfaces that contain methods in their definition. It also fails to generate schemas even if a type contains unused references to other types or interfaces that contain async functions (Promise return types). Therefore, in order to generate the `api\schemas\api.schema.json` some manual intervention was needed. + +Once these limitations are not an issue the `api\schemas\t2sQuicktypeUtil.js` script should be moved to the root level of the project and a new npm script `"api-schema-gen": "node t2sQuicktypeUtil.js src/api schemas/api/api.schema.json"` should be added. + +`api\schemas\api.schema.json` - partially auto-generated schema from the existing `src\api` types. +`api\schemas\baseImplementationMetadata.schema.json` - Used by bridging types that leave out the metadata of the calling application as it does not apply to bridging. +`api\schemas\intentResolution.schema.json` - At the moment it is not possible to auto-generate this due to limitations in the generation tool (quicktype) +`api\schemas\t2sQuicktypeUtil.js` - Script used to run the generation of the schema from the types. Should be moved to the root level of the repo once fully-automated generation can be achieved. diff --git a/website/static/schemas/2.1/api/api.schema.json b/website/static/schemas/2.1/api/api.schema.json new file mode 100644 index 000000000..04ab19a4c --- /dev/null +++ b/website/static/schemas/2.1/api/api.schema.json @@ -0,0 +1,450 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/api/api.schema.json", + "definitions": { + "AppIdentifier": { + "description": "Identifies an application, or instance of an application, and is used to target FDC3 API calls, such as `fdc3.open` or `fdc3.raiseIntent` at specific applications or application instances.\n\nWill always include at least an `appId` field, which uniquely identifies a specific app.\n\nIf the `instanceId` field is set then the `AppMetadata` object represents a specific instance of the application that may be addressed using that Id.", + "title": "AppIdentifier", + "type": "object", + "properties": { + "appId": { + "description": "The unique application identifier located within a specific application directory instance. An example of an appId might be 'app@sub.root'", + "type": "string", + "title": "appId" + }, + "instanceId": { + "description": "An optional instance identifier, indicating that this object represents a specific instance of the application described.", + "type": "string", + "title": "instanceId" + }, + "desktopAgent": { + "description": "The Desktop Agent that the app is available on. Used in Desktop Agent Bridging to identify the Desktop Agent to target.", + "type": "string", + "title": "desktopAgent" + } + }, + "unevaluatedProperties": false, + "required": [ + "appId" + ] + }, + "Icon": { + "description": "SPDX-License-Identifier: Apache-2.0\nCopyright FINOS FDC3 contributors - see NOTICE file", + "title": "Icon", + "type": "object", + "properties": { + "src": { + "description": "The icon url", + "type": "string", + "title": "src" + }, + "size": { + "description": "The icon dimension, formatted as `x`.", + "type": "string", + "title": "size" + }, + "type": { + "description": "Icon media type. If not present the Desktop Agent may use the src file extension.", + "type": "string", + "title": "type" + } + }, + "additionalProperties": false, + "required": [ + "src" + ] + }, + "Image": { + "description": "SPDX-License-Identifier: Apache-2.0\nCopyright FINOS FDC3 contributors - see NOTICE file", + "title": "Image", + "type": "object", + "properties": { + "src": { + "description": "The image url.", + "type": "string", + "title": "src" + }, + "size": { + "description": "The image dimension, formatted as `x`.", + "type": "string", + "title": "size" + }, + "type": { + "description": "Image media type. If not present the Desktop Agent may use the src file extension.", + "type": "string", + "title": "type" + }, + "label": { + "description": "Caption for the image.", + "type": "string", + "title": "label" + } + }, + "additionalProperties": false, + "required": [ + "src" + ] + }, + "AppMetadata": { + "description": "Extends an `AppIdentifier`, describing an application or instance of an application, with additional descriptive metadata that is usually provided by an FDC3 App Directory that the desktop agent connects to.\n\nThe additional information from an app directory can aid in rendering UI elements, such as a launcher menu or resolver UI. This includes a title, description, tooltip and icon and screenshot URLs.\n\nNote that as `AppMetadata` instances are also `AppIdentifiers` they may be passed to the `app` argument of `fdc3.open`, `fdc3.raiseIntent` etc.", + "title": "AppMetadata", + "type": "object", + "properties": { + "name": { + "description": "The 'friendly' app name. \nThis field was used with the `open` and `raiseIntent` calls in FDC3 <2.0, which now require an `AppIdentifier` wth `appId` set. \nNote that for display purposes the `title` field should be used, if set, in preference to this field.", + "type": "string", + "title": "name" + }, + "version": { + "description": "The Version of the application.", + "type": "string", + "title": "version" + }, + "instanceMetadata": { + "description": "An optional set of, implementation specific, metadata fields that can be used to disambiguate instances, such as a window title or screen position. Must only be set if `instanceId` is set.", + "type": "object", + "additionalProperties": {}, + "title": "instanceMetadata" + }, + "title": { + "description": "A more user-friendly application title that can be used to render UI elements", + "type": "string", + "title": "title" + }, + "tooltip": { + "description": "A tooltip for the application that can be used to render UI elements", + "type": "string", + "title": "tooltip" + }, + "description": { + "description": "A longer, multi-paragraph description for the application that could include markup", + "type": "string", + "title": "description" + }, + "icons": { + "description": "A list of icon URLs for the application that can be used to render UI elements", + "type": "array", + "items": { + "$ref": "#/definitions/Icon" + }, + "title": "icons" + }, + "screenshots": { + "description": "Images representing the app in common usage scenarios that can be used to render UI elements", + "type": "array", + "items": { + "$ref": "#/definitions/Image" + }, + "title": "screenshots" + }, + "resultType": { + "description": "The type of output returned for any intent specified during resolution. May express a particular context type (e.g. \"fdc3.instrument\"), channel (e.g. \"channel\") or a channel that will receive a specified type (e.g. \"channel\").", + "type": [ + "null", + "string" + ], + "title": "resultType" + }, + "appId": { + "description": "The unique application identifier located within a specific application directory instance. An example of an appId might be 'app@sub.root'", + "type": "string", + "title": "appId" + }, + "instanceId": { + "description": "An optional instance identifier, indicating that this object represents a specific instance of the application described.", + "type": "string", + "title": "instanceId" + }, + "desktopAgent": { + "description": "The Desktop Agent that the app is available on. Used in Desktop Agent Bridging to identify the Desktop Agent to target.", + "type": "string", + "title": "desktopAgent" + } + }, + "additionalProperties": false, + "required": [ + "appId" + ] + }, + "IntentMetadata": { + "description": "Intent descriptor", + "title": "IntentMetadata", + "type": "object", + "properties": { + "name": { + "description": "The unique name of the intent that can be invoked by the raiseIntent call", + "type": "string", + "title": "name" + }, + "displayName": { + "description": "Display name for the intent.", + "type": "string", + "title": "displayName" + } + }, + "additionalProperties": false, + "required": [ + "displayName", + "name" + ] + }, + "AppIntent": { + "description": "An interface that relates an intent to apps", + "title": "AppIntent", + "type": "object", + "properties": { + "intent": { + "$ref": "#/definitions/IntentMetadata", + "description": "Details of the intent whose relationship to resolving applications is being described.", + "title": "intent" + }, + "apps": { + "description": "Details of applications that can resolve the intent.", + "type": "array", + "items": { + "$ref": "#/definitions/AppMetadata" + }, + "title": "apps" + } + }, + "additionalProperties": false, + "required": [ + "apps", + "intent" + ] + }, + "DisplayMetadata": { + "description": "A system channel will be global enough to have a presence across many apps. This gives us some hints\nto render them in a standard way. It is assumed it may have other properties too, but if it has these,\nthis is their meaning.", + "title": "DisplayMetadata", + "type": "object", + "properties": { + "name": { + "description": "A user-readable name for this channel, e.g: `\"Red\"`", + "type": "string", + "title": "name" + }, + "color": { + "description": "The color that should be associated within this channel when displaying this channel in a UI, e.g: `0xFF0000`.", + "type": "string", + "title": "color" + }, + "glyph": { + "description": "A URL of an image that can be used to display this channel", + "type": "string", + "title": "glyph" + } + }, + "additionalProperties": false + }, + "Channel": { + "description": "Represents a context channel that applications can use to send and receive\ncontext data.\n\nPlease note that There are differences in behavior when you interact with a\nUser channel via the `DesktopAgent` interface and the `Channel` interface.\nSpecifically, when 'joining' a User channel or adding a context listener\nwhen already joined to a channel via the `DesktopAgent` interface, existing\ncontext (matching the type of the context listener) on the channel is\nreceived by the context listener immediately. Whereas, when a context\nlistener is added via the Channel interface, context is not received\nautomatically, but may be retrieved manually via the `getCurrentContext()`\nfunction.", + "title": "Channel", + "type": "object", + "properties": { + "id": { + "description": "Constant that uniquely identifies this channel.", + "type": "string", + "title": "id" + }, + "type": { + "description": "Uniquely defines each channel type.\nCan be \"user\", \"app\" or \"private\".", + "enum": [ + "app", + "private", + "user" + ], + "type": "string", + "title": "type" + }, + "displayMetadata": { + "description": "Channels may be visualized and selectable by users. DisplayMetadata may be used to provide hints on how to see them.\nFor App channels, displayMetadata would typically not be present.", + "$ref": "#/definitions/DisplayMetadata", + "title": "displayMetadata" + } + }, + "additionalProperties": false, + "required": [ + "id", + "type" + ] + }, + "ContextMetadata": { + "description": "Metadata relating to a context or intent and context received through the\n`addContextListener` and `addIntentListener` functions.", + "title": "ContextMetadata", + "type": "object", + "properties": { + "source": { + "$ref": "#/definitions/AppIdentifier", + "description": "Identifier for the app instance that sent the context and/or intent.", + "title": "source" + } + }, + "additionalProperties": false, + "required": [ + "source" + ] + }, + "DesktopAgentIdentifier": { + "description": "Identifies a particular Desktop Agent in Desktop Agent Bridging scenarios\nwhere a request needs to be directed to a Desktop Agent rather than a specific app, or a\nresponse message is returned by the Desktop Agent (or more specifically its resolver)\nrather than a specific app. Used as a substitute for `AppIdentifier` in cases where no\napp details are available or are appropriate.", + "title": "DesktopAgentIdentifier", + "type": "object", + "properties": { + "desktopAgent": { + "description": "Used in Desktop Agent Bridging to attribute or target a message to a\nparticular Desktop Agent.", + "type": "string", + "title": "desktopAgent" + } + }, + "unevaluatedProperties": false, + "required": [ + "desktopAgent" + ] + }, + "OpenError": { + "description": "Constants representing the errors that can be encountered when calling the `open` method on the DesktopAgent object (`fdc3`).", + "title": "OpenError", + "enum": [ + "AppNotFound", + "AppTimeout", + "DesktopAgentNotFound", + "ErrorOnLaunch", + "MalformedContext", + "ResolverUnavailable" + ], + "type": "string" + }, + "ResolveError": { + "description": "Constants representing the errors that can be encountered when calling the `findIntent`, `findIntentsByContext`, `raiseIntent` or `raiseIntentForContext` methods on the DesktopAgent (`fdc3`).", + "title": "ResolveError", + "enum": [ + "DesktopAgentNotFound", + "IntentDeliveryFailed", + "MalformedContext", + "NoAppsFound", + "ResolverTimeout", + "ResolverUnavailable", + "TargetAppUnavailable", + "TargetInstanceUnavailable", + "UserCancelledResolution" + ], + "type": "string" + }, + "ResultError": { + "title": "ResultError", + "enum": [ + "IntentHandlerRejected", + "NoResultReturned" + ], + "type": "string" + }, + "ChannelError": { + "title": "ChannelError", + "enum": [ + "AccessDenied", + "CreationFailed", + "MalformedContext", + "NoChannelFound" + ], + "type": "string" + }, + "BridgingError": { + "title": "BridgingError", + "enum": [ + "AgentDisconnected", + "NotConnectedToBridge", + "ResponseToBridgeTimedOut", + "MalformedMessage" + ], + "type": "string" + }, + "ImplementationMetadata": { + "description": "Metadata relating to the FDC3 Desktop Agent implementation and its provider.", + "title": "ImplementationMetadata", + "type": "object", + "properties": { + "fdc3Version": { + "description": "The version number of the FDC3 specification that the implementation provides.\nThe string must be a numeric semver version, e.g. 1.2 or 1.2.1.", + "type": "string", + "title": "fdc3Version" + }, + "provider": { + "description": "The name of the provider of the Desktop Agent implementation (e.g. Finsemble, Glue42, OpenFin etc.).", + "type": "string", + "title": "provider" + }, + "providerVersion": { + "description": "The version of the provider of the Desktop Agent implementation (e.g. 5.3.0).", + "type": "string", + "title": "providerVersion" + }, + "optionalFeatures": { + "description": "Metadata indicating whether the Desktop Agent implements optional features of\nthe Desktop Agent API.", + "type": "object", + "properties": { + "OriginatingAppMetadata": { + "description": "Used to indicate whether the exposure of 'originating app metadata' for\ncontext and intent messages is supported by the Desktop Agent.", + "type": "boolean", + "title": "OriginatingAppMetadata" + }, + "UserChannelMembershipAPIs": { + "description": "Used to indicate whether the optional `fdc3.joinUserChannel`,\n`fdc3.getCurrentChannel` and `fdc3.leaveCurrentChannel` are implemented by\nthe Desktop Agent.", + "type": "boolean", + "title": "UserChannelMembershipAPIs" + }, + "DesktopAgentBridging": { + "description": "Used to indicate whether the experimental Desktop Agent Bridging\nfeature is implemented by the Desktop Agent.", + "type": "boolean", + "title": "DesktopAgentBridging" + } + }, + "additionalProperties": false, + "required": [ + "DesktopAgentBridging", + "OriginatingAppMetadata", + "UserChannelMembershipAPIs" + ], + "title": "optionalFeatures" + }, + "appMetadata": { + "$ref": "#/definitions/AppMetadata", + "description": "The calling application instance's own metadata, according to the Desktop Agent (MUST include at least the `appId` and `instanceId`).", + "title": "appMetadata" + } + }, + "additionalProperties": false, + "required": [ + "appMetadata", + "fdc3Version", + "optionalFeatures", + "provider" + ] + }, + "IntentResolution": { + "description": "IntentResolution provides a standard format for data returned upon resolving an intent.\n\n```javascript\n//resolve a \"Chain\" type intent\nlet resolution = await agent.raiseIntent(\"intentName\", context);\n\n//resolve a \"Client-Service\" type intent with a data response or a Channel\nlet resolution = await agent.raiseIntent(\"intentName\", context);\ntry {\n\t const result = await resolution.getResult();\n if (result && result.broadcast) {\n console.log(`${resolution.source} returned a channel with id ${result.id}`);\n } else if (result){\n console.log(`${resolution.source} returned data: ${JSON.stringify(result)}`);\n } else {\n console.error(`${resolution.source} didn't return data`\n }\n} catch(error) {\n console.error(`${resolution.source} returned an error: ${error}`);\n}\n\n// Use metadata about the resolving app instance to target a further intent\nawait agent.raiseIntent(\"intentName\", context, resolution.source);\n```", + "title": "IntentResolution", + "type": "object", + "properties": { + "source": { + "$ref": "#/definitions/AppIdentifier", + "description": "Identifier for the app instance that was selected (or started) to resolve the intent.\n`source.instanceId` MUST be set, indicating the specific app instance that\nreceived the intent.", + "title": "source" + }, + "intent": { + "description": "The intent that was raised. May be used to determine which intent the user\nchose in response to `fdc3.raiseIntentForContext()`.", + "type": "string", + "title": "intent" + }, + "version": { + "description": "The version number of the Intents schema being used.", + "type": "string", + "title": "version" + } + }, + "additionalProperties": false, + "required": [ + "intent", + "source" + ] + } + } +} diff --git a/website/static/schemas/2.1/api/baseImplementationMetadata.schema.json b/website/static/schemas/2.1/api/baseImplementationMetadata.schema.json new file mode 100644 index 000000000..3522c31bc --- /dev/null +++ b/website/static/schemas/2.1/api/baseImplementationMetadata.schema.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/api/baseImplementationMetadata.schema.json", + "title": "BaseImplementationMetadata", + "description": "Metadata relating to the FDC3 Desktop Agent implementation and its provider.", + "type": "object", + "properties": { + "fdc3Version": { + "description": "The version number of the FDC3 specification that the implementation provides.\nThe string must be a numeric semver version, e.g. 1.2 or 1.2.1.", + "type": "string", + "title": "fdc3Version" + }, + "provider": { + "description": "The name of the provider of the Desktop Agent implementation (e.g. Finsemble, Glue42, OpenFin etc.).", + "type": "string", + "title": "provider" + }, + "providerVersion": { + "description": "The version of the provider of the Desktop Agent implementation (e.g. 5.3.0).", + "type": "string", + "title": "providerVersion" + }, + "optionalFeatures": { + "description": "Metadata indicating whether the Desktop Agent implements optional features of\nthe Desktop Agent API.", + "type": "object", + "properties": { + "OriginatingAppMetadata": { + "description": "Used to indicate whether the exposure of 'originating app metadata' for\ncontext and intent messages is supported by the Desktop Agent.", + "type": "boolean", + "title": "OriginatingAppMetadata" + }, + "UserChannelMembershipAPIs": { + "description": "Used to indicate whether the optional `fdc3.joinUserChannel`,\n`fdc3.getCurrentChannel` and `fdc3.leaveCurrentChannel` are implemented by\nthe Desktop Agent.", + "type": "boolean", + "title": "UserChannelMembershipAPIs" + }, + "DesktopAgentBridging": { + "description": "Used to indicate whether the experimental Desktop Agent Bridging\nfeature is implemented by the Desktop Agent.", + "type": "boolean", + "title": "DesktopAgentBridging" + } + }, + "additionalProperties": false, + "required": [ + "DesktopAgentBridging", + "OriginatingAppMetadata", + "UserChannelMembershipAPIs" + ], + "title": "optionalFeatures" + } + }, + "additionalProperties": false, + "required": [ + "fdc3Version", + "optionalFeatures", + "provider" + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/api/t2sQuicktypeUtil.js b/website/static/schemas/2.1/api/t2sQuicktypeUtil.js new file mode 100644 index 000000000..54816c0e0 --- /dev/null +++ b/website/static/schemas/2.1/api/t2sQuicktypeUtil.js @@ -0,0 +1,69 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + * Copyright FINOS FDC3 contributors - see NOTICE file + */ + +/** Utility for preparing arguments to quicktype, which workaround a specific + * quicktype bug in command line argument handling (where a directory is used + * as input the source language argument is ignored which causes our schemas + * to be interpreted as JSON input, rather than JSONSchema). + * Bug issue: + * */ + +const path = require('path'); +const fs = require('fs'); +const exec = require('child_process').exec; + +const args = process.argv.slice(2); +const outputPath = args.pop(); +const inputs = args; + +console.log('Inputs: ' + inputs.join(' | ')); +console.log('Output path argument: ' + outputPath); + +let source = ''; + +let dirIndex = 0; + +const excludedTypes = [ + 'DesktopAgent.ts', + 'Listener.ts', + 'Methods.ts', + 'PrivateChannel.ts', + 'Types.ts', + 'RecommendedChannels.ts', +]; + +let sources = ''; + +while (dirIndex < inputs.length) { + if (inputs[dirIndex].endsWith('.ts')) { + sources += `--src ${path.join(inputs[dirIndex])} `; + } else { + fs.readdirSync(inputs[dirIndex], { withFileTypes: true }).forEach(file => { + if (file.isDirectory()) { + inputs.push(path.join(inputs[dirIndex], file.name)); + } else { + if (!excludedTypes.includes(file.name)) { + sources += `--src ${path.join(inputs[dirIndex], file.name)} `; + } + } + }); + } + dirIndex++; +} + +// Normalise path to local quicktype executable. +const quicktypeExec = ['.', 'node_modules', '.bin', 'quicktype'].join(path.sep); + +const command = `${quicktypeExec} -l schema -o ${outputPath} ${sources}`; +console.log('command to run: ' + command); + +exec(command, function(error, stdout, stderr) { + if (stdout) { + console.log(stdout); + } + if (stderr) { + console.log(stderr); + } +}); diff --git a/website/static/schemas/2.1/app-directory.html b/website/static/schemas/2.1/app-directory.html new file mode 100644 index 000000000..a9d3f3be1 --- /dev/null +++ b/website/static/schemas/2.1/app-directory.html @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/website/static/schemas/2.1/appd.schema.json b/website/static/schemas/2.1/appd.schema.json new file mode 100644 index 000000000..034c7bc2b --- /dev/null +++ b/website/static/schemas/2.1/appd.schema.json @@ -0,0 +1,1531 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "FDC3 Application Directory", + "version": "2.1", + "description": "Application Directory specification providing both interface definition and objects necessary to construct an application directory service.", + "x-logo": { + "url": "/img/fdc3-logo-2019-color.png", + "altText": "FDC3 logo" + } + }, + "security": [ + { + "bearerAuth": [] + } + ], + "paths": { + "/v2/apps/{appId}": { + "get": { + "summary": "Retrieve an application definition", + "parameters": [ + { + "name": "appId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Application" + }, + "examples": { + "MyAppDefinition": { + "$ref": "#/components/examples/MyAppDefinition" + }, + "FDC3WorkbenchAppDefinition": { + "$ref": "#/components/examples/FDC3WorkbenchAppDefinition" + } + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + }, + "examples": { + "Error400Example": { + "$ref": "#/components/examples/Error400Example" + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + }, + "examples": { + "Error403Example": { + "$ref": "#/components/examples/Error403Example" + } + } + } + } + }, + "500": { + "description": "Server error", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + }, + "examples": { + "Error500Example": { + "$ref": "#/components/examples/Error500Example" + } + } + } + } + } + }, + "tags": [ + "Application" + ] + } + }, + "/v2/apps": { + "get": { + "summary": "Retrieve all application definitions", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AllApplicationsResponse" + }, + "examples": { + "AllAppsResponse": { + "$ref": "#/components/examples/AllAppsResponse" + } + } + } + } + }, + "400": { + "description": "Bad request", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + }, + "examples": { + "Error400Example": { + "$ref": "#/components/examples/Error400Example" + } + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + }, + "examples": { + "Error403Example": { + "$ref": "#/components/examples/Error403Example" + } + } + } + } + }, + "500": { + "description": "Server error", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + }, + "examples": { + "Error500Example": { + "$ref": "#/components/examples/Error500Example" + } + } + } + } + } + }, + "tags": [ + "Application" + ] + } + }, + "/v1/apps/{appId}": { + "get": { + "deprecated": true, + "summary": "Retrieve an application definition", + "parameters": [ + { + "name": "appId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplicationV1" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + }, + "403": { + "description": "Forbidden: Certificate authentication is not allowed for the requested user.", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + }, + "500": { + "description": "Server error, see response body for further details.", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + } + }, + "tags": [ + "Application" + ] + } + }, + "/v1/apps": { + "post": { + "deprecated": true, + "summary": "Create a new application definition", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplicationSearchResponseV1" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + }, + "403": { + "description": "Forbidden: Certificate authentication is not allowed for the requested user.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + }, + "500": { + "description": "Server error, see response body for further details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + } + }, + "tags": [ + "Application" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplicationV1" + } + } + }, + "required": true + } + } + }, + "/v1/apps/search": { + "get": { + "deprecated": true, + "summary": "Retrieve a list of applications based on parameters provided. Depending on implementation, parameter values should self describe search format and type (e.g. Regex)", + "parameters": [ + { + "in": "query", + "name": "appId", + "schema": { + "type": "string" + }, + "required": false, + "description": "The unique application identifier located within a specific application directory instance." + }, + { + "in": "query", + "name": "name", + "schema": { + "type": "string" + }, + "required": false, + "description": "The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document." + }, + { + "in": "query", + "name": "version", + "schema": { + "type": "string" + }, + "required": false, + "description": "Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA)" + }, + { + "in": "query", + "name": "title", + "schema": { + "type": "string" + }, + "required": false, + "description": "Optional title for the application, if missing use appName, typically used in a launcher UI." + }, + { + "in": "query", + "name": "tooltip", + "schema": { + "type": "string" + }, + "required": false, + "description": "Optional tooltip description e.g. for a launcher" + }, + { + "in": "query", + "name": "description", + "schema": { + "type": "string" + }, + "required": false, + "description": "Description of the application. This will typically be a 1-2 paragraph style blurb about the application. Allow mark up language" + }, + { + "in": "query", + "name": "intent_name", + "schema": { + "type": "string" + }, + "required": false, + "description": "name of intent" + }, + { + "in": "query", + "name": "intent_displayName", + "schema": { + "type": "string" + }, + "required": false, + "description": "displayName of intent" + }, + { + "in": "query", + "name": "intent_context", + "schema": { + "type": "string" + }, + "required": false, + "description": "search contexts list" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplicationSearchResponseV1" + } + } + } + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + }, + "403": { + "description": "Forbidden: Certificate authentication is not allowed for the requested user.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + }, + "500": { + "description": "Server error, see response body for further details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorDTO" + } + } + } + } + }, + "tags": [ + "Application" + ] + } + } + }, + "servers": [ + { + "url": "/appd" + } + ], + "components": { + "securitySchemes": { + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT" + } + }, + "schemas": { + "ErrorDTO": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + }, + "BaseApplication": { + "properties": { + "appId": { + "type": "string", + "description": "The unique application identifier located within a specific application directory instance." + }, + "title": { + "type": "string", + "description": "Title for the application, typically used in a launcher UI." + }, + "type": { + "$ref": "#/components/schemas/Type" + }, + "details": { + "$ref": "#/components/schemas/LaunchDetails" + }, + "name": { + "type": "string", + "description": "Deprecated in favour of using `appId` to identify apps and `title` for their display names. The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document.", + "deprecated": true + }, + "version": { + "type": "string", + "description": "Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA)" + }, + "tooltip": { + "type": "string", + "description": "Optional tooltip description e.g. for a launcher" + }, + "lang": { + "type": "string", + "pattern": "^[a-z]{2}(-[a-zA-Z0-9]{2,8}){0,1}$", + "description": "A language tag that specifies the primary language of both the application and its AppD entry, as defined by IETF RFC 5646." + }, + "description": { + "type": "string", + "description": "Description of the application. This will typically be a 1-2 paragraph style blurb about the application. " + }, + "categories": { + "description": "An array of string categories that describe the application. These are meant as a hint to catalogs or stores listing FDC3-enabled apps and it is expected that these will make a best effort to find appropriate categories (or category) under which to list the app. AppD record authors are encouraged to use lower-case and, where possible, to select categories from the following list:\n\n- allocations\n- analytics\n- charts\n- chat\n- communication\n- compliance\n- crm\n- developer tools\n- events\n- execution management\n- file sharing\n- market data\n- news\n- networking\n- office apps\n- order management\n- other\n- portfolio management\n- presentation\n- pricing\n- productivity\n- research\n- risk\n- screen sharing\n- security\n- spreadsheet\n- trade cost analysis\n- trading system\n- training\n- travel\n- video\n- visualization\n- weather\n", + "type": "array", + "items": { + "type": "string" + } + }, + "icons": { + "type": "array", + "description": "Holds Icons used for the application, a Launcher may be able to use multiple Icon sizes or there may be a 'button' Icon", + "items": { + "$ref": "#/components/schemas/Icon" + } + }, + "screenshots": { + "type": "array", + "description": "Array of images to show the user when they are looking at app description. Each image can have an optional description/tooltip", + "items": { + "$ref": "#/components/schemas/Screenshot" + } + }, + "contactEmail": { + "type": "string", + "format": "email", + "description": "Optional e-mail to receive queries about the application" + }, + "supportEmail": { + "type": "string", + "format": "email", + "description": "Optional e-mail to receive support requests for the application" + }, + "moreInfo": { + "type": "string", + "format": "uri", + "description": "Optional URL that provides more information about the application" + }, + "publisher": { + "type": "string", + "description": "The name of the company that owns the application. The publisher has control over their namespace/app/signature." + }, + "customConfig": { + "deprecated": true, + "type": "array", + "description": "An optional set of name value pairs that can be used to deliver custom data from an App Directory to a launcher. Deprecated due to a lack of a standard means of retrieval via the Desktop Agent API. To be replaced in a future version with an `applicationConfig` element and standard API to retrieve it. See issue [#1006](https://github.com/finos/FDC3/issues/1006) for details.", + "items": { + "$ref": "#/components/schemas/NameValuePair" + } + }, + "hostManifests": { + "$ref": "#/components/schemas/HostManifests" + }, + "interop": { + "$ref": "#/components/schemas/Interop" + } + } + }, + "Application": { + "description": "Defines an application retrieved from an FDC3 App Directory, which can then be launched. Launching typically means running for a user on a desktop. The details around 'launching' including who or what might do it, and how the launch action is initiated are discussed elsewhere in the FDC3 App Directory spec.", + "required": [ + "appId", + "title", + "type", + "details" + ], + "allOf": [ + { + "$ref": "#/components/schemas/BaseApplication" + }, + { + "type": "object", + "properties": { + "localizedVersions": { + "$ref": "#/components/schemas/LocalizedVersions" + } + } + } + ] + }, + "AllApplicationsResponse": { + "properties": { + "applications": { + "type": "array", + "description": "List of applications", + "items": { + "$ref": "#/components/schemas/Application" + } + }, + "message": { + "type": "string", + "description": "Response message providing status of query" + } + } + }, + "NameValuePair": { + "description": "Simple name value pair", + "properties": { + "name": { + "type": "string", + "description": "name" + }, + "value": { + "type": "string", + "description": "value" + } + } + }, + "Icon": { + "description": "Icon holder", + "properties": { + "src": { + "type": "string", + "format": "uri", + "description": "Icon URL" + }, + "size": { + "type": "string", + "description": "Icon dimension formatted as `x`" + }, + "type": { + "type": "string", + "description": "Image media type. If not present the Desktop Agent may use the src file extension" + } + }, + "required": [ + "src" + ], + "additionalProperties": false + }, + "Screenshot": { + "description": "Images representing the app in common usage scenarios", + "properties": { + "src": { + "type": "string", + "format": "uri", + "description": "App Image URL" + }, + "size": { + "type": "string", + "description": "Image dimension formatted as `x`" + }, + "type": { + "type": "string", + "description": "Image media type. If not present the Desktop Agent may use the src file extension." + }, + "label": { + "type": "string", + "description": "Optional caption for the image" + } + }, + "required": [ + "src" + ], + "additionalProperties": false + }, + "Type": { + "type": "string", + "description": "The technology type that is used to launch and run the application. Each application type implies a particular set of launch `details`.\nThe supported types include:\n\n- `web`: Web applications launched via a URL\n- `native`: Native applications pre-installed on a device and launch via a filesystem path\n- `citrix`: Apps virtualized via Citrix\n- `onlineNative`: Native apps that have an online launcher, e.g. online ClickOnce app deployments.\n- `other`: Used to represent apps that do not conform to or cannot be launched via the other types, and are likely to be defined solely by a hostManifest.\n\nFDC3 Desktop Agents MUST support at least the `web` application type and MAY support any or all of the other types.", + "enum": [ + "web", + "native", + "citrix", + "onlineNative", + "other" + ] + }, + "LaunchDetails": { + "description": "The type specific launch details of the application. These details are intended to be vendor-agnostic and MAY be duplicated or overridden by details provided in the hostManifests object for a specific host.", + "anyOf": [ + { + "$ref": "#/components/schemas/WebAppDetails" + }, + { + "$ref": "#/components/schemas/NativeAppDetails" + }, + { + "$ref": "#/components/schemas/CitrixAppDetails" + }, + { + "$ref": "#/components/schemas/OnlineNativeAppDetails" + }, + { + "$ref": "#/components/schemas/OtherAppDetails" + } + ] + }, + "WebAppDetails": { + "description": "Properties used to launch apps with `type: web`.", + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Application start URL." + } + }, + "additionalProperties": false + }, + "NativeAppDetails": { + "description": "Properties used to launch apps with `type: native` that are already installed on the device.", + "required": [ + "path" + ], + "properties": { + "path": { + "type": "string", + "description": "The path on disk from which the application is launched." + }, + "arguments": { + "type": "string", + "description": "Arguments that must be passed on the command line to launch the app in the expected configuration." + } + }, + "additionalProperties": false + }, + "CitrixAppDetails": { + "description": "Properties used to launch apps virtualized apps with `type: citrix`.", + "required": [ + "alias" + ], + "properties": { + "alias": { + "type": "string", + "description": "The Citrix alias / name of the virtual app (passed to the Citrix SelfService qlaunch parameter)." + }, + "arguments": { + "type": "string", + "description": "Arguments that must be passed on the command line to launch the app in the expected configuration." + } + }, + "additionalProperties": false + }, + "OnlineNativeAppDetails": { + "description": "Properties used to launch a native apps with `type: onlineNative` that have an online launcher, e.g. online ClickOnce app deployments.", + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "Application URL." + } + }, + "additionalProperties": false + }, + "OtherAppDetails": { + "description": "Apps with `type: other` are defined by a hostManifest and do not require other details.", + "additionalProperties": false + }, + "HostManifests": { + "type": "object", + "description": "A mapping from host name to a host-specific application manifest object or URI from which that manifest can be retrieved. The manifest should provide details required to launch and use the application within the specified host. The manifest _MAY_ duplicate or override information provided in the `details` field.", + "additionalProperties": { + "x-additionalPropertiesName": "Host name", + "oneOf": [ + { + "type": "string", + "format": "uri" + }, + { + "$ref": "#/components/schemas/HostManifest" + } + ] + } + }, + "HostManifest": { + "type": "object", + "description": "Object containing all host specific properties." + }, + "LocalizedVersions": { + "type": "object", + "description": "Provides localized alternatives to any field of the AppD record, which may also refer to an alternative version of the application that is also localized (e.g. by providing an alternative URL). The keys to this object should be language tags as defined by IETF RFC 5646, e.g. en, en-GB or fr-FR.\n", + "additionalProperties": { + "x-additionalPropertiesName": "Language tag", + "$ref": "#/components/schemas/BaseApplication" + } + }, + "Intent": { + "description": "Definition of an intent that an app listens for", + "required": [ + "contexts" + ], + "properties": { + "displayName": { + "type": "string", + "description": "Optional display name for the intent. Deprecated in favour of the intent name, which is common amongst all apps that support it, where the display name may vary as it is defined in the app's AppD record.", + "deprecated": true + }, + "contexts": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A comma separated list of the types of contexts the intent offered by the application can process, where the first part of the context type is the namespace e.g.\"fdc3.contact, org.symphony.contact\"" + }, + "resultType": { + "type": "string", + "description": "An optional type for output returned by the application, if any, when resolving this intent. May indicate a context type by type name (e.g. \"fdc3.instrument\"), a channel (e.g. \"channel\") or a combination that indicates a channel that returns a particular context type (e.g. \"channel\")." + }, + "customConfig": { + "deprecated": true, + "type": "object", + "description": "Custom configuration for the intent that may be required for a particular desktop agent. Deprecated due to a lack of defined use cases." + } + } + }, + "Interop": { + "type": "object", + "description": "Metadata that describes how the application uses FDC3 APIs. This metadata serves multiple purposes:\n\n- It supports intent resolution by a desktop agent, by declaring what intents an app listens for.\n- It may be used, for example in an app catalog UI, to find apps that 'interoperate with' other apps. \n- It provides a standard location to document how the app interacts with user channels, app channels, and intents, for use by other app developers and desktop assemblers.", + "properties": { + "intents": { + "type": "object", + "description": "Describes the app's interactions with intents.", + "properties": { + "listensFor": { + "type": "object", + "description": "A mapping of Intents names that an app listens for via `fdc3.addIntentListener()` to their configuration. \n\nUsed to support intent resolution by desktop agents. Replaces the `intents` element used in appD records prior to FDC3 2.0.", + "additionalProperties": { + "x-additionalPropertiesName": "Intent name", + "$ref": "#/components/schemas/Intent" + } + }, + "raises": { + "type": "object", + "description": "A mapping of Intent names that an app raises (via `fdc3.raiseIntent`) to an array of context type names that it may be raised with.\n\nUse the intent name \"any\" to represent use of the `fdc3.raiseIntentForContext` and `fdc3.findIntentForContext` functions, which allow the user to select from intents available for a specified context type.\n\nThis metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers.", + "additionalProperties": { + "x-additionalPropertiesName": "Intent name", + "type": "array", + "description": "Context type names that the intent may be raised with.", + "items": { + "type": "string" + } + } + } + } + }, + "userChannels": { + "type": "object", + "description": "Describes the application's use of context types on User Channels.\n\nThis metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers.", + "properties": { + "broadcasts": { + "type": "array", + "description": "Context type names that are broadcast by the application.", + "items": { + "type": "string" + } + }, + "listensFor": { + "type": "array", + "description": "Context type names that the application listens for.", + "items": { + "type": "string" + } + } + } + }, + "appChannels": { + "type": "array", + "description": "Describes the application's use of App Channels.\n\nThis metadata is not currently used by the desktop agent, but is provided to help find apps that will interoperate with this app and to document API interactions for use by other app developers.", + "items": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "description": "The id of the App Channel. N.b. in FDC3 2.0 this field was incorrectly called `name`." + }, + "description": { + "type": "string", + "description": "A description of how the channel is used." + }, + "broadcasts": { + "type": "array", + "description": "Context type names that are broadcast by the application on the channel.", + "items": { + "type": "string" + } + }, + "listensFor": { + "type": "array", + "description": "Context type names that the application listens for on the channel.", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "AppImageV1": { + "description": "App Image holder", + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "App Image URL" + } + } + }, + "IconV1": { + "description": "(Deprecated v1 API version) Icon holder", + "properties": { + "icon": { + "type": "string", + "format": "uri", + "description": "Icon URL" + } + } + }, + "IntentV1": { + "description": "(Deprecated v1 API version) An intent definition as defined by spec https://github.com/FDC3/Intents/blob/master/src/Intent.yaml", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the intent to 'launch'. In this case the name of an Intent supported by an application." + }, + "displayName": { + "type": "string", + "description": "An optional display name for the intent that may be used in UI instead of the name." + }, + "contexts": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A comma separated list of the types of contexts the intent offered by the application can process, where the first part of the context type is the namespace e.g.\"fdc3.contact, org.symphony.contact\"" + }, + "customConfig": { + "deprecated": true, + "type": "object", + "description": "Custom configuration for the intent that may be required for a particular desktop agent. Deprecated due to a lack of defined use cases." + } + } + }, + "ApplicationV1": { + "description": "(Deprecated v1 API version) Defines an application retrieved from an FDC3 App Directory, which can then be launched. Launching typically means running for a user on a desktop. The details around 'launching' including who or what might do it, and how the launch action is initiated are discussed elsewhere in the FDC3 App Directory spec.", + "required": [ + "appId", + "name", + "manifest", + "manifestType" + ], + "properties": { + "appId": { + "type": "string", + "description": "The unique application identifier located within a specific application directory instance." + }, + "name": { + "type": "string", + "description": "The name of the application. The name should be unique within an FDC3 App Directory instance. The exception to the uniqueness constraint is that an App Directory can hold definitions for multiple versions of the same app. The same appName could occur in other directories. We are not currently specifying app name conventions in the document." + }, + "manifest": { + "type": "string", + "description": "URI or full JSON of the application manifest providing all details related to launch and use requirements as described by the vendor. The format of this manifest is vendor specific, but can be identified by the manifestType attribute." + }, + "manifestType": { + "type": "string", + "description": "The manifest type which relates to the format and structure of the manifest content. The definition is based on the vendor specific format and definition outside of this specification." + }, + "version": { + "type": "string", + "description": "Version of the application. This allows multiple app versions to be defined using the same app name. This can be a triplet but can also include things like 1.2.5 (BETA)" + }, + "title": { + "type": "string", + "description": "Optional title for the application, if missing use appName, typically used in a launcher UI." + }, + "tooltip": { + "type": "string", + "description": "Optional tooltip description e.g. for a launcher" + }, + "description": { + "type": "string", + "description": "Description of the application. This will typically be a 1-2 paragraph style blurb about the application. Allow mark up language" + }, + "images": { + "type": "array", + "description": "Array of images to show the user when they are looking at app description. Each image can have an optional description/tooltip", + "items": { + "$ref": "#/components/schemas/AppImageV1" + } + }, + "contactEmail": { + "type": "string", + "format": "email", + "description": "Optional e-mail to receive queries about the application" + }, + "supportEmail": { + "type": "string", + "format": "email", + "description": "Optional e-mail to receive support requests for the application" + }, + "publisher": { + "type": "string", + "description": "The name of the company that owns the application. The publisher has control over their namespace/app/signature." + }, + "icons": { + "type": "array", + "description": "Holds Icons used for the application, a Launcher may be able to use multiple Icon sizes or there may be a 'button' Icon", + "items": { + "$ref": "#/components/schemas/IconV1" + } + }, + "customConfig": { + "deprecated": true, + "type": "array", + "description": "An optional set of name value pairs that can be used to deliver custom data from an App Directory to a launcher.", + "items": { + "$ref": "#/components/schemas/NameValuePair" + } + }, + "intents": { + "type": "array", + "description": "The list of intents implemented by the application as defined by https://github.com/FDC3/Intents/blob/master/src/Intent.yaml", + "items": { + "$ref": "#/components/schemas/IntentV1" + } + } + } + }, + "ApplicationSearchResponseV1": { + "properties": { + "applications": { + "type": "array", + "description": "List of applications", + "items": { + "$ref": "#/components/schemas/ApplicationV1" + } + }, + "message": { + "type": "string", + "description": "Response message providing status of query" + } + } + } + }, + "examples": { + "FDC3WorkbenchAppDefinition": { + "value": { + "appId": "fdc3-workbench", + "title": "FDC3 Workbench", + "description": "Development and test tool for FDC3 desktop agents and apps", + "categories": [ + "developer tools", + "training" + ], + "version": "1.0.0", + "tooltip": "FDC3 Workbench", + "lang": "en-US", + "icons": [ + { + "src": "https://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png" + } + ], + "screenshots": [ + { + "src": "https://fdc3.finos.org/docs/assets/fdc3-logo.png", + "label": "FDC3 logo" + } + ], + "contactEmail": "fdc3@finos.org", + "supportEmail": "fdc3-maintainers@finos.org", + "moreInfo": "https://fdc3.finos.org", + "publisher": "FDC3", + "type": "web", + "details": { + "url": "https://fdc3.finos.org/toolbox/fdc3-workbench/" + }, + "hostManifests": { + "Glue42": { + "type": "window", + "icon": "https://fdc3.finos.org/docs/assets/fdc3-logo.png", + "details": { + "height": 640, + "width": 560, + "left": 120, + "top": 120, + "mode": "tab", + "allowChannels": true, + "loader": { + "enabled": true, + "hideOnLoad": true + } + }, + "customProperties": { + "folder": "FDC3 Toolbox" + } + }, + "Finsemble": { + "window": { + "left": 120, + "top": 120, + "width": 800, + "height": 750, + "options": { + "minWidth": 75 + } + }, + "foreign": { + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Toolbar": { + "iconURL": "http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png" + }, + "Window Manager": { + "FSBLHeader": true, + "persistWindowState": true + } + } + }, + "interop": { + "autoConnect": true + } + }, + "Web App Manifest": "https://example.com/fdc3-workbench.json" + }, + "localizedVersions": { + "fr-FR": { + "title": "FDC3 Table de travail", + "description": "Outil de développement et de test pour les desktop agents et applications FDC3" + } + } + }, + "summary": "A sample app definition for the FDC3 Workbench" + }, + "MyAppDefinition": { + "value": { + "appId": "my-application", + "title": "My Application", + "description": "An example application that uses FDC3 and fully describes itself in an AppD record.", + "categories": [ + "market data", + "research", + "news" + ], + "version": "1.0.0", + "tooltip": "My example application definition", + "lang": "en-US", + "icons": [ + { + "src": "http://example.domain.com/assets/my-app-icon.png", + "size": "256x256", + "type": "image/png" + } + ], + "screenshots": [ + { + "src": "http://example.domain.com/assets/my-app-screenshot-1.png", + "label": "The first screenshot of my example app", + "type": "image/png", + "size": "800x600" + }, + { + "src": "http://example.domain.com/assets/my-app-screenshot-2.png", + "label": "The second screenshot of my example app", + "type": "image/png", + "size": "800x600" + } + ], + "contactEmail": "fdc3@finos.org", + "supportEmail": "fdc3-maintainers@finos.org", + "moreInfo": "http://example.domain.com/", + "publisher": "Example App, Inc.", + "type": "web", + "details": { + "url": "http://example.domain.com/app.html" + }, + "hostManifests": { + "Finsemble": { + "window": { + "left": 120, + "top": 120, + "width": 600, + "height": 800, + "options": { + "minWidth": 75 + } + }, + "foreign": { + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "FSBLHeader": true, + "persistWindowState": true + } + } + }, + "interop": { + "autoConnect": true + } + }, + "Glue42": { + "type": "window", + "details": { + "height": 800, + "width": 600, + "left": 120, + "top": 120, + "mode": "tab", + "allowChannels": true, + "loader": { + "enabled": true, + "hideOnLoad": true + } + }, + "customProperties": { + "folder": "FDC3 Toolbox" + } + }, + "Web App Manifest": "http://example.domain.com/my-app.json" + }, + "interop": { + "intents": { + "listensFor": { + "ViewChart": { + "contexts": [ + "fdc3.instrument" + ] + }, + "myApp.GetPrice": { + "contexts": [ + "fdc3.instrument" + ], + "resultType": "myApp.quote" + } + }, + "raises": { + "ViewOrders": [ + "fdc3.instrument", + "fdc3.organization" + ], + "StartEmail": [ + "fdc3.email" + ] + } + }, + "userChannels": { + "broadcasts": [ + "fdc3.instrument", + "fdc3.organization" + ], + "listensFor": [ + "fdc3.instrument", + "fdc3.organization" + ] + }, + "appChannels": [ + { + "id": "myApp.quotes,", + "description": "Used to share a stream of quotes for currently displayed instrument and may be used to change the currently displayed symbol,", + "broadcasts": [ + "myApp.quote" + ], + "listensFor": [ + "fdc3.instrument" + ] + } + ] + }, + "localizedVersions": { + "fr-FR": { + "title": "Mon application,", + "description": "Un exemple d'application qui utilise FDC3 et se décrit entièrement dans un enregistrement AppD." + } + } + }, + "summary": "A sample app definition that describes the app's use of interop." + }, + "AllAppsResponse": { + "value": { + "applications": [ + { + "appId": "my-application", + "title": "My Application", + "description": "An example application that uses FDC3 and fully describes itself in an AppD record.", + "categories": [ + "market data", + "research", + "news" + ], + "version": "1.0.0", + "tooltip": "My example application definition", + "lang": "en-US", + "icons": [ + { + "src": "http://example.domain.com/assets/my-app-icon.png", + "size": "256x256", + "type": "image/png" + } + ], + "screenshots": [ + { + "src": "http://example.domain.com/assets/my-app-screenshot-1.png", + "label": "The first screenshot of my example app", + "type": "image/png", + "size": "800x600" + }, + { + "src": "http://example.domain.com/assets/my-app-screenshot-2.png", + "label": "The second screenshot of my example app", + "type": "image/png", + "size": "800x600" + } + ], + "contactEmail": "fdc3@finos.org", + "supportEmail": "fdc3-maintainers@finos.org", + "moreInfo": "http://example.domain.com/", + "publisher": "Example App, Inc.", + "type": "web", + "details": { + "url": "http://example.domain.com/app.html" + }, + "hostManifests": { + "Finsemble": { + "window": { + "left": 120, + "top": 120, + "width": 600, + "height": 800, + "options": { + "minWidth": 75 + } + }, + "foreign": { + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Window Manager": { + "FSBLHeader": true, + "persistWindowState": true + } + } + }, + "interop": { + "autoConnect": true + } + }, + "Glue42": { + "type": "window", + "details": { + "height": 800, + "width": 600, + "left": 120, + "top": 120, + "mode": "tab", + "allowChannels": true, + "loader": { + "enabled": true, + "hideOnLoad": true + } + }, + "customProperties": { + "folder": "FDC3 Toolbox" + } + }, + "Web App Manifest": "http://example.domain.com/my-app.json" + }, + "interop": { + "intents": { + "listensFor": { + "ViewChart": { + "contexts": [ + "fdc3.instrument" + ] + }, + "myApp.GetPrice": { + "contexts": [ + "fdc3.instrument" + ], + "resultType": "myApp.quote" + } + }, + "raises": { + "ViewOrders": [ + "fdc3.instrument", + "fdc3.organization" + ], + "StartEmail": [ + "fdc3.email" + ] + } + }, + "userChannels": { + "broadcasts": [ + "fdc3.instrument", + "fdc3.organization" + ], + "listensFor": [ + "fdc3.instrument", + "fdc3.organization" + ] + }, + "appChannels": [ + { + "id": "myApp.quotes,", + "description": "Used to share a stream of quotes for currently displayed instrument and may be used to change the currently displayed symbol,", + "broadcasts": [ + "myApp.quote" + ], + "listensFor": [ + "fdc3.instrument" + ] + } + ] + }, + "localizedVersions": { + "fr-FR": { + "title": "Mon application,", + "description": "Un exemple d'application qui utilise FDC3 et se décrit entièrement dans un enregistrement AppD." + } + } + }, + { + "appId": "fdc3-workbench", + "title": "FDC3 Workbench", + "description": "Development and test tool for FDC3 desktop agents and apps", + "categories": [ + "developer tools", + "training" + ], + "version": "1.0.0", + "tooltip": "FDC3 Workbench", + "lang": "en-US", + "icons": [ + { + "src": "https://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png" + } + ], + "screenshots": [ + { + "src": "https://fdc3.finos.org/docs/assets/fdc3-logo.png,", + "label": "FDC3 logo" + } + ], + "contactEmail": "fdc3@finos.org", + "supportEmail": "fdc3-maintainers@finos.org", + "publisher": "FDC3,", + "type": "web", + "details": { + "url": "https://fdc3.finos.org/toolbox/fdc3-workbench/" + }, + "hostManifests": { + "Glue42": { + "type": "window", + "icon": "https://fdc3.finos.org/docs/assets/fdc3-logo.png", + "details": { + "height": 640, + "width": 560, + "left": 120, + "top": 120, + "mode": "tab", + "allowChannels": true, + "loader": { + "enabled": true, + "hideOnLoad": true + } + }, + "customProperties": { + "folder": "FDC3 Toolbox" + } + }, + "Finsemble": { + "window": { + "left": 120, + "top": 120, + "width": 800, + "height": 750, + "options": { + "minWidth": 75 + } + }, + "foreign": { + "components": { + "App Launcher": { + "launchableByUser": true + }, + "Toolbar": { + "iconURL": "http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png" + }, + "Window Manager": { + "FSBLHeader": true, + "persistWindowState": true + } + } + }, + "interop": { + "autoConnect": true + } + }, + "Web App Manifest": "https://example.com/fdc3-workbench.json" + }, + "localizedVersions": { + "fr-FR": { + "title": "FDC3 Table de travail", + "description": "Outil de développement et de test pour les desktop agents et applications FDC3" + } + } + } + ], + "message": "OK" + }, + "summary": "A sample 'all applications' listing response" + }, + "Error400Example": { + "value": { + "code": 400, + "message": "There was an error in your request." + }, + "summary": "A sample Bad Request error." + }, + "Error403Example": { + "value": { + "code": 403, + "message": "Certificate authentication failed for the requested user." + }, + "summary": "A sample Forbidden error." + }, + "Error500Example": { + "value": { + "code": 500, + "message": "An internal server error occurred. See the response body for further details." + }, + "summary": "A sample Server error." + } + } + } + } \ No newline at end of file diff --git a/website/static/schemas/2.1/bridging/agentErrorResponse.schema.json b/website/static/schemas/2.1/bridging/agentErrorResponse.schema.json new file mode 100644 index 000000000..c3627f654 --- /dev/null +++ b/website/static/schemas/2.1/bridging/agentErrorResponse.schema.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/agentErrorResponse.schema.json", + "title": "Agent Error Response Message", + "type": "object", + "description": "A response message from a Desktop Agent to the Bridge containing an error, to be used in preference to the standard response when an error needs to be returned.", + "properties": { + "type": { + "title": "Response Message Type", + "type": "string", + "enum": [ + "findInstancesResponse", + "findIntentResponse", + "findIntentsByContextResponse", + "getAppMetadataResponse", + "openResponse", + "raiseIntentResponse", + "raiseIntentResultResponse" + ], + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Response' appended." + }, + "payload": { + "title": "Error Response Message Payload", + "type": "object", + "description": "Error message payload containing an standardized error string.", + "properties": { + "error": { + "$ref": "common.schema.json#/$defs/ErrorMessages" + } + }, + "unevaluatedProperties": false, + "required": ["error"] + }, + "meta": { + "$ref": "agentResponse.schema.json#/$defs/AgentResponseMeta" + } + }, + "additionalProperties": false, + "required": ["type", "payload", "meta"] +} diff --git a/website/static/schemas/2.1/bridging/agentRequest.schema.json b/website/static/schemas/2.1/bridging/agentRequest.schema.json new file mode 100644 index 000000000..23712217b --- /dev/null +++ b/website/static/schemas/2.1/bridging/agentRequest.schema.json @@ -0,0 +1,65 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/agentRequest.schema.json", + "title": "Agent Request Message", + "type": "object", + "description": "A request message from a Desktop Agent to the Bridge.", + "properties": { + "type": { + "title": "Request Message type", + "type": "string", + "enum": [ + "broadcastRequest", + "findInstancesRequest", + "findIntentRequest", + "findIntentsByContextRequest", + "getAppMetadataRequest", + "openRequest", + "PrivateChannel.broadcast", + "PrivateChannel.eventListenerAdded", + "PrivateChannel.onAddContextListener", + "PrivateChannel.onDisconnect", + "PrivateChannel.onUnsubscribe", + "raiseIntentRequest" + ], + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Request' appended." + }, + "payload": { + "title": "Message payload", + "type": "object", + "description": "The message payload typically contains the arguments to FDC3 API functions." + }, + "meta": { + "$ref": "#/$defs/AgentRequestMeta" + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false, + "$defs": { + "AgentRequestMeta": { + "title": "Agent Request Metadata", + "description": "Metadata for a request message sent by Desktop Agents to the Bridge.", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + }, + "source": { + "title": "Source identifier", + "description": "Field that represents the source application that the request was received from, or the source Desktop Agent if it issued the request itself.", + "$ref": "common.schema.json#/$defs/RequestSource" + }, + "destination": { + "title": "Destination identifier", + "description": "Optional field that represents the destination that the request should be routed to. Must be set by the Desktop Agent for API calls that include a target app parameter and must include the name of the Desktop Agent hosting the target application.", + "$ref": "common.schema.json#/$defs/BridgeParticipantIdentifier" + } + }, + "required": ["requestUuid", "timestamp"], + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/agentResponse.schema.json b/website/static/schemas/2.1/bridging/agentResponse.schema.json new file mode 100644 index 000000000..1f23d08ca --- /dev/null +++ b/website/static/schemas/2.1/bridging/agentResponse.schema.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/agentResponse.schema.json", + "title": "Agent Response Message", + "type": "object", + "description": "A response message from a Desktop Agent to the Bridge.", + "properties": { + "type": { + "title": "Response Message Type", + "type": "string", + "enum": [ + "findInstancesResponse", + "findIntentResponse", + "findIntentsByContextResponse", + "getAppMetadataResponse", + "openResponse", + "raiseIntentResponse", + "raiseIntentResultResponse" + ], + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Response' appended." + }, + "payload": { + "title": "Response Message Payload", + "type": "object", + "description": "The message payload typically contains return values for FDC3 API functions." + }, + "meta": { + "$ref": "#/$defs/AgentResponseMeta" + } + }, + "additionalProperties": false, + "required": ["type", "payload", "meta"], + "$defs": { + "AgentResponseMeta": { + "title": "Agent Response Metadata", + "description": "Metadata for a response messages sent by a Desktop Agent to the Bridge", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "responseUuid": { + "$ref": "common.schema.json#/$defs/ResponseUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + } + }, + "required": ["requestUuid", "responseUuid", "timestamp"], + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/bridgeErrorResponse.schema.json b/website/static/schemas/2.1/bridging/bridgeErrorResponse.schema.json new file mode 100644 index 000000000..3e88440ea --- /dev/null +++ b/website/static/schemas/2.1/bridging/bridgeErrorResponse.schema.json @@ -0,0 +1,55 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/bridgeErrorResponse.schema.json", + "title": "Bridge Error Response Message", + "type": "object", + "description": "A response message from the Bridge back to the original Desktop Agent that raised the request, used where all connected agents returned errors.", + "properties": { + "type": { + "title": "Response Message Type", + "type": "string", + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Response' appended." + }, + "payload": { + "title": "Response Error Message Payload", + "type": "object", + "description": "The error message payload contains details of an error return to the app or agent that raised the original request.", + "properties": { + "error": { + "$ref": "common.schema.json#/$defs/ErrorMessages" + } + } + }, + "meta": { + "$ref": "#/$defs/BridgeErrorResponseMeta" + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false, + "$defs": { + "BridgeErrorResponseMeta": { + "title": "Bridge Response Metadata", + "description": "Metadata required in a response message collated and/or forwarded on by the Bridge", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "responseUuid": { + "$ref": "common.schema.json#/$defs/ResponseUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + }, + "errorSources": { + "$ref": "common.schema.json#/$defs/BridgeResponseErrorSources" + }, + "errorDetails": { + "$ref": "common.schema.json#/$defs/BridgeResponseErrorDetails" + } + }, + "required": ["requestUuid", "responseUuid", "timestamp", "errorSources", "errorDetails"], + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/bridgeRequest.schema.json b/website/static/schemas/2.1/bridging/bridgeRequest.schema.json new file mode 100644 index 000000000..338a83069 --- /dev/null +++ b/website/static/schemas/2.1/bridging/bridgeRequest.schema.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/bridgeRequest.schema.json", + "title": "Bridge Request Message", + "type": "object", + "description": "A request message forwarded from the Bridge onto a Desktop Agent connected to it.", + "properties": { + "type": { + "title": "Message type", + "type": "string", + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Request' appended." + }, + "payload": { + "title": "Message payload", + "type": "object", + "description": "The message payload typically contains the arguments to FDC3 API functions." + }, + "meta": { + "$ref": "#/$defs/BridgeRequestMeta" + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false, + "$defs": { + "BridgeRequestMeta": { + "title": "Bridge Request Metadata", + "description": "Metadata required in a request message forwarded on by the Bridge", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + }, + "source": { + "title": "Bridge Source identifier", + "description": "Field that represents the source application that the request was received from, or the source Desktop Agent if it issued the request itself. The Desktop Agent identifier MUST be set by the bridge.", + "$ref": "common.schema.json#/$defs/BridgeParticipantIdentifier" + }, + "destination": { + "title": "Destination identifier", + "description": "Optional field that represents the destination that the request should be routed to. Must be set by the Desktop Agent for API calls that include a target app parameter and must include the name of the Desktop Agent hosting the target application.", + "$ref": "common.schema.json#/$defs/BridgeParticipantIdentifier" + } + }, + "required": ["requestUuid", "timestamp", "source"], + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/bridgeResponse.schema.json b/website/static/schemas/2.1/bridging/bridgeResponse.schema.json new file mode 100644 index 000000000..c4a1ab21c --- /dev/null +++ b/website/static/schemas/2.1/bridging/bridgeResponse.schema.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/bridgeResponse.schema.json", + "title": "Bridge Response Message", + "type": "object", + "description": "A response message from the Bridge back to the original Desktop Agent that raised the request.", + "properties": { + "type": { + "title": "Response Message Type", + "type": "string", + "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Response' appended." + }, + "payload": { + "title": "Response Message Payload", + "type": "object", + "description": "The message payload typically contains return values for FDC3 API functions." + }, + "meta": { + "$ref": "#/$defs/BridgeResponseMeta" + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false, + "$defs": { + "BridgeResponseMeta": { + "title": "Bridge Response Metadata", + "description": "Metadata required in a response message collated and/or forwarded on by the Bridge", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "responseUuid": { + "$ref": "common.schema.json#/$defs/ResponseUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + }, + "sources": { + "$ref": "common.schema.json#/$defs/BridgeResponseSources" + }, + "errorSources": { + "$ref": "common.schema.json#/$defs/BridgeResponseErrorSources" + }, + "errorDetails": { + "$ref": "common.schema.json#/$defs/BridgeResponseErrorDetails" + } + }, + "required": ["requestUuid", "responseUuid", "timestamp"], + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/broadcastAgentRequest.schema.json b/website/static/schemas/2.1/bridging/broadcastAgentRequest.schema.json new file mode 100644 index 000000000..38578435d --- /dev/null +++ b/website/static/schemas/2.1/bridging/broadcastAgentRequest.schema.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/broadcastAgentRequest.schema.json", + "title": "Broadcast Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/BroadcastRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "BroadcastRequestBase": { + "title": "Broadcast Request", + "type":"object", + "description": "A request to broadcast context on a channel.", + "properties": { + "type": { + "title": "Broadcast Request Message Type", + "const": "broadcastRequest" + }, + "payload": { + "title": "broadcast Request Payload", + "type": "object", + "properties": { + "channelId": { + "type": "string", + "title": "Channel Id", + "description": "The Id of the PrivateChannel that the broadcast was sent on" + }, + "context": { + "$ref": "../context/context.schema.json", + "title": "Context", + "description": "The context object that was the payload of a broadcast message." + } + }, + "additionalProperties": false, + "required": ["channelId", "context"] + }, + "meta": { + "type": "object", + "title": "broadcast request metadata", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + } + }, + "required": ["source"], + "additionalProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/broadcastBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/broadcastBridgeRequest.schema.json new file mode 100644 index 000000000..cc00a69d8 --- /dev/null +++ b/website/static/schemas/2.1/bridging/broadcastBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/broadcastBridgeRequest.schema.json", + "title": "Broadcast Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "broadcastAgentRequest.schema.json#/$defs/BroadcastRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/common.schema.json b/website/static/schemas/2.1/bridging/common.schema.json new file mode 100644 index 000000000..1581bd49c --- /dev/null +++ b/website/static/schemas/2.1/bridging/common.schema.json @@ -0,0 +1,115 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/common.schema.json", + "title": "Bridging Commons", + "type": "object", + "description": "Common elements referenced by other schemas", + "$defs": { + "RequestUuid": { + "title": "Request UUID", + "type": "string", + "description": "UUID for the request" + }, + "ResponseUuid": { + "title": "Response UUID", + "type": "string", + "description": "UUID for this specific response message." + }, + "Timestamp": { + "title": "Timestamp", + "type": "string", + "format": "date-time", + "description": "Timestamp at which request was generated" + }, + "RequestSource": { + "title": "Source identifier", + "description": "Field that represents the source application that a request or response was received from, or the source Desktop Agent if it issued the request or response itself.", + "oneOf": [ + { + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + }, + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + } + ] + }, + "AppRequestSource": { + "title": "App Source identifier", + "description": "Field that represents the source application that a request or response was received from.", + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + }, + "AgentDestination": { + "title": "Agent Destination identifier", + "description": "Field that represents a destination Desktop Agent that a request is to be sent to.", + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + }, + "AppDestination": { + "title": "App Destination identifier", + "description": "Field that represents a destination App on a remote Desktop Agent that a request is to be sent to.", + "allOf": [ + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + }, + { + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + } + ] + }, + "BridgeParticipantIdentifier": { + "title": "Bridge Participant Identifier", + "description": "Represents identifiers that MUST include the Desktop Agent name and MAY identify a specific app or instance.", + "oneOf": [ + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + }, + { + "allOf": [ + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + }, + { + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + } + ] + } + ] + }, + "BridgeResponseSources": { + "title": "Desktop Agents that responded", + "type": "array", + "items": [ + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + } + ], + "description": "Array of DesktopAgentIdentifiers for the sources that generated responses to the request. Will contain a single value for individual responses and multiple values for responses that were collated by the bridge. May be omitted if all sources errored. MUST include the `desktopAgent` field when returned by the bridge." + }, + "BridgeResponseErrorSources": { + "title": "Desktop Agents that errored", + "type": "array", + "items": [ + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + } + ], + "description": "Array of DesktopAgentIdentifiers for responses that were not returned to the bridge before the timeout or because an error occurred. May be omitted if all sources responded without errors. MUST include the `desktopAgent` field when returned by the bridge." + }, + "ErrorMessages": { + "oneOf": [ + { "$ref": "../api/api.schema.json#/definitions/ChannelError" }, + { "$ref": "../api/api.schema.json#/definitions/OpenError" }, + { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, + { "$ref": "../api/api.schema.json#/definitions/ResultError" }, + { "$ref": "../api/api.schema.json#/definitions/BridgingError" } + ] + }, + "BridgeResponseErrorDetails": { + "title": "Response Error Details", + "type": "array", + "items": { + "$ref": "#/$defs/ErrorMessages" + }, + "description": "Array of error message strings for responses that were not returned to the bridge before the timeout or because an error occurred. Should be the same length as the `errorSources` array and ordered the same. May be omitted if all sources responded without errors." + } + } +} diff --git a/website/static/schemas/2.1/bridging/connectionStep.schema.json b/website/static/schemas/2.1/bridging/connectionStep.schema.json new file mode 100644 index 000000000..c9d8c3283 --- /dev/null +++ b/website/static/schemas/2.1/bridging/connectionStep.schema.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/connectionStep.schema.json", + "title": "Connection Step Message", + "type": "object", + "description": "A message used during the connection flow for a Desktop Agent to the Bridge. Used for messages sent in either direction.", + "properties": { + "type": { + "title": "Connection Step Message type", + "type": "string", + "enum": [ + "hello", + "handshake", + "authenticationFailed", + "connectedAgentsUpdate" + ], + "description": "Identifies the type of the connection step message." + }, + "payload": { + "title": "Message payload", + "type": "object", + "description": "The message payload, containing data pertaining to this connection step.", + "unevaluatedProperties": false + }, + "meta": { + "$ref": "#/$defs/ConnectionStepMeta" + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false, + "$defs": { + "ConnectionStepMeta": { + "title": "Connection Step Metadata", + "description": "Metadata for this connection step message.", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + }, + "responseUuid": { + "$ref": "common.schema.json#/$defs/ResponseUuid" + } + }, + "required": ["timestamp"], + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/connectionStep2Hello.schema.json b/website/static/schemas/2.1/bridging/connectionStep2Hello.schema.json new file mode 100644 index 000000000..32cd9a873 --- /dev/null +++ b/website/static/schemas/2.1/bridging/connectionStep2Hello.schema.json @@ -0,0 +1,71 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/connectionStep2Hello.schema.json", + "title": "ConnectionStep2Hello", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/ConnectionStep2HelloBase" + }, + { + "$ref": "connectionStep.schema.json" + } + ], + "$defs": { + "ConnectionStep2HelloBase": { + "type":"object", + "title": "ConnectionStep2Hello", + "description": "Hello message sent by the Bridge to anyone connecting to the Bridge (enables identification as a bridge and confirmation of whether authentication is required)", + "properties": { + "type": { + "title": "Connection Step 2 Message Type", + "const": "hello" + }, + "payload": { + "title": "Connection Step 2 Payload", + "type": "object", + "properties": { + "desktopAgentBridgeVersion": { + "title": "Desktop Agent Bridge Version Number", + "description": "The version of the Bridge", + "type": "string" + }, + "supportedFDC3Versions": { + "title": "Supported FDC3 Versions", + "type": "array", + "description": "The FDC3 versions supported by the Bridge", + "items": { + "type": "string" + } + }, + "authRequired": { + "title": "Authentication Required", + "type": "boolean", + "description": "A flag indicating whether the Desktop Agent Bridge requires authentication or not." + }, + "authToken": { + "title": "Authentication Token", + "type": "string", + "description": "An optional Desktop Agent Bridge JWT authentication token if the Desktop Agent want to authenticate a bridge." + } + }, + "additionalProperties": false, + "required": ["desktopAgentBridgeVersion", "supportedFDC3Versions", "authRequired"] + }, + "meta": { + "title": "Connection Step 2 Metadata", + "type": "object", + "properties": { + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + } + }, + "additionalProperties": false, + "required": ["timestamp"] + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/website/static/schemas/2.1/bridging/connectionStep3Handshake.schema.json b/website/static/schemas/2.1/bridging/connectionStep3Handshake.schema.json new file mode 100644 index 000000000..4d346109c --- /dev/null +++ b/website/static/schemas/2.1/bridging/connectionStep3Handshake.schema.json @@ -0,0 +1,77 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/connectionStep3Handshake.schema.json", + "title": "ConnectionStep3Handshake", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/ConnectionStep3HandshakeBase" + }, + { + "$ref": "connectionStep.schema.json" + } + ], + "$defs": { + "ConnectionStep3HandshakeBase": { + "type":"object", + "title": "ConnectionStep3Handshake", + "description": "Handshake message sent by the Desktop Agent to the Bridge (including requested name, channel state and authentication data)", + "properties": { + "type": { + "title": "Connection Step 3 Message Type", + "const": "handshake" + }, + "payload": { + "title": "Connection Step 3 Payload", + "type": "object", + "properties": { + "implementationMetadata": { + "title": "Desktop Agent ImplementationMetadata", + "description": "Desktop Agent ImplementationMetadata trying to connect to the bridge.", + "$ref": "../api/baseImplementationMetadata.schema.json" + }, + "requestedName": { + "title": "Requested name", + "description": "The requested Desktop Agent name", + "type": "string" + }, + "channelsState": { + "title": "Channel State", + "type": "object", + "description": "The current state of the Desktop Agent's channels, excluding any private channels, as a mapping of channel id to an array of Context objects, most recent first.", + "additionalProperties": { + "title": "Channel ", + "type": "array", + "items": { + "$ref": "../context/context.schema.json" + } + } + }, + "authToken": { + "title": "Authentication Token", + "type": "string" + } + }, + "additionalProperties": false, + "required": ["implementationMetadata", "requestedName", "channelsState"] + }, + "meta": { + "title": "Connection Step 3 Metadata", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + } + }, + "additionalProperties": false, + "required": ["requestUuid", "timestamp"] + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/website/static/schemas/2.1/bridging/connectionStep4AuthenticationFailed.schema.json b/website/static/schemas/2.1/bridging/connectionStep4AuthenticationFailed.schema.json new file mode 100644 index 000000000..c9cace702 --- /dev/null +++ b/website/static/schemas/2.1/bridging/connectionStep4AuthenticationFailed.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/connectionStep4AuthenticationFailed.schema.json", + "title": "ConnectionStep4AuthenticationFailed", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/ConnectionStep4AuthenticationFailedBase" + }, + { + "$ref": "connectionStep.schema.json" + } + ], + "$defs": { + "ConnectionStep4AuthenticationFailedBase": { + "type":"object", + "title": "ConnectionStep4AuthenticationFailed", + "description": "Message sent by Bridge to Desktop Agent if their authentication fails.", + "properties": { + "type": { + "title": "Connection Step 4 Message Type", + "const": "authenticationFailed" + }, + "payload": { + "title": "Connection Step 4 Payload", + "type": "object", + "properties": { + "message": { + "title": "Authentication failed message", + "type": "string" + } + }, + "additionalProperties": false + }, + "meta": { + "title": "Connection Step 4 Metadata", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "responseUuid": { + "$ref": "common.schema.json#/$defs/ResponseUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + } + }, + "additionalProperties": false, + "required": ["requestUuid", "responseUuid", "timestamp"] + } + }, + "required": ["type", "meta"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/website/static/schemas/2.1/bridging/connectionStep6ConnectedAgentsUpdate.schema.json b/website/static/schemas/2.1/bridging/connectionStep6ConnectedAgentsUpdate.schema.json new file mode 100644 index 000000000..c90330f71 --- /dev/null +++ b/website/static/schemas/2.1/bridging/connectionStep6ConnectedAgentsUpdate.schema.json @@ -0,0 +1,83 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/connectionStep6ConnectedAgentsUpdate.schema.json", + "title": "ConnectionStep6ConnectedAgentsUpdate", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/ConnectionStep6ConnectedAgentsUpdateBase" + }, + { + "$ref": "connectionStep.schema.json" + } + ], + "$defs": { + "ConnectionStep6ConnectedAgentsUpdateBase": { + "type":"object", + "title": "ConnectionStep6ConnectedAgentsUpdateBase", + "description": "Message sent by Bridge to all Desktop Agent when an agent joins or leaves the bridge, includes the details of all agents, the change made and the expected channel state for all agents.", + "properties": { + "type": { + "title": "Connection Step 6 Message Type", + "const": "connectedAgentsUpdate" + }, + "payload": { + "title": "Connection Step 6 Payload", + "type": "object", + "properties": { + "addAgent": { + "title": "Agents To Add", + "type": "string", + "description": "Should be set when an agent first connects to the bridge and provide its assigned name." + }, + "removeAgent": { + "title": "Agents To Remove", + "type": "string", + "description": "Should be set when an agent disconnects from the bridge and provide the name that no longer is assigned." + }, + "allAgents": { + "title": "All Connected Agents", + "type": "array", + "description": "Desktop Agent Bridge implementation metadata of all connected agents.", + "items": { + "$ref": "../api/baseImplementationMetadata.schema.json" + } + }, + "channelsState": { + "title": "Channel State", + "type": "object", + "description": "The updated state of channels that should be adopted by the agents. Should only be set when an agent is connecting to the bridge.", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "../context/context.schema.json" + } + } + } + }, + "additionalProperties": false, + "required": ["allAgents"] + }, + "meta": { + "title": "Connection Step 6 Metadata", + "type": "object", + "properties": { + "requestUuid": { + "$ref": "common.schema.json#/$defs/RequestUuid" + }, + "responseUuid": { + "$ref": "common.schema.json#/$defs/ResponseUuid" + }, + "timestamp": { + "$ref": "common.schema.json#/$defs/Timestamp" + } + }, + "additionalProperties": false, + "required": ["requestUuid", "responseUuid", "timestamp"] + } + }, + "required": ["type", "payload", "meta"], + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/website/static/schemas/2.1/bridging/findInstancesAgentErrorResponse.schema.json b/website/static/schemas/2.1/bridging/findInstancesAgentErrorResponse.schema.json new file mode 100644 index 000000000..d0f541872 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findInstancesAgentErrorResponse.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findInstancesAgentErrorResponse.schema.json", + "title": "FindInstances Agent Error Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindInstancesErrorResponseBase" + }, + { + "$ref": "agentErrorResponse.schema.json" + } + ], + "$defs": { + "FindInstancesErrorResponseBase": { + "title": "FindInstances Error Response", + "type": "object", + "description": "A response to a findInstances request that contains an error.", + "properties": { + "type": { + "title": "FindInstances Response Message Type", + "const": "findInstancesResponse" + }, + "payload": { + "title": "FindInstances Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "FindInstances Error Message", + "oneOf": [ + { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, + { "$ref": "../api/api.schema.json#/definitions/BridgingError" } + ] + } + }, + "required": ["error"], + "additionalProperties": false + }, + "meta": { + "title": "FindInstances Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findInstancesAgentRequest.schema.json b/website/static/schemas/2.1/bridging/findInstancesAgentRequest.schema.json new file mode 100644 index 000000000..900dd06d4 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findInstancesAgentRequest.schema.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findInstancesAgentRequest.schema.json", + "title": "FindInstances Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindInstancesRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "FindInstancesRequestBase": { + "title": "FindInstances Request", + "type": "object", + "description": "A request for details of instances of a particular app", + "properties":{ + "type": { + "title": "FindInstances Request Message Type", + "const": "findInstancesRequest" + }, + "payload": { + "type": "object", + "title": "FindInstances Request Payload", + "properties": { + "app": { + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + } + }, + "required": ["app"], + "additionalProperties": false + }, + "meta": { + "title": "FindInstances request metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "destination": { + "$ref": "common.schema.json#/$defs/AgentDestination" + }, + "source": { + "oneOf": [ + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + }, + { + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + } + ] + } + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findInstancesAgentResponse.schema.json b/website/static/schemas/2.1/bridging/findInstancesAgentResponse.schema.json new file mode 100644 index 000000000..4f68969f8 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findInstancesAgentResponse.schema.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findInstancesAgentResponse.schema.json", + "title": "FindInstances Agent Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindInstancesResponseBase" + }, + { + "$ref": "agentResponse.schema.json" + } + ], + "$defs": { + "FindInstancesResponseBase": { + "title": "FindInstances Response", + "type": "object", + "description": "A response to a findInstances request.", + "properties": { + "type": { + "title": "FindInstances Response Message Type", + "const": "findInstancesResponse" + }, + "payload": { + "title": "FindInstances Response Payload", + "type": "object", + "properties": { + "appIdentifiers": { + "type": "array", + "items": { + "$ref": "../api/api.schema.json#/definitions/AppMetadata" + } + } + }, + "required": ["appIdentifiers"], + "additionalProperties": false + }, + "meta": { + "title": "FindInstances Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findInstancesBridgeErrorResponse.schema.json b/website/static/schemas/2.1/bridging/findInstancesBridgeErrorResponse.schema.json new file mode 100644 index 000000000..f6397a9de --- /dev/null +++ b/website/static/schemas/2.1/bridging/findInstancesBridgeErrorResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findInstancesBridgeErrorResponse.schema.json", + "title": "FindInstances Bridge Error Response", + "type": "object", + "allOf": [ + { + "$ref": "findInstancesAgentErrorResponse.schema.json#/$defs/FindInstancesErrorResponseBase" + }, + { + "$ref": "bridgeErrorResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/findInstancesBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/findInstancesBridgeRequest.schema.json new file mode 100644 index 000000000..bf1f9b0f0 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findInstancesBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findInstancesBridgeRequest.schema.json", + "title": "FindInstances Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "findInstancesAgentRequest.schema.json#/$defs/FindInstancesRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/findInstancesBridgeResponse.schema.json b/website/static/schemas/2.1/bridging/findInstancesBridgeResponse.schema.json new file mode 100644 index 000000000..cd40c2883 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findInstancesBridgeResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findInstancesBridgeResponse.schema.json", + "title": "FindInstances Bridge Response", + "type": "object", + "allOf": [ + { + "$ref": "findInstancesAgentResponse.schema.json#/$defs/FindInstancesResponseBase" + }, + { + "$ref": "bridgeResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/findIntentAgentErrorResponse.schema.json b/website/static/schemas/2.1/bridging/findIntentAgentErrorResponse.schema.json new file mode 100644 index 000000000..23d7749b8 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentAgentErrorResponse.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentAgentErrorResponse.schema.json", + "title": "FindIntent Agent Error Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindIntentErrorResponseBase" + }, + { + "$ref": "agentErrorResponse.schema.json" + } + ], + "$defs": { + "FindIntentErrorResponseBase": { + "title": "FindIntent Error Response", + "type": "object", + "description": "A response to a findIntent request that contains an error.", + "properties": { + "type": { + "title": "FindIntent Response Message Type", + "const": "findIntentResponse" + }, + "payload": { + "title": "FindIntent Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "FindIntent Error Message", + "oneOf": [ + { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, + { "$ref": "../api/api.schema.json#/definitions/BridgingError" } + ] + } + }, + "required": ["error"], + "additionalProperties": false + }, + "meta": { + "title": "FindIntent Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findIntentAgentRequest.schema.json b/website/static/schemas/2.1/bridging/findIntentAgentRequest.schema.json new file mode 100644 index 000000000..7fd8b1b3d --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentAgentRequest.schema.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentAgentRequest.schema.json", + "title": "FindIntent Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindIntentRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "FindIntentRequestBase": { + "title": "FindIntent Request", + "type": "object", + "description": "A request for details of apps available to resolve a particular intent and context pair.", + "properties": { + "type": { + "title": "FindIntent Request Message Type", + "const": "findIntentRequest" + }, + "payload": { + "title": "FindIntent Request Payload", + "type": "object", + "properties": { + "intent": { + "title": "Intent name", + "type": "string" + }, + "context": { + "title": "Context argument", + "$ref": "../context/context.schema.json" + } + }, + "required": ["intent"], + "additionalProperties": false + }, + "meta": { + "title" : "FindIntent Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": true + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findIntentAgentResponse.schema.json b/website/static/schemas/2.1/bridging/findIntentAgentResponse.schema.json new file mode 100644 index 000000000..a71b69a77 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentAgentResponse.schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentAgentResponse.schema.json", + "title": "FindIntent Agent Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindIntentResponseBase" + }, + { + "$ref": "agentResponse.schema.json" + } + ], + "$defs": { + "FindIntentResponseBase": { + "title": "FindIntent Response", + "type": "object", + "description": "A response to a findIntent request.", + "properties": { + "type": { + "title": "FindIntent Response Message Type", + "const": "findIntentResponse" + }, + "payload": { + "title": "FindIntent Response Payload", + "type": "object", + "properties": { + "appIntent": { + "$ref": "../api/api.schema.json#/definitions/AppIntent" + } + }, + "required": ["appIntent"], + "additionalProperties": false + }, + "meta": { + "title": "FindIntent Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findIntentBridgeErrorResponse.schema.json b/website/static/schemas/2.1/bridging/findIntentBridgeErrorResponse.schema.json new file mode 100644 index 000000000..00ff7bdde --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentBridgeErrorResponse.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentBridgeErrorResponse.schema.json", + "title": "FindIntent Bridge Error Response", + "type": "object", + "allOf": [ + { + "$ref": "findIntentAgentErrorResponse.schema.json#/$defs/FindIntentErrorResponseBase" + }, + + { + "$ref": "bridgeErrorResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/findIntentBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/findIntentBridgeRequest.schema.json new file mode 100644 index 000000000..458a7e114 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentBridgeRequest.schema.json", + "title": "FindIntent Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "findIntentAgentRequest.schema.json#/$defs/FindIntentRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/findIntentBridgeResponse.schema.json b/website/static/schemas/2.1/bridging/findIntentBridgeResponse.schema.json new file mode 100644 index 000000000..d0da73404 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentBridgeResponse.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentBridgeResponse.schema.json", + "title": "FindIntent Bridge Response", + "type": "object", + "allOf": [ + { + "$ref": "findIntentAgentResponse.schema.json#/$defs/FindIntentResponseBase" + }, + + { + "$ref": "bridgeResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/findIntentsByContextAgentErrorResponse.schema.json b/website/static/schemas/2.1/bridging/findIntentsByContextAgentErrorResponse.schema.json new file mode 100644 index 000000000..f77695501 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentsByContextAgentErrorResponse.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextAgentErrorResponse.schema.json", + "title": "FindIntentsByContext Agent Error Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindIntentsByContextErrorResponseBase" + }, + { + "$ref": "agentErrorResponse.schema.json" + } + ], + "$defs": { + "FindIntentsByContextErrorResponseBase": { + "title": "FindIntentsByContext Error Response", + "type": "object", + "description": "A response to a findIntentsByContext request that contains an error.", + "properties": { + "type": { + "title": "FindIntentsByContext Response Message Type", + "const": "findIntentsByContextResponse" + }, + "payload": { + "title": "FindIntentsByContext Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "FindIntentsByContext Error Message", + "oneOf": [ + { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, + { "$ref": "../api/api.schema.json#/definitions/BridgingError" } + ] + } + }, + "additionalProperties": false, + "required": ["error"] + }, + "meta": { + "title": "FindIntentsByContext Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findIntentsByContextAgentRequest.schema.json b/website/static/schemas/2.1/bridging/findIntentsByContextAgentRequest.schema.json new file mode 100644 index 000000000..8ace4d65c --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentsByContextAgentRequest.schema.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextAgentRequest.schema.json", + "title": "FindIntentsByContext Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindIntentsByContextRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "FindIntentsByContextRequestBase": { + "title": "FindIntentsByContext Request", + "type": "object", + "description": "A request for details of intents and apps available to resolve them for a particular context.", + "properties": { + "type": { + "title": "FindIntentsByContext Request Message Type", + "const": "findIntentsByContextRequest" + }, + "payload": { + "title": "FindIntentsByContext Request Payload", + "type": "object", + "properties": { + "context": { + "$ref": "../context/context.schema.json" + } + }, + "required": ["context"], + "additionalProperties": false + }, + "meta": { + "title": "FindIntentsByContext Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + } + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findIntentsByContextAgentResponse.schema.json b/website/static/schemas/2.1/bridging/findIntentsByContextAgentResponse.schema.json new file mode 100644 index 000000000..c3ffa0e1a --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentsByContextAgentResponse.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextAgentResponse.schema.json", + "title": "FindIntentsByContext Agent Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/FindIntentsByContextResponseBase" + }, + { + "$ref": "agentResponse.schema.json" + } + ], + "$defs": { + "FindIntentsByContextResponseBase": { + "title": "FindIntentsByContext Response", + "type": "object", + "description": "A response to a findIntentsByContext request.", + "properties": { + "type": { + "title": "FindIntentsByContext Response Message Type", + "const": "findIntentsByContextResponse" + }, + "payload": { + "title": "FindIntentsByContext Response Payload", + "type": "object", + "properties": { + "appIntents": { + "type": "array", + "items": { + "$ref": "../api/api.schema.json#/definitions/AppIntent" + }, + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": ["appIntents"] + }, + "meta": { + "title": "FindIntentsByContext Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/findIntentsByContextBridgeErrorResponse.schema.json b/website/static/schemas/2.1/bridging/findIntentsByContextBridgeErrorResponse.schema.json new file mode 100644 index 000000000..9576ecacf --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentsByContextBridgeErrorResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextBridgeErrorResponse.schema.json", + "title": "FindIntentsByContext Bridge Error Response", + "type": "object", + "allOf": [ + { + "$ref": "findIntentsByContextAgentErrorResponse.schema.json#/$defs/FindIntentsByContextErrorResponseBase" + }, + { + "$ref": "bridgeErrorResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/findIntentsByContextBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/findIntentsByContextBridgeRequest.schema.json new file mode 100644 index 000000000..799d265f4 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentsByContextBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextBridgeRequest.schema.json", + "title": "FindIntentsByContext Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "findIntentsByContextAgentRequest.schema.json#/$defs/FindIntentsByContextRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/findIntentsByContextBridgeResponse.schema.json b/website/static/schemas/2.1/bridging/findIntentsByContextBridgeResponse.schema.json new file mode 100644 index 000000000..7fe622557 --- /dev/null +++ b/website/static/schemas/2.1/bridging/findIntentsByContextBridgeResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextBridgeResponse.schema.json", + "title": "FindIntentsByContext Bridge Response", + "type": "object", + "allOf": [ + { + "$ref": "findIntentsByContextAgentResponse.schema.json#/$defs/FindIntentsByContextResponseBase" + }, + { + "$ref": "bridgeResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/getAppMetadataAgentErrorResponse.schema.json b/website/static/schemas/2.1/bridging/getAppMetadataAgentErrorResponse.schema.json new file mode 100644 index 000000000..e5e2fab5b --- /dev/null +++ b/website/static/schemas/2.1/bridging/getAppMetadataAgentErrorResponse.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataAgentErrorResponse.schema.json", + "title": "GetAppMetadata Agent Error Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/GetAppMetadataErrorResponseBase" + }, + { + "$ref": "agentErrorResponse.schema.json" + } + ], + "$defs": { + "GetAppMetadataErrorResponseBase": { + "title": "GetAppMetadata Error Response", + "type": "object", + "description": "A response to a getAppMetadata request that contains an error.", + "properties": { + "type": { + "title": "GetAppMetadata Response Message Type", + "const": "getAppMetadataResponse" + }, + "payload": { + "title": "GetAppMetadata Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "GetAppMetadata Error Message", + "oneOf": [ + { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, + { "$ref": "../api/api.schema.json#/definitions/BridgingError" } + ] + } + }, + "required": ["error"], + "additionalProperties": false + }, + "meta": { + "title": "GetAppMetadata Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/getAppMetadataAgentRequest.schema.json b/website/static/schemas/2.1/bridging/getAppMetadataAgentRequest.schema.json new file mode 100644 index 000000000..64e6217fa --- /dev/null +++ b/website/static/schemas/2.1/bridging/getAppMetadataAgentRequest.schema.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataAgentRequest.schema.json", + "title": "GetAppMetadata Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/GetAppMetadataRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "GetAppMetadataRequestBase": { + "title": "GetAppMetadata Request", + "type": "object", + "description": "A request for metadata about an app", + "properties": { + "type": { + "title": "GetAppMetadata Request Message Type", + "const": "getAppMetadataRequest" + }, + "payload": { + "title": "GetAppMetadata Request Payload", + "type": "object", + "properties": { + "app": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "required": ["app"], + "additionalProperties": false + }, + "meta": { + "title" : "GetAppMetadata Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "destination": { + "$ref": "common.schema.json#/$defs/AgentDestination" + }, + "source": { + "$ref": "common.schema.json#/$defs/RequestSource" + } + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/getAppMetadataAgentResponse.schema.json b/website/static/schemas/2.1/bridging/getAppMetadataAgentResponse.schema.json new file mode 100644 index 000000000..fba358416 --- /dev/null +++ b/website/static/schemas/2.1/bridging/getAppMetadataAgentResponse.schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataAgentResponse.schema.json", + "title": "GetAppMetadata Agent Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/GetAppMetadataResponseBase" + }, + { + "$ref": "agentResponse.schema.json" + } + ], + "$defs": { + "GetAppMetadataResponseBase": { + "title": "GetAppMetadata Response", + "type": "object", + "description": "A response to a getAppMetadata request.", + "properties": { + "type": { + "title": "GetAppMetadata Response Message Type", + "const": "getAppMetadataResponse" + }, + "payload": { + "title": "GetAppMetadata Response Payload", + "type": "object", + "properties": { + "appMetadata": { + "$ref": "../api/api.schema.json#/definitions/AppMetadata" + } + }, + "required": ["appMetadata"], + "additionalProperties": false + }, + "meta": { + "title": "GetAppMetadata Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/getAppMetadataBridgeErrorResponse.schema.json b/website/static/schemas/2.1/bridging/getAppMetadataBridgeErrorResponse.schema.json new file mode 100644 index 000000000..089ce18dc --- /dev/null +++ b/website/static/schemas/2.1/bridging/getAppMetadataBridgeErrorResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataBridgeErrorResponse.schema.json", + "title": "GetAppMetadata Bridge Error Response", + "type": "object", + "allOf": [ + { + "$ref": "getAppMetadataAgentErrorResponse.schema.json#/$defs/GetAppMetadataErrorResponseBase" + }, + { + "$ref": "bridgeErrorResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/getAppMetadataBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/getAppMetadataBridgeRequest.schema.json new file mode 100644 index 000000000..7e463d703 --- /dev/null +++ b/website/static/schemas/2.1/bridging/getAppMetadataBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataBridgeRequest.schema.json", + "title": "GetAppMetadata Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "getAppMetadataAgentRequest.schema.json#/$defs/GetAppMetadataRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/getAppMetadataBridgeResponse.schema.json b/website/static/schemas/2.1/bridging/getAppMetadataBridgeResponse.schema.json new file mode 100644 index 000000000..59edbeb9e --- /dev/null +++ b/website/static/schemas/2.1/bridging/getAppMetadataBridgeResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataBridgeResponse.schema.json", + "title": "GetAppMetadata Bridge Response", + "type": "object", + "allOf": [ + { + "$ref": "getAppMetadataAgentResponse.schema.json#/$defs/GetAppMetadataResponseBase" + }, + { + "$ref": "bridgeResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/openAgentErrorResponse.schema.json b/website/static/schemas/2.1/bridging/openAgentErrorResponse.schema.json new file mode 100644 index 000000000..cedc0adce --- /dev/null +++ b/website/static/schemas/2.1/bridging/openAgentErrorResponse.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/openAgentErrorResponse.schema.json", + "title": "Open Agent Error Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/OpenErrorResponseBase" + }, + { + "$ref": "agentErrorResponse.schema.json" + } + ], + "$defs": { + "OpenErrorResponseBase": { + "title": "Open Error Response", + "type": "object", + "description": "A response to an open request that contains an error", + "properties": { + "type": { + "title": "Open Response Message Type", + "const": "openResponse" + }, + "payload": { + "title": "Open Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "Open Error Message", + "oneOf": [ + { "$ref": "../api/api.schema.json#/definitions/OpenError" }, + { "$ref": "../api/api.schema.json#/definitions/BridgingError" } + ] + } + }, + "required": ["error"], + "additionalProperties": false + }, + "meta": { + "title": "Open Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/openAgentRequest.schema.json b/website/static/schemas/2.1/bridging/openAgentRequest.schema.json new file mode 100644 index 000000000..7f4ec4888 --- /dev/null +++ b/website/static/schemas/2.1/bridging/openAgentRequest.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/openAgentRequest.schema.json", + "title": "Open Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/OpenRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "OpenRequestBase": { + "title": "Open Request", + "type": "object", + "description": "A request to open an application", + "properties": { + "type": { + "title": "Open Request Message Type", + "const": "openRequest" + }, + "payload": { + "title": "Open Request Payload", + "type": "object", + "properties": { + "app": { + "type": "object", + "title": "App to open", + "description": "The application to open on the specified Desktop Agent", + "allOf": [ + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + }, + { + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + } + ] + }, + "context": { + "$ref": "../context/context.schema.json" + } + }, + "required": ["app"], + "additionalProperties": false + }, + "meta": { + "title": "Open Request Metadata", + "properties": { + "requestUuid": true, + "timestamp": true, + "destination": { + "$ref": "common.schema.json#/$defs/AgentDestination" + }, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + } + }, + "required": ["source"], + "additionalProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/openAgentResponse.schema.json b/website/static/schemas/2.1/bridging/openAgentResponse.schema.json new file mode 100644 index 000000000..1d7490638 --- /dev/null +++ b/website/static/schemas/2.1/bridging/openAgentResponse.schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/openAgentResponse.schema.json", + "title": "Open Agent Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/OpenResponseBase" + }, + { + "$ref": "agentResponse.schema.json" + } + ], + "$defs": { + "OpenResponseBase": { + "title": "Open Response", + "type": "object", + "description": "A response to an open request", + "properties": { + "type": { + "title": "Open Response Message Type", + "const": "openResponse" + }, + "payload": { + "title": "Open Response Payload", + "type": "object", + "properties": { + "appIdentifier": { + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + } + }, + "required": ["appIdentifier"], + "additionalProperties": false + }, + "meta": { + "title": "Open Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/openBridgeErrorResponse.schema.json b/website/static/schemas/2.1/bridging/openBridgeErrorResponse.schema.json new file mode 100644 index 000000000..9eebf6f3e --- /dev/null +++ b/website/static/schemas/2.1/bridging/openBridgeErrorResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/openBridgeErrorResponse.schema.json", + "title": "Open Bridge Error Response", + "type": "object", + "allOf": [ + { + "$ref": "openAgentErrorResponse.schema.json#/$defs/OpenErrorResponseBase" + }, + { + "$ref": "bridgeErrorResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/openBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/openBridgeRequest.schema.json new file mode 100644 index 000000000..d6b4c2177 --- /dev/null +++ b/website/static/schemas/2.1/bridging/openBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/openBridgeRequest.schema.json", + "title": "Open Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "openAgentRequest.schema.json#/$defs/OpenRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/openBridgeResponse.schema.json b/website/static/schemas/2.1/bridging/openBridgeResponse.schema.json new file mode 100644 index 000000000..253250d6f --- /dev/null +++ b/website/static/schemas/2.1/bridging/openBridgeResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/openBridgeResponse.schema.json", + "title": "Open Bridge Response", + "type": "object", + "allOf": [ + { + "$ref": "openAgentResponse.schema.json#/$defs/OpenResponseBase" + }, + { + "$ref": "bridgeResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/privateChannelBroadcastAgentRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelBroadcastAgentRequest.schema.json new file mode 100644 index 000000000..4dffc22d3 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelBroadcastAgentRequest.schema.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelBroadcastAgentRequest.schema.json", + "title": "PrivateChannelBroadcast Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/PrivateChannelBroadcastRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "PrivateChannelBroadcastRequestBase": { + "title": "PrivateChannelBroadcast Request", + "type": "object", + "description": "A request to broadcast on a PrivateChannel.", + "properties": { + "type": { + "title": "Private Channel Broadcast Message type", + "const": "PrivateChannel.broadcast" + }, + "payload": { + "title": "PrivateChannelBroadcast Request Payload", + "type": "object", + "properties": { + "channel": { + "type": "string", + "title": "Channel Id", + "description": "The Id of the PrivateChannel that the broadcast was sent on" + }, + "context": { + "$ref": "../context/context.schema.json", + "title": "Context", + "description": "The context object that was the payload of a broadcast message." + } + }, + "additionalProperties": false, + "required": ["channelId", "context"] + }, + "meta": { + "title": "PrivateChannelBroadcast Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + }, + "destination": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/privateChannelBroadcastBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelBroadcastBridgeRequest.schema.json new file mode 100644 index 000000000..0116f2022 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelBroadcastBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelBroadcastBridgeRequest.schema.json", + "title": "PrivateChannelBroadcast Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "privateChannelBroadcastAgentRequest.schema.json#/$defs/PrivateChannelBroadcastRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/privateChannelEventListenerAddedAgentRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelEventListenerAddedAgentRequest.schema.json new file mode 100644 index 000000000..cc84c5fb1 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelEventListenerAddedAgentRequest.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelEventListenerAddedAgentRequest.schema.json", + "title": "PrivateChannelEventListenerAdded Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/PrivateChannelEventListenerAddedRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "PrivateChannelEventListenerAddedRequestBase": { + "title": "PrivateChannelEventListenerAdded Request", + "type": "object", + "description": "A request to forward on an EventListenerAdded event, relating to a PrivateChannel", + "properties": { + "type": { + "title": "Private Channel EventListenerAdded Message type", + "const": "PrivateChannel.eventListenerAdded" + }, + "payload": { + "title": "PrivateChannelEventListenerAdded Request Payload", + "type": "object", + "properties": { + "channel": { + "type": "string" + }, + "context": { + "type": "string" + } + }, + "additionalProperties": false, + "required": ["channel", "context"] + }, + "meta": { + "title": "PrivateChannelEventListenerAdded Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + }, + "destination": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/privateChannelEventListenerAddedBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelEventListenerAddedBridgeRequest.schema.json new file mode 100644 index 000000000..d346ac056 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelEventListenerAddedBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelEventListenerAddedBridgeRequest.schema.json", + "title": "PrivateChannelEventListenerAdded Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "privateChannelEventListenerAddedAgentRequest.schema.json#/$defs/PrivateChannelEventListenerAddedRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json new file mode 100644 index 000000000..4a0ed1b4e --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json", + "title": "PrivateChannelEventListenerRemoved Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/PrivateChannelEventListenerRemovedRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "PrivateChannelEventListenerRemovedRequestBase": { + "title": "PrivateChannelEventListenerRemoved Request", + "type": "object", + "description": "A request to forward on an EventListenerRemoved event, relating to a PrivateChannel", + "properties": { + "type": { + "title": "Private Channel EventListenerRemoved Message type", + "const": "PrivateChannel.eventListenerRemoved" + }, + "payload": { + "title": "PrivateChannelEventListenerRemoved Request Payload", + "type": "object", + "properties": { + "channel": { + "type": "string" + }, + "listenerType": { + "type": "string" + } + }, + "additionalProperties": false, + "required": ["channel", "listenerType"] + }, + "meta": { + "title": "PrivateChannelEventListenerRemoved Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + }, + "destination": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/privateChannelEventListenerRemovedBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelEventListenerRemovedBridgeRequest.schema.json new file mode 100644 index 000000000..1febecfb2 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelEventListenerRemovedBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelEventListenerRemovedBridgeRequest.schema.json", + "title": "PrivateChannelEventListenerRemoved Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "privateChannelEventListenerRemovedAgentRequest.schema.json#/$defs/PrivateChannelEventListenerRemovedRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/privateChannelOnAddContextListenerAgentRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelOnAddContextListenerAgentRequest.schema.json new file mode 100644 index 000000000..c068cdfbf --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelOnAddContextListenerAgentRequest.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnAddContextListenerAgentRequest.schema.json", + "title": "PrivateChannelOnAddContextListener Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/PrivateChannelOnAddContextListenerRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "PrivateChannelOnAddContextListenerRequestBase": { + "title": "PrivateChannelOnAddContextListener Request", + "type": "object", + "description": "A request to forward on an AddContextListener event, relating to a PrivateChannel", + "properties": { + "type": { + "title": "Private Channel OnAddContextListener Message type", + "const": "PrivateChannel.onAddContextListener" + }, + "payload": { + "title": "PrivateChannelOnAddContextListener Request Payload", + "type": "object", + "properties": { + "channel": { + "type": "string" + }, + "contextType": { + "type": "string" + } + }, + "additionalProperties": false, + "required": ["channel", "contextType"] + }, + "meta": { + "title": "PrivateChannelOnAddContextListener Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + }, + "destination": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/privateChannelOnAddContextListenerBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelOnAddContextListenerBridgeRequest.schema.json new file mode 100644 index 000000000..7f16c6861 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelOnAddContextListenerBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnAddContextListenerBridgeRequest.schema.json", + "title": "PrivateChannelOnAddContextListener Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "privateChannelOnAddContextListenerAgentRequest.schema.json#/$defs/PrivateChannelOnAddContextListenerRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/privateChannelOnDisconnectAgentRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelOnDisconnectAgentRequest.schema.json new file mode 100644 index 000000000..ae72691f9 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelOnDisconnectAgentRequest.schema.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnDisconnectAgentRequest.schema.json", + "title": "PrivateChannelOnDisconnect Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/PrivateChannelOnDisconnectRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "PrivateChannelOnDisconnectRequestBase": { + "title": "PrivateChannelOnDisconnect Request", + "type": "object", + "description": "A request to forward on a Disconnect event, relating to a PrivateChannel", + "properties": { + "type": { + "title": "Private Channel OnDisconnect Message type", + "const": "PrivateChannel.onDisconnect" + }, + "payload": { + "title": "PrivateChannelOnDisconnect Request Payload", + "type": "object", + "properties": { + "channel": { + "type": "string" + } + }, + "additionalProperties": false, + "required": ["channel"] + }, + "meta": { + "title": "PrivateChannelOnDisconnect Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + }, + "destination": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "unevaluatedProperties": false + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/privateChannelOnDisconnectBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelOnDisconnectBridgeRequest.schema.json new file mode 100644 index 000000000..b744ef082 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelOnDisconnectBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnDisconnectBridgeRequest.schema.json", + "title": "PrivateChannelOnDisconnect Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "privateChannelOnDisconnectAgentRequest.schema.json#/$defs/PrivateChannelOnDisconnectRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/privateChannelOnUnsubscribeAgentRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelOnUnsubscribeAgentRequest.schema.json new file mode 100644 index 000000000..409b462f1 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelOnUnsubscribeAgentRequest.schema.json @@ -0,0 +1,56 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnUnsubscribeAgentRequest.schema.json", + "title": "PrivateChannelOnUnsubscribe Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/PrivateChannelOnUnsubscribeRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "PrivateChannelOnUnsubscribeRequestBase": { + "title": "PrivateChannelOnUnsubscribe Request", + "type": "object", + "description": "A request to forward on an Unsubscribe event, relating to a PrivateChannel", + "properties": { + "type": { + "title": "Private Channel OnUnsubscribe Message type", + "const": "PrivateChannel.onUnsubscribe" + }, + "payload": { + "title": "PrivateChannelOnUnsubscribe Request Payload", + "type": "object", + "properties": { + "channel": { + "type": "string" + }, + "contextType": { + "type": "string" + } + }, + "additionalProperties": false, + "required": ["channel", "contextType"] + }, + "meta": { + "title": "PrivateChannelOnUnsubscribe Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + }, + "destination": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "unevaluatedProperties": false + } + } + } + } +} diff --git a/website/static/schemas/2.1/bridging/privateChannelOnUnsubscribeBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/privateChannelOnUnsubscribeBridgeRequest.schema.json new file mode 100644 index 000000000..e44db8d43 --- /dev/null +++ b/website/static/schemas/2.1/bridging/privateChannelOnUnsubscribeBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnUnsubscribeBridgeRequest.schema.json", + "title": "PrivateChannelOnUnsubscribe Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "privateChannelOnUnsubscribeAgentRequest.schema.json#/$defs/PrivateChannelOnUnsubscribeRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentAgentErrorResponse.schema.json b/website/static/schemas/2.1/bridging/raiseIntentAgentErrorResponse.schema.json new file mode 100644 index 000000000..564e4062e --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentAgentErrorResponse.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentAgentErrorResponse.schema.json", + "title": "RaiseIntent Agent Error Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/RaiseIntentErrorResponseBase" + }, + { + "$ref": "agentErrorResponse.schema.json" + } + ], + "$defs": { + "RaiseIntentErrorResponseBase": { + "title": "RaiseIntent Error Response", + "type": "object", + "description": "A response to a request to raise an intent that contains an error.", + "properties": { + "type": { + "title": "RaiseIntent Response Message type", + "const": "raiseIntentResponse" + }, + "payload": { + "title": "RaiseIntent Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "RaiseIntent Error Message", + "oneOf": [ + { "$ref": "../api/api.schema.json#/definitions/ResolveError" }, + { "$ref": "../api/api.schema.json#/definitions/BridgingError" } + ] + } + }, + "required": ["error"], + "additionalProperties": false + }, + "meta": { + "title": "RaiseIntent Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentAgentRequest.schema.json b/website/static/schemas/2.1/bridging/raiseIntentAgentRequest.schema.json new file mode 100644 index 000000000..ab75d517d --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentAgentRequest.schema.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentAgentRequest.schema.json", + "title": "RaiseIntent Agent Request", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/RaiseIntentRequestBase" + }, + { + "$ref": "agentRequest.schema.json" + } + ], + "$defs": { + "RaiseIntentRequestBase": { + "title": "RaiseIntent Request", + "type": "object", + "description": "A request to raise an intent.", + "properties": { + "type": { + "title": "RaiseIntent Request Message type", + "const": "raiseIntentRequest" + }, + "payload": { + "title": "RaiseIntent Request Payload", + "type": "object", + "properties": { + "intent": { + "type": "string" + }, + "context": { + "$ref": "../context/context.schema.json" + }, + "app": { + "$ref": "common.schema.json#/$defs/AppDestination" + } + }, + "required": ["intent", "context", "app"], + "additionalProperties": false + }, + "meta": { + "title": "RaiseIntent Request Metadata", + "type": "object", + "properties": { + "requestUuid": true, + "timestamp": true, + "destination": { + "$ref": "common.schema.json#/$defs/AppDestination" + }, + "source": { + "$ref": "common.schema.json#/$defs/AppRequestSource" + } + }, + "unevaluatedProperties": false, + "required": ["requestUuid","timestamp","destination","source"] + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentAgentResponse.schema.json b/website/static/schemas/2.1/bridging/raiseIntentAgentResponse.schema.json new file mode 100644 index 000000000..997255a44 --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentAgentResponse.schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentAgentResponse.schema.json", + "title": "RaiseIntent Agent Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/RaiseIntentResponseBase" + }, + { + "$ref": "agentResponse.schema.json" + } + ], + "$defs": { + "RaiseIntentResponseBase": { + "title": "RaiseIntent Response", + "type": "object", + "description": "A response to a request to raise an intent.", + "properties": { + "type": { + "title": "RaiseIntent Response Message type", + "const": "raiseIntentResponse" + }, + "payload": { + "title": "RaiseIntent Response Payload", + "type": "object", + "properties": { + "intentResolution": { + "$ref": "../api/api.schema.json#/definitions/IntentResolution" + } + }, + "required": ["intentResolution"], + "additionalProperties": false + }, + "meta": { + "title": "RaiseIntent Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentBridgeErrorResponse.schema.json b/website/static/schemas/2.1/bridging/raiseIntentBridgeErrorResponse.schema.json new file mode 100644 index 000000000..fb0c63955 --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentBridgeErrorResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentBridgeErrorResponse.schema.json", + "title": "RaiseIntent Bridge Error Response", + "type": "object", + "allOf": [ + { + "$ref": "raiseIntentAgentErrorResponse.schema.json#/$defs/RaiseIntentErrorResponseBase" + }, + { + "$ref": "bridgeErrorResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentBridgeRequest.schema.json b/website/static/schemas/2.1/bridging/raiseIntentBridgeRequest.schema.json new file mode 100644 index 000000000..c88091ac0 --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentBridgeRequest.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentBridgeRequest.schema.json", + "title": "RaiseIntent Bridge Request", + "type": "object", + "allOf": [ + { + "$ref": "raiseIntentAgentRequest.schema.json#/$defs/RaiseIntentRequestBase" + }, + { + "$ref": "bridgeRequest.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentBridgeResponse.schema.json b/website/static/schemas/2.1/bridging/raiseIntentBridgeResponse.schema.json new file mode 100644 index 000000000..5163e1a55 --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentBridgeResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentBridgeResponse.schema.json", + "title": "RaiseIntent Bridge Response", + "type": "object", + "allOf": [ + { + "$ref": "raiseIntentAgentResponse.schema.json#/$defs/RaiseIntentResponseBase" + }, + { + "$ref": "bridgeResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentResultAgentErrorResponse.schema.json b/website/static/schemas/2.1/bridging/raiseIntentResultAgentErrorResponse.schema.json new file mode 100644 index 000000000..7b6fa83f6 --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentResultAgentErrorResponse.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentResultAgentErrorResponse.schema.json", + "title": "RaiseIntent Result Agent Error Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/RaiseIntentResultErrorResponseBase" + }, + { + "$ref": "agentErrorResponse.schema.json" + } + ], + "$defs": { + "RaiseIntentResultErrorResponseBase": { + "title": "RaiseIntent Result Error Response", + "type": "object", + "description": "A secondary response to a request to raise an intent used to deliver the intent result, which contains an error", + "properties": { + "type": { + "title": "RaiseIntent Result Response Message type", + "const": "raiseIntentResultResponse" + }, + "payload": { + "title": "RaiseIntent Result Error Response Payload", + "type": "object", + "properties": { + "error": { + "title": "RaiseIntent Result Error Message", + "oneOf": [ + { "$ref": "../api/api.schema.json#/definitions/ResultError" }, + { "$ref": "../api/api.schema.json#/definitions/BridgingError" } + ] + } + }, + "required": ["error"], + "additionalProperties": false + }, + "meta": { + "title": "RaiseIntent Result Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentResultAgentResponse.schema.json b/website/static/schemas/2.1/bridging/raiseIntentResultAgentResponse.schema.json new file mode 100644 index 000000000..afe63ceba --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentResultAgentResponse.schema.json @@ -0,0 +1,73 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentResultAgentResponse.schema.json", + "title": "RaiseIntent Result Agent Response", + "type": "object", + "allOf": [ + { + "$ref": "#/$defs/RaiseIntentResultResponseBase" + }, + { + "$ref": "agentResponse.schema.json" + } + ], + "$defs": { + "RaiseIntentResultResponseBase": { + "title": "RaiseIntent Result Response", + "type": "object", + "description": "A secondary response to a request to raise an intent used to deliver the intent result", + "properties": { + "type": { + "title": "RaiseIntent Result Response Message type", + "const": "raiseIntentResultResponse" + }, + "payload": { + "title": "RaiseIntent Result Response Payload", + "type": "object", + "properties": { + "intentResult": { + "title": "IntentResult", + "anyOf": [ + { + "type": "object", + "title": "IntentResult Context", + "properties": { + "context": { + "$ref": "../context/context.schema.json" + } + }, + "required": ["context"], + "additionalProperties": false + }, + { + "type": "object", + "title": "IntentResult Channel", + "properties": { + "channel": { + "$ref": "../api/api.schema.json#/definitions/Channel" + } + }, + "required": ["channel"], + "additionalProperties": false + }, + { + "type": "object", + "title": "IntentResult Void", + "properties": {}, + "additionalProperties": false + } + ] + } + }, + "required": ["intentResult"], + "additionalProperties": false + }, + "meta": { + "title": "RaiseIntent Result Response Metadata", + "type": "object" + } + }, + "additionalProperties": false + } + } +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentResultBridgeErrorResponse.schema.json b/website/static/schemas/2.1/bridging/raiseIntentResultBridgeErrorResponse.schema.json new file mode 100644 index 000000000..9ce064ec8 --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentResultBridgeErrorResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentResultBridgeErrorResponse.schema.json", + "title": "RaiseIntent Result Bridge Error Response", + "type": "object", + "allOf": [ + { + "$ref": "raiseIntentResultAgentErrorResponse.schema.json#/$defs/RaiseIntentResultErrorResponseBase" + }, + { + "$ref": "bridgeErrorResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridging/raiseIntentResultBridgeResponse.schema.json b/website/static/schemas/2.1/bridging/raiseIntentResultBridgeResponse.schema.json new file mode 100644 index 000000000..7a2e28edb --- /dev/null +++ b/website/static/schemas/2.1/bridging/raiseIntentResultBridgeResponse.schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentResultBridgeResponse.schema.json", + "title": "RaiseIntent Result Bridge Response", + "type": "object", + "allOf": [ + { + "$ref": "raiseIntentResultAgentResponse.schema.json#/$defs/RaiseIntentResultResponseBase" + }, + { + "$ref": "bridgeResponse.schema.json" + } + ] +} diff --git a/website/static/schemas/2.1/bridgingAsyncAPI/README.md b/website/static/schemas/2.1/bridgingAsyncAPI/README.md new file mode 100644 index 000000000..f097af5b5 --- /dev/null +++ b/website/static/schemas/2.1/bridgingAsyncAPI/README.md @@ -0,0 +1,38 @@ +# Agent Bridging AsyncAPI schema + +This folder contains an AsyncAPI schema that may be used to generate clients and server stubs for Desktop Agent Bridging. It is based on references to the JSON schema files that define the various messages in the adjacent schemas/bridging folder. + +Example commands to generate code from the AsyncAPI schema: +(run from the root of your FDC3 checkout) + +First run: + +```ps +npm install -g @asyncapi/generator +``` + +Then: + +- .NET + + ```ps + ag --install schemas/bridgingAsyncAPI/bridgingAsyncAPI.json @asyncapi/dotnet-nats-template -o ../some/path/outside/FDC3/folder + ``` + +- Node.js + + ```ps + ag --install schemas/bridgingAsyncAPI/bridgingAsyncAPI.json @asyncapi/nodejs-ws-template -o ../some/path/outside/FDC3/folder -p server=local + ``` + +- Markdown + + ```ps + ag --install schemas/bridgingAsyncAPI/bridgingAsyncAPI.json @asyncapi/markdown-template -o ../some/path/outside/FDC3/folder + ``` + +- HTML + + ```ps + ag --install schemas/bridgingAsyncAPI/bridgingAsyncAPI.json @asyncapi/html-template -o ../some/path/outside/FDC3/folder + ``` diff --git a/website/static/schemas/2.1/bridgingAsyncAPI/bridgingAsyncAPI.json b/website/static/schemas/2.1/bridgingAsyncAPI/bridgingAsyncAPI.json new file mode 100644 index 000000000..657a4212c --- /dev/null +++ b/website/static/schemas/2.1/bridgingAsyncAPI/bridgingAsyncAPI.json @@ -0,0 +1,407 @@ +{ + "asyncapi": "2.6.0", + "info": { + "title": "Desktop Agent Bridge", + "version": "1.0.0", + "description": "API for an FDC3 Desktop Agent to communicate with an FDC3 Desktop Agent Bridge and through it, other Desktop Agents.", + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0" + } + }, + "servers": { + "local": { + "url": "ws://localhost:4475", + "description": "Desktop agent bridge server exposing websocket connection", + "protocol": "ws" + } + }, + "defaultContentType": "application/json", + "channels": { + "/": { + "publish": { + "message": { + "oneOf": [ + { + "$ref": "#/components/messages/handshake" + }, + { + "$ref": "#/components/messages/broadcastRequest-Agent" + }, + { + "$ref": "#/components/messages/findInstancesRequest-Agent" + }, + { + "$ref": "#/components/messages/findInstancesResponse-Agent" + }, + { + "$ref": "#/components/messages/findInstancesErrorResponse-Agent" + }, + { + "$ref": "#/components/messages/findIntentRequest-Agent" + }, + { + "$ref": "#/components/messages/findIntentResponse-Agent" + }, + { + "$ref": "#/components/messages/findIntentErrorResponse-Agent" + }, + { + "$ref": "#/components/messages/findIntentsByContextRequest-Agent" + }, + { + "$ref": "#/components/messages/findIntentsByContextResponse-Agent" + }, + { + "$ref": "#/components/messages/findIntentsByContextErrorResponse-Agent" + }, + { + "$ref": "#/components/messages/getAppMetadataRequest-Agent" + }, + { + "$ref": "#/components/messages/getAppMetadataResponse-Agent" + }, + { + "$ref": "#/components/messages/getAppMetadataErrorResponse-Agent" + }, + { + "$ref": "#/components/messages/openRequest-Agent" + }, + { + "$ref": "#/components/messages/openResponse-Agent" + }, + { + "$ref": "#/components/messages/openErrorResponse-Agent" + }, + { + "$ref": "#/components/messages/raiseIntentRequest-Agent" + }, + { + "$ref": "#/components/messages/raiseIntentResponse-Agent" + }, + { + "$ref": "#/components/messages/raiseIntentErrorResponse-Agent" + }, + { + "$ref": "#/components/messages/privateChannelBroadcast-Agent" + }, + { + "$ref": "#/components/messages/privateChannelEventListenerAdded-Agent" + }, + { + "$ref": "#/components/messages/privateChannelEventListenerRemoved-Agent" + }, + { + "$ref": "#/components/messages/privateChannelOnAddContextListener-Agent" + }, + { + "$ref": "#/components/messages/privateChannelOnDisconnect-Agent" + }, + { + "$ref": "#/components/messages/privateChannelOnUnsubscribe-Agent" + }, + { + "$ref": "#/components/messages/privateChannelOnDisconnect-Agent" + }, + { + "$ref": "#/components/messages/raiseIntentResultResponse-Agent" + }, + { + "$ref": "#/components/messages/raiseIntentResultErrorResponse-Agent" + } + ] + }, + "description": "Messages sent by A Desktop Agent to a Bridge", + "operationId": "Send" + }, + "subscribe": { + "message": { + "oneOf": [ + { + "$ref": "#/components/messages/hello" + }, + { + "$ref": "#/components/messages/authenticationFailed" + }, + { + "$ref": "#/components/messages/connectedAgentsUpdate" + }, + { + "$ref": "#/components/messages/findInstancesResponse-Bridge" + }, + { + "$ref": "#/components/messages/findInstancesErrorResponse-Bridge" + }, + { + "$ref": "#/components/messages/findIntentResponse-Bridge" + }, + { + "$ref": "#/components/messages/findIntentErrorResponse-Bridge" + }, + { + "$ref": "#/components/messages/findIntentsByContextResponse-Bridge" + }, + { + "$ref": "#/components/messages/findIntentsByContextErrorResponse-Bridge" + }, + { + "$ref": "#/components/messages/getAppMetadataResponse-Bridge" + }, + { + "$ref": "#/components/messages/getAppMetadataErrorResponse-Bridge" + }, + { + "$ref": "#/components/messages/openResponse-Bridge" + }, + { + "$ref": "#/components/messages/openErrorResponse-Bridge" + }, + { + "$ref": "#/components/messages/raiseIntentResponse-Bridge" + }, + { + "$ref": "#/components/messages/raiseIntentErrorResponse-Bridge" + }, + { + "$ref": "#/components/messages/raiseIntentResultResponse-Bridge" + }, + { + "$ref": "#/components/messages/raiseIntentResultErrorResponse-Bridge" + } + ] + }, + "description": "Messages sent by a Bridge to a Desktop Agent", + "operationId": "Receive" + } + } + }, + "components": { + "messages": { + "broadcastRequest-Agent": { + "payload": { + "$ref": "../bridging/broadcastAgentRequest.schema.json#" + } + }, + "hello": { + "payload": { + "$ref": "../bridging/connectionStep2Hello.schema.json#" + } + }, + "handshake": { + "payload": { + "$ref": "../bridging/connectionStep3Handshake.schema.json#" + } + }, + "authenticationFailed": { + "payload": { + "$ref": "../bridging/connectionStep4AuthenticationFailed.schema.json#" + } + }, + "connectedAgentsUpdate": { + "payload": { + "$ref": "../bridging/connectionStep6ConnectedAgentsUpdate.schema.json#" + } + }, + "findInstancesRequest-Agent": { + "payload": { + "$ref": "../bridging/findInstancesAgentRequest.schema.json#" + } + }, + "findInstancesResponse-Agent": { + "payload": { + "$ref": "../bridging/findInstancesAgentResponse.schema.json#" + } + }, + "findInstancesErrorResponse-Agent": { + "payload": { + "$ref": "../bridging/findInstancesAgentErrorResponse.schema.json#" + } + }, + "findInstancesResponse-Bridge": { + "payload": { + "$ref": "../bridging/findInstancesBridgeResponse.schema.json#" + } + }, + "findInstancesErrorResponse-Bridge": { + "payload": { + "$ref": "../bridging/findInstancesBridgeErrorResponse.schema.json#" + } + }, + "findIntentRequest-Agent": { + "payload": { + "$ref": "../bridging/findIntentAgentRequest.schema.json#" + } + }, + "findIntentResponse-Agent": { + "payload": { + "$ref": "../bridging/findIntentAgentResponse.schema.json#" + } + }, + "findIntentErrorResponse-Agent": { + "payload": { + "$ref": "../bridging/findIntentAgentErrorResponse.schema.json#" + } + }, + "findIntentResponse-Bridge": { + "payload": { + "$ref": "../bridging/findIntentBridgeResponse.schema.json#" + } + }, + "findIntentErrorResponse-Bridge": { + "payload": { + "$ref": "../bridging/findIntentBridgeErrorResponse.schema.json#" + } + }, + "findIntentsByContextRequest-Agent": { + "payload": { + "$ref": "../bridging/findIntentsByContextAgentRequest.schema.json#" + } + }, + "findIntentsByContextResponse-Agent": { + "payload": { + "$ref": "../bridging/findIntentsByContextAgentResponse.schema.json#" + } + }, + "findIntentsByContextErrorResponse-Agent": { + "payload": { + "$ref": "../bridging/findIntentsByContextAgentErrorResponse.schema.json#" + } + }, + "findIntentsByContextResponse-Bridge": { + "payload": { + "$ref": "../bridging/findIntentsByContextBridgeResponse.schema.json#" + } + }, + "findIntentsByContextErrorResponse-Bridge": { + "payload": { + "$ref": "../bridging/findIntentsByContextBridgeErrorResponse.schema.json#" + } + }, + "getAppMetadataRequest-Agent": { + "payload": { + "$ref": "../bridging/getAppMetadataAgentRequest.schema.json#" + } + }, + "getAppMetadataResponse-Agent": { + "payload": { + "$ref": "../bridging/getAppMetadataAgentResponse.schema.json#" + } + }, + "getAppMetadataErrorResponse-Agent": { + "payload": { + "$ref": "../bridging/getAppMetadataAgentErrorResponse.schema.json#" + } + }, + "getAppMetadataResponse-Bridge": { + "payload": { + "$ref": "../bridging/getAppMetadataBridgeResponse.schema.json#" + } + }, + "getAppMetadataErrorResponse-Bridge": { + "payload": { + "$ref": "../bridging/getAppMetadataBridgeErrorResponse.schema.json#" + } + }, + "openRequest-Agent": { + "payload": { + "$ref": "../bridging/openAgentRequest.schema.json#" + } + }, + "openResponse-Agent": { + "payload": { + "$ref": "../bridging/openAgentResponse.schema.json#" + } + }, + "openErrorResponse-Agent": { + "payload": { + "$ref": "../bridging/openAgentErrorResponse.schema.json#" + } + }, + "openResponse-Bridge": { + "payload": { + "$ref": "../bridging/openBridgeResponse.schema.json#" + } + }, + "openErrorResponse-Bridge": { + "payload": { + "$ref": "../bridging/openBridgeErrorResponse.schema.json#" + } + }, + "privateChannelBroadcast-Agent": { + "payload": { + "$ref": "../bridging/privateChannelBroadcastAgentRequest.schema.json#" + } + }, + "privateChannelEventListenerAdded-Agent": { + "payload": { + "$ref": "../bridging/privateChannelEventListenerAddedAgentRequest.schema.json#" + } + }, + "privateChannelEventListenerRemoved-Agent": { + "payload": { + "$ref": "../bridging/privateChannelEventListenerRemovedAgentRequest.schema.json#" + } + }, + "privateChannelOnAddContextListener-Agent": { + "payload": { + "$ref": "../bridging/privateChannelOnAddContextListenerAgentRequest.schema.json#" + } + }, + "privateChannelOnDisconnect-Agent": { + "payload": { + "$ref": "../bridging/privateChannelOnDisconnectAgentRequest.schema.json#" + } + }, + "privateChannelOnUnsubscribe-Agent": { + "payload": { + "$ref": "../bridging/privateChannelOnUnsubscribeAgentRequest.schema.json#" + } + }, + "raiseIntentRequest-Agent": { + "payload": { + "$ref": "../bridging/raiseIntentAgentRequest.schema.json#" + } + }, + "raiseIntentResponse-Agent": { + "payload": { + "$ref": "../bridging/raiseIntentAgentResponse.schema.json#" + } + }, + "raiseIntentErrorResponse-Agent": { + "payload": { + "$ref": "../bridging/raiseIntentAgentErrorResponse.schema.json#" + } + }, + "raiseIntentResponse-Bridge": { + "payload": { + "$ref": "../bridging/raiseIntentBridgeResponse.schema.json#" + } + }, + "raiseIntentErrorResponse-Bridge": { + "payload": { + "$ref": "../bridging/raiseIntentBridgeErrorResponse.schema.json#" + } + }, + "raiseIntentResultResponse-Agent": { + "payload": { + "$ref": "../bridging/raiseIntentResultAgentResponse.schema.json#" + } + }, + "raiseIntentResultErrorResponse-Agent": { + "payload": { + "$ref": "../bridging/raiseIntentResultAgentErrorResponse.schema.json#" + } + }, + "raiseIntentResultResponse-Bridge": { + "payload": { + "$ref": "../bridging/raiseIntentResultBridgeResponse.schema.json#" + } + }, + "raiseIntentResultErrorResponse-Bridge": { + "payload": { + "$ref": "../bridging/raiseIntentResultBridgeErrorResponse.schema.json#" + } + } + } + } +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/action.schema.json b/website/static/schemas/2.1/context/action.schema.json new file mode 100644 index 000000000..3e76d9b39 --- /dev/null +++ b/website/static/schemas/2.1/context/action.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/action.schema.json", + "title": "Action", + "description": "A representation of an FDC3 Action (specified via a Context or Context & Intent) that can be inserted inside another object, for example a chat message.\n\nThe action may be completed by calling `fdc3.raiseIntent()` with the specified Intent and Context, or, if only a context is specified, by calling `fdc3.raiseIntentForContext()` (which the Desktop Agent will resolve by presenting the user with a list of available Intents for the Context).\n\nAccepts an optional `app` parameter in order to specify a specific app.", + "allOf": [{ + "type": "object", + "properties": { + "type": { "const": "fdc3.action" }, + "title": { + "title": "Action Title", + "description": "A human readable display name for the action", + "type": "string" + }, + "intent": { + "title": "Action Intent", + "description": "Optional Intent to raise to perform the actions. Should reference an intent type name, such as those defined in the FDC3 Standard. If intent is not set then `fdc3.raiseIntentForContext` should be used to perform the action as this will usually allow the user to choose the intent to raise.", + "type": "string" + }, + "context": { + "title": "Action Context", + "description": "A context object with which the action will be performed", + "$ref": "context.schema.json#" + }, + "app": { + "title": "Action Target App", + "description": "An optional target application identifier that should perform the action", + "allOf": [ + { "$ref": "../api/api.schema.json#/definitions/AppIdentifier" } + ] + } + }, + "required": [ + "title", "context" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.action", + "title": "Click to view Chart", + "intent": "ViewChart", + "context": { + "type": "fdc3.chart", + "instruments": [ + { + "type": "fdc3.instrument", + "id": { + "ticker": "EURUSD" + } + } + ], + "range": { + "type": "fdc3.dateRange", + "starttime": "2020-09-01T08:00:00.000Z", + "endtime": "2020-10-31T08:00:00.000Z" + }, + "style": "candle" + }, + "app" :{ + "appId": "MyChartViewingApp", + "instanceId": "instance1" + } + } + ] +} diff --git a/website/static/schemas/2.1/context/chart.schema.json b/website/static/schemas/2.1/context/chart.schema.json new file mode 100644 index 000000000..435cf832a --- /dev/null +++ b/website/static/schemas/2.1/context/chart.schema.json @@ -0,0 +1,88 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/chart.schema.json", + "type": "object", + "title": "Chart", + "description": "A context type representing details of a Chart, which may be used to request plotting of a particular chart or to otherwise share details of its composition, such as:\n\n- A list of instruments for comparison\n- The time period to plot the chart over\n- The style of chart (line, bar, mountain, candle etc.)\n- Other settings such as indicators to calculate, or data representing drawings and annotations.\n\nIn addition to handling requests to plot charts, a charting application may use this type to output a representation of what it is currently displaying so that it can be recorded by another application.", + "allOf": [{ + "type": "object", + "properties": { + "type": { "const": "fdc3.chart" }, + "instruments": { + "title": "Instruments to plot", + "description": "An array of instrument contexts whose data should be plotted.", + "type": "array", + "items": { + "$ref": "instrument.schema.json#" + } + }, + "range": { + "title": "Time Range", + "description": "The time range that should be plotted", + "allOf": [{ + "$ref": "timerange.schema.json#" + }] + }, + "style": { + "title": "Chart style", + "description": "The type of chart that should be plotted", + "type": "string", + "enum": [ "line", "bar", "stacked-bar", "mountain", "candle", "pie", "scatter", "histogram", "heatmap", "custom"] + }, + "otherConfig": { + "title": "Other configuration", + "description": "It is common for charts to support other configuration, such as indicators, annotations etc., which do not have standardized formats, but may be included in the `otherConfig` array as context objects.", + "type": "array", + "items": { + "$ref": "context.schema.json#" + } + } + }, + "required": ["instruments"] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.chart", + "instruments": [ + { + "type": "fdc3.instrument", + "id": { + "ticker": "AAPL" + } + }, + { + "type": "fdc3.instrument", + "id": { + "ticker": "GOOG" + } + } + ], + "range": { + "type": "fdc3.timeRange", + "startTime": "2020-09-01T08:00:00.000Z", + "endTime": "2020-10-31T08:00:00.000Z" + }, + "style": "line", + "otherConfig": [ + { + "type": "somevendor.someproduct.indicator", + "name": "stddev", + "parameters": { + "period": 10, + "matype": "exponential" + } + }, + { + "type": "someothervendor.someotherproduct.formula", + "formula": "standard-deviation", + "fields": { + "lookback": 10, + "type": "ema" + } + } + ] + } + ] +} diff --git a/website/static/schemas/2.1/context/chatInitSettings.schema.json b/website/static/schemas/2.1/context/chatInitSettings.schema.json new file mode 100644 index 000000000..ddc0923c3 --- /dev/null +++ b/website/static/schemas/2.1/context/chatInitSettings.schema.json @@ -0,0 +1,115 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/chatInitSettings.schema.json", + "type": "object", + "title": "ChatInitSettings", + "description": "A collection of settings to start a new chat conversation", + "allOf": [{ + "type": "object", + "properties": { + "type": { "const": "fdc3.chat.initSettings" }, + "chatName": { + "title": "Chat name", + "description": "Name to apply to the chat created", + "type": "string" + }, + "members": { + "title": "Chat members", + "description": "Contacts to add to the chat", + "$ref": "contactList.schema.json#" + }, + "message": { + "title": "Initial chat message", + "description": "An initial message to post in the chat when created.", + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "message.schema.json#" + } + ] + }, + "options": { + "title": "Chat options", + "description": "Option settings that affect the creation of the chat", + "type": "object", + "properties": { + "groupRecipients": { + "title": "Group recipients option", + "description": "if false a separate chat will be created for each member", + "type": "boolean" + }, + "isPublic": { + "title": "Public chat option", + "description": "if true the room will be visible to everyone in the chat application", + "type": "boolean" + }, + "allowHistoryBrowsing": { + "title": "Allow history browsing option", + "description": "if true members will be allowed to browse past messages", + "type": "boolean" + }, + "allowMessageCopy": { + "title": "Allow message copy option", + "description": "if true members will be allowed to copy/paste messages", + "type": "boolean" + }, + "allowAddUser": { + "title": "All adding users option", + "description": "if true members will be allowed to add other members to the chat", + "type": "boolean" + } + } + } + } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.chat.initSettings", + "chatName": "Chat ABCD", + "members": { + "type": "fdc3.contactList", + "contacts": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane@mail.com" + } + }, + { + "type": "fdc3.contact", + "name": "John Doe", + "id": { + "email": "john@mail.com" + } + } + ] + }, + "options": { + "groupRecipients": true, + "isPublic": false, + "allowHistoryBrowsing": true, + "allowMessageCopy": true + }, + "message": { + "type": "fdc3.message", + "text": { + "text/plain": "Hey all, can we discuss the issue together? I attached a screenshot" + }, + "entities": { + "0": { + "type": "fdc3.fileAttachment", + "data": { + "name": "myImage.png", + "dataUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII" + } + } + } + } + } + ] +} diff --git a/website/static/schemas/2.1/context/chatMessage.schema.json b/website/static/schemas/2.1/context/chatMessage.schema.json new file mode 100644 index 000000000..d7036fb36 --- /dev/null +++ b/website/static/schemas/2.1/context/chatMessage.schema.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/chatMessage.schema.json", + "type": "object", + "title": "Chat Message", + "description": "A context representing a chat message. Typically used to send the message or to pre-populate a message for sending.", + "allOf": [{ + "type": "object", + "properties": { + "type": { "const": "fdc3.chat.message" }, + "chatRoom": { "$ref": "chatRoom.schema.json#" }, + "message": { + "title": "Chat message", + "description": "The content of the message to post in the chat when created.", + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "message.schema.json#" + } + ] + } + }, + "required": ["type", "chatRoom", "message"] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [{ + "type": "fdc3.chat.message", + "chatRoom": { + "type": "fdc3.chat.room", + "providerName": "Symphony", + "id": { + "streamId": "j75xqXy25NBOdacUI3FNBH" + } + }, + "message": "A message to send" + }] +} diff --git a/website/static/schemas/2.1/context/chatRoom.schema.json b/website/static/schemas/2.1/context/chatRoom.schema.json new file mode 100644 index 000000000..0e22a4cf7 --- /dev/null +++ b/website/static/schemas/2.1/context/chatRoom.schema.json @@ -0,0 +1,48 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/chatRoom.schema.json", + "type": "object", + "title": "Chat Room", + "description": "Reference to the chat room which could be used to send a message to the room", + "allOf": [{ + "type": "object", + "properties": { + "type": { "const": "fdc3.chat.room" }, + "providerName": { + "title": "Chat provider name", + "description": "The name of the service that hosts the chat", + "type": "string" + }, + "id": { + "title": "Chat room id", + "description": "Identifier(s) for the chat - currently unstandardized", + "type": "object" + }, + "url": { + "title": "Chat URL", + "description": "Universal url to access to the room. It could be opened from a browser, a mobile app, etc...", + "type": "string", + "format": "uri" + }, + "name": { + "title": "Chat name", + "description": "Display name for the chat room", + "type": "string" + } + }, + "required": ["providerName", "id"] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.chat.room", + "providerName": "Symphony", + "id": { + "streamId": "j75xqXy25NBOdacUI3FNBH" + }, + "url": "http://symphony.com/ref/room/j75xqXy25NBOdacUI3FNBH___pqSsuJRdA", + "name": "My new room" + } + ] +} diff --git a/website/static/schemas/2.1/context/chatSearchCriteria.schema.json b/website/static/schemas/2.1/context/chatSearchCriteria.schema.json new file mode 100644 index 000000000..0ba1465ca --- /dev/null +++ b/website/static/schemas/2.1/context/chatSearchCriteria.schema.json @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/chatSearchCriteria.schema.json", + "type": "object", + "title": "Chat Search Criteria", + "description": "A context type that represents a simple search criterion, based on a list of other context objects, that can be used to search or filter messages in a chat application.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.chat.searchCriteria" + }, + "criteria": { + "title": "Criteria array", + "description": "An array of criteria that should match chats returned from by a search.\n\n⚠️ Operators (and/or/not) are not defined in `fdc3.chat.searchCriteria`. It is up to the application that processes the FDC3 Intent to choose and apply the operators between the criteria.\n\nEmpty search criteria can be supported to allow resetting of filters.", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "instrument.schema.json#" + }, + { + "$ref": "organization.schema.json#" + }, + { + "$ref": "contact.schema.json#" + }, + { + "type": "string", + "title": "Free text", + "description": "Free text to be used for a keyword search" + } + ] + } + } + }, + "required": [ + "criteria" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.chat.searchCriteria", + "criteria": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + { + "type": "fdc3.instrument", + "id": { + "ticker": "TSLA" + }, + "name": "Tesla, inc." + }, + "annual return" + ] + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/contact.schema.json b/website/static/schemas/2.1/context/contact.schema.json new file mode 100644 index 000000000..dcc8abea2 --- /dev/null +++ b/website/static/schemas/2.1/context/contact.schema.json @@ -0,0 +1,48 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/contact.schema.json", + "type": "object", + "title": "Contact", + "description": "A person contact that can be engaged with through email, calling, messaging, CMS, etc.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.contact" + }, + "id": { + "type": "object", + "title": "Contact Identifiers", + "description": "Identifiers that relate to the Contact represented by this context", + "properties": { + "email": { + "type": "string", + "format": "email", + "title": "Email address", + "description": "The email address for the contact" + }, + "FDS_ID": { + "type": "string", + "title": "FDS ID", + "description": "FactSet Permanent Identifier representing the contact" + } + } + } + }, + "required": [ + "id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + } + ] +} diff --git a/website/static/schemas/2.1/context/contactList.schema.json b/website/static/schemas/2.1/context/contactList.schema.json new file mode 100644 index 000000000..4f13792b3 --- /dev/null +++ b/website/static/schemas/2.1/context/contactList.schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/contactList.schema.json", + "type": "object", + "title": "ContactList", + "description": "A collection of contacts, e.g. for chatting to or calling multiple contacts.\n\nThe contact list schema does not explicitly include identifiers in the `id` section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.contactList" + }, + "contacts": { + "type": "array", + "title": "List of Contacts", + "description": "An array of contact contexts that forms the list.", + "items": { + "$ref": "contact.schema.json#" + } + } + }, + "required": [ + "contacts" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.contactList", + "contacts": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + { + "type": "fdc3.contact", + "name": "John Doe", + "id": { + "email": "john.doe@mail.com" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/context.schema.json b/website/static/schemas/2.1/context/context.schema.json new file mode 100644 index 000000000..ec8b06c56 --- /dev/null +++ b/website/static/schemas/2.1/context/context.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/context.schema.json", + "type": "object", + "title": "Context", + "description": "The `fdc3.context` type defines the basic contract or \"shape\" for all data exchanged by FDC3 operations. As such, it is not really meant to be used on its own, but is imported by more specific type definitions (standardized or custom) to provide the structure and properties shared by all FDC3 context data types.\n\nThe key element of FDC3 context types is their mandatory `type` property, which is used to identify what type of data the object represents, and what shape it has.\n\nThe FDC3 context type, and all derived types, define the minimum set of fields a context data object of a particular type can be expected to have, but this can always be extended with custom fields as appropriate.", + "allOf": [ + { + "$ref": "#/definitions/DocumentedContext" + }, + { + "$ref": "#/definitions/BaseContext" + } + ], + "definitions": { + "BaseContext": { + "$comment": "Base definition for the Context object without documentation (which will be imported into all derived types unless separated).", + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "id": { + "type": "object", + "unevaluatedProperties": { + "type": "string" + } + } + }, + "additionalProperties": true, + "required": [ + "type" + ] + }, + "DocumentedContext": { + "$comment": "Base definition for the Context object without documentation (which will be imported into all derived types unless separated).", + "type": "object", + "properties": { + "type": { + "type": "string", + "title": "Type", + "description": "The type property is the only _required_ part of the FDC3 context data schema. The FDC3 [API](https://fdc3.finos.org/docs/api/spec) relies on the `type` property being present to route shared context data appropriately.\n\nFDC3 [Intents](https://fdc3.finos.org/docs/intents/spec) also register the context data types they support in an FDC3 [App Directory](https://fdc3.finos.org/docs/app-directory/overview), used for intent discovery and routing.\n\nStandardized FDC3 context types have well-known `type` properties prefixed with the `fdc3` namespace, e.g. `fdc3.instrument`. For non-standard types, e.g. those defined and used by a particular organization, the convention is to prefix them with an organization-specific namespace, e.g. `blackrock.fund`.\n\nSee the [Context Data Specification](https://fdc3.finos.org/docs/context/spec) for more information about context data types." + }, + "name": { + "type": "string", + "title": "Name", + "description": "Context data objects may include a name property that can be used for more information, or display purposes. Some derived types may require the name object as mandatory, depending on use case." + }, + "id": { + "type": "object", + "title": "Id", + "description": "Context data objects may include a set of equivalent key-value pairs that can be used to help applications identify and look up the context type they receive in their own domain. The idea behind this design is that applications can provide as many equivalent identifiers to a target application as possible, e.g. an instrument may be represented by an ISIN, CUSIP or Bloomberg identifier.\n\nIdentifiers do not make sense for all types of data, so the `id` property is therefore optional, but some derived types may choose to require at least one identifier.", + "unevaluatedProperties": { + "type": "string" + } + } + }, + "additionalProperties": true, + "required": [ + "type" + ] + } + } +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/country.schema.json b/website/static/schemas/2.1/context/country.schema.json new file mode 100644 index 000000000..83921b58b --- /dev/null +++ b/website/static/schemas/2.1/context/country.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/country.schema.json", + "type": "object", + "title": "Country", + "description": "A country entity.\n\nNotes:\n\n- It is valid to include extra properties and metadata as part of the country payload, but the minimum requirement is for at least one standardized identifier to be provided\n\n - `COUNTRY_ISOALPHA2` SHOULD be preferred.\n\n- Try to only use country identifiers as intended and specified in the [ISO standard](https://en.wikipedia.org/wiki/ISO_3166-1). E.g. the `COUNTRY_ISOALPHA2` property must be a recognized value and not a proprietary two-letter code. If the identifier you want to share is not a standardized and recognized one, rather define a property that makes it clear what value it is. This makes it easier for target applications.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.country" + }, + "id": { + "type": "object", + "properties": { + "COUNTRY_ISOALPHA2": { + "type": "string", + "title": "COUNTRY_ISOALPHA2", + "description": "Two-letter ISO country code" + }, + "COUNTRY_ISOALPHA3": { + "type": "string", + "title": "COUNTRY_ISOALPHA3", + "description": "Three-letter ISO country code" + }, + "ISOALPHA2": { + "type": "string", + "title": "ISOALPHA2", + "description": "Two-letter ISO country code. Deprecated in FDC3 2.0 in favour of the version prefixed with `COUNTRY_`.", + "deprecated": true + }, + "ISOALPHA3": { + "type": "string", + "title": "ISOALPHA3", + "description": "Three-letter ISO country code. Deprecated in FDC3 2.0 in favour of the version prefixed with `COUNTRY_`.", + "deprecated": true + } + } + } + }, + "required": [ + "id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.country", + "name": "Sweden", + "id": { + "COUNTRY_ISOALPHA2": "SE" + } + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/currency.schema.json b/website/static/schemas/2.1/context/currency.schema.json new file mode 100644 index 000000000..2eeb6254b --- /dev/null +++ b/website/static/schemas/2.1/context/currency.schema.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/currency.schema.json", + "type": "object", + "title": "Currency", + "description": "A context representing an individual Currency.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.currency" + }, + "name": { + "type": "string", + "title": "Currency name", + "description": "The name of the currency for display purposes" + }, + "id": { + "type": "object", + "properties": { + "CURRENCY_ISOCODE": { + "type": "string", + "pattern": "^[A-Z]{3}$", + "title": "CURRENCY_ISOCODE", + "description": "The `CURRENCY_ISOCODE` should conform to 3 character alphabetic codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html)" + } + } + } + }, + "required": [ + "id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.currency", + "name": "US Dollar", + "id": { + "CURRENCY_ISOCODE": "USD" + } + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/email.schema.json b/website/static/schemas/2.1/context/email.schema.json new file mode 100644 index 000000000..2336535a7 --- /dev/null +++ b/website/static/schemas/2.1/context/email.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/email.schema.json", + "type": "object", + "title": "Email", + "description": "A collection of information to be used to initiate an email with a Contact or ContactList.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.email" + }, + "recipients": { + "title": "Email Recipients", + "description": "One or more receipients for the email.", + "oneOf": [ + { + "$ref": "contact.schema.json#" + }, + { + "$ref": "contactList.schema.json#" + } + ] + }, + "subject": { + "title": "Email Subject", + "description": "Subject line for the email.", + "type": "string" + }, + "textBody": { + "title": "Email Body", + "description": "Body content for the email.", + "type": "string" + } + }, + "required": [ + "recipients" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.email", + "recipients": { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@example.com" + } + }, + "subject": "The information you requested", + "textBody": "Blah, blah, blah ..." + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/instrument.schema.json b/website/static/schemas/2.1/context/instrument.schema.json new file mode 100644 index 000000000..9b4fee6b2 --- /dev/null +++ b/website/static/schemas/2.1/context/instrument.schema.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/instrument.schema.json", + "type": "object", + "title": "Instrument", + "description": "A financial instrument from any asset class.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.instrument" + }, + "id": { + "title": "Instrument identifiers", + "description": "Any combination of instrument identifiers can be used together to resolve ambiguity, or for a better match. Not all applications will use the same instrument identifiers, which is why FDC3 allows for multiple to be specified. In general, the more identifiers an application can provide, the easier it will be to achieve interoperability.\n\nIt is valid to include extra properties and metadata as part of the instrument payload, but the minimum requirement is for at least one instrument identifier to be provided.\n\nTry to only use instrument identifiers as intended. E.g. the `ticker` property is meant for tickers as used by an exchange.\nIf the identifier you want to share is not a ticker or one of the other standardized fields, define a property that makes it clear what the value represents. Doing so will make interpretation easier for the developers of target applications.", + "type": "object", + "properties": { + "BBG": { + "type": "string", + "title": "Bloomberg security", + "description": "" + }, + "CUSIP": { + "type": "string", + "title": "CUSIP", + "description": "" + }, + "FDS_ID": { + "type": "string", + "title": "FactSet Permanent Security Identifier", + "description": "" + }, + "FIGI": { + "type": "string", + "title": "Open FIGI", + "description": "" + }, + "ISIN": { + "type": "string", + "title": "ISIN", + "description": "" + }, + "PERMID": { + "type": "string", + "title": "Refinitiv PERMID", + "description": "" + }, + "RIC": { + "type": "string", + "title": "Refinitiv Identification Code", + "description": " " + }, + "SEDOL": { + "type": "string", + "title": "SEDOL", + "description": "" + }, + "ticker": { + "type": "string", + "title": "Stock ticker", + "description": "Unstandardized stock tickers" + } + } + }, + "market": { + "description": "The `market` map can be used to further specify the instrument and help achieve interoperability between disparate data sources. This is especially useful when using an `id` field that is not globally unique.", + "type": "object", + "properties": { + "MIC": { + "type": "string", + "title": "Market Identifier Code", + "description": "" + }, + "name": { + "type": "string", + "title": "Market Name", + "description": "Human readable market name" + }, + "COUNTRY_ISOALPHA2": { + "type": "string", + "title": "Country ISO Code", + "description": "" + }, + "BBG": { + "type": "string", + "title": "Bloomberg Market Identifier", + "description": "" + } + }, + "unevaluatedProperties": { + "type": "string" + } + } + }, + "required": [ + "type","id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.instrument", + "name": "Microsoft", + "id": { + "ticker": "MSFT", + "RIC": "MSFT.OQ", + "ISIN": "US5949181045" + }, + "market": { + "MIC": "XNAS" + } + } + ] +} diff --git a/website/static/schemas/2.1/context/instrumentList.schema.json b/website/static/schemas/2.1/context/instrumentList.schema.json new file mode 100644 index 000000000..f914c573c --- /dev/null +++ b/website/static/schemas/2.1/context/instrumentList.schema.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/instrumentList.schema.json", + "type": "object", + "title": "InstrumentList", + "description": "A collection of instruments. Use this type for use cases that require not just a single instrument, but multiple (e.g. to populate a watchlist). However, when holding information for each instrument is required, it is recommended to use the [Portfolio](Portfolio) type.\n\nThe instrument list schema does not explicitly include identifiers in the `id` section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.instrumentList" + }, + "instruments": { + "type": "array", + "title": "List of instruments", + "description": "An array of instrument contexts that forms the list.", + "items": { + "$ref": "instrument.schema.json#" + } + } + }, + "required": [ + "instruments" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.instrumentList", + "instruments": [ + { + "type": "fdc3.instrument", + "id": { + "ticker": "AAPL" + }, + "market": { + "MIC": "XNAS" + } + }, + { + "type": "fdc3.instrument", + "id": { + "ISIN": "US5949181045" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/interaction.schema.json b/website/static/schemas/2.1/context/interaction.schema.json new file mode 100644 index 000000000..9a1bed460 --- /dev/null +++ b/website/static/schemas/2.1/context/interaction.schema.json @@ -0,0 +1,127 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/interaction.schema.json", + "type": "object", + "title": "Interaction", + "description": "An `Interaction` is a significant direct exchange of ideas or information between a number of participants, e.g. a Sell Side party and one or more Buy Side parties. An `Interaction` might be a call, a meeting (physical or virtual), an IM or the preparation of some specialist data, such as financial data for a given company or sector.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.interaction" + }, + "id": { + "type": "object", + "title": "Interaction Id", + "description": "Can be used by a target application to pass an identifier back to the originating application after an interaction record has been created, updated or deleted. An interaction ID does not need to be populated by the originating application, however the target application could store it for future reference and SHOULD return it in a `TransactionResult`.", + "properties": { + "URI": { + "type": "string", + "title": "Interaction URI", + "description": "Can be used by a target application to pass a record's link back to the originating application. This offers the originating application a way to open the record for a user to view." + }, + "SALESFORCE": { + "type": "string", + "title": "Salesforce ID", + "description": "Interactions ID in Salesforce" + }, + "SINGLETRACK": { + "type": "string", + "title": "SingleTrack ID", + "description": "Interaction ID in SingleTrack" + } + } + }, + "participants": { + "title": "Interaction Participants", + "description": "A list of contacts involved in the interaction", + "$ref": "contactList.schema.json#" + }, + "timeRange": { + "title": "Interaction Time range", + "description": "The time range over which the interaction occurred", + "$ref": "timerange.schema.json#" + }, + "interactionType": { + "title": "Interaction Type", + "description": "`interactionType` SHOULD be one of `'Instant Message'`, `'Email'`, `'Call'`, or `'Meeting'` although other string values are permitted.", + "anyOf": [ + { + "type": "string", + "enum": [ + "Instant Message", + "Email", + "Call", + "Meeting" + ] + }, + { + "type": "string" + } + ] + }, + "description": { + "title": "Interaction Description", + "description": "A human-readable description of the interaction", + "type": "string" + }, + "initiator": { + "title": "Interaction Initiator", + "description": "The contact that initiated the interaction", + "$ref": "contact.schema.json#" + }, + "origin": { + "title": "Interaction Origin", + "description": "Used to represent the application or service that the interaction was created from to aid in tracing the source of an interaction.", + "type": "string" + } + }, + "required": [ + "participants", + "timeRange", + "interactionType", + "description" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.interaction", + "participants": { + "type": "fdc3.contactList", + "contacts": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + { + "type": "fdc3.contact", + "name": "John Doe", + "id": { + "email": "john.doe@mail.com" + } + } + ] + }, + "interactionType": "Instant Message", + "timeRange": { + "type": "fdc3.timeRange", + "startTime": "2022-02-10T15:12:00Z" + }, + "description": "Laboris libero dapibus fames elit adipisicing eu, fermentum, dignissimos laboriosam, erat, risus qui deserunt. Praesentium! Reiciendis. Hic harum nostrud, harum potenti amet? Mauris. Pretium aliquid animi, eget eiusmod integer proident. Architecto ipsum blandit ducimus, possimus illum sunt illum necessitatibus ab litora sed, nonummy integer minus corrupti ducimus iste senectus accumsan, fugiat nostrud? Pede vero dictumst excepturi, iure earum consequuntur voluptatum", + "initiator": { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + "origin": "Outlook" + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/message.schema.json b/website/static/schemas/2.1/context/message.schema.json new file mode 100644 index 000000000..e8ab82e42 --- /dev/null +++ b/website/static/schemas/2.1/context/message.schema.json @@ -0,0 +1,120 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/message.schema.json", + "type": "object", + "title": "Message", + "description": "A chat message to be sent through an instant messaging application. Can contain one or several text bodies (organized by mime-type, plaintext or markdown), as well as attached entities (either arbitrary file attachments or FDC3 actions to be embedded in the message). To be put inside a ChatInitSettings object.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.message" + }, + "text": { + "type": "object", + "title": "Message text", + "description": "A map of string mime-type to string content", + "properties": { + "text/plain": { + "type": "string", + "title": "Plain text", + "description": "Plain text encoded content." + }, + "text/markdown": { + "title": "Markdown text", + "description": "Markdown encoded content", + "type": "string" + } + } + }, + "entities": { + "type": "object", + "title": "Message entities", + "description": "A map of string IDs to entities that should be attached to the message, such as an action to perform, a file attachment, or other FDC3 context object.", + "additionalProperties": { + "anyOf": [ + { + "$ref": "action.schema.json#" + }, + { + "type": "object", + "title": "File attachment", + "description": "A File attachment encoded in the form of a data URI", + "properties": { + "type": { + "const": "fdc3.entity.fileAttachment" + }, + "data": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "File name", + "description": "The name of the attached file" + }, + "dataUri": { + "type": "string", + "format": "uri", + "title": "", + "description": "A data URI encoding the content of the file to be attached" + } + }, + "required": [ + "name", + "dataUri" + ] + } + }, + "required": [ + "type", + "data" + ] + } + ] + } + } + } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.message", + "text": { + "text/plain": "Hey all, can we discuss the issue together? I attached a screenshot and a link to the current exchange rate" + }, + "entities": { + "picture1": { + "type": "fdc3.fileAttachment", + "data": { + "name": "myImage.png", + "dataUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII" + } + }, + "eurusd_action": { + "type": "fdc3.action", + "title": "Click to view Chart", + "intent": "ViewChart", + "context": { + "type": "fdc3.chart", + "instruments": [ + { + "type": "fdc3.instrument", + "id": { + "ticker": "EURUSD" + } + } + ], + "range": { + "type": "fdc3.dateRange", + "starttime": "2020-09-01T08:00:00.000Z", + "endtime": "2020-10-31T08:00:00.000Z" + }, + "style": "candle" + } + } + } + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/nothing.schema.json b/website/static/schemas/2.1/context/nothing.schema.json new file mode 100644 index 000000000..b64d47879 --- /dev/null +++ b/website/static/schemas/2.1/context/nothing.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/nothing.schema.json", + "type": "object", + "title": "Nothing", + "description": "A type that explicitly represents a lack of context.\n\nNotes:\n\n- Intended to be used in situations where no context is desired.\n- For example:\n - Raising an intent without context (e.g. opening a blank order form, or chat interface without a contact selected).\n - Resetting context on a channel (e.g. when context is used to set a filter in other applications a null context might release the filter).\n- An explicit representation of a Null or empty context allows apps to declare support for a lack of context, for example in their intent metadata in an app directory.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.nothing" + } + } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.nothing" + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/order.schema.json b/website/static/schemas/2.1/context/order.schema.json new file mode 100644 index 000000000..acf9fb3c5 --- /dev/null +++ b/website/static/schemas/2.1/context/order.schema.json @@ -0,0 +1,76 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/order.schema.json", + "type": "object", + "title": "Order", + "description": "@experimental context type representing an order. To be used with OMS and EMS systems.\n\nThis type currently only defines a required `id` field, which should provide a reference to the order in one or more systems, an optional human readable `name` field to be used to summarize the order and an optional `details` field that may be used to provide additional detail about the order, including a context representing a `product`, which may be extended with arbitrary properties. The `details.product` field is currently typed as a unspecified Context type, but both `details` and `details.product` are expected to be standardized in future.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.order" + }, + "id": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Order Identifiers", + "description": "One or more identifiers that refer to the order in an OMS, EMS or related system. Specific key names for systems are expected to be standardized in future." + }, + "name": { + "type": "string", + "title": "Name", + "description": "An optional human-readable summary of the order." + }, + "details": { + "type": "object", + "title": "Order Details", + "description": "Optional additional details about the order, which may include a product element that is an, as yet undefined but extensible, Context", + "properties": { + "product": { + "$ref": "product.schema.json" + } + }, + "additionalProperties": true + } + }, + "required": [ + "type", + "id" + ], + "additionalProperties": true + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.order", + "name": "...", + "id": { + "myOMS": "12345" + }, + "details": { + "product": { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } + } + }, + { + "type": "fdc3.order", + "id": { + "myOMS": "ABC123" + } + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/orderList.schema.json b/website/static/schemas/2.1/context/orderList.schema.json new file mode 100644 index 000000000..db451c004 --- /dev/null +++ b/website/static/schemas/2.1/context/orderList.schema.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/orderList.schema.json", + "type": "object", + "title": "OrderList", + "description": "@experimental A list of orders. Use this type for use cases that require not just a single order, but multiple.\n\nThe OrderList schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.orderList" + }, + "orders": { + "type": "array", + "items": { + "$ref": "order.schema.json#" + }, + "title": "List of Orders", + "description": "An array of order contexts that forms the list." + } + }, + "required": [ + "type", + "orders" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.orderList", + "orders": [ + { + "type": "fdc3.order", + "id": { + "myOMS": "ABC123" + } + }, + { + "type": "fdc3.order", + "id": { + "myOMS": "DEF456" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/organization.schema.json b/website/static/schemas/2.1/context/organization.schema.json new file mode 100644 index 000000000..8af85a925 --- /dev/null +++ b/website/static/schemas/2.1/context/organization.schema.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/organization.schema.json", + "type": "object", + "title": "Organization", + "description": "An entity that can be used when referencing private companies and other organizations where a specific instrument is not available or desired e.g. CRM and News workflows.\n\nIt is valid to include extra properties and metadata as part of the organization payload, but the minimum requirement is for at least one specified identifier to be provided.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.organization" + }, + "id": { + "type": "object", + "title": "Organization Identifiers", + "description": "Identifiers for the organization, at least one must be provided.", + "minProperties": 1, + "properties": { + "LEI": { + "type": "string", + "title": "Legal Entity Identifier", + "description": "The Legal Entity Identifier (LEI) is a 20-character, alpha-numeric code based on the ISO 17442 standard developed by the International Organization for Standardization (ISO). It connects to key reference information that enables clear and unique identification of legal entities participating in financial transactions." + }, + "PERMID": { + "type": "string", + "title": "Organization", + "description": "Refinitiv Permanent Identifiers, or PermID for the organization" + }, + "FDS_ID": { + "type": "string", + "title": "Organization", + "description": "FactSet Permanent Identifier representing the organization" + } + } + } + }, + "required": [ + "id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.organization", + "name": "Cargill, Incorporated", + "id": { + "LEI": "QXZYQNMR4JZ5RIRN4T31", + "FDS_ID": "00161G-E" + } + } + ] +} diff --git a/website/static/schemas/2.1/context/portfolio.schema.json b/website/static/schemas/2.1/context/portfolio.schema.json new file mode 100644 index 000000000..1a0199ced --- /dev/null +++ b/website/static/schemas/2.1/context/portfolio.schema.json @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/portfolio.schema.json", + "type": "object", + "title": "Portfolio", + "description": "A financial portfolio made up of multiple positions (holdings) in several instruments. Contrast this with e.g. the [InstrumentList](InstrumentList) type, which is just a list of instruments.\n\nThis is a good example of how types can be composed and extended with extra properties to define more complex types.\n\nThe Portfolio type consists of an array of [Position](Position) types, each of which refers to a single [Instrument](Instrument) and a holding amount for that instrument.\n\nThe portfolio schema does not explicitly include identifiers in the `id` section, as there bis not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.portfolio" + }, + "positions": { + "type": "array", + "items": { + "$ref": "position.schema.json#" + }, + "title": "Portfolio positions", + "description": "The List of Positions which make up the Portfolio" + } + }, + "required": [ + "positions" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.portfolio", + "positions": [ + { + "type": "fdc3.position", + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "AAPL" + } + }, + "holding": 2000000 + }, + { + "type": "fdc3.position", + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + }, + "holding": 1500000 + }, + { + "type": "fdc3.position", + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "IBM" + } + }, + "holding": 3000000 + } + ] + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/position.schema.json b/website/static/schemas/2.1/context/position.schema.json new file mode 100644 index 000000000..4b3969bd2 --- /dev/null +++ b/website/static/schemas/2.1/context/position.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/position.schema.json", + "type": "object", + "title": "Position", + "description": "A financial position made up of an instrument and a holding in that instrument. This type is a good example of how new context types can be composed from existing types.\n\nIn this case, the instrument and the holding amount for that instrument are required values.\n\nThe [Position](Position) type goes hand-in-hand with the [Portfolio](Portfolio) type, which represents multiple holdings in a combination of instruments.\n\nThe position schema does not explicitly include identifiers in the `id` section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.position" + }, + "instrument": { + "$ref": "instrument.schema.json#", + "title": "The financial instrument that this position relates to", + "description": "" + }, + "holding": { + "type": "number", + "title": "The size of the holding represented by this position", + "description": "The amount of the holding, e.g. a number of shares" + } + }, + "required": [ + "instrument", + "holding" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.position", + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "AAPL" + } + }, + "holding": 2000000 + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/product.schema.json b/website/static/schemas/2.1/context/product.schema.json new file mode 100644 index 000000000..633fb9515 --- /dev/null +++ b/website/static/schemas/2.1/context/product.schema.json @@ -0,0 +1,55 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/product.schema.json", + "type": "object", + "title": "Product", + "description": "@experimental context type representing a tradable product. To be used with OMS and EMS systems.\n\nThis type is currently only loosely defined as an extensible context object, with an optional instrument field.\n\nThe Product schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.product" + }, + "id": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Product Identifiers", + "description": "One or more identifiers that refer to the product. Specific key names for systems are expected to be standardized in future." + }, + "name": { + "type": "string", + "title": "Product Name", + "description": "A human-readable summary of the product." + }, + "instrument": { + "$ref": "instrument.schema.json", + "title": "Product Instrument", + "description": " financial instrument that relates to the definition of this product" + } + }, + "required": [ + "type", + "id" + ], + "additionalProperties": true + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/timerange.schema.json b/website/static/schemas/2.1/context/timerange.schema.json new file mode 100644 index 000000000..9014ef99d --- /dev/null +++ b/website/static/schemas/2.1/context/timerange.schema.json @@ -0,0 +1,62 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/timerange.schema.json", + "type": "object", + "title": "TimeRange", + "description": "A context representing a period of time. Any user interfaces that represent or visualize events or activity over time can be filtered or focused on a particular time period, e.g.:\n\n- A pricing chart\n- A trade blotter\n- A record of client contact/activity in a CRM\n\nExample use cases:\n\n- User may want to view pricing/trades/customer activity for a security over a particular time period, the time range might be specified as the context for the `ViewChart` intent OR it might be embedded in another context (e.g. a context representing a chart to plot).\n- User filters a visualization (e.g. a pricing chart) to show a particular period, the `TimeRange` is broadcast and other visualizations (e.g. a heatmap of activity by instrument, or industry sector etc.) receive it and filter themselves to show data over the same range.\n\nNotes:\n\n- A `TimeRange` may be closed (i.e. `startTime` and `endTime` are both known) or open (i.e. only one of `startTime` or `endTime` is known).\n- Ranges corresponding to dates (e.g. `2022-05-12` to `2022-05-19`) should be specified using times as this prevents issues with timezone conversions and inclusive/exclusive date ranges.\n- String fields representing times are encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html).\n - A timezone indicator should be specified, e.g. `\"2022-05-12T15:18:03Z\"` or `\"2022-05-12T16:18:03+01:00\"`\n - Times MAY be specified with millisecond precision, e.g. `\"2022-05-12T15:18:03.349Z\"`", + "allOf": [ + { + "properties": { + "type": { + "const": "fdc3.timerange" + }, + "startTime": { + "type": "string", + "format": "date-time", + "title": "Start Time", + "description": "The start time of the range, encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator." + }, + "endTime": { + "type": "string", + "format": "date-time", + "title": "End Time", + "description": "The end time of the range, encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator." + } + } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "anyOf": [ + { + "required": [ + "startTime", + "endTime" + ] + }, + { + "required": [ + "startTime" + ] + }, + { + "required": [ + "endTime" + ] + } + ], + "examples": [ + { + "type": "fdc3.timeRange", + "startTime": "2022-03-30T15:44:44Z", + "endTime": "2022-04-30T23:59:59ZS" + }, + { + "type": "fdc3.timeRange", + "startTime": "2022-03-30T15:44:44+00:00" + }, + { + "type": "fdc3.timeRange", + "endTime": "2022-03-30T16:44:44.123Z" + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/trade.schema.json b/website/static/schemas/2.1/context/trade.schema.json new file mode 100644 index 000000000..ea5452960 --- /dev/null +++ b/website/static/schemas/2.1/context/trade.schema.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/trade.schema.json", + "type": "object", + "title": "Trade", + "description": "@experimental context type representing a trade. To be used with execution systems.\n\nThis type currently only defines a required `id` field, which should provide a reference to the trade in one or more systems, an optional human readable `name` field to be used to summarize the trade and a required `product` field that may be used to provide additional detail about the trade, which is currently typed as a unspecified Context type, but `product` is expected to be standardized in future.\n\n The Trade schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.trade" + }, + "id": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Trade Identifiers", + "description": "One or more identifiers that refer to the trade in an OMS, EMS or related system. Specific key names for systems are expected to be standardized in future." + }, + "name": { + "type": "string", + "title": "Trade Name", + "description": "A human-readable summary of the trade." + }, + "product": { + "$ref": "product.schema.json", + "title": "Traded product", + "description": "A product that is the subject of th trade." + } + }, + "required": [ + "type", "id", "product" + ], + "additionalProperties": true + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.trade", + "name": "...", + "id": { + "myEMS": "12345" + }, + "product": { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } + } + ] +} diff --git a/website/static/schemas/2.1/context/tradeList.schema.json b/website/static/schemas/2.1/context/tradeList.schema.json new file mode 100644 index 000000000..61dc5c1d2 --- /dev/null +++ b/website/static/schemas/2.1/context/tradeList.schema.json @@ -0,0 +1,74 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/tradeList.schema.json", + "type": "object", + "title": "TradeList", + "description": "@experimental A list of trades. Use this type for use cases that require not just a single trade, but multiple.\n\nThe TradeList schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.tradeList" + }, + "trades": { + "type": "array", + "items": { + "$ref": "trade.schema.json#" + }, + "title": "List of Trades", + "description": "An array of trade contexts that forms the list." + } + }, + "required": [ + "type", + "trades" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.tradeList", + "trades": [ + { + "type": "fdc3.trade", + "name": "...", + "id": { + "myEMS": "12345" + }, + "product": { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } + }, + { + "type": "fdc3.trade", + "id": { + "myEMS": "67890" + }, + "product": { + "type": "fdc3.product", + "id": { + "productId": "DEF456" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "TSLA" + } + } + } + } + ] + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/transactionresult.schema.json b/website/static/schemas/2.1/context/transactionresult.schema.json new file mode 100644 index 000000000..4ebc4da1d --- /dev/null +++ b/website/static/schemas/2.1/context/transactionresult.schema.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/transactionresult.schema.json", + "type": "object", + "title": "TransactionResult", + "description": "A context type representing the result of a transaction initiated via FDC3, which SHOULD be returned as an `IntentResult` by intents that create, retrieve, update or delete content or records in another application. Its purpose is to provide a status and message (where needed) for the transaction and MAY wrap a returned context object.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.transactionResult" + }, + "status": { + "type": "string", + "enum": [ + "Created", + "Deleted", + "Updated", + "Failed" + ], + "title": "Transaction Status", + "description": "The status of the transaction being reported." + }, + "context": { + "$ref": "context.schema.json#", + "title": "Transaction Result Context", + "description": "A context object returned by the transaction, possibly with updated data." + } + }, + "message": { + "type": "string", + "title": "Transaction Message", + "description": "A human readable message describing the outcome of the transaction." + }, + "required": [ + "type", + "status" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.transactionResult", + "status": "Updated", + "context": { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + "message": "record with id 'jane.doe@mail.com' was updated" + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/2.1/context/valuation.schema.json b/website/static/schemas/2.1/context/valuation.schema.json new file mode 100644 index 000000000..0800a2b3d --- /dev/null +++ b/website/static/schemas/2.1/context/valuation.schema.json @@ -0,0 +1,59 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/valuation.schema.json", + "type": "object", + "title": "Valuation", + "description": "A context type representing the price and value of a holding.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.valuation" + }, + "value": { + "type": "number", + "title": "Value", + "description": "The value of the holding, expresses in the nominated currency." + }, + "price": { + "type": "number", + "title": "Price per unit", + "description": "The price per unit the the valuation is based on." + }, + "CURRENCY_ISOCODE": { + "type": "string", + "pattern": "^[A-Z]{3}$", + "title": "Valuation Currency", + "description": "The valuation currency, which should conform to 3 character alphabetic codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html)" + }, + "valuationTime": { + "type": "string", + "format": "date-time", + "title": "Valuation time", + "description": "The time at which the valuation was performed, encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator included." + }, + "expiryTime": { + "type": "string", + "format": "date-time", + "title": "Expiry Time", + "description": "The time at which this valuation expires, encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator included." + } + }, + "required": [ + "value", + "CURRENCY_ISOCODE" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.valuation", + "value": 500.0, + "price": 5.0, + "CURRENCY_ISOCODE": "USD", + "expiryTime": "2022-05-13T16:16:24+01:00" + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/api/t2sQuicktypeUtil.js b/website/static/schemas/next/api/t2sQuicktypeUtil.js index 86e6c270b..54816c0e0 100644 --- a/website/static/schemas/next/api/t2sQuicktypeUtil.js +++ b/website/static/schemas/next/api/t2sQuicktypeUtil.js @@ -1,3 +1,8 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + * Copyright FINOS FDC3 contributors - see NOTICE file + */ + /** Utility for preparing arguments to quicktype, which workaround a specific * quicktype bug in command line argument handling (where a directory is used * as input the source language argument is ignored which causes our schemas diff --git a/website/static/schemas/next/app-directory.yaml b/website/static/schemas/next/app-directory.yaml deleted file mode 100644 index 694d9b521..000000000 --- a/website/static/schemas/next/app-directory.yaml +++ /dev/null @@ -1,1290 +0,0 @@ -openapi: 3.0.0 -info: - title: FDC3 Application Directory - version: 'next' - description: > - Application Directory specification providing both interface - definition and objects necessary to construct an application directory - service. - x-logo: - url: '/img/fdc3-logo-2019-color.png' - altText: FDC3 logo -security: -- bearerAuth: [] -paths: - '/v2/apps/{appId}': - get: - summary: Retrieve an application definition - parameters: - - name: appId - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Application' - examples: - MyAppDefinition: - $ref: '#/components/examples/MyAppDefinition' - FDC3WorkbenchAppDefinition: - $ref: '#/components/examples/FDC3WorkbenchAppDefinition' - '400': - description: Bad request - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - examples: - Error400Example: - $ref: '#/components/examples/Error400Example' - '403': - description: Forbidden - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - examples: - Error403Example: - $ref: '#/components/examples/Error403Example' - '500': - description: Server error - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - examples: - Error500Example: - $ref: '#/components/examples/Error500Example' - tags: - - Application - /v2/apps: - get: - summary: Retrieve all application definitions - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/AllApplicationsResponse' - examples: - AllAppsResponse: - $ref: '#/components/examples/AllAppsResponse' - '400': - description: Bad request - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - examples: - Error400Example: - $ref: '#/components/examples/Error400Example' - '403': - description: Forbidden - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - examples: - Error403Example: - $ref: '#/components/examples/Error403Example' - '500': - description: Server error - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - examples: - Error500Example: - $ref: '#/components/examples/Error500Example' - tags: - - Application - '/v1/apps/{appId}': - get: - deprecated: true - summary: Retrieve an application definition - parameters: - - name: appId - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ApplicationV1' - '400': - description: Bad request. - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - '403': - description: >- - Forbidden: Certificate authentication is not allowed for the - requested user. - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - '500': - description: 'Server error, see response body for further details.' - content: - '*/*': - schema: - $ref: '#/components/schemas/ErrorDTO' - tags: - - Application - /v1/apps: - post: - deprecated: true - summary: Create a new application definition - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ApplicationSearchResponseV1' - '400': - description: Bad request. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDTO' - '403': - description: >- - Forbidden: Certificate authentication is not allowed for the - requested user. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDTO' - '500': - description: 'Server error, see response body for further details.' - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDTO' - tags: - - Application - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ApplicationV1' - required: true - /v1/apps/search: - get: - deprecated: true - summary: Retrieve a list of applications based on parameters provided. Depending on implementation, parameter - values should self describe search format and type (e.g. Regex) - parameters: - - in: query - name: appId - schema: - type: string - required: false - description: > - The unique application identifier located within a specific - application directory instance. - - in: query - name: name - schema: - type: string - required: false - description: > - The name of the application. - - The name should be unique within an FDC3 App Directory instance. The - exception to the uniqueness constraint is that an App Directory can - hold definitions for multiple versions of the same app. - - The same appName could occur in other directories. We are not - currently specifying app name conventions in the document. - - in: query - name: version - schema: - type: string - required: false - description: >- - Version of the application. This allows multiple app versions to be - defined using the same app name. This can be a triplet but can also - include things like 1.2.5 (BETA) - - in: query - name: title - schema: - type: string - required: false - description: >- - Optional title for the application, if missing use appName, - typically used in a launcher UI. - - in: query - name: tooltip - schema: - type: string - required: false - description: Optional tooltip description e.g. for a launcher - - in: query - name: description - schema: - type: string - required: false - description: >- - Description of the application. This will typically be a 1-2 - paragraph style blurb about the application. Allow mark up language - - in: query - name: intent_name - schema: - type: string - required: false - description: name of intent - - in: query - name: intent_displayName - schema: - type: string - required: false - description: displayName of intent - - in: query - name: intent_context - schema: - type: string - required: false - description: search contexts list - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/ApplicationSearchResponseV1' - '400': - description: Bad request. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDTO' - '403': - description: >- - Forbidden: Certificate authentication is not allowed for the - requested user. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDTO' - '500': - description: 'Server error, see response body for further details.' - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorDTO' - tags: - - Application - -servers: - - url: /appd -components: - securitySchemes: - bearerAuth: # arbitrary name for the security scheme - type: http - scheme: bearer - bearerFormat: JWT # optional, arbitrary value for documentation purposes - schemas: - ErrorDTO: - type: object - properties: - code: - type: integer - format: int32 - message: - type: string - BaseApplication: - properties: - appId: - type: string - description: > - The unique application identifier located within a specific - application directory instance. - title: - type: string - description: >- - Title for the application, typically used in a launcher UI. - type: - $ref: '#/components/schemas/Type' - details: - $ref: '#/components/schemas/LaunchDetails' - name: - type: string - description: > - Deprecated in favour of using `appId` to identify apps and `title` - for their display names. - - The name of the application. - - The name should be unique within an FDC3 App Directory instance. The - exception to the uniqueness constraint is that an App Directory can - hold definitions for multiple versions of the same app. - - The same appName could occur in other directories. We are not - currently specifying app name conventions in the document. - deprecated: true - version: - type: string - description: >- - Version of the application. This allows multiple app versions to be - defined using the same app name. This can be a triplet but can also - include things like 1.2.5 (BETA) - tooltip: - type: string - description: Optional tooltip description e.g. for a launcher - lang: - type: string - pattern: '^[a-z]{2}(-[a-zA-Z0-9]{2,8}){0,1}$' - description: >- - A language tag that specifies the primary language of both the - application and its AppD entry, as defined by IETF RFC 5646. - description: - type: string - description: >- - Description of the application. This will typically be a 1-2 - paragraph style blurb about the application. - categories: - description: | - An array of string categories that describe the application. - These are meant as a hint to catalogs or stores listing FDC3-enabled - apps and it is expected that these will make a best effort to find - appropriate categories (or category) under which to list the app. - AppD record authors are encouraged to use lower-case and, where - possible, to select categories from the following list: - - - allocations - - analytics - - charts - - chat - - communication - - compliance - - crm - - developer tools - - events - - execution management - - file sharing - - market data - - news - - networking - - office apps - - order management - - other - - portfolio management - - presentation - - pricing - - productivity - - research - - risk - - screen sharing - - security - - spreadsheet - - trade cost analysis - - trading system - - training - - travel - - video - - visualization - - weather - type: array - items: - type: string - icons: - type: array - description: >- - Holds Icons used for the application, a Launcher may be able to use - multiple Icon sizes or there may be a 'button' Icon - items: - $ref: '#/components/schemas/Icon' - screenshots: - type: array - description: >- - Array of images to show the user when they are looking at app - description. Each image can have an optional description/tooltip - items: - $ref: '#/components/schemas/Screenshot' - contactEmail: - type: string - format: email - description: Optional e-mail to receive queries about the application - supportEmail: - type: string - format: email - description: Optional e-mail to receive support requests for the application - moreInfo: - type: string - format: uri - description: Optional URL that provides more information about the application - publisher: - type: string - description: >- - The name of the company that owns the application. The publisher has - control over their namespace/app/signature. - customConfig: - deprecated: true - type: array - description: >- - An optional set of name value pairs that can be used to deliver - custom data from an App Directory to a launcher. Deprecated due to a - lack of a standard means of retrieval via the Desktop Agent API. To - be replaced in a future version with an `applicationConfig` element - and standard API to retrieve it. See issue - [#1006](https://github.com/finos/FDC3/issues/1006) for details. - items: - $ref: '#/components/schemas/NameValuePair' - hostManifests: - $ref: '#/components/schemas/HostManifests' - interop: - $ref: '#/components/schemas/Interop' - Application: - description: > - Defines an application retrieved from an FDC3 App Directory, which can - then be launched. - - Launching typically means running for a user on a desktop. - The details around 'launching' including who or what might do it, and how the launch action is initiated are - discussed elsewhere in the FDC3 App Directory spec. - required: - - appId - - title - - type - - details - allOf: - - $ref: '#/components/schemas/BaseApplication' - - type: object - properties: - localizedVersions: - $ref: '#/components/schemas/LocalizedVersions' - AllApplicationsResponse: - properties: - applications: - type: array - description: | - List of applications - items: - $ref: '#/components/schemas/Application' - message: - type: string - description: | - Response message providing status of query - NameValuePair: - description: Simple name value pair - properties: - name: - type: string - description: name - value: - type: string - description: value - Icon: - description: Icon holder - properties: - src: - type: string - format: uri - description: Icon URL - size: - type: string - description: Icon dimension formatted as `x` - type: - type: string - description: Image media type. If not present the Desktop Agent may use the src file extension - Screenshot: - description: Images representing the app in common usage scenarios - properties: - src: - type: string - format: uri - description: App Image URL - size: - type: string - description: Image dimension formatted as `x` - type: - type: string - description: Image media type. If not present the Desktop Agent may use the src file extension. - label: - type: string - description: Optional caption for the image - Type: - type: string - description: | - The technology type that is used to launch and run the application. - Each application type implies a particular set of launch `details`. - The supported types include: - - - `web`: Web applications launched via a URL - - `native`: Native applications pre-installed on a device and launch via a filesystem path - - `citrix`: Apps virtualized via Citrix - - `onlineNative`: Native apps that have an online launcher, e.g. online ClickOnce app deployments. - - `other`: Used to represent apps that do not conform to or cannot be launched via the other types, and are likely to be defined solely by a hostManifest. - - FDC3 Desktop Agents MUST support at least the `web` application type and MAY support any or all of the other types. - enum: - - web - - native - - citrix - - onlineNative - - other - LaunchDetails: - description: >- - The type specific launch details of the application. These details are intended to be - vendor-agnostic and MAY be duplicated or overridden by details provided in the hostManifests - object for a specific host. - oneOf: - - $ref: '#/components/schemas/WebAppDetails' - - $ref: '#/components/schemas/NativeAppDetails' - - $ref: '#/components/schemas/CitrixAppDetails' - - $ref: '#/components/schemas/OnlineNativeAppDetails' - - $ref: '#/components/schemas/OtherAppDetails' - WebAppDetails: - description: 'Properties used to launch apps with `type: web`.' - required: - - url - properties: - url: - type: string - format: uri - description: Application start URL. - additionalProperties: false - NativeAppDetails: - description: 'Properties used to launch apps with `type: native` that are already installed on the device.' - required: - - path - properties: - path: - type: string - description: The path on disk from which the application is launched. - arguments: - type: string - description: Arguments that must be passed on the command line to launch the app in the expected configuration. - additionalProperties: false - CitrixAppDetails: - description: 'Properties used to launch apps virtualized apps with `type: citrix`.' - required: - - alias - properties: - alias: - type: string - description: The Citrix alias / name of the virtual app (passed to the Citrix SelfService qlaunch parameter). - arguments: - type: string - description: Arguments that must be passed on the command line to launch the app in the expected configuration. - additionalProperties: false - OnlineNativeAppDetails: - description: 'Properties used to launch a native apps with `type: onlineNative` that have an online launcher, e.g. online ClickOnce app deployments.' - required: - - url - properties: - url: - type: string - format: uri - description: Application URL. - additionalProperties: false - OtherAppDetails: - description: 'Apps with `type: other` are defined by a hostManifest and do not require other details.' - additionalProperties: false - HostManifests: - type: object - description: >- - A mapping from host name to a host-specific application manifest object or URI - from which that manifest can be retrieved. The manifest should provide details required to - launch and use the application within the specified host. The manifest _MAY_ duplicate or - override information provided in the `details` field. - additionalProperties: - x-additionalPropertiesName: Host name - oneOf: - - type: string # URI pointing to a JSON containing all host specific properties - format: uri - - $ref: '#/components/schemas/HostManifest' - HostManifest: - type: object - description: >- - Object containing all host specific properties. - LocalizedVersions: - type: object # keys should be constrained to valid language tags '^[a-z]{2}(-[a-zA-Z0-9]{2,8}){0,1}$' - not possible to express in OpenAPI without moving to v3.1.0 and the javascript/jsonschema version - description: > - Provides localized alternatives to any field of the AppD record, which may also refer to an alternative - version of the application that is also localized (e.g. by providing an alternative URL). - The keys to this object should be language tags as defined by IETF RFC 5646, e.g. en, en-GB or fr-FR. - additionalProperties: - x-additionalPropertiesName: Language tag - $ref: '#/components/schemas/BaseApplication' # due to a bug in redoc this may display as a recursive definition, it is not. It will render correctly in swagger and other OpenAPI parsers. - Intent: - description: >- - Definition of an intent that an app listens for - required: - - contexts - properties: - displayName: - type: string - description: Optional display name for the intent. Deprecated in favour of the intent name, which is common amongst all apps that support it, where the display name may vary as it is defined in the app's AppD record. - deprecated: true - contexts: - type: array - items: - type: string - description: >- - A comma separated list of the types of contexts the intent offered by the application can process, - where the first part of the context type is the namespace e.g."fdc3.contact, org.symphony.contact" - resultType: - type: string - description: >- - An optional type for output returned by the application, if any, when resolving this intent. - May indicate a context type by type name (e.g. "fdc3.instrument"), a channel (e.g. "channel") - or a combination that indicates a channel that returns a particular context type - (e.g. "channel"). - customConfig: - deprecated: true - type: object - description: >- - Custom configuration for the intent that may be required for a - particular desktop agent. Deprecated due to a lack of defined use cases. - Interop: - type: object - description: | - Metadata that describes how the application uses FDC3 APIs. This metadata serves multiple purposes: - - - It supports intent resolution by a desktop agent, by declaring what intents an app listens for. - - It may be used, for example in an app catalog UI, to find apps that 'interoperate with' other apps. - - It provides a standard location to document how the app interacts with user channels, app channels, - and intents, for use by other app developers and desktop assemblers. - properties: - intents: - type: object - description: Describes the app's interactions with intents. - properties: - listensFor: - type: object - description: | - A mapping of Intents names that an app listens for via `fdc3.addIntentListener()` to their - configuration. - - Used to support intent resolution by desktop agents. Replaces the `intents` element used in appD records prior to FDC3 2.0. - additionalProperties: - x-additionalPropertiesName: Intent name - $ref: '#/components/schemas/Intent' - raises: - type: object - description: | - A mapping of Intent names that an app raises (via `fdc3.raiseIntent`) to an array of context - type names that it may be raised with. - - Use the intent name "any" to represent use of the `fdc3.raiseIntentForContext` and - `fdc3.findIntentForContext` functions, which allow the user to select from intents available for a - specified context type. - - This metadata is not currently used by the desktop agent, but is provided to help find apps - that will interoperate with this app and to document API interactions for use by other app - developers. - additionalProperties: - x-additionalPropertiesName: Intent name - type: array - description: Context type names that the intent may be raised with. - items: - type: string - userChannels: - type: object - description: | - Describes the application's use of context types on User Channels. - - This metadata is not currently used by the desktop agent, but is provided to help find apps - that will interoperate with this app and to document API interactions for use by other app - developers. - properties: - broadcasts: - type: array - description: Context type names that are broadcast by the application. - items: - type: string - listensFor: - type: array - description: Context type names that the application listens for. - items: - type: string - appChannels: - type: array - description: | - Describes the application's use of App Channels. - - This metadata is not currently used by the desktop agent, but is provided to help find apps - that will interoperate with this app and to document API interactions for use by other app - developers. - items: - type: object - required: - - id - properties: - id: - type: string - description: > - The id of the App Channel. - N.b. in FDC3 2.0 this field was incorrectly called `name`. - description: - type: string - description: A description of how the channel is used. - broadcasts: - type: array - description: Context type names that are broadcast by the application on the channel. - items: - type: string - listensFor: - type: array - description: Context type names that the application listens for on the channel. - items: - type: string - AppImageV1: - description: App Image holder - properties: - url: - type: string - format: uri - description: App Image URL - IconV1: - description: (Deprecated v1 API version) Icon holder - properties: - icon: - type: string - format: uri - description: Icon URL - IntentV1: - description: >- - (Deprecated v1 API version) An intent definition as defined by spec - https://github.com/FDC3/Intents/blob/master/src/Intent.yaml - required: - - name - properties: - name: - type: string - description: The name of the intent to 'launch'. In this case the name of an Intent supported by an application. - displayName: - type: string - description: An optional display name for the intent that may be used in UI instead of the name. - contexts: - type: array - items: - type: string - description: >- - A comma separated list of the types of contexts the intent offered by the application can process. - where the first part of the context type is the namespace e.g."fdc3.contact, org.symphony.contact" - customConfig: - deprecated: true - type: object - description: >- - Custom configuration for the intent that may be required for a - particular desktop agent. Deprecated due to a lack of defined use cases. - ApplicationV1: - description: > - (Deprecated v1 API version) Defines an application retrieved from an FDC3 App Directory, which can - then be launched. - Launching typically means running for a user on a desktop. - The details around 'launching' including who or what might do it, and how the launch action is initiated are - discussed elsewhere in the FDC3 App Directory spec. - required: - - appId - - name - - manifest - - manifestType - properties: - appId: - type: string - description: > - The unique application identifier located within a specific - application directory instance. - name: - type: string - description: > - The name of the application. - The name should be unique within an FDC3 App Directory instance. The - exception to the uniqueness constraint is that an App Directory can - hold definitions for multiple versions of the same app. - The same appName could occur in other directories. We are not - currently specifying app name conventions in the document. - manifest: - type: string - description: > - URI or full JSON of the application manifest providing all details related to launch - and use requirements as described by the vendor. - The format of this manifest is vendor specific, but can be identified by - the manifestType attribute. - manifestType: - type: string - description: > - The manifest type which relates to the format and structure of the manifest content. - The definition is based on the vendor specific format and definition outside of this specification. - version: - type: string - description: >- - Version of the application. This allows multiple app versions to be - defined using the same app name. This can be a triplet but can also - include things like 1.2.5 (BETA) - title: - type: string - description: >- - Optional title for the application, if missing use appName, - typically used in a launcher UI. - tooltip: - type: string - description: Optional tooltip description e.g. for a launcher - description: - type: string - description: >- - Description of the application. This will typically be a 1-2 - paragraph style blurb about the application. Allow mark up language - images: - type: array - description: >- - Array of images to show the user when they are looking at app - description. Each image can have an optional description/tooltip - items: - $ref: '#/components/schemas/AppImageV1' - contactEmail: - type: string - format: email - description: Optional e-mail to receive queries about the application - supportEmail: - type: string - format: email - description: Optional e-mail to receive support requests for the application - publisher: - type: string - description: >- - The name of the company that owns the application. The publisher has - control over their namespace/app/signature. - icons: - type: array - description: >- - Holds Icons used for the application, a Launcher may be able to use - multiple Icon sizes or there may be a 'button' Icon - items: - $ref: '#/components/schemas/IconV1' - customConfig: - deprecated: true - type: array - description: >- - An optional set of name value pairs that can be used to deliver - custom data from an App Directory to a launcher. - items: - $ref: '#/components/schemas/NameValuePair' - intents: - type: array - description: > - The list of intents implemented by the application as defined by - https://github.com/FDC3/Intents/blob/master/src/Intent.yaml - items: - $ref: '#/components/schemas/IntentV1' - ApplicationSearchResponseV1: - properties: - applications: - type: array - description: | - List of applications - items: - $ref: '#/components/schemas/ApplicationV1' - message: - type: string - description: | - Response message providing status of query - examples: - FDC3WorkbenchAppDefinition: - value: - appId: fdc3-workbench - title: FDC3 Workbench - description: Development and test tool for FDC3 desktop agents and apps - categories: [developer tools, training] - version: 1.0.0 - tooltip: FDC3 Workbench - lang: en-US - icons: - - src: https://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png - screenshots: - - src: https://fdc3.finos.org/docs/assets/fdc3-logo.png - label: FDC3 logo - contactEmail: fdc3@finos.org - supportEmail: fdc3-maintainers@finos.org - moreInfo: https://fdc3.finos.org #update to point to implementations page when it exists - publisher: FDC3 - type: web - details: - url: https://fdc3.finos.org/toolbox/fdc3-workbench/ - hostManifests: { - Glue42: { - type: window, - icon: https://fdc3.finos.org/docs/assets/fdc3-logo.png, - details: { - height: 640, - width: 560, - left: 120, - top: 120, - mode: tab, - allowChannels: true, - loader: { - enabled: true, - hideOnLoad: true - } - }, - customProperties: { - folder: FDC3 Toolbox - } - }, - Finsemble: { - window: { - left: 120, - top: 120, - width: 800, - height: 750, - options: { - minWidth: 75 - } - }, - foreign: { - components: { - App Launcher: { - launchableByUser: true - }, - Toolbar: { - iconURL: http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png - }, - Window Manager: { - FSBLHeader: true, - persistWindowState: true - } - } - }, - interop: { - autoConnect: true - } - }, - Web App Manifest: https://example.com/fdc3-workbench.json - } - localizedVersions: { - fr-FR: { - title: FDC3 Table de travail, - description: Outil de développement et de test pour les desktop agents et applications FDC3 - } - } - summary: A sample app definition for the FDC3 Workbench - MyAppDefinition: - value: - appId: my-application - title: My Application - description: An example application that uses FDC3 and fully describes itself in an AppD record. - categories: [market data, research, news] - version: 1.0.0 - tooltip: My example application definition - lang: en-US - icons: - - src: http://example.domain.com/assets/my-app-icon.png - size: 256x256 - type: image/png - screenshots: - - src: http://example.domain.com/assets/my-app-screenshot-1.png - label: The first screenshot of my example app - type: image/png - size: 800x600 - - src: http://example.domain.com/assets/my-app-screenshot-2.png - label: The second screenshot of my example app - type: image/png - size: 800x600 - contactEmail: fdc3@finos.org - supportEmail: fdc3-maintainers@finos.org - moreInfo: http://example.domain.com/ - publisher: Example App, Inc. - type: web - details: - url: http://example.domain.com/app.html - hostManifests: { - Finsemble: { - window: { - left: 120, - top: 120, - width: 600, - height: 800, - options: { - minWidth: 75 - } - }, - foreign: { - components: { - App Launcher: { - launchableByUser: true - }, - Window Manager: { - FSBLHeader: true, - persistWindowState: true - } - } - }, - interop: { - autoConnect: true - } - }, - Glue42: { - type: window, - details: { - height: 800, - width: 600, - left: 120, - top: 120, - mode: tab, - allowChannels: true, - loader: { - enabled: true, - hideOnLoad: true - } - }, - customProperties: { - folder: FDC3 Toolbox - } - }, - Web App Manifest: http://example.domain.com/my-app.json - } - interop: - intents: - listensFor: - ViewChart: - contexts: - - fdc3.instrument - myApp.GetPrice: - contexts: - - fdc3.instrument - resultType: myApp.quote - raises: - ViewOrders: - - fdc3.instrument - - fdc3.organization - StartEmail: - - fdc3.email - userChannels: - broadcasts: - - fdc3.instrument - - fdc3.organization - listensFor: - - fdc3.instrument - - fdc3.organization - appChannels: - - id: myApp.quotes, - description: >- - Used to share a stream of quotes for currently displayed instrument and may be used to change the currently displayed symbol, - broadcasts: - - myApp.quote - listensFor: - - fdc3.instrument - localizedVersions: - fr-FR: - title: Mon application, - description: Un exemple d'application qui utilise FDC3 et se décrit entièrement dans un enregistrement AppD. - summary: A sample app definition that describes the app's use of interop. - AllAppsResponse: - value: - applications: # you can't $ref inside a $ref so example is repeated here for search response - - appId: my-application - title: My Application - description: An example application that uses FDC3 and fully describes itself in an AppD record. - categories: [market data, research, news] - version: 1.0.0 - tooltip: My example application definition - lang: en-US - icons: - - src: http://example.domain.com/assets/my-app-icon.png - size: 256x256 - type: image/png - screenshots: - - src: http://example.domain.com/assets/my-app-screenshot-1.png - label: The first screenshot of my example app - type: image/png - size: 800x600 - - src: http://example.domain.com/assets/my-app-screenshot-2.png - label: The second screenshot of my example app - type: image/png - size: 800x600 - contactEmail: fdc3@finos.org - supportEmail: fdc3-maintainers@finos.org - moreInfo: http://example.domain.com/ - publisher: Example App, Inc. - type: web - details: - url: http://example.domain.com/app.html - hostManifests: { - Finsemble: { - window: { - left: 120, - top: 120, - width: 600, - height: 800, - options: { - minWidth: 75 - } - }, - foreign: { - components: { - App Launcher: { - launchableByUser: true - }, - Window Manager: { - FSBLHeader: true, - persistWindowState: true - } - } - }, - interop: { - autoConnect: true - } - }, - Glue42: { - type: window, - details: { - height: 800, - width: 600, - left: 120, - top: 120, - mode: tab, - allowChannels: true, - loader: { - enabled: true, - hideOnLoad: true - } - }, - customProperties: { - folder: FDC3 Toolbox - } - }, - Web App Manifest: http://example.domain.com/my-app.json - } - interop: - intents: - listensFor: - ViewChart: - contexts: - - fdc3.instrument - myApp.GetPrice: - contexts: - - fdc3.instrument - resultType: myApp.quote - raises: - ViewOrders: - - fdc3.instrument - - fdc3.organization - StartEmail: - - fdc3.email - userChannels: - broadcasts: - - fdc3.instrument - - fdc3.organization - listensFor: - - fdc3.instrument - - fdc3.organization - appChannels: - - id: myApp.quotes, - description: >- - Used to share a stream of quotes for currently displayed instrument and may be used to change the currently displayed symbol, - broadcasts: - - myApp.quote - listensFor: - - fdc3.instrument - localizedVersions: - fr-FR: - title: Mon application, - description: Un exemple d'application qui utilise FDC3 et se décrit entièrement dans un enregistrement AppD. - - appId: fdc3-workbench - title: FDC3 Workbench - description: Development and test tool for FDC3 desktop agents and apps - categories: [developer tools, training] - version: 1.0.0 - tooltip: FDC3 Workbench - lang: en-US - icons: - - src: https://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png - screenshots: - - src: https://fdc3.finos.org/docs/assets/fdc3-logo.png, - label: FDC3 logo - contactEmail: fdc3@finos.org, - supportEmail: fdc3-maintainers@finos.org, - publisher: FDC3, - type: web - details: - url: https://fdc3.finos.org/toolbox/fdc3-workbench/ - hostManifests: { - Glue42: { - type: window, - icon: https://fdc3.finos.org/docs/assets/fdc3-logo.png, - details: { - height: 640, - width: 560, - left: 120, - top: 120, - mode: tab, - allowChannels: true, - loader: { - enabled: true, - hideOnLoad: true - } - }, - customProperties: { - folder: FDC3 Toolbox - } - }, - Finsemble: { - window: { - left: 120, - top: 120, - width: 800, - height: 750, - options: { - minWidth: 75 - } - }, - foreign: { - components: { - App Launcher: { - launchableByUser: true - }, - Toolbar: { - iconURL: http://fdc3.finos.org/toolbox/fdc3-workbench/fdc3-icon-256.png - }, - Window Manager: { - FSBLHeader: true, - persistWindowState: true - } - } - }, - interop: { - autoConnect: true - } - }, - Web App Manifest: https://example.com/fdc3-workbench.json - } - localizedVersions: { - fr-FR: { - title: FDC3 Table de travail, - description: Outil de développement et de test pour les desktop agents et applications FDC3 - } - } - message: OK - summary: A sample 'all applications' listing response - Error400Example: - value: - code: 400 - message: There was an error in your request. - summary: A sample Bad Request error. - Error403Example: - value: - code: 403 - message: Certificate authentication failed for the requested user. - summary: A sample Forbidden error. - Error500Example: - value: - code: 500 - message: An internal server error occurred. See the response body for further details. - summary: A sample Server error. diff --git a/website/static/schemas/next/bridging/agentRequest.schema.json b/website/static/schemas/next/bridging/agentRequest.schema.json index bf11e36f4..714293942 100644 --- a/website/static/schemas/next/bridging/agentRequest.schema.json +++ b/website/static/schemas/next/bridging/agentRequest.schema.json @@ -20,8 +20,7 @@ "PrivateChannel.onAddContextListener", "PrivateChannel.onDisconnect", "PrivateChannel.onUnsubscribe", - "raiseIntentRequest", - "raiseIntentResultResponse" + "raiseIntentRequest" ], "description": "Identifies the type of the message and it is typically set to the FDC3 function name that the message relates to, e.g. 'findIntent', with 'Request' appended." }, diff --git a/website/static/schemas/next/bridging/findInstancesAgentRequest.schema.json b/website/static/schemas/next/bridging/findInstancesAgentRequest.schema.json index cf9bc12cb..3ea08288f 100644 --- a/website/static/schemas/next/bridging/findInstancesAgentRequest.schema.json +++ b/website/static/schemas/next/bridging/findInstancesAgentRequest.schema.json @@ -42,7 +42,14 @@ "$ref": "common.schema.json#/$defs/AgentDestination" }, "source": { - "$ref": "common.schema.json#/$defs/AppRequestSource" + "oneOf": [ + { + "$ref": "../api/api.schema.json#/definitions/DesktopAgentIdentifier" + }, + { + "$ref": "../api/api.schema.json#/definitions/AppIdentifier" + } + ] } }, "unevaluatedProperties": false diff --git a/website/static/schemas/next/bridging/privateChannelBroadcastAgentRequest.schema.json b/website/static/schemas/next/bridging/privateChannelBroadcastAgentRequest.schema.json index 16c4ca25e..e5f070306 100644 --- a/website/static/schemas/next/bridging/privateChannelBroadcastAgentRequest.schema.json +++ b/website/static/schemas/next/bridging/privateChannelBroadcastAgentRequest.schema.json @@ -25,7 +25,7 @@ "title": "PrivateChannelBroadcast Request Payload", "type": "object", "properties": { - "channelId": { + "channel": { "type": "string", "title": "Channel Id", "description": "The Id of the PrivateChannel that the broadcast was sent on" diff --git a/website/static/schemas/next/context/action.schema.json b/website/static/schemas/next/context/action.schema.json index a985015a7..693dd622d 100644 --- a/website/static/schemas/next/context/action.schema.json +++ b/website/static/schemas/next/context/action.schema.json @@ -1,35 +1,67 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://fdc3.finos.org/schemas/next/context/action.schema.json", - "type": "object", "title": "Action", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.action" }, - "title": { - "type": "string" - }, - "intent": { - "type": "string", - "description": "A reference an intent type name, such as those defined in the FDC3 Standard" - }, - "context": { - "type": "object", - "$ref": "context.schema.json#" - }, - "app": { + "description": "A representation of an FDC3 Action (specified via a Context or Context & Intent) that can be inserted inside another object, for example a chat message.\n\nThe action may be completed by calling `fdc3.raiseIntent()` with the specified Intent and Context, or, if only a context is specified, by calling `fdc3.raiseIntentForContext()` (which the Desktop Agent will resolve by presenting the user with a list of available Intents for the Context).\n\nAccepts an optional `app` parameter in order to specify a specific app.", + "allOf": [{ "type": "object", "properties": { - "appId": { "type": "string" }, - "instanceId": { "type": "string" } + "type": { "const": "fdc3.action" }, + "title": { + "title": "Action Title", + "description": "A human readable display name for the action", + "type": "string" + }, + "intent": { + "title": "Action Intent", + "description": "Optional Intent to raise to perform the actions. Should reference an intent type name, such as those defined in the FDC3 Standard. If intent is not set then `fdc3.raiseIntentForContext` should be used to perform the action as this will usually allow the user to choose the intent to raise.", + "type": "string" + }, + "context": { + "title": "Action Context", + "description": "A context object with which the action will be performed", + "$ref": "context.schema.json#" + }, + "app": { + "title": "Action Target App", + "description": "An optional target application identifier that should perform the action", + "allOf": [ + { "$ref": "../api/api.schema.json#/definitions/AppIdentifier" } + ] + } }, - "required": ["appId"] + "required": [ + "title", "context" + ] }, - "customConfig": { - "type": "object" + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.action", + "title": "Click to view Chart", + "intent": "ViewChart", + "context": { + "type": "fdc3.chart", + "instruments": [ + { + "type": "fdc3.instrument", + "id": { + "ticker": "EURUSD" + } + } + ], + "range": { + "type": "fdc3.dateRange", + "starttime": "2020-09-01T08:00:00.000Z", + "endtime": "2020-10-31T08:00:00.000Z" + }, + "style": "candle" + }, + "app" :{ + "appId": "MyChartViewingApp", + "instanceId": "instance1" + } } - }, - "required": [ - "title", "context" ] } diff --git a/website/static/schemas/next/context/chart.schema.json b/website/static/schemas/next/context/chart.schema.json index 215326f61..171f9e594 100644 --- a/website/static/schemas/next/context/chart.schema.json +++ b/website/static/schemas/next/context/chart.schema.json @@ -3,28 +3,86 @@ "$id": "https://fdc3.finos.org/schemas/next/context/chart.schema.json", "type": "object", "title": "Chart", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.chart" }, - "instruments": { - "type": "array", - "items": { - "$ref": "instrument.schema.json#" - } + "description": "A context type representing details of a Chart, which may be used to request plotting of a particular chart or to otherwise share details of its composition, such as:\n\n- A list of instruments for comparison\n- The time period to plot the chart over\n- The style of chart (line, bar, mountain, candle etc.)\n- Other settings such as indicators to calculate, or data representing drawings and annotations.\n\nIn addition to handling requests to plot charts, a charting application may use this type to output a representation of what it is currently displaying so that it can be recorded by another application.", + "allOf": [{ + "type": "object", + "properties": { + "type": { "const": "fdc3.chart" }, + "instruments": { + "title": "Instruments to plot", + "description": "An array of instrument contexts whose data should be plotted.", + "type": "array", + "items": { + "$ref": "instrument.schema.json#" + } + }, + "range": { + "title": "Time Range", + "description": "The time range that should be plotted", + "allOf": [{ + "$ref": "timerange.schema.json#" + }] + }, + "style": { + "title": "Chart style", + "description": "The type of chart that should be plotted", + "type": "string", + "enum": [ "line", "bar", "stacked-bar", "mountain", "candle", "pie", "scatter", "histogram", "heatmap", "custom"] + }, + "otherConfig": { + "title": "Other configuration", + "description": "It is common for charts to support other configuration, such as indicators, annotations etc., which do not have standardized formats, but may be included in the `otherConfig` array as context objects.", + "type": "array", + "items": { + "$ref": "context.schema.json#" + } + } + }, + "required": ["instruments"] }, - "range": { - "$ref": "timerange.schema.json#" - }, - "style": { - "type": "string", - "enum": [ "line", "bar", "stacked-bar", "mountain", "candle", "pie", "scatter", "histogram", "heatmap", "custom"] - }, - "otherConfig": { - "type": "array", - "items": { - "$ref": "context.schema.json#" - } + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.chart", + "instruments": [ + { + "type": "fdc3.instrument", + "id": { + "ticker": "AAPL" + } + }, + { + "type": "fdc3.instrument", + "id": { + "ticker": "GOOG" + } + } + ], + "range": { + "type": "fdc3.timeRange", + "startTime": "2020-09-01T08:00:00.000Z", + "endTime": "2020-10-31T08:00:00.000Z" + }, + "style": "line", + "otherConfig": [ + { + "type": "somevendor.someproduct.indicator", + "name": "stddev", + "parameters": { + "period": 10, + "matype": "exponential" + } + }, + { + "type": "someothervendor.someotherproduct.formula", + "formula": "standard-deviation", + "fields": { + "lookback": 10, + "type": "ema" + } + } + ] } - }, - "required": ["instruments"] + ] } diff --git a/website/static/schemas/next/context/chatInitSettings.schema.json b/website/static/schemas/next/context/chatInitSettings.schema.json index e2e967c1c..45711cd8b 100644 --- a/website/static/schemas/next/context/chatInitSettings.schema.json +++ b/website/static/schemas/next/context/chatInitSettings.schema.json @@ -1,36 +1,115 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://fdc3.finos.org/schemas/next/context/chatInitSettings.schema.json", - "type": "object", - "title": "ChatInitSettings", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/context/chatInitSettings.schema.json", + "type": "object", + "title": "ChatInitSettings", + "description": "A collection of settings to start a new chat conversation", + "allOf": [{ + "type": "object", + "properties": { "type": { "const": "fdc3.chat.initSettings" }, "chatName": { - "type": "string" + "title": "Chat name", + "description": "Name to apply to the chat created", + "type": "string" }, "members": { - "$ref": "contactList.schema.json#" + "title": "Chat members", + "description": "Contacts to add to the chat", + "$ref": "contactList.schema.json#" }, "message": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "message.schema.json#" - } - ] + "title": "Initial chat message", + "description": "An initial message to post in the chat when created.", + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "message.schema.json#" + } + ] }, "options": { - "type": "object", - "properties": { - "groupRecipients": {"type": "boolean"}, - "isPublic": {"type": "boolean"}, - "allowHistoryBrowsing": {"type": "boolean"}, - "allowMessageCopy": {"type": "boolean"}, - "allowAddUser": {"type": "boolean"} + "title": "Chat options", + "description": "Option settings that affect the creation of the chat", + "type": "object", + "properties": { + "groupRecipients": { + "title": "Group recipients option", + "description": "if false a separate chat will be created for each member", + "type": "boolean" + }, + "isPublic": { + "title": "Public chat option", + "description": "if true the room will be visible to everyone in the chat application", + "type": "boolean" + }, + "allowHistoryBrowsing": { + "title": "Allow history browsing option", + "description": "if true members will be allowed to browse past messages", + "type": "boolean" + }, + "allowMessageCopy": { + "title": "Allow message copy option", + "description": "if true members will be allowed to copy/paste messages", + "type": "boolean" + }, + "allowAddUser": { + "title": "All adding users option", + "description": "if true members will be allowed to add other members to the chat", + "type": "boolean" + } + } + } + } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.chat.initSettings", + "chatName": "Chat ABCD", + "members": { + "type": "fdc3.contactList", + "contacts": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane@mail.com" + } + }, + { + "type": "fdc3.contact", + "name": "John Doe", + "id": { + "email": "john@mail.com" + } + } + ] + }, + "options": { + "groupRecipients": true, + "isPublic": false, + "allowHistoryBrowsing": true, + "allowMessageCopy": true + }, + "message": { + "type": "fdc3.message", + "text": { + "text/plain": "Hey all, can we discuss the issue together? I attached a screenshot" + }, + "entities": { + "0": { + "type": "fdc3.fileAttachment", + "data": { + "name": "myImage.png", + "dataUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII" } + } } + } } + ] } diff --git a/website/static/schemas/next/context/chatMessage.schema.json b/website/static/schemas/next/context/chatMessage.schema.json index be443e915..d469d3805 100644 --- a/website/static/schemas/next/context/chatMessage.schema.json +++ b/website/static/schemas/next/context/chatMessage.schema.json @@ -2,12 +2,39 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://fdc3.finos.org/schemas/next/context/chatMessage.schema.json", "type": "object", - "title": "ChatMessage", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.chat.message" }, - "chatRoom": { "$ref": "chatRoom.schema.json#" }, - "message": { "$ref": "message.schema.json#" } - }, - "required": ["type", "chatRoom", "message"] + "title": "Chat Message", + "description": "A context representing a chat message. Typically used to send the message or to pre-populate a message for sending.", + "allOf": [{ + "type": "object", + "properties": { + "type": { "const": "fdc3.chat.message" }, + "chatRoom": { "$ref": "chatRoom.schema.json#" }, + "message": { + "title": "Chat message", + "description": "The content of the message to post in the chat when created.", + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "message.schema.json#" + } + ] + } + }, + "required": ["type", "chatRoom", "message"] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [{ + "type": "fdc3.chat.message", + "chatRoom": { + "type": "fdc3.chat.room", + "providerName": "Symphony", + "id": { + "streamId": "j75xqXy25NBOdacUI3FNBH" + } + }, + "message": "A message to send" + }] } diff --git a/website/static/schemas/next/context/chatRoom.schema.json b/website/static/schemas/next/context/chatRoom.schema.json index d0cd00664..d04fdf2f9 100644 --- a/website/static/schemas/next/context/chatRoom.schema.json +++ b/website/static/schemas/next/context/chatRoom.schema.json @@ -2,14 +2,47 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://fdc3.finos.org/schemas/next/context/chatRoom.schema.json", "type": "object", - "title": "ChatRoom", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.chat.room" }, - "providerName": { "type": "string" }, - "id": { "type": "object" }, - "url": { "type": "string" }, - "name": { "type": "string" } - }, - "required": ["providerName", "id"] + "title": "Chat Room", + "description": "Reference to the chat room which could be used to send a message to the room", + "allOf": [{ + "type": "object", + "properties": { + "type": { "const": "fdc3.chat.room" }, + "providerName": { + "title": "Chat provider name", + "description": "The name of the service that hosts the chat", + "type": "string" + }, + "id": { + "title": "Chat room id", + "description": "Identifier(s) for the chat - currently unstandardized", + "type": "object" + }, + "url": { + "title": "Chat URL", + "description": "Universal url to access to the room. It could be opened from a browser, a mobile app, etc...", + "type": "string", + "format": "uri" + }, + "name": { + "title": "Chat name", + "description": "Display name for the chat room", + "type": "string" + } + }, + "required": ["providerName", "id"] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.chat.room", + "providerName": "Symphony", + "id": { + "streamId": "j75xqXy25NBOdacUI3FNBH" + }, + "url": "http://symphony.com/ref/room/j75xqXy25NBOdacUI3FNBH___pqSsuJRdA", + "name": "My new room" + } + ] } diff --git a/website/static/schemas/next/context/chatSearchCriteria.schema.json b/website/static/schemas/next/context/chatSearchCriteria.schema.json index 95cdf90d7..e6210ae82 100644 --- a/website/static/schemas/next/context/chatSearchCriteria.schema.json +++ b/website/static/schemas/next/context/chatSearchCriteria.schema.json @@ -2,21 +2,65 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://fdc3.finos.org/schemas/next/context/chatSearchCriteria.schema.json", "type": "object", - "title": "ChatSearchCriteria", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.chat.searchCriteria" }, - "criteria": { - "type": "array", - "items": { - "anyOf": [ - { "$ref":"instrument.schema.json#" }, - { "$ref": "organization.schema.json#" }, - { "$ref": "contact.schema.json#" }, - { "type": "string" } - ] - } + "title": "Chat Search Criteria", + "description": "A context type that represents a simple search criterion, based on a list of other context objects, that can be used to search or filter messages in a chat application.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.chat.searchCriteria" + }, + "criteria": { + "title": "Criteria array", + "description": "An array of criteria that should match chats returned from by a search.\n\n⚠️ Operators (and/or/not) are not defined in `fdc3.chat.searchCriteria`. It is up to the application that processes the FDC3 Intent to choose and apply the operators between the criteria.\n\nEmpty search criteria can be supported to allow resetting of filters.", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "instrument.schema.json#" + }, + { + "$ref": "organization.schema.json#" + }, + { + "$ref": "contact.schema.json#" + }, + { + "type": "string", + "title": "Free text", + "description": "Free text to be used for a keyword search" + } + ] + } + } + }, + "required": [ + "criteria" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.chat.searchCriteria", + "criteria": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + { + "type": "fdc3.instrument", + "id": { + "ticker": "TSLA" + }, + "name": "Tesla, inc." + }, + "annual return" + ] } - }, - "required": ["criteria"] -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/contact.schema.json b/website/static/schemas/next/context/contact.schema.json index 6aef5f52e..e2066b58c 100644 --- a/website/static/schemas/next/context/contact.schema.json +++ b/website/static/schemas/next/context/contact.schema.json @@ -3,16 +3,46 @@ "$id": "https://fdc3.finos.org/schemas/next/context/contact.schema.json", "type": "object", "title": "Contact", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.contact" }, - "id": { + "description": "A person contact that can be engaged with through email, calling, messaging, CMS, etc.", + "allOf": [ + { "type": "object", "properties": { - "email": { "type": "string" }, - "FDS_ID": { "type": "string" } + "type": { + "const": "fdc3.contact" + }, + "id": { + "type": "object", + "title": "Contact Identifiers", + "description": "Identifiers that relate to the Contact represented by this context", + "properties": { + "email": { + "type": "string", + "format": "email", + "title": "Email address", + "description": "The email address for the contact" + }, + "FDS_ID": { + "type": "string", + "title": "FDS ID", + "description": "FactSet Permanent Identifier representing the contact" + } + } + } + }, + "required": [ + "id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" } } - }, - "required": ["id"] + ] } diff --git a/website/static/schemas/next/context/contactList.schema.json b/website/static/schemas/next/context/contactList.schema.json index 57bf2a532..ed571f38c 100644 --- a/website/static/schemas/next/context/contactList.schema.json +++ b/website/static/schemas/next/context/contactList.schema.json @@ -3,13 +3,48 @@ "$id": "https://fdc3.finos.org/schemas/next/context/contactList.schema.json", "type": "object", "title": "ContactList", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.contactList" }, - "contacts": { - "type": "array", - "items": { "$ref": "contact.schema.json#" } + "description": "A collection of contacts, e.g. for chatting to or calling multiple contacts.\n\nThe contact list schema does not explicitly include identifiers in the `id` section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.contactList" + }, + "contacts": { + "type": "array", + "title": "List of Contacts", + "description": "An array of contact contexts that forms the list.", + "items": { + "$ref": "contact.schema.json#" + } + } + }, + "required": [ + "contacts" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.contactList", + "contacts": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + { + "type": "fdc3.contact", + "name": "John Doe", + "id": { + "email": "john.doe@mail.com" + } + } + ] } - }, - "required": ["contacts"] -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/context.schema.json b/website/static/schemas/next/context/context.schema.json index b14861b52..8c84dd866 100644 --- a/website/static/schemas/next/context/context.schema.json +++ b/website/static/schemas/next/context/context.schema.json @@ -3,14 +3,65 @@ "$id": "https://fdc3.finos.org/schemas/next/context/context.schema.json", "type": "object", "title": "Context", - "properties": { - "type": { "type": "string" }, - "name": { "type": "string" }, - "id": { + "description": "The `fdc3.context` type defines the basic contract or \"shape\" for all data exchanged by FDC3 operations. As such, it is not really meant to be used on its own, but is imported by more specific type definitions (standardized or custom) to provide the structure and properties shared by all FDC3 context data types.\n\nThe key element of FDC3 context types is their mandatory `type` property, which is used to identify what type of data the object represents, and what shape it has.\n\nThe FDC3 context type, and all derived types, define the minimum set of fields a context data object of a particular type can be expected to have, but this can always be extended with custom fields as appropriate.", + "allOf": [ + { + "$ref": "#/definitions/DocumentedContext" + }, + { + "$ref": "#/definitions/BaseContext" + } + ], + "definitions": { + "BaseContext": { + "$comment": "Base definition for the Context object without documentation (which will be imported into all derived types unless separated).", + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "id": { + "type": "object", + "unevaluatedProperties": { + "type": "string" + } + } + }, + "additionalProperties": true, + "required": [ + "type" + ] + }, + "DocumentedContext": { + "$comment": "Base definition for the Context object without documentation (which will be imported into all derived types unless separated).", "type": "object", - "unevaluatedProperties": { "type": "string" } + "properties": { + "type": { + "type": "string", + "title": "Type", + "description": "The type property is the only _required_ part of the FDC3 context data schema. The FDC3 [API](https://fdc3.finos.org/docs/api/spec) relies on the `type` property being present to route shared context data appropriately.\n\nFDC3 [Intents](https://fdc3.finos.org/docs/intents/spec) also register the context data types they support in an FDC3 [App Directory](https://fdc3.finos.org/docs/app-directory/overview), used for intent discovery and routing.\n\nStandardized FDC3 context types have well-known `type` properties prefixed with the `fdc3` namespace, e.g. `fdc3.instrument`. For non-standard types, e.g. those defined and used by a particular organization, the convention is to prefix them with an organization-specific namespace, e.g. `blackrock.fund`.\n\nSee the [Context Data Specification](https://fdc3.finos.org/docs/context/spec) for more information about context data types." + }, + "name": { + "type": "string", + "title": "Name", + "description": "Context data objects may include a name property that can be used for more information, or display purposes. Some derived types may require the name object as mandatory, depending on use case." + }, + "id": { + "type": "object", + "title": "Id", + "description": "Context data objects may include a set of equivalent key-value pairs that can be used to help applications identify and look up the context type they receive in their own domain. The idea behind this design is that applications can provide as many equivalent identifiers to a target application as possible, e.g. an instrument may be represented by an ISIN, CUSIP or Bloomberg identifier.\n\nIdentifiers do not make sense for all types of data, so the `id` property is therefore optional, but some derived types may choose to require at least one identifier.", + "unevaluatedProperties": { + "type": "string" + } + } + }, + "additionalProperties": true, + "required": [ + "type" + ] } - }, - "additionalItems": true, - "required": ["type"] -} + } +} \ No newline at end of file diff --git a/website/static/schemas/next/context/country.schema.json b/website/static/schemas/next/context/country.schema.json index 2a0a6a763..66bb354e6 100644 --- a/website/static/schemas/next/context/country.schema.json +++ b/website/static/schemas/next/context/country.schema.json @@ -3,18 +3,55 @@ "$id": "https://fdc3.finos.org/schemas/next/context/country.schema.json", "type": "object", "title": "Country", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.country" }, - "id": { + "description": "A country entity.\n\nNotes:\n\n- It is valid to include extra properties and metadata as part of the country payload, but the minimum requirement is for at least one standardized identifier to be provided\n\n - `COUNTRY_ISOALPHA2` SHOULD be preferred.\n\n- Try to only use country identifiers as intended and specified in the [ISO standard](https://en.wikipedia.org/wiki/ISO_3166-1). E.g. the `COUNTRY_ISOALPHA2` property must be a recognized value and not a proprietary two-letter code. If the identifier you want to share is not a standardized and recognized one, rather define a property that makes it clear what value it is. This makes it easier for target applications.", + "allOf": [ + { "type": "object", "properties": { - "COUNTRY_ISOALPHA2": { "type": "string" }, - "COUNTRY_ISOALPHA3": { "type": "string" }, - "ISOALPHA2": { "type": "string" }, - "ISOALPHA3": { "type": "string" } + "type": { + "const": "fdc3.country" + }, + "id": { + "type": "object", + "properties": { + "COUNTRY_ISOALPHA2": { + "type": "string", + "title": "COUNTRY_ISOALPHA2", + "description": "Two-letter ISO country code" + }, + "COUNTRY_ISOALPHA3": { + "type": "string", + "title": "COUNTRY_ISOALPHA3", + "description": "Three-letter ISO country code" + }, + "ISOALPHA2": { + "type": "string", + "title": "ISOALPHA2", + "description": "Two-letter ISO country code. Deprecated in FDC3 2.0 in favour of the version prefixed with `COUNTRY_`.", + "deprecated": true + }, + "ISOALPHA3": { + "type": "string", + "title": "ISOALPHA3", + "description": "Three-letter ISO country code. Deprecated in FDC3 2.0 in favour of the version prefixed with `COUNTRY_`.", + "deprecated": true + } + } + } + }, + "required": [ + "id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.country", + "name": "Sweden", + "id": { + "COUNTRY_ISOALPHA2": "SE" } } - }, - "required": ["id"] -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/currency.schema.json b/website/static/schemas/next/context/currency.schema.json index aa0c08455..a58b5b75c 100644 --- a/website/static/schemas/next/context/currency.schema.json +++ b/website/static/schemas/next/context/currency.schema.json @@ -3,17 +3,44 @@ "$id": "https://fdc3.finos.org/schemas/next/context/currency.schema.json", "type": "object", "title": "Currency", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.currency" }, - "name": { "type": "string" }, - "id": { + "description": "A context representing an individual Currency.", + "allOf": [ + { "type": "object", "properties": { - "CURRENCY_ISOCODE": { "type": "string", "pattern": "^[A-Z]{3}$"} + "type": { + "const": "fdc3.currency" + }, + "name": { + "type": "string", + "title": "Currency name", + "description": "The name of the currency for display purposes" + }, + "id": { + "type": "object", + "properties": { + "CURRENCY_ISOCODE": { + "type": "string", + "pattern": "^[A-Z]{3}$", + "title": "CURRENCY_ISOCODE", + "description": "The `CURRENCY_ISOCODE` should conform to 3 character alphabetic codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html)" + } + } + } + }, + "required": [ + "id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.currency", + "name": "US Dollar", + "id": { + "CURRENCY_ISOCODE": "USD" } } - - }, - "required": ["id"] -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/email.schema.json b/website/static/schemas/next/context/email.schema.json index 4ec814dcf..eb863bfa6 100644 --- a/website/static/schemas/next/context/email.schema.json +++ b/website/static/schemas/next/context/email.schema.json @@ -3,17 +3,55 @@ "$id": "https://fdc3.finos.org/schemas/next/context/email.schema.json", "type": "object", "title": "Email", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.email" }, - "recipients": { - "oneOf": [ - { "$ref": "contact.schema.json#" }, - { "$ref": "contactList.schema.json#" } + "description": "A collection of information to be used to initiate an email with a Contact or ContactList.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.email" + }, + "recipients": { + "title": "Email Recipients", + "description": "One or more receipients for the email.", + "oneOf": [ + { + "$ref": "contact.schema.json#" + }, + { + "$ref": "contactList.schema.json#" + } + ] + }, + "subject": { + "title": "Email Subject", + "description": "Subject line for the email.", + "type": "string" + }, + "textBody": { + "title": "Email Body", + "description": "Body content for the email.", + "type": "string" + } + }, + "required": [ + "recipients" ] }, - "subject": { "type": "string" }, - "textBody": { "type": "string" } - }, - "required": ["recipients"] -} + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.email", + "recipients": { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@example.com" + } + }, + "subject": "The information you requested", + "textBody": "Blah, blah, blah ..." + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/instrument.schema.json b/website/static/schemas/next/context/instrument.schema.json index eee0f800f..7ea8435d8 100644 --- a/website/static/schemas/next/context/instrument.schema.json +++ b/website/static/schemas/next/context/instrument.schema.json @@ -3,34 +3,114 @@ "$id": "https://fdc3.finos.org/schemas/next/context/instrument.schema.json", "type": "object", "title": "Instrument", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.instrument" }, - "id": { + "description": "A financial instrument from any asset class.", + "allOf": [ + { "type": "object", "properties": { - "BBG": { "type": "string" }, - "CUSIP": { "type": "string" }, - "FDS_ID": { "type": "string" }, - "FIGI": { "type": "string" }, - "ISIN": { "type": "string" }, - "PERMID": { "type": "string" }, - "RIC": { "type": "string" }, - "SEDOL": { "type": "string" }, - "ticker": { "type": "string" } - } + "type": { + "const": "fdc3.instrument" + }, + "id": { + "title": "Instrument identifiers", + "description": "Any combination of instrument identifiers can be used together to resolve ambiguity, or for a better match. Not all applications will use the same instrument identifiers, which is why FDC3 allows for multiple to be specified. In general, the more identifiers an application can provide, the easier it will be to achieve interoperability.\n\nIt is valid to include extra properties and metadata as part of the instrument payload, but the minimum requirement is for at least one instrument identifier to be provided.\n\nTry to only use instrument identifiers as intended. E.g. the `ticker` property is meant for tickers as used by an exchange.\nIf the identifier you want to share is not a ticker or one of the other standardized fields, define a property that makes it clear what the value represents. Doing so will make interpretation easier for the developers of target applications.", + "type": "object", + "properties": { + "BBG": { + "type": "string", + "title": "Bloomberg security", + "description": "" + }, + "CUSIP": { + "type": "string", + "title": "CUSIP", + "description": "" + }, + "FDS_ID": { + "type": "string", + "title": "FactSet Permanent Security Identifier", + "description": "" + }, + "FIGI": { + "type": "string", + "title": "Open FIGI", + "description": "" + }, + "ISIN": { + "type": "string", + "title": "ISIN", + "description": "" + }, + "PERMID": { + "type": "string", + "title": "Refinitiv PERMID", + "description": "" + }, + "RIC": { + "type": "string", + "title": "Refinitiv Identification Code", + "description": " " + }, + "SEDOL": { + "type": "string", + "title": "SEDOL", + "description": "" + }, + "ticker": { + "type": "string", + "title": "Stock ticker", + "description": "Unstandardized stock tickers" + } + } + }, + "market": { + "description": "The `market` map can be used to further specify the instrument and help achieve interoperability between disparate data sources. This is especially useful when using an `id` field that is not globally unique.", + "type": "object", + "properties": { + "MIC": { + "type": "string", + "title": "Market Identifier Code", + "description": "" + }, + "name": { + "type": "string", + "title": "Market Name", + "description": "Human readable market name" + }, + "COUNTRY_ISOALPHA2": { + "type": "string", + "title": "Country ISO Code", + "description": "" + }, + "BBG": { + "type": "string", + "title": "Bloomberg Market Identifier", + "description": "" + } + }, + "unevaluatedProperties": { + "type": "string" + } + } + }, + "required": [ + "type","id" + ] }, - "market": { - "type": "object", - "properties": { - "MIC": { "type": "string" }, - "name": { "type": "string" }, - "COUNTRY_ISOALPHA2": { "type": "string" }, - "BBG": { "type": "string" } + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.instrument", + "name": "Microsoft", + "id": { + "ticker": "MSFT", + "RIC": "MSFT.OQ", + "ISIN": "US5949181045" }, - "unevaluatedProperties": { "type": "string" } + "market": { + "MIC": "XNAS" + } } - - }, - "required": ["id"] -} \ No newline at end of file + ] +} diff --git a/website/static/schemas/next/context/instrumentList.schema.json b/website/static/schemas/next/context/instrumentList.schema.json index ceca78935..4fb2627ea 100644 --- a/website/static/schemas/next/context/instrumentList.schema.json +++ b/website/static/schemas/next/context/instrumentList.schema.json @@ -3,13 +3,49 @@ "$id": "https://fdc3.finos.org/schemas/next/context/instrumentList.schema.json", "type": "object", "title": "InstrumentList", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.instrumentList" }, - "instruments": { - "type": "array", - "items": { "$ref": "instrument.schema.json#" } + "description": "A collection of instruments. Use this type for use cases that require not just a single instrument, but multiple (e.g. to populate a watchlist). However, when holding information for each instrument is required, it is recommended to use the [Portfolio](Portfolio) type.\n\nThe instrument list schema does not explicitly include identifiers in the `id` section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.instrumentList" + }, + "instruments": { + "type": "array", + "title": "List of instruments", + "description": "An array of instrument contexts that forms the list.", + "items": { + "$ref": "instrument.schema.json#" + } + } + }, + "required": [ + "instruments" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.instrumentList", + "instruments": [ + { + "type": "fdc3.instrument", + "id": { + "ticker": "AAPL" + }, + "market": { + "MIC": "XNAS" + } + }, + { + "type": "fdc3.instrument", + "id": { + "ISIN": "US5949181045" + } + } + ] } - }, - "required": ["instruments"] -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/interaction.schema.json b/website/static/schemas/next/context/interaction.schema.json index b5ed532d3..bf001f03f 100644 --- a/website/static/schemas/next/context/interaction.schema.json +++ b/website/static/schemas/next/context/interaction.schema.json @@ -3,35 +3,125 @@ "$id": "https://fdc3.finos.org/schemas/next/context/interaction.schema.json", "type": "object", "title": "Interaction", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.interaction" }, - "participants": { - "$ref": "contactList.schema.json#" - }, - "timeRange": { - "$ref": "timerange.schema.json#" - }, - "interactionType": { - "anyOf": [ - { - "type": "string", - "enum": ["Instant Message", "Email", "Call", "Meeting"] + "description": "An `Interaction` is a significant direct exchange of ideas or information between a number of participants, e.g. a Sell Side party and one or more Buy Side parties. An `Interaction` might be a call, a meeting (physical or virtual), an IM or the preparation of some specialist data, such as financial data for a given company or sector.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.interaction" + }, + "id": { + "type": "object", + "title": "Interaction Id", + "description": "Can be used by a target application to pass an identifier back to the originating application after an interaction record has been created, updated or deleted. An interaction ID does not need to be populated by the originating application, however the target application could store it for future reference and SHOULD return it in a `TransactionResult`.", + "properties": { + "URI": { + "type": "string", + "title": "Interaction URI", + "description": "Can be used by a target application to pass a record's link back to the originating application. This offers the originating application a way to open the record for a user to view." + }, + "SALESFORCE": { + "type": "string", + "title": "Salesforce ID", + "description": "Interactions ID in Salesforce" + }, + "SINGLETRACK": { + "type": "string", + "title": "SingleTrack ID", + "description": "Interaction ID in SingleTrack" + } + } + }, + "participants": { + "title": "Interaction Participants", + "description": "A list of contacts involved in the interaction", + "$ref": "contactList.schema.json#" + }, + "timeRange": { + "title": "Interaction Time range", + "description": "The time range over which the interaction occurred", + "$ref": "timerange.schema.json#" + }, + "interactionType": { + "title": "Interaction Type", + "description": "`interactionType` SHOULD be one of `'Instant Message'`, `'Email'`, `'Call'`, or `'Meeting'` although other string values are permitted.", + "anyOf": [ + { + "type": "string", + "enum": [ + "Instant Message", + "Email", + "Call", + "Meeting" + ] + }, + { + "type": "string" + } + ] }, - { + "description": { + "title": "Interaction Description", + "description": "A human-readable description of the interaction", + "type": "string" + }, + "initiator": { + "title": "Interaction Initiator", + "description": "The contact that initiated the interaction", + "$ref": "contact.schema.json#" + }, + "origin": { + "title": "Interaction Origin", + "description": "Used to represent the application or service that the interaction was created from to aid in tracing the source of an interaction.", "type": "string" } + }, + "required": [ + "participants", + "timeRange", + "interactionType", + "description" ] }, - "description": { - "type": "string" - }, - "initiator": { - "$ref": "contact.schema.json#" - }, - "origin": { - "type": "string" + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.interaction", + "participants": { + "type": "fdc3.contactList", + "contacts": [ + { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + { + "type": "fdc3.contact", + "name": "John Doe", + "id": { + "email": "john.doe@mail.com" + } + } + ] + }, + "interactionType": "Instant Message", + "timeRange": { + "type": "fdc3.timeRange", + "startTime": "2022-02-10T15:12:00Z" + }, + "description": "Laboris libero dapibus fames elit adipisicing eu, fermentum, dignissimos laboriosam, erat, risus qui deserunt. Praesentium! Reiciendis. Hic harum nostrud, harum potenti amet? Mauris. Pretium aliquid animi, eget eiusmod integer proident. Architecto ipsum blandit ducimus, possimus illum sunt illum necessitatibus ab litora sed, nonummy integer minus corrupti ducimus iste senectus accumsan, fugiat nostrud? Pede vero dictumst excepturi, iure earum consequuntur voluptatum", + "initiator": { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + "origin": "Outlook" } - }, - "required": ["participants", "timeRange", "interactionType", "description"] + ] } \ No newline at end of file diff --git a/website/static/schemas/next/context/message.schema.json b/website/static/schemas/next/context/message.schema.json index 9d2050b7b..b776eb11e 100644 --- a/website/static/schemas/next/context/message.schema.json +++ b/website/static/schemas/next/context/message.schema.json @@ -3,53 +3,118 @@ "$id": "https://fdc3.finos.org/schemas/next/context/message.schema.json", "type": "object", "title": "Message", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.message" }, - "text": { + "description": "A chat message to be sent through an instant messaging application. Can contain one or several text bodies (organized by mime-type, plaintext or markdown), as well as attached entities (either arbitrary file attachments or FDC3 actions to be embedded in the message). To be put inside a ChatInitSettings object.", + "allOf": [ + { "type": "object", "properties": { - "text/plain": { - "type": "string" + "type": { + "const": "fdc3.message" }, - "text/markdown": { - "type": "string" - } - } - }, - "entities": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "$ref": "action.schema.json#" - }, - { - "type": "object", - "properties": { - "type": { - "const": "fdc3.entity.fileAttachment" + "text": { + "type": "object", + "title": "Message text", + "description": "A map of string mime-type to string content", + "properties": { + "text/plain": { + "type": "string", + "title": "Plain text", + "description": "Plain text encoded content." + }, + "text/markdown": { + "title": "Markdown text", + "description": "Markdown encoded content", + "type": "string" + } + } + }, + "entities": { + "type": "object", + "title": "Message entities", + "description": "A map of string IDs to entities that should be attached to the message, such as an action to perform, a file attachment, or other FDC3 context object.", + "additionalProperties": { + "anyOf": [ + { + "$ref": "action.schema.json#" }, - "data": { + { "type": "object", + "title": "File attachment", + "description": "A File attachment encoded in the form of a data URI", "properties": { - "name": { - "type": "string" + "type": { + "const": "fdc3.entity.fileAttachment" }, - "dataUri": { - "type": "string" + "data": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "File name", + "description": "The name of the attached file" + }, + "dataUri": { + "type": "string", + "format": "uri", + "title": "", + "description": "A data URI encoding the content of the file to be attached" + } + }, + "required": [ + "name", + "dataUri" + ] } }, "required": [ - "name", - "dataUri" + "type", + "data" ] } + ] + } + } + } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.message", + "text": { + "text/plain": "Hey all, can we discuss the issue together? I attached a screenshot and a link to the current exchange rate" + }, + "entities": { + "picture1": { + "type": "fdc3.fileAttachment", + "data": { + "name": "myImage.png", + "dataUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII" + } + }, + "eurusd_action": { + "type": "fdc3.action", + "title": "Click to view Chart", + "intent": "ViewChart", + "context": { + "type": "fdc3.chart", + "instruments": [ + { + "type": "fdc3.instrument", + "id": { + "ticker": "EURUSD" + } + } + ], + "range": { + "type": "fdc3.dateRange", + "starttime": "2020-09-01T08:00:00.000Z", + "endtime": "2020-10-31T08:00:00.000Z" }, - "required": ["type", "data"] + "style": "candle" } - ] + } } } - } -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/nothing.schema.json b/website/static/schemas/next/context/nothing.schema.json index a7d67095e..2b970c895 100644 --- a/website/static/schemas/next/context/nothing.schema.json +++ b/website/static/schemas/next/context/nothing.schema.json @@ -3,8 +3,21 @@ "$id": "https://fdc3.finos.org/schemas/next/context/nothing.schema.json", "type": "object", "title": "Nothing", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.nothing" } - } -} + "description": "A type that explicitly represents a lack of context.\n\nNotes:\n\n- Intended to be used in situations where no context is desired.\n- For example:\n - Raising an intent without context (e.g. opening a blank order form, or chat interface without a contact selected).\n - Resetting context on a channel (e.g. when context is used to set a filter in other applications a null context might release the filter).\n- An explicit representation of a Null or empty context allows apps to declare support for a lack of context, for example in their intent metadata in an app directory.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.nothing" + } + } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.nothing" + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/order.schema.json b/website/static/schemas/next/context/order.schema.json index baa8381b9..fcf975011 100644 --- a/website/static/schemas/next/context/order.schema.json +++ b/website/static/schemas/next/context/order.schema.json @@ -1,74 +1,76 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://fdc3.finos.org/schemas/next/context/order.schema.json", - "type": "object", - "title": "Order", - "description": "@experimental context type representing an order. To be used with OMS and EMS systems.\n\nThis type currently only defines a required `id` field, which should provide a reference to the order in one or more systems, an optional human readable `name` field to be used to summarize the order and an optional `details` field that may be used to provide additional detail about the order, including a context representing a `product`, which may be extended with arbitrary properties. The `details.product` field is currently typed as a unspecified Context type, but both `details` and `details.product` are expected to be standardized in future.", - "allOf": [ - { - "$ref": "context.schema.json#" - } - ], - "properties": { - "type": { - "const": "fdc3.order" - }, - "id": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "title": "Order Identifiers", - "description": "One or more identifiers that refer to the order in an OMS, EMS or related system. Specific key names for systems are expected to be standardized in future." - }, - "name": { - "type": "string", - "title": "Name", - "description": "An optional human-readable summary of the order." - }, - "details": { - "type": "object", - "title": "Order Details", - "description": "Optional additional details about the order, which may include a product element that is an, as yet undefined but extensible, Context", - "properties": { - "product": { - "$ref": "product.schema.json" - } - }, - "additionalProperties": true - } - }, - "required": [ - "type", "id" - ], - "additionalProperties": true, - "examples": [ - { - "type": "fdc3.order", - "name": "...", - "id": { - "myOMS": "12345" - }, - "details": { - "product": { - "type": "fdc3.product", - "id": { - "productId": "ABC123" - }, - "instrument": { - "type": "fdc3.instrument", - "id": { - "ticker": "MSFT" - } - } - } - } - }, - { - "type": "fdc3.order", - "id": { - "myOMS": "ABC123" - } - } - ] -} + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/next/context/order.schema.json", + "type": "object", + "title": "Order", + "description": "@experimental context type representing an order. To be used with OMS and EMS systems.\n\nThis type currently only defines a required `id` field, which should provide a reference to the order in one or more systems, an optional human readable `name` field to be used to summarize the order and an optional `details` field that may be used to provide additional detail about the order, including a context representing a `product`, which may be extended with arbitrary properties. The `details.product` field is currently typed as a unspecified Context type, but both `details` and `details.product` are expected to be standardized in future.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.order" + }, + "id": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Order Identifiers", + "description": "One or more identifiers that refer to the order in an OMS, EMS or related system. Specific key names for systems are expected to be standardized in future." + }, + "name": { + "type": "string", + "title": "Name", + "description": "An optional human-readable summary of the order." + }, + "details": { + "type": "object", + "title": "Order Details", + "description": "Optional additional details about the order, which may include a product element that is an, as yet undefined but extensible, Context", + "properties": { + "product": { + "$ref": "product.schema.json" + } + }, + "additionalProperties": true + } + }, + "required": [ + "type", + "id" + ], + "additionalProperties": true + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.order", + "name": "...", + "id": { + "myOMS": "12345" + }, + "details": { + "product": { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } + } + }, + { + "type": "fdc3.order", + "id": { + "myOMS": "ABC123" + } + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/orderList.schema.json b/website/static/schemas/next/context/orderList.schema.json index bfc532e32..b282ce3e0 100644 --- a/website/static/schemas/next/context/orderList.schema.json +++ b/website/static/schemas/next/context/orderList.schema.json @@ -3,14 +3,47 @@ "$id": "https://fdc3.finos.org/schemas/next/context/orderList.schema.json", "type": "object", "title": "OrderList", - "description": "@experimental A list of orders", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.orderList" }, - "orders": { - "type": "array", - "items": { "$ref": "order.schema.json#" } + "description": "@experimental A list of orders. Use this type for use cases that require not just a single order, but multiple.\n\nThe OrderList schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.orderList" + }, + "orders": { + "type": "array", + "items": { + "$ref": "order.schema.json#" + }, + "title": "List of Orders", + "description": "An array of order contexts that forms the list." + } + }, + "required": [ + "type", + "orders" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.orderList", + "orders": [ + { + "type": "fdc3.order", + "id": { + "myOMS": "ABC123" + } + }, + { + "type": "fdc3.order", + "id": { + "myOMS": "DEF456" + } + } + ] } - }, - "required": ["type", "orders"] -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/organization.schema.json b/website/static/schemas/next/context/organization.schema.json index 7a791496e..84716863c 100644 --- a/website/static/schemas/next/context/organization.schema.json +++ b/website/static/schemas/next/context/organization.schema.json @@ -3,17 +3,52 @@ "$id": "https://fdc3.finos.org/schemas/next/context/organization.schema.json", "type": "object", "title": "Organization", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.organization" }, - "id": { + "description": "An entity that can be used when referencing private companies and other organizations where a specific instrument is not available or desired e.g. CRM and News workflows.\n\nIt is valid to include extra properties and metadata as part of the organization payload, but the minimum requirement is for at least one specified identifier to be provided.", + "allOf": [ + { "type": "object", "properties": { - "LEI": { "type": "string" }, - "PERMID": { "type": "string" }, - "FDS_ID": { "type": "string" } + "type": { + "const": "fdc3.organization" + }, + "id": { + "type": "object", + "title": "Organization Identifiers", + "description": "Identifiers for the organization, at least one must be provided.", + "minProperties": 1, + "properties": { + "LEI": { + "type": "string", + "title": "Legal Entity Identifier", + "description": "The Legal Entity Identifier (LEI) is a 20-character, alpha-numeric code based on the ISO 17442 standard developed by the International Organization for Standardization (ISO). It connects to key reference information that enables clear and unique identification of legal entities participating in financial transactions." + }, + "PERMID": { + "type": "string", + "title": "Organization", + "description": "Refinitiv Permanent Identifiers, or PermID for the organization" + }, + "FDS_ID": { + "type": "string", + "title": "Organization", + "description": "FactSet Permanent Identifier representing the organization" + } + } + } + }, + "required": [ + "id" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.organization", + "name": "Cargill, Incorporated", + "id": { + "LEI": "QXZYQNMR4JZ5RIRN4T31", + "FDS_ID": "00161G-E" } } - }, - "required": ["id"] + ] } diff --git a/website/static/schemas/next/context/portfolio.schema.json b/website/static/schemas/next/context/portfolio.schema.json index 64202e02f..c2a69a194 100644 --- a/website/static/schemas/next/context/portfolio.schema.json +++ b/website/static/schemas/next/context/portfolio.schema.json @@ -3,13 +3,64 @@ "$id": "https://fdc3.finos.org/schemas/next/context/portfolio.schema.json", "type": "object", "title": "Portfolio", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.portfolio" }, - "positions": { - "type": "array", - "items": { "$ref": "position.schema.json#" } + "description": "A financial portfolio made up of multiple positions (holdings) in several instruments. Contrast this with e.g. the [InstrumentList](InstrumentList) type, which is just a list of instruments.\n\nThis is a good example of how types can be composed and extended with extra properties to define more complex types.\n\nThe Portfolio type consists of an array of [Position](Position) types, each of which refers to a single [Instrument](Instrument) and a holding amount for that instrument.\n\nThe portfolio schema does not explicitly include identifiers in the `id` section, as there bis not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.portfolio" + }, + "positions": { + "type": "array", + "items": { + "$ref": "position.schema.json#" + }, + "title": "Portfolio positions", + "description": "The List of Positions which make up the Portfolio" + } + }, + "required": [ + "positions" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.portfolio", + "positions": [ + { + "type": "fdc3.position", + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "AAPL" + } + }, + "holding": 2000000 + }, + { + "type": "fdc3.position", + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + }, + "holding": 1500000 + }, + { + "type": "fdc3.position", + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "IBM" + } + }, + "holding": 3000000 + } + ] } - }, - "required": ["positions"] -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/position.schema.json b/website/static/schemas/next/context/position.schema.json index e2a948aee..4e90bcec5 100644 --- a/website/static/schemas/next/context/position.schema.json +++ b/website/static/schemas/next/context/position.schema.json @@ -3,12 +3,42 @@ "$id": "https://fdc3.finos.org/schemas/next/context/position.schema.json", "type": "object", "title": "Position", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.position" }, - "instrument": { "$ref": "instrument.schema.json#" }, - "holding": { "type": "number" } - }, - "required": ["instrument", "holding"] -} - + "description": "A financial position made up of an instrument and a holding in that instrument. This type is a good example of how new context types can be composed from existing types.\n\nIn this case, the instrument and the holding amount for that instrument are required values.\n\nThe [Position](Position) type goes hand-in-hand with the [Portfolio](Portfolio) type, which represents multiple holdings in a combination of instruments.\n\nThe position schema does not explicitly include identifiers in the `id` section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.position" + }, + "instrument": { + "$ref": "instrument.schema.json#", + "title": "The financial instrument that this position relates to", + "description": "" + }, + "holding": { + "type": "number", + "title": "The size of the holding represented by this position", + "description": "The amount of the holding, e.g. a number of shares" + } + }, + "required": [ + "instrument", + "holding" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.position", + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "AAPL" + } + }, + "holding": 2000000 + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/product.schema.json b/website/static/schemas/next/context/product.schema.json index a1571d4f9..df20ae614 100644 --- a/website/static/schemas/next/context/product.schema.json +++ b/website/static/schemas/next/context/product.schema.json @@ -3,11 +3,9 @@ "$id": "https://fdc3.finos.org/schemas/next/context/product.schema.json", "type": "object", "title": "Product", - "description": "@experimental context type representing a tradable product. To be used with OMS and EMS systems.\n\nThis type is currently only loosely defined as an extensible context object, with an optional instrument field.", + "description": "@experimental context type representing a tradable product. To be used with OMS and EMS systems.\n\nThis type is currently only loosely defined as an extensible context object, with an optional instrument field.\n\nThe Product schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", "allOf": [ { - "$ref": "context.schema.json#" - },{ "type": "object", "properties": { "type": { @@ -23,16 +21,22 @@ }, "name": { "type": "string", - "title": "Name", + "title": "Product Name", "description": "A human-readable summary of the product." - }, + }, "instrument": { - "$ref": "instrument.schema.json" + "$ref": "instrument.schema.json", + "title": "Product Instrument", + "description": " financial instrument that relates to the definition of this product" } }, - "required": ["type","id"], + "required": [ + "type", + "id" + ], "additionalProperties": true - } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } ], "examples": [ { @@ -48,4 +52,4 @@ } } ] -} +} \ No newline at end of file diff --git a/website/static/schemas/next/context/timerange.schema.json b/website/static/schemas/next/context/timerange.schema.json index 5b6b326f5..442dd3b11 100644 --- a/website/static/schemas/next/context/timerange.schema.json +++ b/website/static/schemas/next/context/timerange.schema.json @@ -3,22 +3,60 @@ "$id": "https://fdc3.finos.org/schemas/next/context/timerange.schema.json", "type": "object", "title": "TimeRange", - "allOf": [{ "$ref": "context.schema.json#" }], + "description": "A context representing a period of time. Any user interfaces that represent or visualize events or activity over time can be filtered or focused on a particular time period, e.g.:\n\n- A pricing chart\n- A trade blotter\n- A record of client contact/activity in a CRM\n\nExample use cases:\n\n- User may want to view pricing/trades/customer activity for a security over a particular time period, the time range might be specified as the context for the `ViewChart` intent OR it might be embedded in another context (e.g. a context representing a chart to plot).\n- User filters a visualization (e.g. a pricing chart) to show a particular period, the `TimeRange` is broadcast and other visualizations (e.g. a heatmap of activity by instrument, or industry sector etc.) receive it and filter themselves to show data over the same range.\n\nNotes:\n\n- A `TimeRange` may be closed (i.e. `startTime` and `endTime` are both known) or open (i.e. only one of `startTime` or `endTime` is known).\n- Ranges corresponding to dates (e.g. `2022-05-12` to `2022-05-19`) should be specified using times as this prevents issues with timezone conversions and inclusive/exclusive date ranges.\n- String fields representing times are encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html).\n - A timezone indicator should be specified, e.g. `\"2022-05-12T15:18:03Z\"` or `\"2022-05-12T16:18:03+01:00\"`\n - Times MAY be specified with millisecond precision, e.g. `\"2022-05-12T15:18:03.349Z\"`", + "allOf": [ + { + "properties": { + "type": { + "const": "fdc3.timerange" + }, + "startTime": { + "type": "string", + "format": "date-time", + "title": "Start Time", + "description": "The start time of the range, encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator." + }, + "endTime": { + "type": "string", + "format": "date-time", + "title": "End Time", + "description": "The end time of the range, encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator." + } + } + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], "anyOf": [ { - "required": ["startTime", "endTime"] + "required": [ + "startTime", + "endTime" + ] }, { - "required": ["startTime"] + "required": [ + "startTime" + ] }, { - "required": ["endTime"] + "required": [ + "endTime" + ] } ], - "properties": { - "type": { "const": "fdc3.timerange" }, - "startTime": { "type": "string", "format": "date-time" }, - "endTime": {"type": "string", "format": "date-time" } - }, - "required": [] -} + "examples": [ + { + "type": "fdc3.timeRange", + "startTime": "2022-03-30T15:44:44Z", + "endTime": "2022-04-30T23:59:59ZS" + }, + { + "type": "fdc3.timeRange", + "startTime": "2022-03-30T15:44:44+00:00" + }, + { + "type": "fdc3.timeRange", + "endTime": "2022-03-30T16:44:44.123Z" + } + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/trade.schema.json b/website/static/schemas/next/context/trade.schema.json index 10a108c31..e8286ae52 100644 --- a/website/static/schemas/next/context/trade.schema.json +++ b/website/static/schemas/next/context/trade.schema.json @@ -3,37 +3,40 @@ "$id": "https://fdc3.finos.org/schemas/next/context/trade.schema.json", "type": "object", "title": "Trade", - "description": "@experimental context type representing a trade. To be used with execution systems.\n\nThis type currently only defines a required `id` field, which should provide a reference to the trade in one or more systems, an optional human readable `name` field to be used to summarize the trade and a required `product` field that may be used to provide additional detail about the trade, which is currently typed as a unspecified Context type, but `product` is expected to be standardized in future.", + "description": "@experimental context type representing a trade. To be used with execution systems.\n\nThis type currently only defines a required `id` field, which should provide a reference to the trade in one or more systems, an optional human readable `name` field to be used to summarize the trade and a required `product` field that may be used to provide additional detail about the trade, which is currently typed as a unspecified Context type, but `product` is expected to be standardized in future.\n\n The Trade schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", "allOf": [ { - "$ref": "context.schema.json#" - } - ], - "properties": { - "type": { - "const": "fdc3.trade" - }, - "id": { "type": "object", - "additionalProperties": { - "type": "string" + "properties": { + "type": { + "const": "fdc3.trade" + }, + "id": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Trade Identifiers", + "description": "One or more identifiers that refer to the trade in an OMS, EMS or related system. Specific key names for systems are expected to be standardized in future." + }, + "name": { + "type": "string", + "title": "Trade Name", + "description": "A human-readable summary of the trade." + }, + "product": { + "$ref": "product.schema.json", + "title": "Traded product", + "description": "A product that is the subject of th trade." + } }, - "title": "Trade Identifiers", - "description": "One or more identifiers that refer to the trade in an OMS, EMS or related system. Specific key names for systems are expected to be standardized in future." + "required": [ + "type", "id", "product" + ], + "additionalProperties": true }, - "name": { - "type": "string", - "title": "Name", - "description": "A human-readable summary of the trade." - }, - "product": { - "$ref": "product.schema.json" - } - }, - "required": [ - "type", "id", "product" + { "$ref": "context.schema.json#/definitions/BaseContext" } ], - "additionalProperties": true, "examples": [ { "type": "fdc3.trade", diff --git a/website/static/schemas/next/context/tradeList.schema.json b/website/static/schemas/next/context/tradeList.schema.json index 49d8b0d27..dee810127 100644 --- a/website/static/schemas/next/context/tradeList.schema.json +++ b/website/static/schemas/next/context/tradeList.schema.json @@ -3,14 +3,72 @@ "$id": "https://fdc3.finos.org/schemas/next/context/tradeList.schema.json", "type": "object", "title": "TradeList", - "description": "@experimental A list of trades.", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.tradeList" }, - "trades": { - "type": "array", - "items": { "$ref": "trade.schema.json#" } + "description": "@experimental A list of trades. Use this type for use cases that require not just a single trade, but multiple.\n\nThe TradeList schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.tradeList" + }, + "trades": { + "type": "array", + "items": { + "$ref": "trade.schema.json#" + }, + "title": "List of Trades", + "description": "An array of trade contexts that forms the list." + } + }, + "required": [ + "type", + "trades" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.tradeList", + "trades": [ + { + "type": "fdc3.trade", + "name": "...", + "id": { + "myEMS": "12345" + }, + "product": { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } + }, + { + "type": "fdc3.trade", + "id": { + "myEMS": "67890" + }, + "product": { + "type": "fdc3.product", + "id": { + "productId": "DEF456" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "TSLA" + } + } + } + } + ] } - }, - "required": ["type", "trades"] -} + ] +} \ No newline at end of file diff --git a/website/static/schemas/next/context/transactionresult.schema.json b/website/static/schemas/next/context/transactionresult.schema.json index 11370018e..2a8cca61c 100644 --- a/website/static/schemas/next/context/transactionresult.schema.json +++ b/website/static/schemas/next/context/transactionresult.schema.json @@ -3,17 +3,55 @@ "$id": "https://fdc3.finos.org/schemas/next/context/transactionresult.schema.json", "type": "object", "title": "TransactionResult", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.transactionResult" }, - "status": { + "description": "A context type representing the result of a transaction initiated via FDC3, which SHOULD be returned as an `IntentResult` by intents that create, retrieve, update or delete content or records in another application. Its purpose is to provide a status and message (where needed) for the transaction and MAY wrap a returned context object.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.transactionResult" + }, + "status": { "type": "string", - "enum": ["Created", "Deleted", "Updated", "Failed"] + "enum": [ + "Created", + "Deleted", + "Updated", + "Failed" + ], + "title": "Transaction Status", + "description": "The status of the transaction being reported." }, - "context": { "$ref": "context.schema.json#" } - }, - "message": { - "type": "string" + "context": { + "$ref": "context.schema.json#", + "title": "Transaction Result Context", + "description": "A context object returned by the transaction, possibly with updated data." + } + }, + "message": { + "type": "string", + "title": "Transaction Message", + "description": "A human readable message describing the outcome of the transaction." + }, + "required": [ + "type", + "status" + ] }, - "required": ["type", "status"] + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.transactionResult", + "status": "Updated", + "context": { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + "message": "record with id 'jane.doe@mail.com' was updated" + } + ] } \ No newline at end of file diff --git a/website/static/schemas/next/context/valuation.schema.json b/website/static/schemas/next/context/valuation.schema.json index 7ad55be71..712764483 100644 --- a/website/static/schemas/next/context/valuation.schema.json +++ b/website/static/schemas/next/context/valuation.schema.json @@ -3,14 +3,57 @@ "$id": "https://fdc3.finos.org/schemas/next/context/valuation.schema.json", "type": "object", "title": "Valuation", - "allOf": [{ "$ref": "context.schema.json#" }], - "properties": { - "type": { "const": "fdc3.valuation" }, - "value": { "type": "number" }, - "price": { "type": "number"}, - "CURRENCY_ISOCODE": { "type": "string", "pattern": "^[A-Z]{3}$" }, - "valuationTime": {"type": "string", "format": "date-time" }, - "expiryTime": {"type": "string", "format": "date-time" } - }, - "required": ["value", "CURRENCY_ISOCODE"] -} + "description": "A context type representing the price and value of a holding.", + "allOf": [ + { + "type": "object", + "properties": { + "type": { + "const": "fdc3.valuation" + }, + "value": { + "type": "number", + "title": "Value", + "description": "The value of the holding, expresses in the nominated currency." + }, + "price": { + "type": "number", + "title": "Price per unit", + "description": "The price per unit the the valuation is based on." + }, + "CURRENCY_ISOCODE": { + "type": "string", + "pattern": "^[A-Z]{3}$", + "title": "Valuation Currency", + "description": "The valuation currency, which should conform to 3 character alphabetic codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html)" + }, + "valuationTime": { + "type": "string", + "format": "date-time", + "title": "Valuation time", + "description": "The time at which the valuation was performed, encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator included." + }, + "expiryTime": { + "type": "string", + "format": "date-time", + "title": "Expiry Time", + "description": "The time at which this valuation expires, encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator included." + } + }, + "required": [ + "value", + "CURRENCY_ISOCODE" + ] + }, + { "$ref": "context.schema.json#/definitions/BaseContext" } + ], + "examples": [ + { + "type": "fdc3.valuation", + "value": 500.0, + "price": 5.0, + "CURRENCY_ISOCODE": "USD", + "expiryTime": "2022-05-13T16:16:24+01:00" + } + ] +} \ No newline at end of file diff --git a/website/versioned_docs/version-1.0/fdc3-standard.md b/website/versioned_docs/version-1.0/fdc3-standard.md index 9ef1b4ab4..bf488e6d1 100644 --- a/website/versioned_docs/version-1.0/fdc3-standard.md +++ b/website/versioned_docs/version-1.0/fdc3-standard.md @@ -6,7 +6,7 @@ original_id: fdc3-standard **Status:** Superceded _**released:** 5th mar 2019_ -_**superceded:** 1st Apr 2020_ +_**superseded:** 1st Apr 2020_ ## Abstract FDC3 aims to provide an open standard for interoperability on the financial desktop. This includes standardized verbs to invoke actions between applications (called "intents"), a standardized data format, an OpenAPI app directory standard, and standardized API operations. diff --git a/website/versioned_docs/version-1.1/fdc3-standard.md b/website/versioned_docs/version-1.1/fdc3-standard.md index 6a61db16e..63b3a6847 100644 --- a/website/versioned_docs/version-1.1/fdc3-standard.md +++ b/website/versioned_docs/version-1.1/fdc3-standard.md @@ -7,7 +7,7 @@ original_id: fdc3-standard **Status:** Superceded _**adopted:** 1st Apr 2020_ _**released:** 14th Apr 2020_ -_**superceded:** 1st Apr 2021_ +_**superseded:** 1st Apr 2021_ ## Abstract FDC3 aims to provide an open standard for interoperability on the financial desktop. This includes standardized verbs to invoke actions between applications (called "intents"), a standardized data format, an OpenAPI app directory standard, and standardized API operations. diff --git a/website/versioned_docs/version-1.2/fdc3-standard.md b/website/versioned_docs/version-1.2/fdc3-standard.md index 2f8ffa26d..13df8b30c 100644 --- a/website/versioned_docs/version-1.2/fdc3-standard.md +++ b/website/versioned_docs/version-1.2/fdc3-standard.md @@ -7,7 +7,7 @@ original_id: fdc3-standard **Status:** Superceded _**adopted:** 1st Apr 2021_ _**released:** 19th Apr 2021_ -_**superceded:** 22nd August 2022_ +_**superseded:** 22nd August 2022_ ## Abstract FDC3 aims to provide an open standard for interoperability on the financial desktop. This includes standardized verbs to invoke actions between applications (called "intents"), a standardized data format, an OpenAPI app directory standard, and standardized API operations. diff --git a/website/versioned_docs/version-2.0/fdc3-standard.md b/website/versioned_docs/version-2.0/fdc3-standard.md index 3d9fcf805..2079a5008 100644 --- a/website/versioned_docs/version-2.0/fdc3-standard.md +++ b/website/versioned_docs/version-2.0/fdc3-standard.md @@ -4,9 +4,10 @@ sidebar_label: Abstract original_id: fdc3-standard --- -**Status:** Current +**Status:** Superceded _**adopted:** 1st July 2022_ _**released:** 22nd August 2022_ +_**superseded:** 31st August 2023_ ## Abstract diff --git a/website/versioned_docs/version-2.1/.markdownlint.jsonc b/website/versioned_docs/version-2.1/.markdownlint.jsonc new file mode 100644 index 000000000..637dd6334 --- /dev/null +++ b/website/versioned_docs/version-2.1/.markdownlint.jsonc @@ -0,0 +1,20 @@ +{ + //Disabled as we often use manual H1 heading for reference pages, + // where the markdown metadata is picked up as the top level heading + "single-h1": false, + //Many lines in md files are longer than 80 chars + "line-length": false, + //We have repeated headings, like 'Properties' or 'Fields' in reference docs. + "no-duplicate-header": { + "siblings_only": true + }, + "no-inline-html": { + "allowed_elements": [ + "Tabs", + "TabItem" + ] + }, + "ul-style": { + "style": "dash" + } +} \ No newline at end of file diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.broadcast.md b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.broadcast.md new file mode 100644 index 000000000..8dcd3ac6f --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.broadcast.md @@ -0,0 +1,90 @@ +--- +id: PrivateChannel.broadcast +sidebar_label: PC.broadcast +title: PrivateChannel.broadcast +--- + +Desktop Agent bridging message exchange for a `broadcast` API call on a [`PrivateChannel`](../../api/ref/PrivateChannel). Generated by API calls: + +- [`PrivateChannel.broadcast(context: Context)`](../../api/ref/Channel#broadcast) (inherited from the [Channel](../../api/ref/Channel#broadcast) class) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request only** + +:::caution + +Some additional tracking of PrivateChannel metadata is required on the Desktop Agent that created each PrivateChannel and on any Desktop Agent interacting with it, in order to use these message exchanges. Please see the [relevant section of the Agent Bridging overview](../spec#privatechannels) for more details. + +::: + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: privateChannel.broadcast() + DA ->> DAB: PrivateChannel.broadcast + DAB ->> DB: PrivateChannel.broadcast +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelBroadcastAgentRequest.schema.json](/schemas/2.1/bridging/privateChannelBroadcastAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelBroadcastBridgeRequest.schema.json](/schemas/2.1/bridging/privateChannelBroadcastBridgeRequest.schema.json) + +### Example + +```javascript +fdc3.addIntentListener("QuoteStream", async (context) => { + const privateChannel: PrivateChannel = await fdc3.createPrivateChannel(); + const symbol = context.id.ticker; + + // This gets called when the remote side adds a context listener + const addContextListener = privateChannel.onAddContextListener((contextType) => { + // broadcast price quotes as they come in from our quote feed + feed.onQuote(symbol, (price) => { + privateChannel.broadcast({ type: "price", price}); + }); + }); + + ... + + return channel; +}); +``` + +Broadcast messages that are sent from Agents that received the private channel from a remote agent are sent to the Desktop Agent that created the channel and returned it as an `IntentResult`, which is responsible for forwarding them onto other subscribers. If a broadcast message is generated on the Agent that created the channel it simply forwards it onto each subscriber. + +Hence, the broadcast message should be repeated once for each subscriber, and modified such that it includes a destination, specified as a full `AppIdentifier`, and the `type` should indicate that it is a `PrivateChannel` broadcast: + +```json +// DAB -> agent-B +{ + "type": "PrivateChannel.broadcast", //modified type for PrivateChannel broadcasts + "payload": { + "channel": "private-channel-ABC123", + "context": { /*contextObj*/} + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" //added by DAB + }, + "destination": { + "appId": "AnotherApp", + "instanceId": "02e235ba-acad-4b66-4c3a-547073be23f1", + "desktopAgent": "agent-B" + } + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.eventListenerAdded.md b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.eventListenerAdded.md new file mode 100644 index 000000000..812a05beb --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.eventListenerAdded.md @@ -0,0 +1,71 @@ +--- +id: PrivateChannel.eventListenerAdded +sidebar_label: PC.eventListenerAdded +title: PrivateChannel.eventListenerAdded +--- + +Desktop Agent bridging message exchange for the addition of an event handler to a [`PrivateChannel`](../../api/ref/PrivateChannel). Generated by API calls: + +- [`PrivateChannel.onAddContextListener(handler: (contextType?: string) => void): Listener`](../../api/ref/PrivateChannel#onaddcontextlistener) +- [`PrivateChannel.onUnsubscribe(handler: (contextType?: string) => void): Listener`](../../api/ref/PrivateChannel#onunsubscribe) +- [`PrivateChannel.onDisconnect(handler: () => void): Listener`](../../api/ref/PrivateChannel#ondisconnect) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request only** + +:::caution + +Some additional tracking of PrivateChannel metadata is required on the Desktop Agent that created each PrivateChannel and on any Desktop Agent interacting with it, in order to use these message exchanges. Please see the [relevant section of the Agent Bridging overview](../spec#privatechannels) for more details. + +::: + +Private channels support a number of additional event listeners (`onAddContextListener`, `onUnsubscribe`, `onDisconnect`), when an application adds one of these event listeners to a private channel that was created remotely and returned as an `IntentResult` (which should be tracked by the Desktop Agent Bridge client) a message needs to be sent to the agent that created the channel to facilitate routing of event messages. A single message type is used for this with a `payload.listenerType` field. + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: adds an event listener + DA ->> DAB: PrivateChannel.eventListenerAdded + DAB ->> DB: PrivateChannel.eventListenerAdded +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelEventListenerAddedAgentRequest.schema.json](/schemas/2.1/bridging/privateChannelEventListenerAddedAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelEventListenerAddedBridgeRequest.schema.json](/schemas/2.1/bridging/privateChannelEventListenerAddedBridgeRequest.schema.json) + +### Example + +```json +// agent-A -> DAB +{ + "type": "PrivateChannel.eventListenerAdded", + "payload": { + "channel": "private-channel-ABC123", + "listenerType": "onAddContextListener" + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" //added by DAB + }, + "destination": { + "appId": "AnotherApp", + "instanceId": "02e235ba-acad-4b66-4c3a-547073be23f1", + "desktopAgent": "agent-B" + } + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.eventListenerRemoved.md b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.eventListenerRemoved.md new file mode 100644 index 000000000..06843f557 --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.eventListenerRemoved.md @@ -0,0 +1,74 @@ +--- +id: PrivateChannel.eventListenerRemoved +sidebar_label: PC.eventListenerRemoved +title: PrivateChannel.eventListenerRemoved +--- + +Desktop Agent bridging message exchange for the removal of an event handler from a [`PrivateChannel`](../../api/ref/PrivateChannel). Generated by API calls: + +- [`listener.unsubscribe(): void`](../../api/ref/Types#listener) + - for [`Listener`](../../api/ref/Types#listener) objects returned by [`PrivateChannel`](../../api/ref/PrivateChannel) functions: + - [`onAddContextListener(handler: (contextType?: string) => void): Promise`](../../api/ref/PrivateChannel#onaddcontextlistener) + - [`onUnsubscribe(handler: (contextType?: string) => void): Promise`](../../api/ref/PrivateChannel#onunsubscribe) + - [`onDisconnect(handler: () => void): Promise`](../../api/ref/PrivateChannel#ondisconnect) +- [`PrivateChannel.disconnect(): void`](../../api/ref/PrivateChannel#disconnect) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request only** + +:::caution + +Some additional tracking of PrivateChannel metadata is required on the Desktop Agent that created each PrivateChannel and on any Desktop Agent interacting with it, in order to use these message exchanges. Please see the [relevant section of the Agent Bridging overview](../spec#privatechannels) for more details. + +::: + +Private channels support a number of additional event listeners (`onAddContextListener`, `onUnsubscribe`, `onDisconnect`), when an application removes an event listener from a PrivateChannel that was created remotely and returned as an `IntentResult` (which should be tracked by the Desktop Agent Bridge client) a message needs to be sent to the agent that created the channel so it can discard retained routing information. A single message type is used for this with a `payload.listenerType` field. + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: removes an event listener + DA ->> DAB: PrivateChannel.eventListenerRemoved + DAB ->> DB: PrivateChannel.eventListenerRemoved +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json](/schemas/2.1/bridging/privateChannelEventListenerRemovedAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelEventListenerRemovedBridgeRequest.schema.json](/schemas/2.1/bridging/privateChannelEventListenerRemovedBridgeRequest.schema.json) + +### Example + +```json +// agent-A -> DAB +{ + "type": "PrivateChannel.eventListenerRemoved", + "payload": { + "channel": "private-channel-ABC123", + "listenerType": "onAddContextListener" + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" //added by DAB + }, + "destination": { + "appId": "AnotherApp", + "instanceId": "02e235ba-acad-4b66-4c3a-547073be23f1", + "desktopAgent": "agent-B" + } + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onAddContextListener.md b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onAddContextListener.md new file mode 100644 index 000000000..5d0b0b453 --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onAddContextListener.md @@ -0,0 +1,69 @@ +--- +id: PrivateChannel.onAddContextListener +sidebar_label: PC.onAddContextListener +title: PrivateChannel.onAddContextListener +--- + +Desktop Agent bridging message exchange for the addition of a [`ContextHandler`](../../api/ref/Types#contexthandler) to a [`PrivateChannel`](../../api/ref/PrivateChannel). Generated by API call: + +- [`PrivateChannel.addContextListener(contextType: string | null, handler: ContextHandler): Promise`](../../api/ref/Channel#addcontextlistener) (inherited from `Channel`) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request only** + +:::caution + +Some additional tracking of PrivateChannel metadata is required on the Desktop Agent that created each PrivateChannel and on any Desktop Agent interacting with it, in order to use these message exchanges. Please see the [relevant section of the Agent Bridging overview](../spec#privatechannels) for more details. + +::: + +When a `ContextListener` is added to a `PrivateChannel` any applications that have added an `onAddContextListener` handler MUST be notified. If the listener is on the agent that created that channel, it should forward the message onto all the registered listeners. If the listener is added on a remote agent it MUST send the message to the agent that created the channel which will repeat it onto the other listeners without modifying the source information. + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: privateChannel.addContextListener() + DA ->> DAB: PrivateChannel.onAddContextListener + DAB ->> DB: PrivateChannel.onAddContextListener +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnAddContextListenerAgentRequest.schema.json](/schemas/2.1/bridging/privateChannelOnAddContextListenerAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnAddContextListenerBridgeRequest.schema.json](/schemas/2.1/bridging/privateChannelOnAddContextListenerBridgeRequest.schema.json) + +### Example + +```json +// agent-A -> DAB +{ + "type": "PrivateChannel.onAddContextListener", + "payload": { + "channel": "private-channel-ABC123", + "contextType": "fdc3.instrument" + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AnotherApp", + "instanceId": "02e235ba-acad-4b66-4c3a-547073be23f1", + "desktopAgent": "agent-B" //added by DAB + }, + "destination": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" + } + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onDisconnect.md b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onDisconnect.md new file mode 100644 index 000000000..e14a84422 --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onDisconnect.md @@ -0,0 +1,68 @@ +--- +id: PrivateChannel.onDisconnect +sidebar_label: PC.onDisconnect +title: PrivateChannel.onDisconnect +--- + +Desktop Agent bridging message exchange for a `disconnect()` API call on [`PrivateChannel`](../../api/ref/PrivateChannel). Generated by API call: + +- [`PrivateChannel.disconnect(): void`](../../api/ref/PrivateChannel#disconnect) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request only** + +:::caution + +Some additional tracking of PrivateChannel metadata is required on the Desktop Agent that created each PrivateChannel and on any Desktop Agent interacting with it, in order to use these message exchanges. Please see the [relevant section of the Agent Bridging overview](../spec#privatechannels) for more details. + +::: + +When the `disconnect` function is is called on a `PrivateChannel` any applications that have added an `onDisconnect` handler or an `onUnsubscribe` handler (which is automatically called when an application disconnects) MUST be notified. If the listener is on the agent that created that channel, it should forward the message onto all the registered listeners. If the listener is added on a remote agent it MUST send the message to the agent that created the channel which will repeat it onto the other listeners without modifying the source information. If the `PrivateChannel` was created by a remote agent, only the single `PrivateChannel.onDisconnect` is required. It is the responsibility of the Desktop Agent that created the channel to ensure that any relevant `onUnsubscribe` handlers are also called by sending additional `PrivateChannel.onUnsubscribe` messages to them before forwarding the `PrivateChannel.onDisconnect`. This applies whether the disconnection occurred on that agent or on a remote agent. + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: privateChannel.disconnect() + DA ->> DAB: PrivateChannel.onDisconnect + DAB ->> DB: PrivateChannel.onDisconnect +``` + +### Request message schemas + +### Schema + +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnDisconnectAgentRequest.schema.json](/schemas/2.1/bridging/privateChannelOnDisconnectAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnDisconnectBridgeRequest.schema.json](/schemas/2.1/bridging/privateChannelOnDisconnectBridgeRequest.schema.json) + +### Example + +```json +// agent-A -> DAB +{ + "type": "PrivateChannel.onDisconnect", + "payload": { + "channel": "private-channel-ABC123" + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AnotherApp", + "instanceId": "02e235ba-acad-4b66-4c3a-547073be23f1", + "desktopAgent": "agent-B" //added by DAB + }, + "destination": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" + } + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onUnsubscribe.md b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onUnsubscribe.md new file mode 100644 index 000000000..2c790f88f --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/PrivateChannel.onUnsubscribe.md @@ -0,0 +1,72 @@ +--- +id: PrivateChannel.onUnsubscribe +sidebar_label: PC.onUnsubscribe +title: PrivateChannel.onUnsubscribe +--- + +Desktop Agent bridging message exchange for the removal of a [`ContextHandler`](../../api/ref/Types#contexthandler) from a [`PrivateChannel`](../../api/ref/PrivateChannel). Generated by API calls: + +- [`listener.unsubscribe()`](../../api/ref/Types#listener) + - for [`Listener`](../../api/ref/Types#listener) objects returned by [`PrivateChannel`](../../api/ref/PrivateChannel) function: + - [`addContextListener(handler: (contextType?: string) => void): Promise`](../../api/ref/Channel#addcontextlistener) (inherited from `Channel`) +- [`PrivateChannel.disconnect()`](../../api/ref/PrivateChannel#disconnect) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request only** + +:::caution + +Some additional tracking of PrivateChannel metadata is required on the Desktop Agent that created each PrivateChannel and on any Desktop Agent interacting with it, in order to use these message exchanges. Please see the [relevant section of the Agent Bridging overview](../spec#privatechannels) for more details. + +::: + +When a `ContextListener` is removed from a `PrivateChannel` (via `listener.unsubscribe`) any applications that have added an `onSubscribe` handler MUST be notified. If the listener is on the agent that created that channel, it should forward the message onto all the registered listeners. If the listener is added on a remote agent it MUST send the message to the agent that created the channel which will repeat it onto the other listeners without modifying the source information. + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: listener.unsubscribe() + DA ->>+ DAB: PrivateChannel.onUnsubscribe + DAB ->>+ DB: PrivateChannel.onUnsubscribe +``` + +### Request message schemas + +### Schema + +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnUnsubscribeAgentRequest.schema.json](/schemas/2.1/bridging/privateChannelOnUnsubscribeAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/privateChannelOnUnsubscribeBridgeRequest.schema.json](/schemas/2.1/bridging/privateChannelOnUnsubscribeBridgeRequest.schema.json) + +### Example + +```json +// DAB -> agent-B +{ + "type": "PrivateChannel.onUnsubscribe", + "payload": { + "channel": "private-channel-ABC123", + "contextType": "fdc3.instrument" + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AnotherApp", + "instanceId": "02e235ba-acad-4b66-4c3a-547073be23f1", + "desktopAgent": "agent-B" //added by DAB + }, + "destination": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" + } + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/broadcast.md b/website/versioned_docs/version-2.1/agent-bridging/ref/broadcast.md new file mode 100644 index 000000000..c44bdff31 --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/broadcast.md @@ -0,0 +1,100 @@ +--- +id: broadcast +sidebar_label: broadcast +title: broadcast +--- + +Desktop Agent bridging message exchange for a `broadcast()` API call on the [`DesktopAgent`](../../api/ref/DesktopAgent) or a [`Channel`](../../api/ref/Channel). Generated by API calls: + +- [`fdc3.broadcast(context: Context): Promise`](../../api/ref/DesktopAgent#broadcast) +- [`Channel.broadcast(context: Context): Promise`](../../api/ref/Channel#broadcast) + +:::caution + +Broadcasts on a [`PrivateChannel`](../../api/ref/PrivateChannel) have a separate message exchange, see [`PrivateChannel.broadcast`](PrivateChannel.broadcast). + +::: + +[Message Exchange Type](../spec#individual-message-exchanges): **Request only** + +E.g. + +```javascript +fdc3.broadcast(contextObj); +``` + +or + +```javascript +(await fdc3.getOrCreateChannel("myChannel")).broadcast(contextObj) +``` + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: fdc3.broadcast() / channel.broadcast() + DA ->> DAB: broadcastRequest + DAB ->> DB: broadcastRequest + DAB ->> DC: broadcastRequest +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/broadcastAgentRequest.schema.json](/schemas/2.1/bridging/broadcastAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/broadcastBridgeRequest.schema.json](/schemas/2.1/bridging/broadcastBridgeRequest.schema.json) + +### Example + +Outward message to the DAB: + +```json +// agent-A -> DAB +{ + "type": "broadcastRequest", + "payload": { + "channelId": "myChannel", + "context": { /*contextObj*/ } + }, + "meta": { + "requestUuid": "", + "timestamp": "2022-03-...", + "source": [{ + "appId": "agentA-app1", + "instanceId": "c6ad5174-6f78-4582-8e96-728d93a4d7d7" + }] + } +} +``` + +which it repeats on to agent-B AND agent-C with the `source.desktopAgent` metadata added. + +```json +// DAB -> agent-B +// DAB -> agent-C +{ + "type": "broadcastRequest", + "payload": { + "channelId": "myChannel", + "context": { /*contextObj*/} + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": [{ + "appId": "agentA-app1", + "instanceId": "c6ad5174-6f78-4582-8e96-728d93a4d7d7", + "desktopAgent": "agent-A" //added by DAB + }] + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/findInstances.md b/website/versioned_docs/version-2.1/agent-bridging/ref/findInstances.md new file mode 100644 index 000000000..fba7be5a9 --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/findInstances.md @@ -0,0 +1,206 @@ +--- +id: findInstances +sidebar_label: findInstances +title: findInstances +--- + +Desktop Agent bridging message exchange for a `findInstances` API call on the [`DesktopAgent`](../../api/ref/DesktopAgent). Generated by API calls: + +- [`findInstances(app: AppIdentifier): Promise>`](../../api/ref/DesktopAgent#findinstances) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request Response (collated)** or **Request Response (single)** + +A Desktop Agent's [`findInstances`](../../api/ref/DesktopAgent#findinstances) API call should return an empty array for known applications and [`ResolveError.NoAppsFound`](../../api/ref/Errors#resolveerror) for unknown apps. Hence, if a findInstances request is received through bridging for a known app with no instances then a normal response should be returned with an empty array. The bridge should add the responding agent to the `sources` array in the collated response as this is a valid response. If the application is not known to the agent an error response should be used instead with the `ResolveError.NoAppsFound` message and the responding Desktop Agent should be added to the `meta.errorSources` of the bridge response. + +In the event that all agents returned an error response, then the bridge will also return an error response, which is passed back to the calling application. However, if any agent returned a valid response (including with an empty array) then the application was known, but had no instances, resulting in an empty array being returned to the calling application. +E.g. + +```javascript +// Retrieve a list of all instances of an application +let instances = await fdc3.findInstances({appId: "MyAppId"}); + +// Retrieve a list of instances of an application on a specified Desktop Agent +let instances = await fdc3.findInstances({appId: "MyAppId", desktopAgent: "agent-A"}); +``` + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: fdc3.findInstances() + DA ->> DAB: findInstancesRequest + DAB ->> DB: findInstancesRequest + DAB ->> DC: findInstancesRequest + DB ->> DAB: findInstancesResponse (B) + DC ->> DAB: findInstancesResponse (C) + DAB ->> DA: findInstancesResponse (B + C) + DA --) AA: resolve (AppIdentifier[]) +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/findInstancesAgentRequest.schema.json](/schemas/2.1/bridging/findInstancesAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findInstancesBridgeRequest.schema.json](/schemas/2.1/bridging/findInstancesBridgeRequest.schema.json) + +### Example + +Outward message to the bridge: + +```json +// agent-A -> DAB +{ + "type": "findInstancesRequest", + "payload": { + "app": { + "appId": "myApp" + } + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6" + } + } +} +``` + +which is repeated on to the target agent as: + +```json +// DAB -> agent-B +{ + "type": "findInstancesRequest", + "payload": { + "app": { + "appId": "myApp" + } + }, + "meta": { + "requestUuid": "", + "timestamp": 2020-03-..., + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" //added by DAB + } + } +} +``` + +:::note +If the `findInstancesRequest` from the requesting agent does not include a `meta.source` field then the Bridge MUST set the `meta.source.desktopAgent` field to attribute the request to the requesting agent. This is the case for all agent request messages that don't require application details. +::: + +If results should be constrained to a particular Desktop Agent, then set a `desktopAgent` field in `payload.app` and a matching `destination` field in `meta`: + +```json +// agent-A -> DAB +{ + "type": "findInstancesRequest", + "payload": { + "app": { + "appId": "myApp", + "desktopAgent": "agent-B" // destination agent + } + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "destination": { "desktopAgent": "agent-B" }, //destination agent + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6" + } + } +} +``` + +The Desktop Agent Bridge should only forward the request to the requested Desktop Agent and handle the message exchange as a **Request Response (single)**. + +## Response format + +### Response message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/findInstancesAgentResponse.schema.json](/schemas/2.1/bridging/findInstancesAgentResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findInstancesAgentErrorResponse.schema.json](/schemas/2.1/bridging/findInstancesAgentErrorResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findInstancesBridgeResponse.schema.json](/schemas/2.1/bridging/findInstancesBridgeResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findInstancesBridgeErrorResponse.schema.json](/schemas/2.1/bridging/findInstancesBridgeErrorResponse.schema.json) + +### Example + +Response message from a Desktop Agent: + +```json +// agent-B -> DAB +{ + "type": "findInstancesResponse", + "payload": { + "appIdentifiers": [ + { "appId": "myApp", "instanceId": "4bf39be1-a25b-4ad5-8dbc-ce37b436a344" }, + { "appId": "myApp", "instanceId": "4f10abb7-4df4-4fc6-8813-bbf0dc1b393d" }, + ] + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + } +} +``` + +The bridge receives and collates the responses, augmenting each appIdentifier with a `desktopAgent` field, producing the following collated response which it sends back to agent-A: + +```json +// DAB -> agent-A +{ + "type": "findInstancesResponse", + "payload": { + "appIdentifiers": [ + { "appId": "myApp", "instanceId": "4bf39be1-a25b-4ad5-8dbc-ce37b436a344", "desktopAgent": "agent-B" }, + //"desktopAgent" added by DAB + { "appId": "myApp", "instanceId": "4f10abb7-4df4-4fc6-8813-bbf0dc1b393d", "desktopAgent": "agent-B" }, + { "appId": "myApp", "instanceId": "920b74f7-1fef-4076-adef-63b82bae0dd9", "desktopAgent": "agent-C" }, + ] + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + "sources": [ //added by DAB + { "desktopAgent": "agent-A" }, + { "desktopAgent": "agent-B" }, + ] + } +} +``` + +:::info +If a target Desktop Agent was specified in the request (via a `desktopAgent` field in `payload.app`), then the DAB is not collating responses and does not need to generate a unique `meta.responseUuid` and MUST quote that given by the responding Desktop Agent. +::: + +:::note +In the event that an agent times out or returns an error, where others respond, its `DesktopAgentIdentifier` should be added to the `meta.errorSources` element instead of `meta.sources`. +::: + +Finally, agent-A combines the data received from the bridge, with its own local response to produce the response to the requesting application: + +```json +// DAB -> agent-A +[ + { "appId": "myApp", "instanceId": "4bf39be1-a25b-4ad5-8dbc-ce37b436a344", "desktopAgent": "agent-B" }, + { "appId": "myApp", "instanceId": "4f10abb7-4df4-4fc6-8813-bbf0dc1b393d", "desktopAgent": "agent-B" }, + { "appId": "myApp", "instanceId": "920b74f7-1fef-4076-adef-63b82bae0dd9", "desktopAgent": "agent-C" }, + { "appId": "myApp", "instanceId": "688dbd5e-21dc-4469-b8cf-4b6a606f9a27" } //local response +] +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/findIntent.md b/website/versioned_docs/version-2.1/agent-bridging/ref/findIntent.md new file mode 100644 index 000000000..84f079b1b --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/findIntent.md @@ -0,0 +1,256 @@ +--- +id: findIntent +sidebar_label: findIntent +title: findIntent +--- + +Desktop Agent bridging message exchange for a `findIntent` API call on the [`DesktopAgent`](../../api/ref/DesktopAgent). Generated by API call: + +- [`findIntent(intent: string, context?: Context, resultType?: string): Promise`](../../api/ref/DesktopAgent#findintent) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request Response (collated)** + +E.g. An application with `appId: "agentA-app1"` and `instanceId: "c6ad5174-6f78-4582-8e96-728d93a4d7d7"` makes the following API call: + +```javascript +let appIntent = await fdc3.findIntent("StartChat", context); +``` + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: fdc3.findIntent() + DA ->> DAB: findIntentRequest + DAB ->> DB: findIntentRequest + DAB ->> DC: findIntentRequest + DB ->> DAB: findIntentResponse (B) + DC ->> DAB: findIntentResponse (C) + DAB ->> DA: findIntentResponse (B + C) + DA --) AA: resolve (AppIntent) +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentAgentRequest.schema.json](/schemas/2.1/bridging/findIntentAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentBridgeRequest.schema.json](/schemas/2.1/bridging/findIntentBridgeRequest.schema.json) + +### Example + +Outward message to the DAB: + +```json +// agent-A -> DAB +{ + "type": "findIntentRequest", + "payload": { + "intent": "StartChat", + "context": {/*contextObj*/} + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": [{ + "appId": "agentA-app1", + "instanceId": "c6ad5174-6f78-4582-8e96-728d93a4d7d7" + }] + } +} +``` + +The DAB fills in the `source.desktopAgent` field and forwards the request to the other Desktop Agents (agent-B AND agent-C): + +```json +// DAB -> agent-B +// DAB -> agent-C +{ + "type": "findIntentRequest", + "payload": { + "intent": "StartChat", + "context": {/*contextObj*/} + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "agentA-app1", + "instanceId": "c6ad5174-6f78-4582-8e96-728d93a4d7d7", + "desktopAgent": "agent-A" //added by DAB + } + } +} +``` + +Note that the `source.desktopAgent` field has been populated with the id of the agent that raised the requests, enabling the routing of responses. + +## Response format + +### Response message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentAgentResponse.schema.json](/schemas/2.1/bridging/findIntentAgentResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentAgentErrorResponse.schema.json](/schemas/2.1/bridging/findIntentAgentErrorResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentBridgeResponse.schema.json](/schemas/2.1/bridging/findIntentBridgeResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentBridgeErrorResponse.schema.json](/schemas/2.1/bridging/findIntentBridgeErrorResponse.schema.json) + +### Example + +Normal response from agent-A, where the request was raised. + +```json +{ + "intent": { "name": "StartChat" }, + "apps": [ + { "appId": "myChat" } + ] +} +``` + +DA agent-B would produce the following response if the request was generated locally: + +```json +{ + "intent": { "name": "StartChat" }, + "apps": [ + { "appId": "Skype", "title": "Skype" /* other AppMetadata fields may be included */}, + { "appId": "Symphony", "title": "Symphony" }, + { "appId": "Symphony", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "Symphony" }, + { "appId": "Slack", "title": "Slack" } + ] +} +``` + +Hence, the response it sends to the bridge is encoded as follows: + +```json +// agent-B -> DAB +{ + "type": "findIntentResponse", + "payload": { + "appIntent": { + "intent": { "name": "StartChat" }, + "apps": [ + { "appId": "Skype", "title": "Skype" /* other AppMetadata fields may be included */ }, + { "appId": "Symphony", "title": "Symphony" }, + { "appId": "Symphony", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "Symphony" }, + { "appId": "Slack", "title": "Slack" } + ] + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + } +} +``` + +Note the response UUID generated by the agent-B and the reference to the request UUID produced by agent-A where the request was originated. Further, note that the `AppMetadata` elements in the `AppIntent` do not have a `desktopAgent` field yet, and the `meta` element does not contain a `sources` element, both of which the bridge will add. + +DA agent-C would produce the following response locally: + +```json +{ + "intent": { "name": "StartChat" }, + "apps": [ + { "appId": "WebIce"} + ] +} +``` + +which is sent back over the bridge as a response to the request message as: + +```json +// agent-C -> DAB +{ + "type": "findIntentResponse", + "payload": { + "appIntent": { + "intent": { "appId": "StartChat" }, + "apps": [ + { "appId": "WebIce"} + ] + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + } +} +``` + +The bridge receives and collates the responses, producing the following collated response which is sends back to agent-A: + +```json +// DAB -> agent-A +{ + "type": "findIntentResponse", + "payload": { + "intent": "StartChat", + "appIntent": { + "intent": { "name": "StartChat" }, + "apps": [ + { "appId": "Skype", "title": "Skype", "desktopAgent": "agent-B" }, //desktopAgent added by DAB + { "appId": "Symphony", "title": "Symphony", "desktopAgent": "agent-B" }, + { "appId": "Symphony", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "Symphony", + "desktopAgent": "agent-B" }, + { "appId": "Slack", "title": "Slack", "desktopAgent": "agent-B" }, + { "appId": "WebIce", "desktopAgent": "agent-C"} + ] + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + "sources": [ //added by DAB + { "desktopAgent": "agent-A" }, + { "desktopAgent": "agent-B" }, + ] + } +} +``` + +:::note + +In the event that an agent referred to in the API call is not connected to the bridge, an agent that was connected times out or returns an error, its `DesktopAgentIdentifier` should be added to the `meta.errorSources` element instead of `meta.sources` and the appropriate error ([`ResolveError.DesktopAgentNotFound`](../../api/ref/Errors#resolveerror), [`BridgingError.ResponseTimedOut`](../../api/ref/Errors#bridgingerror) or [`BridgingError.AgentDisconnected`](../../api/ref/Errors#bridgingerror)) should be added to `meta.errorDetails`. + +::: + +Finally, agent-A combines the data received from the bridge, with its own local response to produce the response to the requesting application: + +```json +// agent-A -> requesting App +{ + "intent": { "name": "StartChat", "displayName": "Chat" }, + "apps": [ + // local to this agent + { "appId": "myChat" }, + //agent-B responses + { "appId": "Skype", "title": "Skype", "desktopAgent": "agent-B" }, + { "appId": "Symphony", "title": "Symphony", "desktopAgent": "agent-B" }, + { "appId": "Symphony", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "Symphony", + "desktopAgent": "agent-B" }, + { "appId": "Slack", "title": "Slack", "desktopAgent": "agent-B" }, + //agent-C responses + { "appId": "WebIce", "desktopAgent": "agent-C"} + ] +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/findIntentsByContext.md b/website/versioned_docs/version-2.1/agent-bridging/ref/findIntentsByContext.md new file mode 100644 index 000000000..5304332cc --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/findIntentsByContext.md @@ -0,0 +1,222 @@ +--- +id: findIntentsByContext +sidebar_label: findIntentsByContext +title: findIntentsByContext +--- + +Desktop Agent bridging message exchange for a `findIntent` API call on the [`DesktopAgent`](../../api/ref/DesktopAgent). Generated by API call: + +- [`findIntentsByContext(context: Context): Promise>`](../../api/ref/DesktopAgent#findintentsbycontext) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request Response (collated)** + +E.g. An application with appId `agentA-app1` makes the following API call: + +```javascript +let appIntentArr = await fdc3.findIntentsByContext(context); +``` + +:::note +The message exchanges for this API call are nearly identical to that used for [`findIntent()`](findIntent), differing only by the lack of an `intent` field in the request message payload and the structure of the response message (where an array of `AppIntents` is returned). +::: + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: fdc3.findIntentsByContext + DA ->> DAB: findIntentsByContextRequest + DAB ->> DB: findIntentsByContextRequest + DAB ->> DC: findIntentsByContextRequest + DB ->> DAB: findIntentsByContextResponse (B) + DC ->> DAB: findIntentsByContextResponse (C) + DAB ->> DA: findIntentsByContextResponse (B + C) + DA --) AA: resolve (AppIntent[]) +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextAgentRequest.schema.json](/schemas/2.1/bridging/findIntentsByContextAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextBridgeRequest.schema.json](/schemas/2.1/bridging/findIntentsByContextBridgeRequest.schema.json) + +### Example + +Outward message to the DAB: + +```json +// agent-A -> DAB +{ + "type": "findIntentsByContextRequest", + "payload": { + "context": {/*contextObj*/} + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "agentA-app1", + "instanceId": "c6ad5174-6f78-4582-8e96-728d93a4d7d7" + } + } +} +``` + +The DAB fills in the `source.desktopAgent` field and forwards the request to the other Desktop Agents (agent-B AND agent-C). + +```json +// DAB -> agent-B +// DAB -> agent-C +{ + "type": "findIntentsByContextRequest", + "payload": { + "context": {/*contextObj*/} + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "agentA-app1", + "instanceId": "c6ad5174-6f78-4582-8e96-728d93a4d7d7", + "desktopAgent": "agent-A" //added by DAB + } + } +} +``` + +## Response format + +### Response message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextAgentResponse.schema.json](/schemas/2.1/bridging/findIntentsByContextAgentResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextAgentErrorResponse.schema.json](/schemas/2.1/bridging/findIntentsByContextAgentErrorResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextBridgeResponse.schema.json](/schemas/2.1/bridging/findIntentsByContextBridgeResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/findIntentsByContextBridgeErrorResponse.schema.json](/schemas/2.1/bridging/findIntentsByContextBridgeErrorResponse.schema.json) + +### Example + +An individual agent (for example agentB) would generate a local response as an array of `AppIntent` objects: + +```json +[ + { + "intent": { "name": "StartChat" }, + "apps": [ + { "appId": "Skype", "title": "Skype" /* other AppMetadata fields may be included */}, + { "appId": "Symphony", "title": "Symphony" }, + { "appId": "Symphony", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "Symphony" }, + { "appId": "Slack", "title": "Slack" } + ] + }, + { + "intent": { "name": "ViewProfile" }, + "apps": [ + { "appId": "myCRM", "title": "My CRM" }, + { "appId": "myCRM", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "My CRM" } + ] + } +] +``` + +This response is encoded and sent to the bridge as: + +```json +// agent-B -> DAB +{ + "type": "findIntentsByContextResponse", + "payload": { + "appIntents": [ + { + "intent": { "name": "StartChat" }, + "apps": [ + { "appId": "Skype", "title": "Skype" /* other AppMetadata fields may be included */}, + { "appId": "Symphony", "title": "Symphony" }, + { "appId": "Symphony", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "Symphony" }, + { "appId": "Slack", "title": "Slack" } + ] + }, + { + "intent": { "name": "ViewProfile" }, + "apps": [ + { "appId": "myCRM", "title": "My CRM" }, + { "appId": "myCRM", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "My CRM" } + ] + } + ] + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + } +} +``` + +Each `AppMetadata` object is augmented by the bridge with a `desktopAgent` field, the responding `DesktopAgentIdentifier` value is added to the `meta.sources` element and the message payload is collated with responses from other agents into a response to the requesting agent: + +```json +// DAB -> agent-A +{ + "type": "findIntentsByContextResponse", + "payload": { + "appIntents": [ + { + "intent": { "name": "StartChat" }, + "apps": [ + //agent-B responses + { "appId": "Skype", "title": "Skype", "desktopAgent": "agent-B" }, + { "appId": "Symphony", "title": "Symphony", "desktopAgent": "agent-B" }, + { "appId": "Symphony", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "Symphony", + "desktopAgent": "agent-B" }, + { "appId": "Slack", "title": "Slack", "desktopAgent": "agent-B" }, + //agent-C response + { "appId": "WebIce", "desktopAgent": "agent-C"} + ] + }, + { + "intent": { "name": "ViewProfile" }, + "apps": [ + //agent-A responses + { "appId": "myCRM", "title": "My CRM", "desktopAgent": "agent-B" }, + { "appId": "myCRM", + "instanceId": "93d2fe3e-a66c-41e1-b80b-246b87120859", + "title": "My CRM", + "desktopAgent": "agent-B" } + //agent-C responses + { "appId": "riskToolkit", "title": "Client Risk Toolkit", "desktopAgent": "agent-C" }, + { "appId": "linkedIn", "title": "LinkedIn", "desktopAgent": "agent-C" } + ] + } + ] + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + "sources": [ + { "desktopAgent": "agent-B" }, + { "desktopAgent": "agent-C" } + ] + } +} +``` + +Finally agent-A combines the payload received with it own response and returns it to the requesting application. diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/getAppMetadata.md b/website/versioned_docs/version-2.1/agent-bridging/ref/getAppMetadata.md new file mode 100644 index 000000000..ab8f6c6cd --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/getAppMetadata.md @@ -0,0 +1,160 @@ +--- +id: getAppMetadata +sidebar_label: getAppMetadata +title: getAppMetadata +--- + +Desktop Agent bridging message exchange for a `getAppMetadata` API call on the [`DesktopAgent`](../../api/ref/DesktopAgent). Generated by API calls: + +- [`getAppMetadata(app: AppIdentifier): Promise`](../../api/ref/DesktopAgent#getappmetadata) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request Response (single)** + +E.g. + +```javascript +let appIdentifier = { appId: "myApp@my.appd.com", desktopAgent: "agent-B" } +let appMetadata = await fdc3.getAppMetadata(appIdentifier); +``` + +:::info +`fdc3.getAppMetadata` calls should only involve the Desktop Agent Bridge where a `desktopAgent` field appears in the AppIdentifier being queried, all other calls should be handled locally by the Desktop Agent. Hence, the `payload.app.desktopAgent` is required on all requests. +::: + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: fdc3.getAppMetadata() + DA ->> DAB: getAppMetadataRequest + DAB ->> DB: getAppMetadataRequest + DB ->> DAB: getAppMetadataResponse (B) + DAB ->> DA: getAppMetadataResponse (B) + DA --) AA: resolve (AppMetadata) +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataAgentRequest.schema.json](/schemas/2.1/bridging/getAppMetadataAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataBridgeRequest.schema.json](/schemas/2.1/bridging/getAppMetadataBridgeRequest.schema.json) + +### Example + +Outward message to the bridge: + +```json +// agent-A -> DAB +{ + "type": "getAppMetadataRequest", + "payload": { + "app": { + { "appId": "myApp@my.appd.com", "desktopAgent": "agent-B" } + } + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6" + } + } +} +``` + +which is repeated on to the target agent as: + +```json +// DAB -> agent-B +{ + "type": "getAppMetadataRequest", + "payload": { + "app": { + { "appId": "myApp@my.appd.com", "desktopAgent": "agent-B" } + } + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" //added by DAB + } + } +} +``` + +## Response format + +### Response message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataAgentResponse.schema.json](/schemas/2.1/bridging/getAppMetadataAgentResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataAgentErrorResponse.schema.json](/schemas/2.1/bridging/getAppMetadataAgentErrorResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataBridgeResponse.schema.json](/schemas/2.1/bridging/getAppMetadataBridgeResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/getAppMetadataBridgeErrorResponse.schema.json](/schemas/2.1/bridging/getAppMetadataBridgeErrorResponse.schema.json) + +### Example + +Response message from a Desktop Agent: + +```json +// agent-B -> DAB +{ + "type": "getAppMetadataResponse", + "payload": { + "appMetadata": { + "appId": "myApp@my.appd.com", + "name": "myApp", + "version": "1.0", + "title": "My example application", + "tooltip": " A tooltip for the application that can be used to render UI elements.", + "description": "A longer, multi-paragraph description for the application that could include mark-up.", + "icons": [..], + "screenshots": [...] + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + } +} +``` + +The bridge receives the response, augments the appMetadata with a `desktopAgent` field, producing the following response which it sends back to agent-A: + +```json +// DAB -> agent-A +{ + "type": "getAppMetadataResponse", + "payload": { + "appMetadata": { + "appId": "myApp@my.appd.com", + "name": "myApp", + "version": "1.0", + "title": "My example application", + "tooltip": " A tooltip for the application that can be used to render UI elements.", + "description": "A longer, multi-paragraph description for the application that could include mark-up.", + "icons": [..], + "screenshots": [...], + "desktopAgent": "agent-B" //added by DAB + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + "sources": [{ "desktopAgent": "agent-B" }] + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/open.md b/website/versioned_docs/version-2.1/agent-bridging/ref/open.md new file mode 100644 index 000000000..1e01c9c7a --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/open.md @@ -0,0 +1,166 @@ +--- +id: open +sidebar_label: open +title: open +--- + +Desktop Agent bridging message exchange for a `open` API call on the [`DesktopAgent`](../../api/ref/DesktopAgent). Generated by API calls: + +- [`open(app: AppIdentifier, context?: Context): Promise`](../../api/ref/DesktopAgent#open) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request Response (single)** + +E.g. + +```javascript +// Open an app without context, using an AppIdentifier object to specify the target and Desktop Agent +let AppIdentifier = {appId: 'myApp-v1.0.1', desktopAgent:"DesktopAgentB"}; +let instanceMetadata = await fdc3.open(AppIdentifier); + +// Open an app with context, using an AppIdentifier object to specify the target and Desktop Agent +let AppIdentifier = {appId: 'myApp-v1.0.1', desktopAgent:"DesktopAgentB"}; +let instanceMetadata = await fdc3.open(AppIdentifier, contextObj); +``` + +Note that it is not currently possible to identify resolve all available applications within a Desktop Agent via the FDC3 API. Hence, `fdc3.open` calls without a specified `desktopAgent` field in their `AppIdentifier`, e.g.: + +```javascript +// Open a target app via AppIdentifier, without a specified Desktop Agent +let AppIdentifier = {appId: 'myApp-v1.0.1'}; +let instanceMetadata = await fdc3.open(AppIdentifier); +``` + +should always be processed locally without be passed to the bridge. + +The `fdc3.open` command should result in a single copy of the specified app being opened and its instance data returned, or an error if it could not be opened. When receiving a response from invoking `fdc3.open` via the Desktop Agent Bridge, the new app instances MUST be initialized before responding as the responding Desktop Agent will need to return an `AppIdentifier` with an `instanceId` field set. + +If the remote Desktop Agent is not currently connected from the bridge, the [`OpenError.DesktopAgentNotFound` error](../../api/ref/Errors#openerror) should be returned in the response from the bridge and the promise returned from the call to `fdc3.open` rejected with it. + +## Message exchange + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: fdc3.open() + DA ->> DAB: openRequest + DAB ->> DB: openRequest + DB ->> DAB: openResponse + DAB ->> DA: openResponse + DA --) AA: resolve (AppIdentifier) +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/openAgentRequest.schema.json](/schemas/2.1/bridging/openAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/openBridgeRequest.schema.json](/schemas/2.1/bridging/openBridgeRequest.schema.json) + +### Example + +Outward message to the bridge: + +```json +// agent-A -> DAB +{ + "type": "openRequest", + "payload": { + "app": { + "appId": "myApp", + "desktopAgent":"agent-B" + }, + "context": {/*contextObj*/} + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6" + } + } +} +``` + +which is repeated on to the target agent as: + +```json +// DAB -> agent-B +{ + "type": "openRequest", + "payload": { + "app": { + "appId": "myApp", + "desktopAgent":"DesktopAgentB" + }, + "context": {/*contextObj*/} + }, + "meta": { + "requestUuid": "", + "timestamp": 2020-03-..., + "source": { + "appId": "AChatApp", + "instanceId": "02e575aa-4c3a-4b66-acad-155073be21f6", + "desktopAgent": "agent-A" //added by DAB + } + } +} +``` + +## Response format + +### Response message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/openAgentResponse.schema.json](/schemas/2.1/bridging/openAgentResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/openAgentErrorResponse.schema.json](/schemas/2.1/bridging/openAgentErrorResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/openBridgeResponse.schema.json](/schemas/2.1/bridging/openBridgeResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/openBridgeErrorResponse.schema.json](/schemas/2.1/bridging/openBridgeErrorResponse.schema.json) + +### Example + +Response message from target Desktop Agent: + +```json +// agent-B -> DAB +{ + "type": "openResponse", + "payload": { + "appIdentifier": { + "appId": "myApp", + "instanceId": "e36d43e1-4fd3-447a-a227-38ec48a92706" + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-..." + } +} +``` + +which is augmented and repeated on by the bridge as: + +```json +// agent-B -> DAB +{ + "type": "openResponse", + "payload": { + "appIdentifier": { + "appId": "myApp", + "instanceId": "e36d43e1-4fd3-447a-a227-38ec48a92706" + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + "sources": [{ "desktopAgent": "agent-B" }] // added by DAB + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/ref/raiseIntent.md b/website/versioned_docs/version-2.1/agent-bridging/ref/raiseIntent.md new file mode 100644 index 000000000..d2f33ef67 --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/ref/raiseIntent.md @@ -0,0 +1,290 @@ +--- +id: raiseIntent +sidebar_label: raiseIntent +title: raiseIntent +--- + +Desktop Agent bridging message exchange for a `raiseIntent` API call on the [`DesktopAgent`](../../api/ref/DesktopAgent). Generated by API calls: + +- [`raiseIntent(intent: string, context: Context, app: AppIdentifier): Promise`](../../api/ref/DesktopAgent#raiseintent) +- [`raiseIntentForContext(context: Context, app: AppIdentifier): Promise`](../../api/ref/DesktopAgent#raiseintentforcontext) + +[Message Exchange Type](../spec#individual-message-exchanges): **Request Multiple Response (single)** + +For Desktop Agent Bridging, a `raiseIntent` message exchange MUST always pass an `app: AppIdentifier` argument to target the intent. Further, if no `instanceId` is set in the `AppIdentifier`, then it should be interpreted to mean *'spawn a new instance of the target application'*. A local FDC3 API implementation call would normally defer to a resolver UI or similar if there are multiple options for resolving a specified `appId` (i.e. existing instance(s) and the option spawning a new instance), whereas this message exchange assumes that resolution has already taken place on the source Desktop Agent. + +Hence, if a target [`AppIdentifier`](../../api/ref/Types#appidentifier) is not passed in the original `DesktopAgent` API call, then the [`findIntent`](findIntent) message exchange should be used to collect options for the local resolver to use. Once an option has been selected (for example because there is only one option, or because the user selected an option in a local intent resolver UI), the `raiseIntent` message exchange may then be used (if a remote option was selected as the resolution) to raise the intent. + +:::info + +The same approach applies to `fdc3.raiseIntentForContext` calls, in that a [`findIntentByContext`](findIntentsByContext) message exchange should be used to collect options for the local resolver to use. Once an option has been selected (for example because there is only one option, or because the user selected an option in a local intent resolver UI), the `raiseIntent` message exchange is then used (if a remote option was selected as the resolution) to raise the intent. + +::: + +e.g. An application with appId `agentA-app1` makes the following API call: + +```javascript +let appIntent = await fdc3.raiseIntent("StartChat", context); +``` + +Agent A should then conduct the `findIntent` message exchange as described above, displaying its Intent resolver UI if necessary. Once an option is selected, the `raiseIntent` message exchange is conducted as if the API call had been made with a target app: + +```javascript +let appIntent = await fdc3.raiseIntent("StartChat", context, {"appId": "Slack", "desktopAgent": "agent-B"}); +``` + +In the event that an agent referred to in the API call is not connected to the bridge, it is connected but times out or returns an error, its `DesktopAgentIdentifier` should be added to the `meta.errorSources` element instead of `meta.sources` in the `raiseIntentResponse` and the appropriate error (which might include any error from the [`ResolveError`](../../api/ref/Errors#resolveerror) enumeration, [`BridgingError.ResponseTimedOut`](../../api/ref/Errors#bridgingerror) or [`BridgingError.AgentDisconnected`](../../api/ref/Errors#bridgingerror)) should be added to `meta.errorDetails`. + +:::tip + +Desktop Agents MAY support the deprecated `raiseIntent` signature that uses the app `name` field by using the `findIntent` message exchange to attempt to resolve the `name` to an `AppIdentifier`. + +::: + +## Message exchange + +:::note + +Agent-C is not involved in the diagram below as the `raiseIntent` is always specified with a target application and Desktop Agent. + +::: + +```mermaid +sequenceDiagram + box Desktop Agent A + participant AA as App A + participant DA as Desktop Agent A + end + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + AA --) DA: fdc3.raiseIntent + DA ->> DAB: raiseIntentRequest + DAB ->> DB: raiseIntentRequest + DB ->> DAB: raiseIntentResponse + DAB ->> DA: raiseIntentResponse + DA -->> AA: resolve (IntentResolution) + AA --) DA: resolution.getResult() + DB ->> DAB: raiseIntentResultResponse + DAB ->> DA: raiseIntentResultResponse + DA --) AA: resolve (IntentResult) +``` + +## Request format + +### Request message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentAgentRequest.schema.json](/schemas/2.1/bridging/raiseIntentAgentRequest.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentBridgeRequest.schema.json](/schemas/2.1/bridging/raiseIntentBridgeRequest.schema.json) + +### Example + +Outward message to the DAB: + +```json +// agent-A -> DAB +{ + "type": "raiseIntentRequest", + "payload": { + "intent": "StartChat", + "context": {/*contextObj*/}, + "app": { // AppIdentifier for chosen resolution including desktopAgent value + "appId": "Slack", + "desktopAgent": "agent-B" + //Note an instanceId may be included to target an already running instance + } + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "agentA-app1", + "instanceId": "c6ad5174-6f78-4582-8e96-728d93a4d7d7" + }, + "destination": { // duplicates the app argument so that the message is routed like any other + "appId": "Slack", + "desktopAgent": "agent-B" + } + } +} +``` + +The bridge fills in the `source.desktopAgent` field and forwards the request to the target Desktop Agent: + +```json +// DAB -> agent-B +{ + "type": "raiseIntentRequest", + "payload": { + "intent": "StartChat", + "context": {/*contextObj*/}, + "app": { + "appId": "Slack", + "desktopAgent": "agent-B" + //Note an instanceId may be included to target an already running instance + } + }, + "meta": { + "requestUuid": "", + "timestamp": "2020-03-...", + "source": { + "appId": "agentA-app1", + "instanceId": "c6ad5174-6f78-4582-8e96-728d93a4d7d7", + "desktopAgent": "agent-A" //added by DAB + }, + "destination": { // duplicates the app argument so that the message is routed like any other + "appId": "Slack", + "desktopAgent": "agent-B" + } + } +} +``` + +## Response format + +### Response message schemas + +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentAgentResponse.schema.json](/schemas/2.1/bridging/raiseIntentAgentResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentAgentErrorResponse.schema.json](/schemas/2.1/bridging/raiseIntentAgentErrorResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentResultAgentResponse.schema.json](/schemas/2.1/bridging/raiseIntentResultAgentResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentResultAgentErrorResponse.schema.json](/schemas/2.1/bridging/raiseIntentResultAgentErrorResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentBridgeResponse.schema.json](/schemas/2.1/bridging/raiseIntentBridgeResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentBridgeErrorResponse.schema.json](/schemas/2.1/bridging/raiseIntentBridgeErrorResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentResultBridgeResponse.schema.json](/schemas/2.1/bridging/raiseIntentResultBridgeResponse.schema.json) +- [https://fdc3.finos.org/schemas/2.1/bridging/raiseIntentResultBridgeErrorResponse.schema.json](/schemas/2.1/bridging/raiseIntentResultBridgeErrorResponse.schema.json) + +### Example + +If the `raiseIntent` request were made locally, agent-B would deliver the intent and context to the target app's `IntentHandler` and respond to the raising application with an `IntentResolution`: + +```javascript +{ + "intent": "StartChat", + "source": { + "appId": "Slack", + "instanceId": "e36d43e1-4fd3-447a-a227-38ec48a92706" + }, + getResult: ƒ +} +``` + +This is encoded and sent to the bridge (omitting the `getResult()` function) as: + +```json +// agent-B -> DAB +{ + "type": "raiseIntentResponse", + "payload": { + "intentResolution": { + "intent": "StartChat", + "source": { + "appId": "Slack", + "instanceId": "e36d43e1-4fd3-447a-a227-38ec48a92706" + } + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-..." + } +} +``` + +:::tip + +When producing a response to a `raiseIntent` request, the instance of the receiving application MUST be initialized (if it does not already exist) and an `instanceId` generated for it before the `IntentResolution` is generated so that it can include the `instanceId`. + +::: + +The bridge will fill in the `intentResolution.source.DesktopAgent` & `source.desktopAgent` and relay the message back to agent-A: + +```json +// DAB -> agent-A +{ + "type": "raiseIntentResponse", + "payload": { + "intentResolution": { + "intent": "StartChat", + "source": { + "appId": "Slack", + "instanceId": "e36d43e1-4fd3-447a-a227-38ec48a92706", + "desktopAgent": "agent-B" // added by DAB + } + } + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + "sources": [{ "desktopAgent": "agent-B" }] // added by DAB + } +} +``` + +When `Slack` produces an `IntentResult` from its `IntentHandler`, or the intent handler finishes running without returning a result, it should send a further `raiseIntentResultResponse` message to indicate that it's finished running and to pass any `IntentResult` onto the raising application (setting either `payload.intentResult.context` or `payload.intentResult.channel` to indicate the type of the `IntentResult`, or leaving `payload.intentResult` empty to indicate a `void` result). There is no need to provide a `source` field in this response as the source information was already provided in the `raiseIntentResponse` message preceding it. + +```json +// agent-B -> DAB +{ + "type": "raiseIntentResultResponse", + "payload": { + "intentResult": { + "context": {/*contextObj*/} + /* for a channel IntentResult use: + "channel": { + "id": "app-channel xyz", + "type": "user" + } + + or for a void result use leave this object empty. + */ + + }, + "meta": { + "requestUuid": "", + "responseUuid": "", //a different UUID should be used for the result response + "timestamp": "2020-03-..." + } +} +``` + +:::tip + +If intent result is private channel see [PrivateChannels](../spec#privatechannels) for additional message exchanges that may be needed. + +::: + +Finally, the bridge augments the response with `sources[0].desktopAgent` and passes it back to Agent-A. + +```json +// DAB -> agent-A +{ + "type": "raiseIntentResultResponse", + "payload": { + "context": {/*contextObj*/} + }, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + "sources": [{ "desktopAgent": "agent-B" }] // added by DAB + } +} +``` + +If the `IntentHandler` returned `void` rather than an intent result `payload` should be empty, e.g.: + +```json +// DAB -> agent-A +{ + "type": "raiseIntentResultResponse", + "payload": {}, + "meta": { + "requestUuid": "", + "responseUuid": "", + "timestamp": "2020-03-...", + "sources": [{ "desktopAgent": "agent-B" }] // added by DAB + } +} +``` diff --git a/website/versioned_docs/version-2.1/agent-bridging/spec.md b/website/versioned_docs/version-2.1/agent-bridging/spec.md new file mode 100644 index 000000000..5fa00f796 --- /dev/null +++ b/website/versioned_docs/version-2.1/agent-bridging/spec.md @@ -0,0 +1,1022 @@ +--- +id: spec +sidebar_label: Overview +title: Agent Bridging Overview (2.1) +--- + +:::info _[@experimental](../fdc3-compliance#experimental-features)_ + +Desktop Agent Bridging is an experimental feature added to FDC3 in 2.1, hence, its design may change in the future and it is exempted from the FDC3 Standard's normal versioning and deprecation polices in order to facilitate any necessary change. + +::: + + + +The FDC3 Desktop Agent API addresses interoperability between apps running within the context of a single Desktop Agent (DA), enabling cross-application workflows and context sharing. + +![A single desktop and FDC3 Desktop Agent](/assets/dab-overview-1.png) + +It is clear, however, that user desktops are substantially more complicated in reality. Some Desktop Agent implementations already provide additional features allowing "external" applications (e.g. those not launched by the Desktop Agent) to connect in order to participate in interoperability. + +![A single desktop and Desktop Agent, with external apps](/assets/dab-overview-2.png) + +Firms that make extensive use of FDC3 have also identified use cases where interoperability workflows span different physical desktops, and have built proprietary bridging solutions (e.g. [Backplane](https://backplane.finos.org/) was originally developed as an in-house solution to this problem). + +![Two physical desktops with a desktop agent each](/assets/dab-overview-3.png) + +With the success of FDC3, usage of vendor-provided Desktop Agents has increased substantially among banks and buy-side institutions. Buy-side firms who are clients of multiple banks' platforms have multiple desktop agents delivered to their desktops. Several software vendors also deliver FDC3-compatible software: some as apps that can run in any Desktop Agent, but some as self-contained applications running in their own desktop agent. They are often multi-component suites of functionality with a customized user experience, and are not simple to export to a different Desktop Agent. In these cases, being able to provide a single installable platform bundled with a Desktop Agent is a far more practical solution for the vendor and customer. + +![Two physical desktops, one with multiple desktop agents](/assets/dab-overview-4.png) + +However, unless the Desktop Agents themselves can interoperate, unfortunately, this approach prevents interoperability rather than promoting it. To support user workflows spanning the whole environment there needs to be some form of network connectivity between Desktop Agents. + +Desktop Agent Bridging addresses the interconnection of Desktop Agents (DAs) such that apps running under different Desktop Agents can also interoperate, allowing workflows to span multiple Desktop Agents. This is achieved, without implementation changes or special handling in the apps, by providing a protocol and service for the Desktop Agents to interoperate with each other instead, allowing application interop to extend across the bridged agents, seamlessly. + +In any Desktop Agent Bridging scenario, it is expected that each DA is being operated by the same user (as the scope of FDC3 contemplates cross-application workflows for a single user, rather than cross-user workflows), although DAs may be run on different machines operated by the same user. Whether a bridge is running for Desktop Agents to connect to, whether it requires the agents to authenticate etc., is in the hands of the user (and their local IT team). + +## Bridging Desktop Agents + +The Desktop Agent Bridging Part of the FDC3 Standard is composed of three components: + +- **[Connection](#connection)**: A means for Desktop Agents to communicate with a bridge, and through that bridge, with each other. +- **[Connection Protocol](#connection-protocol)**: A protocol defining message exchanges necessary to connect to a Bridge and to perform initial state synchronization. +- **[Messaging Protocol](#messaging-protocol)**: A protocol defining message exchanges that allow FDC3 API interop to extend across multiple Desktop Agents. + +Detail on each of these components is defined in the following sections. + +:::note + +Although this specification defines a particular [connection](#connection) type (based on a websocket server), it has been divided into parts so that the protocol definitions might be reused to implement a bridge over an alternative connection in future. + +::: + +:::tip + +The Desktop Agent Bridging protocol has been designed such that an application using the FDC3 API does not need to make any significant changes in order to make use of the Bridging connection between its Desktop Agent and another agent. This is achieved via messaging workflows that allow the bridged agents to cooperate on behalf of the applications, for example, by retrieving options for intent resolution from other agent or forwarding on messages that were broadcast on channels. + +However, Bridging should still be visible to applications, which is achieved through the addition of a `desktopAgent` field to the `AppIdentifier` type allowing it to indicate that an app or app instance exists on another agent, as well as a number of new error messages that may be returned to indicate bridging issues. + +::: + +### Agent Bridging Compliance + +Agent Bridging is introduced in FDC3 2.1 as an [@experimental](../fdc3-compliance#experimental-features) feature of the FDC3 Standard, included to enable implementation by and feedback from the FDC3 community. As such, it is currently optional for the purposes of compliance and is exempted from the normal versioning and deprecation polices in order to facilitate any refinement needed. + +### JSON Message Protocol & JSON Schema + +The connection and messaging protocols that the Desktop Agent Bridging Part defines are based on messages encoded in JSON. [JSON Schema](https://json-schema.org/) is used to define the format of each message in the protocol and should be considered the 'source of truth' for each and may be used to validate that individual messages are in the correct format. However, examples are provided in the documentation in TypeScript and JavaScript formats for convenience. TypeScript interfaces for individual messages, included in the FDC3 NPM module, are generated from the JSON Schema source files using [quicktype](https://quicktype.io/). + +## Connection + +### Topology + +In order to implement Desktop Agent Bridging some means for Desktop Agents to connect to and communicate with each other is needed. This Standard assumes that Desktop Agent Bridging is implemented via a standalone 'bridge' which each agent connects to and will use to route messages to or from other agents. This topology is similar to a star topology in networking, where the Desktop Agent Bridge (a 'bridge') will be the central node acting as a router. + +```mermaid +flowchart TD; + A[DA A] + B[DA B] + C[DA C] + D[DA D] + E{Bridge} + E <--> |websocket| A + E <--> |websocket| B + C <--> |websocket| E + D <--> |websocket| E +``` + +Other possible topologies include peer-to-peer or client/server networks, however, these introduce significant additional complexity into multiple aspects of the bridging protocol that must be implemented by Desktop Agents, (including discovery, authentication and message routing), where a star topology/standalone bridge enables a relatively simple set of protocols, with the most difficult parts being implemented in the bridge itself. + +Whilst the standalone bridge represents a single point of failure for the interconnection of Desktop Agents, it will also be significantly simpler than a full Desktop Agent implementation. Further, failures may be mitigated by setting the bridge up as a system service, such that it is started when the user's computer is started and may be restarted automatically if it fails. In the event of a bridge failure or manual shutdown, then Desktop Agents will no longer be bridged and should act as single agents. + +By using the Desktop Agent Bridging Connection and Messaging protocols, a bridge will implement "server" behavior by: + +- Accepting connections from client Desktop Agents, receiving and authenticating credentials and assigning a name (for routing purposes) +- Receiving requests from client Desktop Agents. +- Routing requests to client Desktop Agents. +- Receiving responses from client Desktop Agents and collating them. +- Routing responses to client Desktop Agents. + +A Desktop Agent will implement "client" behavior by: + +- Connecting to the bridge, providing authentication credentials and receiving an assigned named (for routing purposes). +- Forwarding requests to the bridge. +- Awaiting response(s) from the bridge. +- Receiving requests from the bridge. +- Sending responses to the bridge. + +Hence, message paths and propagation are simple. All messages to other Desktop Agents are passed to the bridge for routing and all messages (both requests and responses) are received back from it, i.e. the bridge is responsible for all message routing. + +#### Multi-Machine Use Cases + +In financial services it is not unusual for a single user to be working with applications on more than one desktop. As Desktop Agents do not span desktops bridging Desktop Agents across multiple machines is an additional use case for Desktop Agent bridging. However, as FDC3 only contemplates interoperability between apps for a single user, it is expected that in multi-machine use cases each machine is being operated by the same user. + +```mermaid +flowchart LR; + A[DA A] + B[DA B] + B1{Bridge 1} + C[DA C] + D[DA D] + B2{Bridge 2} + + subgraph PC1 [PC 1] + direction RL + B1 <--> |websocket| A + B1 <--> |websocket| B + end + subgraph PC2 [PC 2] + direction LR + B2 <--> |websocket| C + B2 <--> |websocket| D + end + PC1 .- |Bridge interconnect| PC2 +``` + +However, cross-machine routing is currently considered to be an internal concern of a Desktop Agent Bridge implementation, with each Desktop Agent simply communicating with a bridge instance located on the same machine. Hence, the connection protocol between bridges themselves is currently beyond the scope of this standard and my be implemented via any suitable means. + +Further, as FDC3 only contemplates interoperability between apps for a single user, it is expected that in multi-machine use cases each machine is being operated by the same user. However, methods of verifying the identity of users are currently beyond the scope of the Standard. + +### Websocket Connection + +Connections between Desktop Agents and the Desktop Agent Bridge will be made via websocket connections, with the bridge acting as the websocket server and each connected Desktop Agent as a client. + +The bridge MUST run on the same machine as the Desktop Agents, and the websocket MUST be bound to the loopback adapter IP address (127.0.0.1), ensuring that the websocket is not exposed to wider networks. + +Bridge implementations SHOULD default to binding the websocket server to a port in the recommended port range 4475 - 4575, enabling simple discovery of a running bridge via attempting socket connections to ports in that range and attempting a handshake (as defined later in this proposal) that will identify the websocket as belong to a Desktop Agent Bridge. A port range MAY be used, in preference to a single nominated port, in order to enable the automatic resolution of port clashes with other services. + +Both DAs and bridge implementations SHOULD support at least connection to the recommended port range and MAY also support configuration for connection to an alternative bridging port or port range. + +#### WebSockets and Multiple Machines + +As the bridge binds its websocket on the loopback address (127.0.0.1) it cannot be connected to from another device. Hence, an instance of the standalone bridge may be run on each device and those instances exchange messages by other means in order to implement the bridge cross-device. + +## Connection Protocol + +On connection to the bridge's websocket, a handshake must be completed that may include an authentication step before a name is assigned to the Desktop Agent for use in routing messages. The purpose of the handshake is to allow: + +- The Desktop Agent to confirm that it is connecting to the Desktop Agent Bridge, rather than another service exposed via a websocket. +- The Desktop Agent Bridge to require that the Desktop Agent authenticate itself, allowing it to control access to the network of bridged Desktop Agents. +- The Desktop Agent to request a particular name by which it will be addressed by other agents and for the bridge to assign the requested name, after confirming that no other agent is connected with that name, or a derivative of that name if it is already in use. + +The bridge is ultimately responsible for assigning each Desktop Agent a name and for routing messages using those names. Desktop Agents MUST accept the name they are assigned by the bridge. + +Exchange standardized handshake messages that identify: + +- That the server is a bridge, including: + - implementation details for logging by DA. + - supported FDC3 version(s). +- That the client is an FDC3 DA, including: + - implementation details (ImplementationMeta returned by fdc3.getInfo() call) for logging by DA and sharing with other DAs. + - already includes supported FDC3 version. + - request for a specific agent name. + +```mermaid +sequenceDiagram + participant DA as Desktop Agent A + participant DAB as Desktop Agent Bridge + participant DB as Desktop Agent B + participant DC as Desktop Agent C + DA -->>+ DAB: connect (step 1) + DAB ->>+ DA: hello (step 2) + DA ->>+ DAB: handshake (steps 3-5) + DAB ->>+ DA: connectedAgentsUpdate (step 6) + DAB ->>+ DB: connectedAgentsUpdate (step 6) + DAB ->>+ DC: connectedAgentsUpdate (step 6) +``` + +### Step 1. Connect to Websocket + +The Desktop Agent attempts to connect to the websocket at the first port in the defined port range. If a connection cannot be made on the current port, move to the next port in the range and reattempt connection. + +In the event that there are no ports remaining in the range, the Desktop Agent SHOULD reset to the beginning of the range, SHOULD pause its attempts to connect and resume later (a minimum wait period of 5 seconds SHOULD be used) + +Note, if the Desktop Agent is configured to run at startup (of the user's machine) it is possible that the Desktop Agent Bridge may start later (or be restarted at some point). Hence, Desktop Agents SHOULD be capable of connecting to the bridge once they are already running (rather than purely at startup). + +### Step 2. Hello + +When a new connection is made to the Desktop Agent Bridge websocket, it sends a `hello` message, including its metadata. + +```typescript +{ + type: "hello", + payload: { + desktopAgentBridgeVersion: string, + supportedFDC3Versions: string[], + authRequired: boolean, + /** The DAB JWT authentication token */ + authToken?: string + }, + meta: { + timestamp: date + } +} +``` + +**Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/connectionStep2Hello.schema.json](/schemas/2.1/bridging/connectionStep2Hello.schema.json) + +A Desktop Agent can use the structure of this message to determine that it has connected to a Desktop Agent Bridge (i.e by checking `msg.type === "hello" && msg.payload.desktopAgentBridgeVersion`), whether it supports a compatible FDC3 version and whether it is expected to provide authentication credentials in the next step (`if(msg.payload.authRequired) { ... }`). + +An optional JWT token can be included in the `hello` message to allow the connecting agent to authenticate the bridge. Verification of the supplied JWT by the DA is optional but recommended, meaning that the DA SHOULD verify the received JWT when one is included in the `hello` message. + +If no hello message is received, the message doesn't match the defined format or validation of the optional JWT fails, the Desktop Agent should return to step 1 and attempt connection to the next port in the range. + +### Step 3. Handshake & Authentication + +The DA must then respond to the `hello` message with a `handshake` request to the bridge, including an auth token (JWT) if required. + +```typescript +{ + type: "handshake", + /** Request body, containing the arguments to the function called.*/ + payload: { + /** The JWT authentication token */ + authToken?: string, + /** Metadata about the Desktop Agent connecting, normally retrieved within the + * context of the Desktop Agent via `fdc3.getInfo()`.*/ + implementationMetadata: { + /** The version number of the FDC3 specification that the implementation + * provides. The string must be a numeric semver version, e.g. 1.2 or 1.2.1. */ + fdc3Version: string, + /** The name of the provider of the FDC3 Desktop Agent Implementation + * (e.g.Finsemble, Glue42, OpenFin etc.). */ + provider: string, + /** The version of the provider of the FDC3 Desktop Agent Implementation (e.g. 5.3.0). */ + providerVersion: string, + /** Metadata indicating whether the Desktop Agent implements optional features of + * the Desktop Agent API. */ + readonly optionalFeatures: { + /** Used to indicate whether the exposure of 'originating app metadata' for + * context and intent messages is supported by the Desktop Agent.*/ + "OriginatingAppMetadata": boolean; + /** Used to indicate whether the optional `fdc3.joinUserChannel`, + * `fdc3.getCurrentChannel` and `fdc3.leaveCurrentChannel` are implemented by + * the Desktop Agent.*/ + "UserChannelMembershipAPIs": boolean; + } + }, + /** The requested DA name */ + requestedName: string, + /** The current state of the Desktop Agent's channels, excluding any private channels, + * as a mapping of channel id to an array of Context objects, most recent first.*/ + channelsState: Record + }, + meta: { + /** Unique UUID for this request */ + requestUuid: string, + /** Timestamp at which request was generated */ + timestamp: date + } +} +``` + +**Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/connectionStep3Handshake.schema.json](/schemas/2.1/bridging/connectionStep3Handshake.schema.json) + +Note that the `meta` element of of the handshake message contains both a `timestamp` field (for logging purposes) and a `requestUuid` field that should be populated with a Universally Unique Identifier (UUID), generated by the Desktop Agent. This `responseUuid` will be used to link the handshake message to a response from the Desktop Agent Bridge that assigns it a name. For more details on UUID generation see [Universally Unique Identifier](#universally-unique-identifier) section. + +If requested by the server, the JWT auth token payload should take the form: + +```typescript +{ + "sub": string, // UUID for the key pair used to sign the token + "iat": date // timestamp at which the the token was generated as specified in ISO 8601 +} +``` + +e.g. + +```json +{ + "sub": "65141135-7200-47d3-9777-eb8786dd31c7", + "iat": "2022-07-06T10:11:43.492Z" +} +``` + +Note that the `sub` SHOULD be a UUID that does NOT need to match the name requested by the Desktop Agent. It will be used to identify the key pair that should be used to validate the JWT token. Further, multiple Desktop Agent's MAY share the same keys for authentication and hence the same `sub`, but they will be assigned different names for routing purposes by the Desktop Agent Bridge. If an agent disconnects from the bridge and later re-connects it MAY request and be assigned the same name it connected with before. + +### Step 4. Auth Confirmation and Name Assignment + +The Desktop Agent Bridge will extract the authentication token `sub` from the JWT token's claims and then verify the token's signature against any public key it has been configured with. If the signature can't be verified, the bridge should respond with the below authentication failed message and the socket should be disconnected by the bridge. + +```typescript +{ + type: "authenticationFailed", + payload: { + message: string + }, + meta: { + /** Timestamp at which response was generated */ + timestamp: Date, + /** UUID for the handshake request */ + requestUuid: string, + /** Unique UUID for this message */ + responseUuid: string, + } +} +``` + +**Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/connectionStep4AuthenticationFailed.schema.json](/schemas/2.1/bridging/connectionStep4AuthenticationFailed.schema.json) + +If authentication succeeds (or is not required), then the Desktop Agent Bridge should assign the Desktop Agent the name requested in the `handshake` message, unless another agent is already connected with that name in which case it should generate a new name which MAY be derived from the requested name. Note that the assigned name is not communicated to the connecting agent until step 6. + +### Step 5. Synchronize the Bridge's Channel State + +Channels are the main stateful mechanism in the FDC3 that we have to consider. A key responsibility of the Desktop Agent Bridge is ensuring that the channel state of the connected agents is kept in-sync. To do so, the states must be synchronized whenever a new agent connects. Hence, the Bridge MUST process the `channelState` provided by the new agent in the `handshake` request, which MUST contain details of each known User Channel or App Channel and its state. The bridge MUST compare the received channel names and states to its own representation of the current state of channels in connected agents, merge that state with that of the new agent and communicate the updated state to all connected agents to ensure that they are synchronized with it. + +Hence, if we assume that the state of each channel can be represented by an ordered array of context objects (most recent first - noting that only the first position, that of the most recent context broadcast, matters), the Desktop Agent Bridge MUST merge the incoming `channelsState` with the `existingChannelsState` as follows: + +```typescript +Object.keys(channelsState).forEach((channelId) => { + if (!existingChannelsState[channelId]) { + //unknown channels: just adopt its state + existingChannelsState[channelId] = channelsState[channelId]; + } else { + //known channels: merge state, with existing state taking precedence + const currentState = existingChannelsState[channelId]; + const incoming = channelsState[channelId]; + incoming.forEach((context) => { + //only add previously unknown context types to the state + if (!currentState.find(element => element.type === context.type)){ + //add to end of array to avoid setting most recent context type at the beginning + currentState.push(context); + } + // else ignore any types that are already known + }); + } +}); +``` + +When multiple agents attempt to connect to the Desktop Agent Bridge at the same time, steps 3-6 of the connection protocol MUST be handled by the Desktop Agent Bridge serially to ensure correct channel state synchronization. + +### Step 6. Connected Agents Update + +The updated `existingChannelsState` will then be shared with all connected agents along with updated details of all connected agents via a `connectedAgentsUpdate` message sent to all connected sockets. The newly connected agent will receive both its assigned name and channel state via this message. The `connectedAgentsUpdate` message will be linked to the handshake request by quoting the `meta.requestUuid` of the `handshake` message. + +The `connectedAgentsUpdate` message will take the form: + +```typescript +{ + type: "connectedAgentsUpdate", + /** Request body, containing the arguments to the function called.*/ + payload: { + /** Should be set when an agent first connects to the bridge and provide + * its assigned name. */ + addAgent?: string, + /** Should be set when an agent disconnects from the bridge and provide + * the name that no longer is assigned. */ + removeAgent?: string, + /** Desktop Agent Bridge implementation metadata of all connected agents. + * Note that this object is extended to include a `desktopAgent` field + * with the name assigned by the DAB. */ + allAgents: ImplementationMetadata[], + /** The updated state of channels that should be adopted by the agents. + * SHOULD only be set when an agent is connecting to the bridge. */ + channelsState?: Record // see step4 + }, + meta: { + /** For a new connection, should be the same as the handshake requestUuid. + * Should be the same as the responseUuid for a disconnection. + */ + requestUuid: string, + /** Unique UUID for this message */ + responseUuid: string, + /** Timestamp at which response was generated */ + timestamp: date, + } +} +``` + +**Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/connectionStep6ConnectedAgentsUpdate.schema.json](/schemas/2.1/bridging/connectionStep6ConnectedAgentsUpdate.schema.json) + +When an agent connects to the bridge, it and other agents connected to the bridge, should adopt the state of any channels that do not currently exist or do not currently contain state of a particular type. This synchronization is NOT performed via broadcast as the context being merged would become the most recent context on the channel, when other contexts may have been broadcast subsequently. Rather, it should be adopted internally by each Desktop Agent, merging it such that it would be received by applications that have added a context listener to the channel or call `channel.getCurrentContext()` on it. + +It should be noted that Desktop Agents will not have context listeners for previously unknown channels, and SHOULD simply record that channel's state for use when that channel is first used. + +For known channel names, the Desktop Agents MUST also compare their current state to that which they have just received and may need to internally adopt context of types not previously seen on a channel. As context listeners can be registered for either a specific type or all types some care is necessary when doing so (as only the most recently transmitted Context should be received by un-typed listeners). Hence, the new context MUST only be passed to a context listener if it was registered specifically for that type and a context of that type did not previously exist on the channel. + +In summary, updating listeners for a known channel should be performed as follows: + +1. The incoming channel state `channelState` for a particular channel should be processed from last to first (most recent context broadcast). +2. If there is no current context of that type, broadcast it to any listeners of that specific type only. +3. If there is a current context of that type, and it does not match the incoming object exactly, broadcast it to listeners of that specific type only. +4. If the most recent (first in the incoming array) type OR value of that type doesn't match the most recent context broadcast on the channel, broadcast it to un-typed listeners only. + +This procedure is the same for both previously connected and connecting agents, however, the merging procedure used by the Desktop Agent Bridge in step 5 will result in apps managed by previously connected agents only rarely receiving context broadcasts (and only for types they have not yet seen on a channel). + +After applying the `connectedAgentsUpdate` message, the newly connected Desktop Agent and other already connected agents are able to begin communicating through the bridge. + +#### Channels + +It is assumed that Desktop Agents SHOULD adopt the recommended 8 channel set (and the respective display metadata). Desktop Agents MAY support channel customization through configuration. + +The Desktop Agent Bridge MAY support channel mapping ability, to deal with issues caused by differing channel sets. + +A key responsibility of the Desktop Agent Bridge is ensuring that the channel state of the connected agents is kept in-sync, which requires an initial synchronization step as part of the connection protocol. + +#### Atomicity and handling concurrent operations + +Handling by the Desktop Agent of the synchronization message from the Desktop Agent Bridge in step 6 of the connection protocol should be atomic to prevent message overlap with `fdc3.broadcast`, `channel.broadcast`, `fdc3.addContextListener` or `channel.getCurrentContext`. I.e. the `connectedAgentsUpdate` message must be processed immediately on receipt by Desktop Agents and updates applied before any other messages are sent or responses processed. + +Similarly, the Desktop Agent Bridge must process steps 3-6 of the connection protocol (receiving a `handshake` messages up to issuing the `connectedAgentsUpdate` messages to all participants) as a single atomic unit, allowing no overlap with the processing of other messages from connected agents (as they might modify the state information it is processing during those steps). + +#### Notification to users of connection events + +Desktop Agents SHOULD provide visual feedback to end users when they or other agents connect or disconnect from the Desktop Agent Bridge (i.e. whenever a `connectedAgentsUpdate` message is received, or a disconnection happens). Doing so will ensure that the end user understands whether their apps and Desktop Agent can communicate with other apps running under other Desktop Agents, and can better attribute any issues with interoperability between them to the probable source. + +### Step 7. Disconnects + +Although not part of the connection protocol, it should be noted that the `connectedAgentsUpdate` message sent in step 6 should also be sent whenever an agent disconnects from the bridge to update other agents. If any agents remain connected, then the `channelState` does not change and can be omitted. However, if the last agent disconnects the bridge SHOULD discard its internal `channelState`, instead of issuing the update. + +## Messaging Protocol + +In order for Desktop Agents to communicate with the Desktop Agent Bridge and thereby other Desktop Agents, a messaging protocol is required. FDC3 supports both 'fire and forget' interactions (such as the broadcast of context messages) and interactions with specific responses (such as raising intents and returning a resolution and optional result), both of which must be handled by that messaging protocol and message formats it defines, as described in this section. + +### Collating Responses + +Whilst some FDC3 requests are 'fire and forget' (e.g. broadcast) the main requests such as `findIntent` or `raiseIntent` expect a response. In a bridging scenario, the response can come from multiple Desktop Agents and therefore need to be aggregated and augmented before they are sent back to the requesting DA. + +:::note +A set of classifications for message exchange types are provided in the [Individual message exchanges](#individual-message-exchanges) section. +::: + +The Desktop Agent Bridge is the responsible entity for collating responses together from all DAs. Whilst this approach may add some complexity to bridge implementations, it will simplify DA implementations since they only need to handle one response. + +The Desktop Agent Bridge MUST allow for timeout configuration. + +The Bridge SHOULD also implement timeout for waiting on DA responses. Assuming the message exchange will be all intra-machine, a recommended maximum timeout of 1500ms SHOULD be used. Similarly, Desktop Agents SHOULD apply a timeout to requests made to the bridge that require a response (collated or otherwise), to handle situations where the bridge is not responding as expected. A recommended maximum timeout of 3000ms SHOULD be used in this case. + +### Message Format + +All messages sent or received by the Desktop Agent Bridge will be encoded in JSON and will have the same basic structure (including those already defined in the connection protocol): + +```typescript +{ + /** Identifier used to declare what aspect of FDC3 that the message relates to. */ + type: string, + /** Request body, containing any the arguments to the FDC3 interactions. */ + payload: { ... }, + /** Metadata relating to the message, its sender and destination. */ + meta: { ... } +} +``` + +Messages can be divided into four categories: + +- Requests from a Desktop Agent: Messages that initiate a particular interaction. +- Requests forwarded by the Bridge: Messages augmented and forwarded on by the Bridge. +- Responses from a Desktop Agent: Messages from a single Desktop Agent that respond to a prior request from the Bridge. +- Responses collated and forwarded by the Bridge: Messages from the Bridge back to the Desktop Agent that initiated an interaction, which may combine the responses from multiple other Desktop Agents. + +Details specific to each are provided in the following sections. + +#### Request Messages + +Request messages from a Desktop Agent use the following format: + +```typescript +{ + /** Identifies the type of the message and it is typically set to the FDC3 + * function name that the message relates to, e.g. 'findIntent', with + * 'Request' appended. */ + type: string, + /** Request body, typically containing the arguments to the function called.*/ + payload: { + /** Used to indicate which channel `broadcast` functions were called on.*/ + channelId?: string, + /** Used as an argument to `findIntent` and `raiseIntent` functions.`*/ + intent?: string, + /** Used as an argument to `broadcast`, `findIntent` and `raiseIntent` + * functions.*/ + context?: Context, + /** Used as an argument to `open`, `raiseIntent`, `getAppMetadata`, and + * `findInstances` functions.*/ + app?: AppIdentifier, + /** Used as an argument to `findIntent` functions. */ + resultType?: string, + /** Context type name used in Private Channel event messages. */ + contextType?: string + }, + /** Metadata used to uniquely identify the message and its sender. */ + meta: { + /** Unique UUID for this request */ + requestUuid: string, + /** Timestamp at which request was generated */ + timestamp: date, + /** Field that represents the source application that the request was + * received from, or the source Desktop Agent if it issued the request + * itself. */ + source: AppIdentifier | DesktopAgentIdentifier, + /** Optional field that represents the destination that the request + * should be routed to. Must be set by the Desktop Agent for API calls + * that include a target app parameter and must include the name of the + * Desktop Agent hosting the target application. */ + destination?: AppIdentifier | DesktopAgentIdentifier + } +} +``` + +**Request Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/agentRequest.schema.json](/schemas/2.1/bridging/agentRequest.schema.json) + +If the FDC3 API call underlying the request message includes a target (typically defined by an `app` argument, in the form of an AppIdentifier object) it is the responsibility of the Desktop Agent to copy that argument into the `meta.destination` field of the message and to ensure that it includes a `meta.destination.desktopAgent` value. If the target is provided in the FDC3 API call, but without a `meta.destination.desktopAgent` value, the Desktop Agent should assume that the call relates to a local application and does not need to send it to the bridge. + +Requests without a `meta.destination` field will be forwarded to all other agents by the bridge, which will also handle the collation of responses which quote the `meta.requestUuid`. + +##### Request Messages Forwarded by the Bridge + +Request messages forwarded by the Bridge onto other Desktop Agents use the same format as incoming requests from Desktop Agents, with the exception that the `desktopAgent` properties of the `meta.source` field MUST be provided, and should be overwritten by the Bridge (based on the connection that the message was received from) to prevent spoofing of request message origins. + +**Bridge Request Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/bridgeRequest.schema.json](/schemas/2.1/bridging/bridgeRequest.schema.json) + +#### Response Messages + +Response messages from a Desktop Agent back to the Bridge use a similar format that is differentiated from requests by the presence of a `meta.responseUuid` field. They MUST also quote the `meta.requestUuid` that they are responding to. + +:::info +Response messages do not include a `meta.destination` as the routing of responses is handled by the Bridge via the `meta.requestUuid` field. They also do not include a `source` field as responses are currently always from the Desktop Agent, and the bridge is required to provide this information itself to prevent spoofing. +::: + +There are two types of each response message, a successful response and an error response. + +##### Successful Responses + +```typescript +{ + /** Identifies the type of the message and it is typically set to the + * FDC3 function name that the message relates to, e.g. 'findIntent', + * with 'Response' appended.*/ + type: string, + /** Response body, containing the actual response data. */ + payload: { + /** Response to `open` */ + appIdentifier?: AppIdentifier, + /** Response to `findInstances` */ + appIdentifiers?: Array, + /** Response to `getAppMetadata` */ + appMetadata?: AppMetadata, + /** Response to `findIntent`*/ + appIntent?: AppIntent, + /** Response to `findIntentsByContext`*/ + appIntents?: AppIntent[], + /** Response to `raiseIntent` functions, returned on delivery of the + * intent and context to the target app. + * Note `getResult()` function should not / can not be included in JSON. */ + intentResolution?: IntentResolution, + /** Secondary response to `raiseIntent`, sent when the `IntentHandler` + * has returned. + * Note: + * - return an empty payload object if the `IntentHandler` returned void. + * - `Channel` functions (`broadcast`, `getCurrentContext`, + * `addContextListener` do not need to be included in JSON).*/ + intentResult?: { + context?: Context, + channel?: Channel + } + }, + meta: { + /** UUID for the request this message is responding to.*/ + requestUuid: string, + /** UUID for this specific response message. */ + responseUuid: string, + /** Timestamp at which request was generated */ + timestamp: Date + } +} +``` + +**Response Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/agentResponse.schema.json](/schemas/2.1/bridging/agentResponse.schema.json) + +##### Error Responses + +```typescript +{ + /** Identifies the type of the message and it is typically set to the + * FDC3 function name that the message relates to, e.g. 'findIntent', + * with 'Response' appended.*/ + type: string, + /** Response body, containing the actual response data. */ + payload: { + /** Standardized error strings from an appropriate FDC3 API Error + * enumeration. */ + error?: string, + }, + meta: { + /** UUID for the request this message is responding to.*/ + requestUuid: string, + /** UUID for this specific response message. */ + responseUuid: string, + /** Timestamp at which request was generated */ + timestamp: Date + } +} +``` + +**Error Response Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/agentErrorResponse.schema.json](/schemas/2.1/bridging/agentErrorResponse.schema.json) + +##### Response Messages Collated and Forwarded by the Bridge + +Responses from individual Desktop Agents are collated by the Bridge and are forwarded on to the the Desktop Agent that initiated the interaction. The format used is very similar to that used for responses by the Desktop Agents, with the exception of the source information in the `meta` field. Specifically, the `meta.source` field does not need to be provided by agents, as responses are currently always provided by the Desktop Agent, whose details will be provided by the bridge when it receives the response. In responses from the bridge, the `meta.source` is replaced by two arrays, `meta.sources` and `meta.errorSources`, which provide details on the Desktop Agents that responded normally or responded with errors. The detail of any errors returned (in the `payload.error` field of a Desktop Agent's response) is collected up into a `meta.errorDetails` field. Moving the error details from the `payload` to the `meta` field enables the return of a valid response to the originating Desktop Agent in cases where some agents produced valid responses, and others produced errors. + +Hence, for responses forwarded by the bridge there are two type of response messages from the Bridge returned to agents, one for requests that received at least one successful response, and another for use when all agents (or the targeted agent) returned an error. + +##### At Least One Successful Response + +```typescript +{ + /** Identifies the type of the message and it is typically set to the + * FDC3 function name that the message relates to, e.g. 'findIntent', + * with 'Response' appended.*/ + type: string, + /** Response body, containing the actual response data. */ + payload: { + /** Response to `open` */ + appIdentifier?: AppIdentifier, + /** Response to `findInstances` */ + appIdentifiers?: Array, + /** Response to `getAppMetadata` */ + appMetadata?: AppMetadata, + /** Response to `findIntent`*/ + appIntent?: AppIntent, + /** Response to `findIntentsByContext`*/ + appIntents?: AppIntent[], + /** Response to `raiseIntent` functions, returned on delivery of the + * intent and context to the target app. + * Note `getResult()` function should not / can not be included in JSON. */ + intentResolution?: IntentResolution, + /** Secondary response to `raiseIntent`, sent when the `IntentHandler` + * has returned. + * Note: + * - return an empty payload object if the `IntentHandler` returned void. + * - `Channel` functions (`broadcast`, `getCurrentContext`, + * `addContextListener` do not need to be included in JSON).*/ + intentResult?: { + context?: Context, + channel?: Channel + } + }, + meta: { + /** UUID for the request this message is responding to.*/ + requestUuid: string, + /** Unique UUID for this collated response (generated by the bridge). */ + responseUuid: string, + /** Timestamp at which the collated response was generated */ + timestamp: Date, + /** Array of AppIdentifiers or DesktopAgentIdentifiers for the sources + * that generated responses to the request. Will contain a single value + * for individual responses and multiple values for responses that were + * collated by the bridge. May be omitted if all sources errored. MUST + * include the `desktopAgent` field when returned by the bridge. */ + sources?: (AppIdentifier | DesktopAgentIdentifier)[], + /** Array of AppIdentifiers or DesktopAgentIdentifiers for responses + * that were not returned to the bridge before the timeout or because + * an error occurred. May be omitted if all sources responded without + * errors. MUST include the `desktopAgent` field when returned by the + * bridge. */ + errorSources?: (AppIdentifier | DesktopAgentIdentifier)[], + /** Array of error message strings for responses that were not returned + * to the bridge before the timeout or because an error occurred. + * Should be the same length as the `errorSources` array and ordered the + * same. May be omitted if all sources responded. */ + errorDetails?: string[] + } +} +``` + +**Response Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/bridgeResponse.schema.json](/schemas/2.1/bridging/bridgeResponse.schema.json) + +##### All Responses are Errors + +:::info +In this case there are no successful responses and the bridge must populate the `payload.error` field in the response to the agent with one of the error messages returned, so that the receiving Desktop Agent may return it to the app that made the original call. +::: + +```typescript +{ + /** Identifies the type of the message and it is typically set to the + * FDC3 function name that the message relates to, e.g. 'findIntent', + * with 'Response' appended.*/ + type: string, + /** Response body, containing the actual response data. */ + payload: { + /** Standardized error string from an appropriate FDC3 API Error + * enumeration. This should also appear in `meta.errorDetails`.*/ + error?: string, + }, + meta: { + /** UUID for the request this message is responding to.*/ + requestUuid: string, + /** Unique UUID for this collated response (generated by the bridge). */ + responseUuid: string, + /** Timestamp at which the collated response was generated */ + timestamp: Date, + /** Array of AppIdentifiers or DesktopAgentIdentifiers for responses + * that were not returned to the bridge before the timeout or because + * an error occurred. May be omitted if all sources responded without + * errors. MUST include the `desktopAgent` field when returned by the + * bridge. */ + errorSources?: (AppIdentifier | DesktopAgentIdentifier)[], + /** Array of error message strings for responses that were not returned + * to the bridge before the timeout or because an error occurred. + * Should be the same length as the `errorSources` array and ordered the + * same. */ + errorDetails?: string[] + } +} +``` + +**Error Response Schema**: [https://fdc3.finos.org/schemas/2.1/bridging/bridgeErrorResponse.schema.json](/schemas/2.1/bridging/bridgeErrorResponse.schema.json) + +### Identifying Individual Messages + +There are a variety of message types that need to be sent between bridged Desktop Agents, several of which will need to be replied to specifically (e.g. a `fdc3.raiseIntent` call should receive an `IntentResolution` when an app has been chosen, and may subsequently receive an `IntentResult` after the intent handler has run). Hence, messages also need a unique identity, which should be generated at the Desktop Agent that is the source of that message, in the form of a Universally Unique Identifier (UUID). Response messages will include the identity of the request message they are related to, allowing multiple message exchanges to be 'in-flight' at the same time. + +Hence, whenever a request message is generated by a Desktop Agent it should contain a unique `meta.requestUuid` value. Response messages should quote that same value in the `meta.requestUuid` field and generate a further unique identity for their response, which is included in the `meta.responseUuid` field. Where a response is collated by the Desktop Agent Bridge, the Bridge should generate its own `meta.responseUuid` for the collated response message. + +Desktop Agent Bridge implementations should consider request messages that omit `meta.requestUuid` and response messages that omit either `meta.requestUuid` or `meta.responseUuid` to be invalid and should discard them. + +#### Universally Unique Identifier + +A UUID (Universally Unique IDentifier), also known as a Globally Unique IDentifier (GUID), is a generated 128-bit text string that is intended to be 'unique across space and time', as defined in [IETF RFC 4122](https://www.ietf.org/rfc/rfc4122.txt). + +There are several types of UUIDs, which vary how they are generated. As Desktop Agents will typically be running on the same machine, system clock and hardware details may not provide sufficient uniqueness in UUIDs generated (including during the connect step, where Desktop Agent name collisions may exist). Hence, it is recommended that both Desktop Agents and Desktop Agent Bridges SHOULD use a version 4 generation type (random). + +### Identifying Desktop Agents Identity and Message Sources + +Desktop Agents will prepare messages in the above format and transmit them to the bridge. However, to target intents and perform other actions that require specific routing between DAs, DAs need to have an identity. Identities should be assigned to Desktop Agents when they connect to the bridge. This allows for multiple copies of the same underlying Desktop Agent implementation to be bridged and ensures that identity clashes can be avoided. + +To facilitate routing of messages between agents, the `AppIdentifier` is expanded to contain an optional `desktopAgent` field: + +```typescript +interface AppIdentifier { + readonly appId: string; + readonly instanceId?: string; + /** The Desktop Agent that the app is available on. Used in Desktop Agent + * Bridging to identify the Desktop Agent to target. + * @experimental Introduced in FDC3 2.1 and may be refined by further changes + * outside the normal FDC3 versioning policy. + **/ + readonly desktopAgent?: string; +} +``` + +Further, a new `DesktopAgentIdentifier` type is introduced to handle cases where a request needs to be directed to a Desktop Agent rather than a specific app, or a response message is returned by the Desktop Agent (or more specifically its resolver) rather than a specific app. This is particularly relevant for `findIntent` message exchanges: + +```typescript +/** @experimental Introduced in FDC3 2.1 and may be refined by further changes + * outside the normal FDC3 versioning policy. */ +interface DesktopAgentIdentifier { + /** Used in Desktop Agent Bridging to attribute or target a message to a + * particular Desktop Agent. */ + readonly desktopAgent: string; +} +``` + +Hence, either an `AppIdentifier` or `DesktopAgentIdentifier` is used as the `meta.source` value of both request or response messages and the source Desktop Agent identity for bridging messages will always be found at `meta.source.desktopAgent`. To prevent spoofing and to simplify the implementation of clients, the source Desktop Agent identity MUST be added to (or overwritten in) each message by the bridge when received. + +A request message may include a `destination` field, set by the source Desktop Agent if the message is intended for a particular Desktop Agent (e.g. to support a `raiseIntent` call with a specified target app or app instance on a particular Desktop Agent). + +Response messages do not include a `destination` field. Instead, a Desktop Agent Bridge implementation MUST retain a record of `requestUuid` fields for request message, until the request is fully resolved, allowing them to determine the destination for the collated responses and effectively enforcing the routing policy for interactions. + +Further, the Desktop Agent Bridge should also inspect the `payload` of both request and response messages and ensure that any `AppIdentifier` objects have been augmented with the correct `desktopAgent` value for the app's host Desktop Agent (e.g. if returning responses to `findIntent`, ensure each `AppIntent.apps[]` entry includes the correct `desktopAgent` value). Further details of any such augmentation are provided in the description of each message exchange. + +### Handling of Error Responses + +The FDC3 Desktop Agent API specifies a number of error enumerations that define specific error strings that should be used as the `message` element of a JavaScript `Error` to be returned to the requesting application via a rejected promise. In the event that an Error must be returned by a Desktop Agent to the Desktop Agent Bridge, the message should be selected from the [Error enumeration](../api/ref/Errors) normally used by the corresponding FDC3 function (i.e. `OpenError` for `open` calls, `ResolveError` for `findIntent` and `raiseIntent` etc.). However, Desktop Agent Bridging does NOT require that an `Error` object is returned across the bridge as it cannot be fully recreated from its constituent fields in JavaScript. Rather, return only the specified message string in the `error` field of the `payload`, which should then be used to initialize a JavaScript `Error` on the receiving end. It is also advisable to output additional logging (in the Desktop Agent Bridge) indicating that the error was originally generated by a remote Desktop Agent and to provide the relevant details. + +For example, a `raiseIntent` targeted at an app instance that no longer exists might generate the following response from the Desktop Agent: + +```json +// e.g. agent-B -> DAB in response to a raiseIntent call +{ + "type": "raiseIntentResponse", + "payload": { + "error": "TargetInstanceUnavailable", //", + "responseUuid": "", + "timestamp": "2020-03-..." + } +} +``` + +For messages that target a specific agent, the Desktop Agent Bridge will augment the message with source information and return it to the calling agent, which will then respond to the app that made the original request. + +If all agents (or the targeted agent) return errors, then a suitable error string should be forwarded in the `payload.error` field as returned by at least one of the agents. This allows the agent that made the original request to return that error to the app that made the original API call. All agents that returned errors should be listed in the `errorSources` array and the error message strings they returned (or that were applied because they timed out) listed in the `errorDetails` array (in the same order as `errorSources`). + +However, API calls that require a collated response from all agents where at least one agent returns a successful response, will result in a successful response from the Desktop Agent Bridge (i.e. no `error` element should be included), with the agents returning errors listed in the `errorSources` array and the error message strings they returned (or that were applied because they timed out) listed in the `errorDetails` array (in the same order as `errorSources`). This allows for successful exchanges on API calls such as `fdc3.findIntent` where some agents do not have options to return and would normally respond with (for example) `ResolveError.NoAppsFound`. + +Finally, to facilitate easier debugging, errors specific to Desktop Agent Bridge are added to the Error enumerations, including: + +```typescript +enum OpenError { + ... + /** Returned if the specified Desktop Agent is not found, via a connected + Desktop Agent Bridge. */ + DesktopAgentNotFound = 'DesktopAgentNotFound', +} + +enum ResolveError { + ... + /** Returned if the specified Desktop Agent is not found, via a connected + Desktop Agent Bridge. */ + DesktopAgentNotFound = 'DesktopAgentNotFound', +} +``` + +And an error enumeration is created for errors related to bridging that may occur on any request, and are returnable through the FDC3 API. + +```typescript +enum BridgingError { + /** Returned if a Desktop Agent did not return a response, via Desktop Agent Bridging, + * within the alloted timeout. */ + ResponseTimedOut = 'ResponseToBridgeTimedOut', + /** Returned if a Desktop Agent that has been targeted by a particular request has + * been disconnected from the Bridge before a response has been received from it. */ + AgentDisconnected = 'AgentDisconnected', + /** Returned for FDC3 API calls that are specified with arguments indicating that + * a remote Desktop Agent should be targeted (e.g. raiseIntent with an app on a + * remote DesktopAgent targeted), when the local Desktop Agent is not connected to + * a bridge. */ + NotConnectedToBridge = 'NotConnectedToBridge', + /** Returned if a message to a Bridge deviates from the schema for that message + * sufficiently that it could not be processed. + */ + MalformedMessage = 'MalformedMessage' +} +``` + +### Handling Malformed Messages + +It is the Bridge's responsibility to validate all messages that flow to and from Desktop Agents. When a request message is malformed the bridge MUST send a bridge error response message with `BridgingError.MalformedMessage` error to the sender. For 'request only' message exchanges, no specific error response schema is provided. Hence, the generic [Bridge Error Response Message schema](#all-responses-are-errors) should be used for such messages (with the type set to match the request message type). + +Where responses to requests from other agents are malformed, the bridge MUST send a bridge error response message with `BridgingError.MalformedMessage` to the sender and record `BridgingError.MalformedMessage` as the error response from the responder that sent the malformed message. + +### Forwarding of Messages and Collating Responses + +When handling request messages, it is the responsibility of the Desktop Agent Bridge to: + +- Receive request messages from connected Desktop Agents. +- Augment request messages with `meta.source.desktopAgent` information (as described above). +- Forward request messages onto either a specific Desktop Agent or all other Desktop Agents. + - The bridge MUST NOT forward the request to the agent that sent the request, nor expect a reply from it. + +For message exchanges that involve responses, it is the responsibility of the Desktop Agent Bridge to: + +- Receive and collate response messages (where necessary) according the `meta.requestUuid` (allowing multiple message exchanges to be 'in-flight' at once). +- Augment response messages with `meta.source.desktopAgent` information (as described above). +- Apply a timeout to the receipt of response messages for each request. +- Produce a single collated response message (where necessary) that incorporates the output of each individual response received and has its own unique `meta.responseUuid` value. +- Deliver the collated and/or augmented response message to the source Desktop Agent that sent the request. + +Collated response messages generated by the bridge use the same format as individual response messages. + +The following pseudo-code defines how messages should be forwarded or collated by the bridge: + +- **if** the message is a request (`meta.requestUuid` is set, but `meta.responseUuid` is not), + - **if** the message includes a `meta.destination` field, + - forward it to the specified destination agent, + - annotate the request as requiring only a response from the specified agent, + - await the response or the specified timeout. + - **else** + - forward it to all other Desktop Agents (not including the source), + - annotate the request as requiring responses from all other connected agents, + - await responses or the specified timeout. +- **else if** the message is a response (both `meta.requestUuid` and `meta.responseUuid` are set) + - **if** the `meta.requestUuid` is known, + - augment any `AppIdentifier` types in the response message with a `desktopAgent` field matching that of the responding Desktop Agent, + - **if** `payload.error` is set in the response add the DesktopAgentIdentifier to the `meta.errorSources` element. + - **else** + - add the DesktopAgentIdentifier to the `meta.sources` element. + - **if** the message exchange requires collation, + - add the message to the collated responses for the request, + - **if** all expected responses have been received (i.e. all connected agents or the specified agent has responded, as appropriate), + - produce the collated response message and return to the requesting Desktop Agent. + - **else** + - await the configured response timeout or further responses, + - **if** the timeout is reached without any responses being received + - produce and return an appropriate [error response](../api/ref/Errors), including details of all Desktop Agents in `errorSources` and the `BridgingError.ResponseTimeOut` message for each in the `errorDetails` array. + - log the timeout for each Desktop Agent that did not respond and check disconnection criteria. + - **else if** the timeout is reached with a partial set of responses, + - produce and return, to requesting Desktop Agent, a collated response and include details of Desktop Agents that timed out in `errorSources` and the `BridgingError.ResponseTimeOut` message for each in the `errorDetails` array. + - log the timeout for each Desktop Agent that did not respond and check disconnection criteria. + - **else** + - forward the response message on to requesting Desktop Agent. + - **else** + - discard the response message (as it is a delayed to a request that has timed out or is otherwise invalid). +- **else** + - the message is invalid and should be discarded. + +### Workflows Broken By Disconnects + +Targeted request and request/response workflows may be broken when a Desktop Agent disconnects from the bridge, which bridge implementations will need to handle. + +Three types of requests: + +1. Fire and forget (i.e. `broadcast`). +2. Requests that require the bridge to collate multiple responses from the bridged Desktop Agents (e.g. `findIntent`). +3. Requests targeted at a specific Desktop Agent that are forwarded to the target Desktop Agent (e.g. `raiseIntent`). + +The latter two types embody workflows that may be broken by an agent disconnecting from the bridge either before or during the processing of the request. + +When processing the disconnection of an agent from the bridge, the bridge MUST examine requests currently 'in-flight' and: + +- For requests that require the bridge to collate multiple responses: + - add the disconnected Desktop Agent's details to the `errorSources` array in the response and the `BridgingError.AgentDisconnected` message to the `errorDetails` array. + - complete requests that no longer require further responses (all other agents have responded), or + - continue to await the timeout (if other agents are yet to respond), or + - return an 'empty' response in the expected format (if no other agents are connected and no data will be received). +- For requests that target a specific agent: + - return the `BridgingError.AgentDisconnected` in the response's `payload.error` field (as the request cannot be completed). + +Finally, in the event that either a Desktop Agent or the bridge itself stops responding, but doesn't fully disconnect, the timeouts (specified earlier in this document) will be used to handle the request as if a disconnection had occurred. + +In the event that a Desktop Agent repeatedly times out, the bridge SHOULD disconnect that agent (and update other agents via the `connectedAgentsUpdate` message specified in the connection protocol), to avoid all requests requiring the full timeout to complete. + +In the event that the bridge repeatedly times out, connected Desktop Agents MAY disconnect from the bridge and attempt to reconnect by returning to Step 1 of the connection protocol. + +### Individual message exchanges + +Individual message exchanges are defined for each of the Desktop Agent methods that require bridging in the reference section of this Part. + +Each section assumes that we have 3 agents connected by a bridge (itself denoted by `DAB` in diagrams): + +- agent-A (denoted by `DA A` in diagrams) +- agent-B (denoted by `DA A` in diagrams) +- agent-C (denoted by `DA A` in diagrams) + +Message exchanges come in a number of formats, which are known as: + +- **Request only**: A request message that does not require a response ('fire and forget'), such as a [`broadcast`](ref/broadcast). +- **Request Response (single)**: A request message that expects a single response from a single Desktop Agent, such as `open` or `getAppMetadata`. +- **Request Response (collated)**: A request message that expects responses from all other Desktop Agents that are collated by the bridge and returned as a single response to the requestor, such as `findIntent` or `findInstances`. +- **Request Multiple Response (single)**: A request message that expects multiple responses from a single Desktop Agent, such as `raiseIntent`. + +The message exchanges defined are: + +- [`broadcast`](ref/broadcast) +- [`findInstances`](ref/findInstances) +- [`findIntent`](ref/findIntent) +- [`findIntentsByContext`](ref/findIntentsByContext) +- [`getAppMetadata`](ref/getAppMetadata) +- [`open`](ref/open) +- [`raiseIntent`](ref/raiseIntent) +- [`PrivateChannel.broadcast`](ref/PrivateChannel.broadcast) +- [`PrivateChannel.eventListenerAdded`](ref/PrivateChannel.eventListenerAdded) +- [`PrivateChannel.eventListenerRemoved`](ref/PrivateChannel.eventListenerRemoved) +- [`PrivateChannel.onAddContextListener`](ref/PrivateChannel.onAddContextListener) +- [`PrivateChannel.onUnsubscribe`](ref/PrivateChannel.onUnsubscribe) +- [`PrivateChannel.onDisconnect`](ref/PrivateChannel.onDisconnect) + +#### PrivateChannels + +`PrivateChannels` are intended to provide a private communication channel for applications. In order to do so, there are differences in how their broadcasts and event messages (used to manage the channel's lifecycle) MUST be handled. + +Broadcasts and event messages should be addressed to the Desktop Agent that created the channel, which will route it to the relevant application and any other listeners. If any of those listeners are remote, the message should be repeated back to the bridge, once for each listener with the destination set as a full `AppIdentifier`. Both these messages and broadcast messages MUST NOT be repeated back to the application that generated them. The source information on repeated messages should be unmodified to ensure that the message is attributed to the original source. + +To facilitate the addressing of messages to the relevant Desktop Agent and `AppIdentifier` some additional tracking of private channel metadata is necessary in each Desktop Agent (or Desktop Agent Bridge Client implementation). For applications receiving a private channel as an `IntentResult`, the `AppIdentifier` with `desktopAgent` field MUST be tracked against the private channel's id. This data MUST be retained until the receiving application sends a `disconnect` message, after which it can be discarded. For applications that have created and returned a private channel, and have subsequently received event messages subscriptions (`onAddContextListener`, `onSubscribe`, `onDisconnect`) the `appIdentifier` with `desktopAgent` field MUST be tracked against the private channel's id and listener type, which will facilitate repeating of messages to registered listeners. This data MUST be retained until the remote application sends a `disconnect` message or a message indicating that the listener has been removed. + +#### FDC3 API calls that do NOT generate bridge messages + +Some FDC3 API calls can be handled locally and do not need to generate request messages to the Desktop Agent Bridge, but are likely to be involved in other exchanges that do generate messages to the bridge (for example adding context or intent handlers). Those calls include: + +- `addContextListener` functions (excluding those for `PrivateChannel` instances) +- `listener.unsubscribe` (excluding those for `PrivateChannel` instances) +- `addIntentListener` +- `getOrCreateChannel` +- `createPrivateChannel` +- `getUserChannels` and `getSystemChannels` +- `joinUserChannel` and `joinChannel` +- `getCurrentChannel` +- `leaveCurrentChannel` +- `getInfo` + +However, `PrivateChannel` instances allow the registration of additional event handlers (for the addition or removal of context listeners) that may be used to manage streaming data sent over them by starting or stopping the stream in response to those events. Hence, the following calls DO generate request messages when used on a PrivateChannel instance: + +- `addContextListener` +- `listener.unsubscribe` +- `disconnect` + +#### Message Schemas and generated sources + +JSONSchema definitions are provided for all Desktop Agent Bridging message exchanges (see links in each reference page), which may be used to validate the correct generation of messages to or from a bridge (a separate schema is provided for the agent and bridge versions of each message). + +The JSONSchema definitions are also used to generate TypeScript interfaces for the messages to aid in implementation of a Desktop Agent Bridge or client library. These may be imported from the FDC3 npm module: + +```typescript +import { BridgingTypes } from "@finos/fdc3"; +const aMessage: BridgingTypes.BroadcastAgentRequest +``` + +or + +```typescript +import { BroadcastAgentRequest } from "@finos/fdc3/dist/bridging/BridgingTypes"; +const aMessage: BroadcastAgentRequest +``` + +Sources may also be generated from the JSONSchema files for other languages. diff --git a/website/versioned_docs/version-2.1/api/ref/Channel.md b/website/versioned_docs/version-2.1/api/ref/Channel.md new file mode 100644 index 000000000..0bd65aefb --- /dev/null +++ b/website/versioned_docs/version-2.1/api/ref/Channel.md @@ -0,0 +1,229 @@ +--- +id: Channel +sidebar_label: Channel +title: Channel +hide_title: true +--- +# `Channel` + +Represents a context channel that applications can join to share context data and provides functions for interacting with it. + +A channel can be either a ["User" channel](../spec#joining-user-channels) (retrieved with [`getUserChannels`](DesktopAgent#getuserchannels)), a custom ["App" channel](../spec#app-channels) (obtained through [`getOrCreateChannel`](DesktopAgent#getorcreatechannel)) or a ["Private" channel](../spec#private-channels) (obtained via an intent result). + +:::note + +There are differences in behavior when you interact with a User channel via the Desktop Agent interface and the Channel interface. Specifically, when 'joining' a User channel or adding a context listener when already joined to a channel via the `DesktopAgent` interface, existing context (matching the type of the context listener) on the channel is received by the context listener immediately. Whereas, when add a context listener via the Channel interface, context is not received automatically, but may be retrieved manually via the [`getCurrentContext()`](#getcurrentcontext) function. + +::: + +Channels each have a unique identifier, some display metadata and operations for broadcasting context to other applications, or receiving context from other applications. + +```ts +interface Channel { + // properties + id: string; + type: "user" | "app" | "private"; + displayMetadata?: DisplayMetadata; + + // functions + broadcast(context: Context): Promise; + getCurrentContext(contextType?: string): Promise; + addContextListener(contextType: string | null, handler: ContextHandler): Promise; + + //deprecated functions + /** + * @deprecated Use `addContextListener(null, handler)` instead of `addContextListener(handler)` + */ + addContextListener(handler: ContextHandler): Promise; +} +``` + +**See also:** + +- [`Context`](Types#context) +- [`Listener`](Types#listener) +- [`DesktopAgent.getUserChannels`](DesktopAgent#getuserchannels) +- [`DesktopAgent.getOrCreateChannel`](DesktopAgent#getorcreatechannel) +- [`DesktopAgent.joinUserChannel`](DesktopAgent#joinuserchannel) + +## Properties + +### `id` + +```ts +public readonly id: string; +``` + +Uniquely identifies the channel. It is either assigned by the desktop agent (User Channel) or defined by an application (App Channel). + +### `type` + +```ts +public readonly type: "user" | "app" | "private"; +``` + +Can be _user_, _app_ or _private_. + +### `displayMetadata` + +```ts +public readonly displayMetadata?: DisplayMetadata; +``` + +DisplayMetadata can be used to provide display hints for User Channels intended to be visualized and selectable by end users. + +**See also:** + +- [`DisplayMetadata`](Metadata#displaymetadata) + +## Functions + +### `addContextListener` + +```ts +public addContextListener(contextType: string | null, handler: ContextHandler): Promise; +``` + +Adds a listener for incoming contexts of the specified _context type_ whenever a broadcast happens on this channel. + +If, when this function is called, the channel already contains context that would be passed to the listener it is NOT called or passed this context automatically (this behavior differs from that of the [`fdc3.addContextListener`](DesktopAgent#addcontextlistener) function). Apps wishing to access to the current context of the channel should instead call the [`getCurrentContext(contextType)`](#getcurrentcontext) function. + +Optional metadata about each context message received, including the app that originated the message, SHOULD be provided by the desktop agent implementation. + +**Examples:** + +Add a listener for any context that is broadcast on the channel: + +```ts +const listener = await channel.addContextListener(null, context => { + if (context.type === 'fdc3.contact') { + // handle the contact + } else if (context.type === 'fdc3.instrument') => { + // handle the instrument + } +}); + +// later +listener.unsubscribe(); +``` + +Adding listeners for specific types of context that is broadcast on the channel: + +```ts +const contactListener = await channel.addContextListener('fdc3.contact', contact => { + // handle the contact +}); + +const instrumentListener = await channel.addContextListener('fdc3.instrument', instrument => { + // handle the instrument +}); + +// later +contactListener.unsubscribe(); +instrumentListener.unsubscribe(); +``` + +**See also:** + +- [`Listener`](Types#listener) +- [`ContextHandler`](Types#contexthandler) +- [`broadcast`](#broadcast) +- [`getCurrentContext`](#getcurrentcontext) + +### `broadcast` + +```typescript +public broadcast(context: Context): Promise; +``` + +Broadcasts a context on the channel. This function can be used without first joining the channel, allowing applications to broadcast on both App Channels and User Channels that they aren't a member of. + +If the broadcast is denied by the channel or the channel is not available, the promise will be rejected with an `Error` with a `message` string from the [`ChannelError`](Errors#channelerror) enumeration. + +Channel implementations should ensure that context messages broadcast by an application on a channel should not be delivered back to that same application if they are joined to the channel. + +If you are working with complex context types composed of other simpler types (as recommended by the [FDC3 Context Data specification](../../context/spec#assumptions)) then you should broadcast each individual type (starting with the simpler types, followed by the complex type) that you want other apps to be able to respond to. Doing so allows applications to filter the context types they receive by adding listeners for specific context types. + +If an application attempts to broadcast an invalid context argument the Promise returned by this function should reject with the [`ChannelError.MalformedContext` error](Errors#channelerror). + +**Example:** + +```javascript +const instrument = { + type: 'fdc3.instrument', + id: { + ticker: 'AAPL' + } +}; + +try { + channel.broadcast(instrument); +} catch (err: ChannelError) { + // handle error +} +``` + +**See also:** + +- [`ChannelError`](Errors#channelerror) +- [`getCurrentContext`](#getcurrentcontext) +- [`addContextListener`](#addcontextlistener) + +### `getCurrentContext` + +```ts +public getCurrentContext(contextType?: string): Promise; +``` + +When a _context type_ is provided, the most recent context matching the type will be returned, or `null` if no matching context is found. + +If no _context type_ is provided, the most recent context that was broadcast on the channel - regardless of type - will be returned. If no context has been set on the channel, it will return `null`. + +It is up to the specific Desktop Agent implementation whether and how recent contexts are stored. For example, an implementation could store context history for a channel in a single array and search through the array for the last context matching a provided type, or context could be maintained as a dictionary keyed by context types. An implementation could also choose not to support context history, in which case this method will return `null` for any context type not matching the type of the most recent context. + +If getting the current context fails, the promise will be rejected with an `Error` with a `message` string from the [`ChannelError`](Errors#channelerror) enumeration. + +**Examples:** + +Without specifying a context type: + +```ts +try { + const context = await channel.getCurrentContext(); +} catch (err: ChannelError) { + // handle error +} +``` + +Specifying a context type: + +```ts +try { + const contact = await channel.getCurrentContext('fdc3.contact'); +} catch (err: ChannelError) { + // handler error +} +``` + +**See also:** + +- [`ChannelError`](Errors#channelerror) +- [`broadcast`](#broadcast) +- [`addContextListener`](#addcontextlistener) + +## Deprecated Functions + +### `addContextListener` (deprecated) + +```ts +/** + * @deprecated Use `addContextListener(null, handler)` instead of `addContextListener(handler)` + */ +public addContextListener(handler: ContextHandler): Promise; +``` + +Adds a listener for incoming contexts whenever a broadcast happens on the channel. + +**See also:** + +- [`addContextListener`](#addcontextlistener) diff --git a/website/versioned_docs/version-2.1/api/ref/DesktopAgent.md b/website/versioned_docs/version-2.1/api/ref/DesktopAgent.md new file mode 100644 index 000000000..991047cb5 --- /dev/null +++ b/website/versioned_docs/version-2.1/api/ref/DesktopAgent.md @@ -0,0 +1,805 @@ +--- +id: DesktopAgent +sidebar_label: DesktopAgent +title: DesktopAgent +hide_title: true +--- +# `DesktopAgent` + +An FDC3 Desktop Agent is a desktop component (or aggregate of components) that serves as an orchestrator for applications in its domain. + +A Desktop Agent can be connected to one or more App Directories and will use directories for application identity and discovery. Typically, a Desktop Agent will contain the proprietary logic of a given platform, handling functionality like explicit application interop workflows where security, consistency, and implementation requirements are proprietary. + +It is expected that the `DesktopAgent` interface is made available via the [`window.fdc3`](Globals#windowfdc3-object) global object, and that the [`fdc3Ready`](Globals#fdc3ready-event) event fires when it is ready to be used. + +```ts +interface DesktopAgent { + // apps + open(app: AppIdentifier, context?: Context): Promise; + findInstances(app: AppIdentifier): Promise>; + getAppMetadata(app: AppIdentifier): Promise; + + // context + broadcast(context: Context): Promise; + addContextListener(contextType: string | null, handler: ContextHandler): Promise; + + // intents + findIntent(intent: string, context?: Context, resultType?: string): Promise; + findIntentsByContext(context: Context, resultType?: string): Promise>; + raiseIntent(intent: string, context: Context, app?: AppIdentifier): Promise; + raiseIntentForContext(context: Context, app?: AppIdentifier): Promise; + addIntentListener(intent: string, handler: IntentHandler): Promise; + + // channels + getOrCreateChannel(channelId: string): Promise; + createPrivateChannel(): Promise; + getUserChannels(): Promise>; + + // OPTIONAL channel management functions + joinUserChannel(channelId: string) : Promise; + getCurrentChannel() : Promise; + leaveCurrentChannel() : Promise; + + //implementation info + getInfo(): Promise; + + //Deprecated functions + addContextListener(handler: ContextHandler): Promise; + getSystemChannels(): Promise>; + joinChannel(channelId: string) : Promise; + open(name: string, context?: Context): Promise; + raiseIntent(intent: string, context: Context, name: string): Promise; + raiseIntentForContext(context: Context, name: string): Promise; +} +``` + +## Functions + +### `addContextListener` + +```ts +addContextListener(contextType: string | null, handler: ContextHandler): Promise; +``` + +Adds a listener for incoming context broadcasts from the Desktop Agent (via a User channel or [`fdc3.open`](#open) API call). If the consumer is only interested in a context of a particular type, they can specify that type. If the consumer is able to receive context of any type or will inspect types received, then they can pass `null` as the `contextType` parameter to receive all context types. + +Context broadcasts are primarily received from apps that are joined to the same User Channel as the listening application, hence, if the application is not currently joined to a User Channel no broadcasts will be received from channels. If this function is called after the app has already joined a channel and the channel already contains context that would be passed to the context listener, then it will be called immediately with that context. + +Context may also be received via this listener if the application was launched via a call to [`fdc3.open`](#open), where context was passed as an argument. In order to receive this, applications SHOULD add their context listener as quickly as possible after launch, or an error MAY be returned to the caller and the context may not be delivered. The exact timeout used is set by the Desktop Agent implementation, but MUST be at least 15 seconds. + +Optional metadata about each context message received, including the app that originated the message, SHOULD be provided by the Desktop Agent implementation. + +**Examples:** + +```js +// any context +const listener = await fdc3.addContextListener(null, context => { ... }); + +// listener for a specific type +const contactListener = await fdc3.addContextListener('fdc3.contact', contact => { ... }); + +// listener that logs metadata for the message a specific type +const contactListener = await fdc3.addContextListener('fdc3.contact', (contact, metadata) => { + console.log(`Received context message\nContext: ${contact}\nOriginating app: ${metadata?.source}`); + //do something else with the context +}); +``` + +**See also:** + +- [`Listener`](Types#listener) +- [`Context`](Types#context) +- [`ContextHandler`](Types#contexthandler) + +### `addIntentListener` + +```ts +addIntentListener(intent: string, handler: IntentHandler): Promise; +``` + +Adds a listener for incoming intents raised by other applications, via calls to [`fdc3.raiseIntent`](#raiseintent) or [`fdc3.raiseIntentForContext`](#raiseintentforcontext). If the application is intended to be launched to resolve raised intents, it SHOULD add its intent listeners as quickly as possible after launch or an error MAY be returned to the caller and the intent and context may not be delivered. The exact timeout used is set by the Desktop Agent implementation, but MUST be at least 15 seconds. + +The handler function may return void or a promise that resolves to a [`IntentResult`](Types#intentresult), which is either a [`Context`](Types#context) object, representing any data that should be returned to the app that raised the intent, or a [`Channel`](Channel), a [`PrivateChannel`](PrivateChannel) over which data responses will be sent, or `void`. The `IntentResult` will be returned to the app that raised the intent via the [`IntentResolution`](Metadata#intentresolution) and retrieved from it using the `getResult()` function. + +The Desktop Agent MUST reject the promise returned by the `getResult()` function of `IntentResolution` if any of the following is true: + +1. The intent handling function's returned promise rejects. +2. The intent handling function returns something other than a promise. +3. The returned promise resolves to an invalid type. + +The [`PrivateChannel`](PrivateChannel) type is provided to support synchronization of data transmitted over returned channels, by allowing both parties to listen for events denoting subscription and unsubscription from the returned channel. `PrivateChannels` are only retrievable via raising an intent. + +Optional metadata about each intent & context message received, including the app that originated the message, SHOULD be provided by the desktop agent implementation. + +**Examples:** + +```js +//Handle a raised intent +const listener = fdc3.addIntentListener('StartChat', context => { + // start chat has been requested by another application + return; +}); + +//Handle a raised intent and log the originating app metadata +const listener = fdc3.addIntentListener('StartChat', (contact, metadata) => { + console.log(`Received intent StartChat\nContext: ${contact}\nOriginating app: ${metadata?.source}`); + return; +}); + +//Handle a raised intent and return Context data via a promise +fdc3.addIntentListener("CreateOrder", (context) => { + return new Promise((resolve) => { + // go create the order + resolve({type: "fdc3.order", id: { "orderId": 1234}}); + }); +}); + +//Handle a raised intent and return a PrivateChannel over which response will be sent +fdc3.addIntentListener("QuoteStream", async (context) => { + const channel: PrivateChannel = await fdc3.createPrivateChannel(); + const symbol = context.id.symbol; + + // Called when the remote side adds a context listener + const addContextListener = channel.onAddContextListener((contextType) => { + // broadcast price quotes as they come in from our quote feed + feed.onQuote(symbol, (price) => { + channel.broadcast({ type: "price", price}); + }); + }); + + // Stop the feed if the remote side closes + const disconnectListener = channel.onDisconnect(() => { + feed.stop(symbol); + }); + + return channel; +}); +``` + +**See also:** + +- [Register an Intent Handler](../spec#register-an-intent-handler) +- [`PrivateChannel`](PrivateChannel) +- [`Listener`](Types#listener) +- [`Context`](Types#context) +- [`IntentHandler`](Types#intenthandler) + +### `broadcast` + +```ts +broadcast(context: Context): Promise; +``` + +Publishes context to other apps on the desktop. Calling `broadcast` at the `DesktopAgent` scope will push the context to whatever _User Channel_ the app is joined to. If the app is not currently joined to a channel, calling `fdc3.broadcast` will have no effect. Apps can still directly broadcast and listen to context on any channel via the methods on the `Channel` class. + +DesktopAgent implementations SHOULD ensure that context messages broadcast to a channel by an application joined to it are not delivered back to that same application. + +If you are working with complex context types composed of other simpler types (as recommended by the [Context Data specification](../../context/spec#assumptions)) then you should broadcast each individual type (starting with the simpler types, followed by the complex type) that you want other apps to be able to respond to. Doing so allows applications to filter the context types they receive by adding listeners for specific context types. + +If an application attempts to broadcast an invalid context argument the Promise returned by this function should reject with the [`ChannelError.MalformedContext` error](Errors#channelerror). + +**Example:** + +```js +const instrument = { + type: 'fdc3.instrument', + id: { + ticker: 'AAPL' + } +}; + +fdc3.broadcast(instrument); +``` + +**See also:** + +- [addContextListener](#addcontextlistener) + +### `createPrivateChannel` + +```ts +createPrivateChannel(): Promise; +``` + +Returns a `Channel` with an auto-generated identity that is intended for private communication between applications. Primarily used to create channels that will be returned to other applications via an IntentResolution for a raised intent. + +If the `PrivateChannel` cannot be created, the returned promise MUST be rejected with an `Error` object with a `message` chosen from the [`ChannelError`](Errors#channelerror) enumeration. + +The `PrivateChannel` type is provided to support synchronization of data transmitted over returned channels, by allowing both parties to listen for events denoting subscription and unsubscription from the returned channel. `PrivateChannels` are only retrievable via raising an intent. + +It is intended that Desktop Agent implementations: + +- SHOULD restrict external apps from listening or publishing on this channel. +- MUST prevent `PrivateChannels` from being retrieved via fdc3.getOrCreateChannel. +- MUST provide the `id` value for the channel as required by the `Channel` interface. + +**Example:** + +```js +fdc3.addIntentListener("QuoteStream", async (context) => { + const channel = await fdc3.createPrivateChannel(); + const symbol = context.id.ticker; + + // This gets called when the remote side adds a context listener + const addContextListener = channel.onAddContextListener((contextType) => { + // broadcast price quotes as they come in from our quote feed + feed.onQuote(symbol, (price) => { + channel.broadcast({ type: "price", price}); + }); + }); + + // This gets called when the remote side calls Listener.unsubscribe() + const unsubscribeListener = channel.onUnsubscribe((contextType) => { + feed.stop(symbol); + }); + + // This gets called if the remote side closes + const disconnectListener = channel.onDisconnect(() => { + feed.stop(symbol); + }); + + return channel; +}); +``` + +**See also:** + +- [`PrivateChannel`](PrivateChannel) +- [`raiseIntent`](#raiseintent) +- [`addIntentListener`](#addintentlistener) + +### `findInstances` + +```ts +findInstances(app: AppIdentifier): Promise>; +``` + +Find all the available instances for a particular application. + +If the application is not known to the agent, the returned promise should be rejected with the `ResolverError.NoAppsFound` error message. However, if the application is known but there are no instances of the specified app the returned promise should resolve to an empty array. + +If the request fails for another reason, the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration, or (if connected to a Desktop Agent Bridge) the [`BridgingError`](Errors#bridgingerror) enumeration. + +**Example:** + +```js +// Retrieve a list of instances of an application +let instances = await fdc3.findInstances({appId: "MyAppId"}); + +// Target a raised intent at a specific instance +let resolution = fdc3.raiseIntent("ViewInstrument", context, instances[0]); +``` + +### `findIntent` + +```ts +findIntent(intent: string, context?: Context, resultType?: string): Promise; +``` + +Find out more information about a particular intent by passing its name, and optionally its context and/or a desired result context type. + +`findIntent` is effectively granting programmatic access to the Desktop Agent's resolver. +It returns a promise resolving to an `AppIntent` which provides details of the intent, its metadata and metadata about the apps and app instances that are registered to handle it. This can be used to raise the intent against a specific app or app instance. + +If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration, or (if connected to a Desktop Agent Bridge) the [`BridgingError`](Errors#bridgingerror) enumeration. This includes the case where no apps are found that resolve the intent, when the [`ResolveError.NoAppsFound`](Errors#resolveerror) message should be used, and when an invalid context object is passed as an argument, when the [`ResolveError.MalformedContext`](Errors#resolveerror) message should be used. + +Result types may be a type name, the string `"channel"` (which indicates that the app will return a channel) or a string indicating a channel that returns a specific type, e.g. `"channel"`. If intent resolution to an app returning a channel is requested, the desktop agent MUST include both apps that are registered as returning a channel and those registered as returning a channel with a specific type in the response. + +**Examples:** + +I know 'StartChat' exists as a concept, and want to know which apps can resolve it: + +```js +const appIntent = await fdc3.findIntent("StartChat"); +// returns a single AppIntent: +// { +// intent: { name: "StartChat" }, +// apps: [ +// { appId: "Skype" }, +// { appId: "Symphony" }, +// { appId: "Slack" } +// ] +// } + +// raise the intent against a particular app +await fdc3.raiseIntent(appIntent.intent.name, context, appIntent.apps[0]); + +//later, we want to raise 'StartChat' intent again +const appIntent = await fdc3.findIntent("StartChat"); +// returns an AppIntent, but with multiple options for resolution, +// which includes an existing instance of an application: +// { +// intent: { name: "StartChat" }, +// apps: [ +// { appId: "Skype" }, +// { appId: "Symphony" }, +// { appId: "Symphony", instanceId: "93d2fe3e-a66c-41e1-b80b-246b87120859" }, +// { appId: "Slack" } +// ] +``` + +An optional input context object and/or `resultType` argument may be specified, which the resolver MUST use to filter the returned applications such that each supports the specified input and result types. + +```js +const appIntent = await fdc3.findIntent("StartChat", contact); + +// returns only apps that support the type of the specified input context: +// { +// intent: { name: "StartChat" }, +// apps: { name: "Symphony" }] +// } + +const appIntent = await fdc3.findIntent("ViewContact", "fdc3.ContactList"); +// returns only apps that return the specified result type: +// { +// intent: { name: "ViewContact" }, +// apps: { appId: "MyCRM", resultType: "fdc3.ContactList"}] +// } + +const appIntent = await fdc3.findIntent("QuoteStream", instrument, "channel"); +// returns only apps that return a channel which will receive the specified input and result types: +// { +// intent: { name: "QuoteStream" }, +// apps: { appId: "MyOMS", resultType: "channel"}] +// } +``` + +**See also:** + +- [`ResolveError`](Errors#resolveerror) + +### `findIntentsByContext` + +```ts +findIntentsByContext(context: Context, resultType?: string): Promise>; +``` + +Find all the available intents for a particular context, and optionally a desired result context type. + +`findIntentsByContext` is effectively granting programmatic access to the Desktop Agent's resolver. +A promise resolving to all the intents, their metadata and metadata about the apps and app instances that registered as handlers is returned, based on the context types the intents have registered. + +If the resolution fails, the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration, or (if connected to a Desktop Agent Bridge) the [`BridgingError`](Errors#bridgingerror) enumeration. This includes the case where no intents with associated apps are found, when the `ResolveError.NoAppsFound` message should be used, and when an invalid context object is passed as an argument, when the [`ResolveError.MalformedContext`](Errors#resolveerror) message should be used. + +The optional `resultType` argument may be a type name, the string `"channel"` (which indicates that the app will return a channel) or a string indicating a channel that returns a specific type, e.g. `"channel"`. If intent resolution to an app returning a channel is requested without a specified context type, the desktop agent MUST include both apps that are registered as returning a channel and those registered as returning a channel with a specific type in the response. + +**Example:** + +I have a context object, and I want to know what I can do with it, hence, I look for intents and apps to resolve them... + +```js +const appIntents = await fdc3.findIntentsByContext(context); + +// returns, for example: +// [ +// { +// intent: { name: "StartCall" }, +// apps: [{ appId: "Skype" }] +// }, +// { +// intent: { name: "StartChat" }, +// apps: [ +// { appId: "Skype" }, +// { appId: "Symphony" }, +// { appId: "Symphony", instanceId: "93d2fe3e-a66c-41e1-b80b-246b87120859" }, +// { appId: "Slack" } +// ] +// }, +// { +// intent: { name: "ViewContact" }, +// apps: [{ appId: "Symphony" }, { appId: "MyCRM", resultType: "fdc3.ContactList"}] +// } +// ]; +``` + +or I look for only intents that are resolved by apps returning a particular result type + +```js +const appIntentsForType = await fdc3.findIntentsByContext(context, "fdc3.ContactList"); +// returns for example: +// [{ +// intent: { name: "ViewContact" }, +// apps: [{ appId: "Symphony" }, { appId: "MyCRM", resultType: "fdc3.ContactList"}] +// }]; + +// select a particular intent to raise +const startChat = appIntents[1]; + +// target a particular app or instance +const selectedApp = startChat.apps[2]; + +// raise the intent, passing the given context, targeting the app +await fdc3.raiseIntent(startChat.intent.name, context, selectedApp); +``` + +**See also:** + +- [`findIntent()`](#findintent) +- [`ResolveError`](Errors#resolveerror) + +### `getAppMetadata` + +```ts +getAppMetadata(app: AppIdentifier): Promise; +``` + +Retrieves the [`AppMetadata`](Metadata#appmetadata) for an [`AppIdentifier`](Types#appidentifier), which provides additional metadata (such as icons, a title and description) from the App Directory record for the application, that may be used for display purposes. + +If the app is not found, the promise MUST be rejected with an `Error` Object with the `message` given by [`ResolveError.TargetAppUnavailable`](Errors#resolveerror), or (if connected to a Desktop Agent Bridge) an error from the [`BridgingError`](Errors#bridgingerror) enumeration. + + +**Examples:** + +```js +let appIdentifier = { appId: "MyAppId@my.appd.com" } +let appMetadata = await fdc3.getAppMetadata(appIdentifier); +``` + +**See also:** + +- [`AppMetadata`](Metadata#appmetadata) +- [`AppIdentifier`](Types#appidentifier) + +### `getCurrentChannel` + +```ts +getCurrentChannel() : Promise; +``` + +OPTIONAL function that returns the `Channel` object for the current User channel membership. In most cases, an application's membership of channels SHOULD be managed via UX provided to the application by the desktop agent, rather than calling this function directly. + +Returns `null` if the app is not joined to a channel. + +**Examples:** + +```js +// get the current channel membership +let current = await fdc3.getCurrentChannel(); +``` + +**See also:** + +- [`Channel`](Channel) + +### `getInfo` + +```ts +getInfo(): Promise; +``` + +Retrieves information about the FDC3 Desktop Agent implementation, including the supported version of the FDC3 specification, the name of the provider of the implementation, its own version number, details of whether optional API features are implemented and the metadata of the calling application according to the desktop agent. + +Returns an [`ImplementationMetadata`](Metadata#implementationmetadata) object. This metadata object can be used to vary the behavior of an application based on the version supported by the Desktop Agent and for logging purposes. + +**Example:** + +```js +import {compareVersionNumbers, versionIsAtLeast} from '@finos/fdc3'; + +if (fdc3.getInfo && versionIsAtLeast(await fdc3.getInfo(), "1.2")) { + await fdc3.raiseIntentForContext(context); +} else { + await fdc3.raiseIntent("ViewChart", context); +} +``` + +The `ImplementationMetadata` object returned also includes the metadata for the calling application, according to the Desktop Agent. This allows the application to retrieve its own `appId`, `instanceId` and other details, e.g.: + +```js +let implementationMetadata = await fdc3.getInfo(); +let {appId, instanceId} = implementationMetadata.appMetadata; +``` + +**See also:** + +- [`ImplementationMetadata`](Metadata#implementationmetadata) +- [`AppMetadata`](Metadata#appmetadata) + +### `getOrCreateChannel` + +```ts +getOrCreateChannel(channelId: string): Promise; +``` + +Returns a `Channel` object for the specified channel, creating it (as an _App_ channel) if it does not exist. + +If the Channel cannot be created or access was denied, the returned promise MUST be rejected with an `Error` Object with a `message` chosen from the `ChannelError` enumeration. + +**Example:** + +```js +try { + const myChannel = await fdc3.getOrCreateChannel("myChannel"); + myChannel.addContextListener(null, context => { /* do something with context */}); +} +catch (err){ + //app could not register the channel +} +``` + +**See also:** + +- [`Channel`](Channel) + +### `getUserChannels` + +```ts +getUserChannels() : Promise>; +``` + +Retrieves a list of the User Channels available for the app to join. + +**Example:** + +```js +const userChannels = await fdc3.getUserChannels(); +const redChannel = userChannels.find(c => c.id === 'red'); +``` + +**See also:** + +- [`Channel`](Channel) + +### `joinUserChannel` + +```ts +joinUserChannel(channelId: string) : Promise; +``` + +OPTIONAL function that joins the app to the specified User channel. In most cases, applications SHOULD be joined to channels via UX provided to the application by the desktop agent, rather than calling this function directly. + +If an app is joined to a channel, all `fdc3.broadcast` calls will go to the channel, and all listeners assigned via `fdc3.addContextListener` will listen on the channel. + +If the channel already contains context that would be passed to context listeners added via `fdc3.addContextListener` then those listeners will be called immediately with that context. + +An app can only be joined to one channel at a time. + +If an error occurs (such as the channel is unavailable or the join request is denied) the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`ChannelError`](Errors#channelerror) enumeration. + +**Examples:** + +```js +// get all user channels +const channels = await fdc3.getUserChannels(); + +// create UI to pick from the User channels + +// join the channel on selection +fdc3.joinUserChannel(selectedChannel.id); + +``` + +**See also:** + +- [`getUserChannels`](#getuserchannels) + +### `leaveCurrentChannel` + +```ts +leaveCurrentChannel() : Promise; +``` + +OPTIONAL function that removes the app from any User channel membership. In most cases, an application's membership of channels SHOULD be managed via UX provided to the application by the desktop agent, rather than calling this function directly. + +Context broadcast and listening through the top-level `fdc3.broadcast` and `fdc3.addContextListener` will be a no-op when the app is not joined to a User channel. + +**Examples:** + +```js +//desktop-agent scope context listener +const fdc3Listener = fdc3.addContextListener(null, context => {}); + +await fdc3.leaveCurrentChannel(); +//the fdc3Listener will now cease receiving context + +//listening on a specific channel though, will continue to work +redChannel.addContextListener(null, channelListener); + +``` + +### `open` + +```ts +open(app: AppIdentifier, context?: Context): Promise; +``` + +Launches an app, specified via an [`AppIdentifier`](Types#appidentifier) object. + +The `open` method differs in use from [`raiseIntent`](#raiseintent). Generally, it should be used when the target application is known but there is no specific intent. For example, if an application is querying an App Directory, `open` would be used to open an app returned in the search results. + +**Note**, if the intent, context and target app name are all known, it is recommended to instead use [`raiseIntent`](#raiseintent) with the `target` argument. + +If a [`Context`](Types#context) object is passed in, this object will be provided to the opened application via a contextListener. The Context argument is functionally equivalent to opening the target app with no context and broadcasting the context directly to it. + +Returns an [`AppIdentifier`](Types#appidentifier) object with the `instanceId` field set to identify the instance of the application opened by this call. + +If an error occurs while opening the app, the promise MUST be rejected with an `Error` Object with a `message` chosen from the [`OpenError`](Errors#openerror) enumeration, or (if connected to a Desktop Agent Bridge) the [`BridgingError`](Errors#bridgingerror) enumeration. + +**Example:** + + ```js +// Open an app without context, using an AppIdentifier object to specify the target +let appIdentifier = { appId: 'myApp-v1.0.1' }; +let instanceIdentifier = await fdc3.open(appIdentifier); + +// Open an app with context +let instanceIdentifier = await fdc3.open(appIdentifier, context); +``` + +**See also:** + +- [`Context`](Types#context) +- [`AppIdentifier`](Types#appidentifier) +- [`AppMetadata`](Metadata#appmetadata) +- [`OpenError`](Errors#openerror) + +### `raiseIntent` + +```ts +raiseIntent(intent: string, context: Context, app?: AppIdentifier): Promise; +``` + +Raises a specific intent for resolution against apps registered with the desktop agent. + +The desktop agent MUST resolve the correct app to target based on the provided intent name and context data. If multiple matching apps are found, a method for resolving the intent to a target app, such as presenting the user with a resolver UI allowing them to pick an app, SHOULD be provided. +Alternatively, the specific app or app instance to target can also be provided. A list of valid target applications and instances can be retrieved via [`findIntent`](DesktopAgent#findintent). + +If a target app for the intent cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration, or (if connected to a Desktop Agent Bridge) the [`BridgingError`](Errors#bridgingerror) enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`. If an invalid context object is passed as an argument the promise MUST be rejected with an `Error` object with the [`ResolveError.MalformedContext`](Errors#resolveerror) string as its `message`. + +If you wish to raise an intent without a context, use the `fdc3.nothing` context type. This type exists so that apps can explicitly declare support for raising an intent without context. + +Returns an [`IntentResolution`](Metadata#intentresolution) object with details of the app instance that was selected (or started) to respond to the intent. + +Issuing apps may optionally wait on the promise that is returned by the `getResult()` member of the `IntentResolution`. This promise will resolve when the _receiving app's_ intent handler function returns and resolves a promise. The Desktop Agent resolves the issuing app's promise with the Context object, Channel object or void that is provided as resolution within the receiving app. The Desktop Agent MUST reject the issuing app's promise, with a string from the [`ResultError`](Errors#resulterror) enumeration, if: (1) the intent handling function's returned promise rejects, (2) the intent handling function doesn't return a valid response (a promise or void), or (3) the returned promise resolves to an invalid type. + +**Example:** + +```js +// raise an intent for resolution by the desktop agent +// a resolver UI may be displayed, or another method of resolving the intent to a +// target applied, if more than one application can resolve the intent +await fdc3.raiseIntent("StartChat", context); + +// or find apps to resolve an intent to start a chat with a given contact +const appIntent = await fdc3.findIntent("StartChat", context); + +// use the metadata of an app or app instance to describe the target app for the intent +await fdc3.raiseIntent("StartChat", context, appIntent.apps[0]); + +//Raise an intent without a context by using the null context type +await fdc3.raiseIntent("StartChat", {type: "fdc3.nothing"}); + +//Raise an intent and retrieve a result from the IntentResolution +let resolution = await agent.raiseIntent("intentName", context); +try { + const result = await resolution.getResult(); + if (result && result.broadcast) { //detect whether the result is Context or a Channel + console.log(`${resolution.source} returned a channel with id ${result.id}`); + } else if (result){ + console.log(`${resolution.source} returned data: ${JSON.stringify(result)}`); + } else { + console.error(`${resolution.source} didn't return anything` + } +} catch(error) { + console.error(`${resolution.source} returned a result error: ${error}`); +} +``` + +**See also:** + +- [Raising Intents](../spec#raising-intents) +- [`Context`](Types#context) +- [`AppIdentifier`](Types#AppIdentifier) +- [`IntentResult`](Types#intentresult) +- [`IntentResolution`](Metadata#intentresolution) +- [`ResolveError`](Errors#resolveerror) +- [`ResultError`](Errors#resulterror) + +### `raiseIntentForContext` + +```ts +raiseIntentForContext(context: Context, app?: AppIdentifier): Promise; +``` + +Finds and raises an intent against apps registered with the desktop agent based purely on the type of the context data. + +The desktop agent SHOULD first resolve to a specific intent based on the provided context if more than one intent is available for the specified context. This MAY be achieved by displaying a resolver UI. It SHOULD then resolve to a specific app to handle the selected intent and specified context. +Alternatively, the specific app or app instance to target can also be provided, in which case any method of resolution SHOULD only consider intents supported by the specified application. + +Using `raiseIntentForContext` is similar to calling `findIntentsByContext`, and then raising an intent against one of the returned apps, except in this case the desktop agent has the opportunity to provide the user with a richer selection interface where they can choose both the intent and target app. + +Returns an `IntentResolution` object, see [`raiseIntent()`](#raiseintent) for details. + +If a target intent and app cannot be found with the criteria provided or the user either closes the resolver UI or otherwise cancels resolution, the promise MUST be rejected with an `Error` object with a `message` chosen from the [`ResolveError`](Errors#resolveerror) enumeration, or (if connected to a Desktop Agent Bridge) the [`BridgingError`](Errors#bridgingerror) enumeration. If a specific target `app` parameter was set, but either the app or app instance is not available, the promise MUST be rejected with an `Error` object with either the `ResolveError.TargetAppUnavailable` or `ResolveError.TargetInstanceUnavailable` string as its `message`. If an invalid context object is passed as an argument the promise MUST be rejected with an `Error` object with the [`ResolveError.MalformedContext`](Errors#resolveerror) string as its `message`. + +**Example:** + +```js +// Display a resolver UI for the user to select an intent and application to resolve it +const intentResolution = await fdc3.raiseIntentForContext(context); + +// Resolve against all intents registered by a specific target app for the specified context +await fdc3.raiseIntentForContext(context, targetAppIdentifier); +``` + +**See also:** + +- [Raising Intents](../spec#raising-intents) +- [`raiseIntent()`](#raiseintent) +- [`Context`](Types#context) +- [`AppIdentifier`](Types#appidentifier) +- [`IntentResolution`](Metadata#intentresolution) +- [`ResolveError`](Errors#resolveerror) + +## Deprecated Functions + +### `addContextListener` (deprecated) + +```ts +addContextListener(handler: ContextHandler): Promise; +``` + +Adds a listener for incoming context broadcasts from the Desktop Agent. Provided for backwards compatibility with versions FDC3 standard <2.0. + +**See also:** + +- [`addContextListener`](#addcontextlistener) + +### `getSystemChannels` (deprecated) + +```ts +getSystemChannels() : Promise>; +``` + +Alias to the [`getUserChannels`](#getuserchannels) function provided for backwards compatibility with version 1.1 & 1.2 of the FDC3 standard. +**See also:** + +- [`getUserChannels`](#getuserchannels) + +### `joinChannel` (deprecated) + +```ts +joinChannel(channelId: string) : Promise; +``` + +Alias to the [`joinUserChannel`](#joinuserchannel) function provided for backwards compatibility with version 1.1 & 1.2 of the FDC3 standard. + +**See also:** + +- [`joinUserChannel`](#joinuserchannel) + +### `open` (deprecated) + +```ts +open(name: string, context?: Context): Promise; +``` + +Version of `open` that launches an app by name rather than `AppIdentifier`. Provided for backwards compatibility with versions of the FDC3 Standard <2.0. + +**See also:** + +- [`open`](#open) + +### `raiseIntent` (deprecated) + +```ts +raiseIntent(intent: string, context: Context, name: string): Promise; +``` + +Version of `raiseIntent` that targets an app by name rather than `AppIdentifier`. Provided for backwards compatibility with versions of the FDC3 Standard <2.0. + +**See also:** + +- [`raiseIntent`](#raiseintent) + +### `raiseIntentForContext` (deprecated) + +```ts +raiseIntentForContext(context: Context, name: string): Promise;; +``` + +Version of `raiseIntentForContext` that targets an app by name rather than `AppIdentifier`. Provided for backwards compatibility with versions of the FDC3 Standard <2.0. + +**See also:** + +- [`raiseIntentForContext`](#raiseintentforcontext) diff --git a/website/versioned_docs/version-2.1/api/ref/Errors.md b/website/versioned_docs/version-2.1/api/ref/Errors.md new file mode 100644 index 000000000..b5a9144f7 --- /dev/null +++ b/website/versioned_docs/version-2.1/api/ref/Errors.md @@ -0,0 +1,199 @@ +--- +title: Errors +--- + +FDC3 API operations may sometimes result in an error, which must be returned to the caller. Errors should be returned by rejecting the promise returned by the API with a JavaScript `Error` object (or equivalent for the language of the implementation). The `Error` Object's message should be chosen from the appropriate Error enumeration below. + +## `ChannelError` + +```typescript +enum ChannelError { + /** Returned if the specified channel is not found when attempting to join a + * channel via the `joinUserChannel` function of the DesktopAgent (`fdc3`). + */ + NoChannelFound = 'NoChannelFound', + + /** SHOULD be returned when a request to join a user channel or to a retrieve + * a Channel object via the `joinUserChannel` or `getOrCreateChannel` methods + * of the DesktopAgent (`fdc3`) object is denied. + */ + AccessDenied = 'AccessDenied', + + /** SHOULD be returned when a channel cannot be created or retrieved via the + * `getOrCreateChannel` method of the DesktopAgent (`fdc3`). + */ + CreationFailed = 'CreationFailed', + + /** Returned if a call to the `broadcast` functions is made with an invalid + * context argument. Contexts should be Objects with at least a `type` field + * that has a `string` value. + */ + MalformedContext = 'MalformedContext', +} +``` + +Contains constants representing the errors that can be encountered when calling channels using the [`joinUserChannel`](DesktopAgent#joinuserchannel) or [`getOrCreateChannel`](DesktopAgent#getorcreatechannel) methods, or the [`getCurrentContext`](Channel#getcurrentcontext), [`broadcast`](Channel#broadcast) or [`addContextListener`](Channel#addcontextlistener) methods on the `Channel` object. + +**See also:** + +- [`DesktopAgent.createPrivateChannel`](DesktopAgent#createprivatechannel) +- [`DesktopAgent.joinUserChannel`](DesktopAgent#joinuserchannel) +- [`DesktopAgent.getOrCreateChannel`](DesktopAgent#getorcreatechannel) +- [`Channel.broadcast`](Channel#broadcast) +- [`Channel.addContextListener`](Channel#addcontextlistener) +- [`Channel.getCurrentContext`](Channel#getcurrentcontext) + +## `OpenError` + +```typescript +enum OpenError { + /** Returned if the specified application is not found.*/ + AppNotFound = 'AppNotFound', + + /** Returned if the specified application fails to launch correctly.*/ + ErrorOnLaunch = 'ErrorOnLaunch', + + /** Returned if the specified application launches but fails to add a context + * listener in order to receive the context passed to the `fdc3.open` call. + */ + AppTimeout = 'AppTimeout', + + /** Returned if the FDC3 desktop agent implementation is not currently able + * to handle the request. + */ + ResolverUnavailable = 'ResolverUnavailable', + + /** Returned if a call to the `open` function is made with an invalid + * context argument. Contexts should be Objects with at least a `type` field + * that has a `string` value. + */ + MalformedContext = 'MalformedContext', + + /** @experimental Returned if the specified Desktop Agent is not found, via a connected + * Desktop Agent Bridge. */ + DesktopAgentNotFound = 'DesktopAgentNotFound', +} +``` + +Contains constants representing the errors that can be encountered when calling the [`open`](DesktopAgent#open) method on the [DesktopAgent](DesktopAgent) object. + +**See also:** + +- [`DesktopAgent.open`](DesktopAgent#open) + +## `ResolveError` + +```typescript +export enum ResolveError { + /** SHOULD be returned if no apps are available that can resolve the intent + * and context combination. + */ + NoAppsFound = 'NoAppsFound', + + /** Returned if the FDC3 desktop agent implementation is not currently able + * to handle the request. + */ + ResolverUnavailable = 'ResolverUnavailable', + + /** Returned if the user cancelled the resolution request, for example by + * closing or cancelling a resolver UI. + */ + UserCancelled = 'UserCancelledResolution', + + /** SHOULD be returned if a timeout cancels an intent resolution that + * required user interaction. Please use `ResolverUnavailable` instead for + * situations where a resolver UI or similar fails. + */ + ResolverTimeout = 'ResolverTimeout', + + /** Returned if a specified target application is not available or a new + * instance of it cannot be opened. + */ + TargetAppUnavailable = 'TargetAppUnavailable', + + /** Returned if a specified target application instance is not available, + * for example because it has been closed. + */ + TargetInstanceUnavailable = 'TargetInstanceUnavailable', + + /** Returned if the intent and context could not be delivered to the selected + * application or instance, for example because it has not added an intent + * handler within a timeout. + */ + IntentDeliveryFailed = 'IntentDeliveryFailed', + + /** Returned if a call to one of the `raiseIntent` functions is made with an + * invalid context argument. Contexts should be Objects with at least a `type` + * field that has a `string` value. + */ + MalformedContext = 'MalformedContext', + + /** @experimental Returned if the specified Desktop Agent is not found, via a connected + * Desktop Agent Bridge. */ + DesktopAgentNotFound = 'DesktopAgentNotFound', +} +``` + +Contains constants representing the errors that can be encountered when calling the [`findIntent`](DesktopAgent#findintent), [`findIntentsByContext`](DesktopAgent#findintentsbycontext), [`raiseIntent`](DesktopAgent#raiseintent) or [`raiseIntentForContext`](DesktopAgent#raiseintentforcontext) methods on the [DesktopAgent](DesktopAgent). + +**See also:** + +- [`DesktopAgent.findIntent`](DesktopAgent#findintent) +- [`DesktopAgent.findIntentsByContext`](DesktopAgent#findintentsbycontext) +- [`DesktopAgent.raiseIntent`](DesktopAgent#raiseintent) +- [`DesktopAgent.raiseIntentForContext`](DesktopAgent#raiseintentforcontext) + +## `ResultError` + +```typescript +enum ResultError { + /** Returned if the intent handler exited without returning a valid result + * (a promise resolving to a Context, Channel object or void). + */ + NoResultReturned = 'NoResultReturned', + + /** Returned if the `IntentHandler` function processing the raised intent + * throws an error or rejects the Promise it returned. + */ + IntentHandlerRejected = 'IntentHandlerRejected', +} +``` + +Contains constants representing the errors that can be encountered when calling the [`getResult`](DesktopAgent#findintent) method on the [IntentResolution](Metadata#intentresolution) Object. + +**See also:** + +- [`DesktopAgent.addIntentListener`](DesktopAgent#addintentlistener) +- [`DesktopAgent.raiseIntent`](DesktopAgent#raiseintent) +- [`IntentResolution`](Metadata#intentresolution) + +## `BridgingError` + +`@experimental` + +```typescript +enum BridgingError { + /** @experimental Returned if a Desktop Agent did not return a response, via + * Desktop Agent Bridging, within the alloted timeout. */ + ResponseTimedOut = 'ResponseToBridgeTimedOut', + /** @experimental Returned if a Desktop Agent that has been targeted by a + * particular request has been disconnected from the Bridge before a + * response has been received from it. */ + AgentDisconnected = 'AgentDisconnected', + /** @experimental Returned for FDC3 API calls that are specified with + * arguments indicating that a remote Desktop agent should be targeted + * (e.g. raiseIntent with an app on a remote DesktopAgent targeted), + * when the local Desktop Agent is not connected to a bridge. */ + NotConnectedToBridge = 'NotConnectedToBridge', + /** @experimental Returned if a message to a Bridge deviates from the schema + * for that message sufficiently that it could not be processed. + */ + MalformedMessage = 'MalformedMessage' +} +``` + +Contains constants representing the errors that can be encountered when queries are forwarded to a Desktop Agent Bridge, but one or more remote Desktop Agents connected to it disconnects, times-out or a malformed message is encountered while a particular request is in flight. These errors may be returned via the FDC3 API when a Desktop Agent is (or was) connected to a Desktop Agent Bridge. + +**See also:** + +- [Agent Bridging - Workflows broken by disconnects](../../agent-bridging/spec##workflows-broken-by-disconnects) diff --git a/website/versioned_docs/version-2.1/api/ref/Globals.md b/website/versioned_docs/version-2.1/api/ref/Globals.md new file mode 100644 index 000000000..4e419c9af --- /dev/null +++ b/website/versioned_docs/version-2.1/api/ref/Globals.md @@ -0,0 +1,64 @@ +--- +title: Globals +--- + +Since FDC3 is typically available to the whole web application, desktop agents are expected to make the [`DesktopAgent`](DesktopAgent) interface available at a global level. + +## `window.fdc3` Object + +The global `fdc3` object can be used to access FDC3 API operations, if the current desktop agent supports FDC3. + +**Example:** + +```ts +// check if fdc3 is available +if (window.fdc3) { + // raise an intent + await window.fdc3.raiseIntent('StartChat', { + type: 'fdc3.contact', + id: { email: 'johndoe@mail.com' } + }) +} +``` + +## `fdc3Ready` Event + +The global `window.fdc3` should only be available after the API is ready to use. To prevent the API from being used before it is ready, implementors should provide an `fdc3Ready` event. + +**Example:** + +```ts +function fdc3Action() { + // Make some fdc3 API calls here +} + +if (window.fdc3) { + fdc3Action(); +} else { + window.addEventListener('fdc3Ready', fdc3Action); +} +``` + +## `fdc3Ready()` Function + +If you are using the `@finos/fdc3` NPM package, it includes a handy wrapper function that will check for the existence of `window.fdc3` and wait on the `fdc3Ready` event for you. + +It returns a promise that will resolve immediately if the `window.fdc3` global is already defined, or reject with an error if the `fdc3Ready` event doesn't fire after a specified timeout period (default: 5 seconds). + +**Example:** + +```ts +import { fdc3Ready, broadcast } from '@finos/fdc3' + +async function fdc3Action() { + try { + await fdc3Ready(1000); // wait for (at most) 1 second + broadcast({ + type: 'fdc3.instrument', + id: { ticker: 'AAPL' } + }) + } catch (error) { + // handle error + } +} +``` diff --git a/website/versioned_docs/version-2.1/api/ref/Metadata.md b/website/versioned_docs/version-2.1/api/ref/Metadata.md new file mode 100644 index 000000000..c149124e5 --- /dev/null +++ b/website/versioned_docs/version-2.1/api/ref/Metadata.md @@ -0,0 +1,383 @@ +--- +title: Metadata +--- + +FDC3 API operations return various types of metadata. + +## `AppIntent` + +```ts +interface AppIntent { + /** Details of the intent whose relationship to resolving applications is + * being described. + */ + readonly intent: IntentMetadata; + + /** Details of applications that can resolve the intent. */ + readonly apps: Array; +} +``` + +An interface that represents the binding of an intent to apps, returned as part of intent discovery. +For each intent, it reference the applications that support that intent. + +**See also:** + +- [`AppMetadata`](#appmetadata) +- [`IntentMetadata`](#intentmetadata) +- [`DesktopAgent.findIntent`](DesktopAgent#findintent) +- [`DesktopAgent.findIntentsByContext`](DesktopAgent#findintentsbycontext) + +## `AppMetadata` + +```ts +interface AppMetadata extends AppIdentifier { + /** + * The 'friendly' app name. This field was used with the `open` and + * `raiseIntent` calls in FDC3 <2.0, which now require an `AppIdentifier` + * with `appId` set. + * + * Note that for display purposes the `title` field should be used, if set, + * in preference to this field. + */ + readonly name?: string; + + /** The version of the application. */ + readonly version?: string; + + /** An optional set of, implementation specific, metadata fields that can be + * used to disambiguate instances, such as a window title or screen position. + * Must only be set if `instanceId` is set. + */ + readonly instanceMetadata?: Record; + + /** A more user-friendly application title that can be used to render UI + * elements. + */ + readonly title?: string; + + /** A tooltip for the application that can be used to render UI elements. */ + readonly tooltip?: string; + + /** A longer, multi-paragraph description for the application that could + * include mark-up. + */ + readonly description?: string; + + /** A list of icon URLs for the application that can be used to render UI + * elements. + */ + readonly icons?: Array; + + /** Images representing the app in common usage scenarios that can be used to render UI elements */ + readonly screenshots?: Array; + + /** The type of result returned for any intent specified during resolution. + * May express a particular context type (e.g. "fdc3.instrument"), channel + * (e.g. "channel") or a channel that will receive a specified type + * (e.g. "channel"). + */ + readonly resultType?: string | null; +} +``` + +Extends an AppIdentifier, describing an application or instance of an application, with additional descriptive metadata that is usually provided by an FDC3 App Directory that the desktop agent connects to. + +The additional information from an app directory can aid in rendering UI elements, such as a launcher menu or resolver UI. This includes a title, description, tooltip and icon and screenshot URLs. + +Note that as `AppMetadata` instances are also `AppIdentifiers` they may be passed to the `app` argument of `fdc3.open`, `fdc3.raiseIntent` etc.. + +**See also:** + +- [`AppIdentifier`](Types#AppIdentifier) +- [`AppIntent.apps`](#appintent) +- [`Icon`](#icon) +- [`Image`](#image) +- [`DesktopAgent.open`](DesktopAgent#open) +- [`DesktopAgent.findIntent`](DesktopAgent#findintent) +- [`DesktopAgent.raiseIntent`](DesktopAgent#raiseintent) + +## `ContextMetadata` + +```ts +interface ContextMetadata { + /** Identifier for the app instance that sent the context and/or intent. + * @experimental + */ + readonly source: AppIdentifier; +} +``` + +Metadata relating to a context or intent & context received through the `addContextListener` and `addIntentListener` functions. Currently identifies the app that originated the context or intent message. + +[`@experimental`](../../fdc3-compliance#experimental-features) Introduced in FDC3 2.0 and may be refined by further changes outside the normal FDC3 versioning policy. + +**See also:** + +- [`AppMetadata`](#appmetadata) +- [`ContextHandler`](Types#contexthandler) +- [`IntentHandler`](Types#intenthandler) +- [`addIntentListener`](DesktopAgent#addintentlistener) +- [`addContextListener`](DesktopAgent#addcontextlistener) +- [`Channel.addContextListener`](Channel#addcontextlistener) + +## `DisplayMetadata` + +```ts +interface DisplayMetadata { + /** + * A user-readable name for this channel, e.g: `"Red"`. */ + readonly name?: string; + + /** + * The color that should be associated within this channel when displaying + * this channel in a UI, e.g: `#FF0000`. May be any color value supported by + * CSS, e.g. name, hex, rgba, etc.. */ + readonly color?: string; + + /** + * A URL of an image that can be used to display this channel. */ + readonly glyph?: string; +} +``` + +A desktop agent (typically for _system_ channels) may want to provide additional information about how a channel can be represented in a UI. A common use case is for color linking. + +**See also:** + +- [`Channel`](Channel) +- [`DesktopAgent.getUserChannels`](DesktopAgent#getuserchannels) + +## `Icon` + +```typescript +interface Icon { + src: string; + size?: string; + type?: string; +} +``` + +Metadata relating to a single icon image at a remote URL, used to represent an application in a user interface. + +AppMetadata includes an icons property allowing multiple icon types to be specified. Various properties may be used by the Desktop Agent to decide which icon is the most suitable to be used considering the application chooser UI, device DPI and formats supported by the system. + +**Example:** + +```js +"icons": [ + { + "src": "https://app.foo.icon/app_icons/lowres.webp", + "size": "48x48", + "type": "image/webp" + }, + { + "src": "https://app.foo.icon/app_icons/hd_hi.svg", + "size": "72x72", + "type": "image/svg+xml" + } +] +``` + +**Properties:** + +- **`src`:** The fully qualified url to the icon. +- **`size`:** The dimensions of the Icon formatted as `x`. +- **`type`:** The media type of the icon. If not provided the Desktop Agent may refer to the src file extension. + +**See also:** + +- [`AppMetadata`](Metadata#appmetadata) + +## `Image` + +```typescript +interface Image { + src: string; + size?: string; + type?: string; + label?: string; +} +``` + +Metadata relating to a single image at a remote URL, used to represent screenshot images. + +AppMetadata includes a screenshots property allowing multiple images to be specified. Various properties may be used by the Desktop Agent to decide which image(s) are the most suitable to be used considering the application chooser UI, device DPI and formats supported by the system. + +**Example:** + +```js +"screenshots": [ + { + "src": "https://app.foo.icon/app_screenshots/dashboard.png", + "size": "800x600", + "type": "image/png", + "label": "Example app dashboard" + }, + { + "src": "https://app.foo.icon/app_screenshots/notifications.png", + "size": "800x600", + "type": "image/png", + "label": "Order notifications view" + } +] +``` + +**Properties:** + +- **`src`:** The fully qualified url to the image. +- **`size`:** The dimensions of the image formatted as `x`. +- **`type`:** The media type of the image. If not provided the Desktop Agent may refer to the src file extension. + +**See also:** + +- [`AppMetadata`](Metadata#appmetadata) + +## `ImplementationMetadata` + +```ts +interface ImplementationMetadata { + /** The version number of the FDC3 specification that the implementation + * provides. The string must be a numeric semver version, e.g. 1.2 or 1.2.1. + */ + readonly fdc3Version: string; + + /** The name of the provider of the FDC3 Desktop Agent Implementation + * (e.g.Finsemble, Glue42, OpenFin etc.). + */ + readonly provider: string; + + /** The version of the provider of the FDC3 Desktop Agent Implementation + * (e.g. 5.3.0). + */ + readonly providerVersion?: string; + + /** Metadata indicating whether the Desktop Agent implements optional features of + * the Desktop Agent API. + */ + readonly optionalFeatures: { + /** Used to indicate whether the exposure of 'originating app metadata' for + * context and intent messages is supported by the Desktop Agent.*/ + readonly OriginatingAppMetadata: boolean; + /** Used to indicate whether the optional `fdc3.joinUserChannel`, + * `fdc3.getCurrentChannel` and `fdc3.leaveCurrentChannel` are implemented by + * the Desktop Agent.*/ + readonly UserChannelMembershipAPIs: boolean; + /** Used to indicate whether the experimental Desktop Agent Bridging + * feature is implemented by the Desktop Agent.*/ + readonly DesktopAgentBridging: boolean; + }; + + /** The calling application instance's own metadata, according to the + * Desktop Agent (MUST include at least the `appId` and `instanceId`). + */ + readonly appMetadata: AppMetadata; +} +``` + +Metadata relating to the FDC3 [DesktopAgent](DesktopAgent) object and its provider, including the supported version of the FDC3 specification, the name of the provider of the implementation, its own version number and the metadata of the calling application according to the desktop agent. + +**See also:** + +- [`AppMetadata`](#appmetadata) +- [`DesktopAgent.getInfo`](DesktopAgent#getinfo) + +## `IntentMetadata` + +```ts +interface IntentMetadata { + /** The unique name of the intent that can be invoked by the raiseIntent call. */ + readonly name: string; + + /** Display name for the intent. + * @deprecated Use the intent name for display as display name may vary for + * each application as it is defined in the app's AppD record. + */ + readonly displayName: string; +} +``` + +The interface used to describe an intent within the platform. + +**See also:** + +- [`AppIntent.intent`](#appintent) + +## `IntentResolution` + +```ts +interface IntentResolution { + + /** Identifier for the app instance that was selected (or started) to resolve + * the intent. `source.instanceId` MUST be set, indicating the specific app + * instance that received the intent. + */ + readonly source: AppIdentifier; + + /** The intent that was raised. May be used to determine which intent the user + * chose in response to `fdc3.raiseIntentForContext()`. + */ + readonly intent: string; + + /** The version number of the Intents schema being used. + */ + readonly version?: string; + + /** Retrieves a promise that will resolve to `Context` data returned + * by the application that resolves the raised intent, a `Channel` + * established and returned by the app resolving the intent or void. + * + * A `Channel` returned MAY be of the `PrivateChannel` type. The + * client can then `addContextListener()` on that channel to, for example, + * receive a stream of data. + * + * If an error occurs (i.e. an error is thrown by the handler function, + * the promise it returns is rejected, or the promise resolved to an invalid + * type) then the Desktop Agent MUST reject the promise returned by the + * `getResult()` function of the `IntentResolution` with a string from + * the `ResultError` enumeration. + */ + getResult(): Promise; +} +``` + +IntentResolution provides a standard format for data returned upon resolving an intent. + +**Examples:** + +```js +// Resolve a "Chain" type intent +let resolution = await agent.raiseIntent("intentName", context); + +// Use metadata about the resolving app instance to target a further intent +try { + const resolution = await fdc3.raiseIntent('StageOrder', context); + ... + + //Some time later + await agent.raiseIntent("UpdateOrder", context, resolution.source); +} +catch (err) { ... } + +//Resolve a "Client-Service" type intent with a data or channel response +let resolution = await agent.raiseIntent("intentName", context); +try { + const result = await resolution.getResult(); + if (result && result.broadcast) { //detect whether the result is Context or a Channel + console.log(`${resolution.source} returned a channel with id ${result.id}`); + } else if (result){ + console.log(`${resolution.source} returned data: ${JSON.stringify(result)}`); + } else { + console.error(`${resolution.source} didn't return anything`); + } +} catch(error) { + console.error(`${resolution.source} returned an error: ${error}`); +} +``` + +**See also:** + +- [`IntentResult`](Types#intentresult) +- [`DesktopAgent.raiseIntent`](DesktopAgent#raiseintent) +- [`DesktopAgent.raiseIntentForContext`](DesktopAgent#raiseintentforcontext) +- [`AppIdentifier`](Types#appidentifier) diff --git a/website/versioned_docs/version-2.1/api/ref/PrivateChannel.md b/website/versioned_docs/version-2.1/api/ref/PrivateChannel.md new file mode 100644 index 000000000..5fc8e9c55 --- /dev/null +++ b/website/versioned_docs/version-2.1/api/ref/PrivateChannel.md @@ -0,0 +1,162 @@ +--- +id: PrivateChannel +sidebar_label: PrivateChannel +title: PrivateChannel +hide_title: true +--- +# `PrivateChannel` + +Object representing a private context channel, which is intended to support secure communication between applications, and extends the `Channel` interface with event handlers which provide information on the connection state of both parties, ensuring that desktop agents do not need to queue or retain messages that are broadcast before a context listener is added and that applications are able to stop broadcasting messages when the other party has disconnected. + +It is intended that Desktop Agent implementations: + +- SHOULD restrict external apps from listening or publishing on this channel. +- MUST prevent `PrivateChannels` from being retrieved via fdc3.getOrCreateChannel. +- MUST provide the `id` value for the channel as required by the `Channel` interface. + +```ts +interface PrivateChannel extends Channel { + // methods + onAddContextListener(handler: (contextType?: string) => void): Listener; + onUnsubscribe(handler: (contextType?: string) => void): Listener; + onDisconnect(handler: () => void): Listener; + disconnect(): void; +} +``` + +**See also:** + +- [`Channel`](Channel) +- [`Listener`](Types#listener) +- [`DesktopAgent.addIntentListener`](DesktopAgent#addintentlistener) +- [`DesktopAgent.createPrivateChannel`](DesktopAgent#createPrivateChannel) +- [`DesktopAgent.raiseIntent`](DesktopAgent#raiseintent) + +## Examples + +### 'Server-side' example + +The intent app establishes and returns a `PrivateChannel` to the client (who is awaiting `getResult()`). When the client calls `addContextlistener()` on that channel, the intent app receives notice via the handler added with `onAddContextListener()` and knows that the client is ready to start receiving quotes. + +The Desktop Agent knows that a channel is being returned by inspecting the object returned from the handler (e.g. check constructor or look for private member). + +Although this interaction occurs entirely in frontend code, we refer to it as the 'server-side' interaction as it receives a request and initiates a stream of responses. + +```typescript +fdc3.addIntentListener("QuoteStream", async (context) => { + const channel: PrivateChannel = await fdc3.createPrivateChannel(); + const symbol = context.id.ticker; + + // This gets called when the remote side adds a context listener + const addContextListener = channel.onAddContextListener((contextType) => { + // broadcast price quotes as they come in from our quote feed + feed.onQuote(symbol, (price) => { + channel.broadcast({ type: "price", price}); + }); + }); + + // This gets called when the remote side calls Listener.unsubscribe() + const unsubscribeListener = channel.onUnsubscribe((contextType) => { + feed.stop(symbol); + }); + + // This gets called if the remote side closes + const disconnectListener = channel.onDisconnect(() => { + feed.stop(symbol); + }); + + return channel; +}); +``` + +### 'Client-side' example + +The 'client' application retrieves a `Channel` by raising an intent with context and awaiting the result. It adds a `ContextListener` so that it can receive messages from it. If a `PrivateChannel` was returned this may in turn trigger a handler added on the 'server-side' with `onAddContextListener()` and start the stream. A listener may also be to clear up if the 'server-side' disconnects from the stream. + +Although this interaction occurs entirely in frontend code, we refer to it as the 'client-side' interaction as it requests and receives a stream of responses. + +```javascript +try { + const resolution3 = await fdc3.raiseIntent("QuoteStream", { type: "fdc3.instrument", id : { symbol: "AAPL" } }); + try { + const result = await resolution3.getResult(); + //check that we got a result and that it's a channel + if (result && result.addContextListener) { + const listener = result.addContextListener("price", (quote) => console.log(quote)); + + //if it's a PrivateChannel + if (result.onDisconnect) { + result.onDisconnect(() => { + console.warn("Quote feed went down"); + }); + + // Sometime later... + listener.unsubscribe(); + } + } else { + console.warn(`${resolution3.source} did not return a channel`); + } + } catch(channelError) { + console.log(`Error: ${resolution3.source} returned an error: ${channelError}`); + } +} catch (resolverError) { + console.error(`Error: Intent was not resolved: ${resolverError}`); +} +``` + +## Methods + +### `onAddContextListener` + +```ts +onAddContextListener(handler: (contextType?: string) => void): Listener; +``` + +Adds a listener that will be called each time that the remote app invokes addContextListener on this channel. + +Desktop Agents MUST call this for each invocation of addContextListener on this channel, including those that occurred before this handler was registered (to prevent race conditions). + +**See also:** + +- [`Channel.addContextListener`](Channel#addcontextlistener) + +### `onUnsubscribe` + +```ts +onUnsubscribe(handler: (contextType?: string) => void): Listener; +``` + +Adds a listener that will be called whenever the remote app invokes `Listener.unsubscribe()` on a context listener that it previously added. + +Desktop Agents MUST call this when disconnect() is called by the other party, for each listener that they had added. + +**See also:** + +- [`Listener`](Types#listener) + +### `onDisconnect` + +```ts +onDisconnect(handler: () => void): Listener; +``` + +Adds a listener that will be called when the remote app terminates, for example when its window is closed or because disconnect was called. This is in addition to calls that will be made to onUnsubscribe listeners. + +**See also:** + +- [`disconnect`](#disconnect) + +### `disconnect` + +```ts +disconnect(): void; +``` + +May be called to indicate that a participant will no longer interact with this channel. + +After this function has been called, Desktop Agents SHOULD prevent apps from broadcasting on this channel and MUST automatically call Listener.unsubscribe() for each listener that they've added (causing any `onUnsubscribe` handler added by the other party to be called) before triggering any onDisconnect handler added by the other party. + +**See also:** + +- [`onUnsubscribe`](#onunsubscribe) +- [`Listener`](Types#listener) diff --git a/website/versioned_docs/version-2.1/api/ref/Types.md b/website/versioned_docs/version-2.1/api/ref/Types.md new file mode 100644 index 000000000..48af5671f --- /dev/null +++ b/website/versioned_docs/version-2.1/api/ref/Types.md @@ -0,0 +1,168 @@ +--- +title: Types +--- + +FDC3 API operations make use of several type declarations. + +## `AppIdentifier` + +Identifies an application, or instance of an application, and is used to target FDC3 API calls at specific applications. +Will always include at least an `appId` property, which can be used with `fdc3.open`, `fdc3.raiseIntent` etc.. +If the `instanceId` field is set then the `AppIdentifier` object represents a specific instance of the application that may be addressed using that Id. + +```ts +interface AppIdentifier { + /** The unique application identifier located within a specific application + * directory instance. An example of an appId might be 'app@sub.root'. + */ + readonly appId: string; + + /** An optional instance identifier, indicating that this object represents a + * specific instance of the application described. + */ + readonly instanceId?: string; + + /** The Desktop Agent that the app is available on. Used in Desktop Agent + * Bridging to identify the Desktop Agent to target. + * @experimental + **/ + readonly desktopAgent?: string; +} +``` + +**See also:** + +- [`AppMetadata`](Metadata#appmetadata) +- [`DesktopAgent.open`](DesktopAgent#open) +- [`DesktopAgent.raiseIntent`](DesktopAgent#raiseintent) +- [`DesktopAgent.raiseIntentForContext`](DesktopAgent#raiseintentforcontext) +- [`IntentResolution`](Metadata#intentresolution) + +## `Context` + +```typescript +interface Context { + id?: { [key: string]: string }; + name?: string; + type: string; +} +``` + +The base interface that all contexts should extend: a context data object adhering to the [FDC3 Context Data specification](../../context/spec). + +This means that it must at least have a `type` property that indicates what type of data it represents, e.g. `'fdc3.contact'`. The `type` property of context objects is important for certain FDC3 operations, like [`Channel.getCurrentContext`](Channel#getCurrentContext) and [`DesktopAgent.addContextListener`](DesktopAgent#addContextListener), which allows you to filter contexts by their type. + +**See also:** + +- [`ContextHandler`](#contexthandler) +- [`DesktopAgent.open`](DesktopAgent#open) +- [`DesktopAgent.broadcast`](DesktopAgent#broadcast) +- [`DesktopAgent.addIntentListener`](DesktopAgent#addintentlistener) +- [`DesktopAgent.addContextListener`](DesktopAgent#addcontextlistener) +- [`DesktopAgent.findIntent`](DesktopAgent#findintent) +- [`DesktopAgent.findIntentsByContext`](DesktopAgent#findintentsbycontext) +- [`DesktopAgent.raiseIntent`](DesktopAgent#raiseintent) +- [`DesktopAgent.raiseIntentForContext`](DesktopAgent#raiseintentforcontext) +- [`Channel.broadcast`](Channel#broadcast) +- [`Channel.getCurrentContext`](Channel#getcurrentcontext) +- [`Channel.addContextListener`](Channel#addcontextlistener) + +## `ContextHandler` + +```typescript +type ContextHandler = (context: Context, metadata?: ContextMetadata) => void; +``` + +Describes a callback that handles a context event. Optional metadata about the context message, including the app that originated the message, may be provided. + +Used when attaching listeners for context broadcasts. + +Optional metadata about the context message, including the app that originated the message, SHOULD be provided by the desktop agent implementation. + +**See also:** + +- [`Context`](#context) +- [`ContextMetadata`](Metadata#contextmetadata) +- [`DesktopAgent.addContextListener`](DesktopAgent#addcontextlistener) +- [`Channel.addContextListener`](Channel#addcontextlistener) + +## `DesktopAgentIdentifier` + +```typescript +/** @experimental */ +interface DesktopAgentIdentifier { + /** Used in Desktop Agent Bridging to attribute or target a message to a + * particular Desktop Agent.**/ + readonly desktopAgent: string; +} +``` + +(Experimental) Identifies a particular Desktop Agent in Desktop Agent Bridging scenarios where a request needs to be directed to a Desktop Agent rather than a specific app, or a response message is returned by the Desktop Agent (or more specifically its resolver) rather than a specific app. Used as a substitute for `AppIdentifier` in cases where no app details are available or are appropriate. + +**See also:** + +* [Agent Bridging - Identifying Desktop Agents Identity and Message Sources](../../agent-bridging/spec#identifying-desktop-agents-identity-and-message-sources) + +## `IntentHandler` + +```typescript +type IntentHandler = (context: Context, metadata?: ContextMetadata) => Promise | void; +``` + +Describes a callback that handles a context event and may return a promise of a Context, Channel object or `void` to be returned to the application that raised the intent. + +Used when attaching listeners for raised intents. + +Optional metadata about the intent & context message, including the app that originated the message, SHOULD be provided by the desktop agent implementation. + +**See also:** + +- [`Context`](#context) +- [`ContextMetadata`](Metadata#contextmetadata) +- [`PrivateChannel`](PrivateChannel) +- [`DesktopAgent.addIntentListener`](DesktopAgent#addintentlistener) +- [`Channel.addContextListener`](Channel#addcontextlistener) + +## `IntentResult` + +```typescript +type IntentResult = Context | Channel | void; +``` + +Describes results that an Intent handler may return that should be communicated back to the app that raised the intent, via the [`IntentResolution`](Metadata#intentresolution). + +Represented as a union type in TypeScript, however, this type may be rendered as an interface in other languages that both the `Context` and `Channel` types implement, allowing either to be returned by an `IntentHandler`. + +**See also:** + +- [`Context`](#context) +- [`Channel`](Channel) +- [`PrivateChannel`](PrivateChannel) +- [`IntentHandler`](#intenthandler) +- [`DesktopAgent.addIntentListener`](DesktopAgent#addintentlistener) +- [`IntentResolution`](Metadata#intentresolution) + +## `Listener` + +A Listener object is returned when an application subscribes to intents or context broadcasts via the [`addIntentListener`](DesktopAgent#addintentlistener) or [`addContextListener`](DesktopAgent#addcontextlistener) methods on the [DesktopAgent](DesktopAgent) object. + +```typescript +interface Listener { + unsubscribe(): void; +} +``` + +### `unsubscribe` + +```ts +unsubscribe(): void; +``` + +Allows an application to unsubscribe from listening to intents or context broadcasts. + +**See also:** + +- [`DesktopAgent.addIntentListener`](DesktopAgent#addintentlistener) +- [`DesktopAgent.addContextListener`](DesktopAgent#addcontextlistener) +- [`Channel.addContextListener`](Channel#addcontextlistener) +- [`ContextHandler`](Types#contexthandler) diff --git a/website/versioned_docs/version-2.1/api/spec.md b/website/versioned_docs/version-2.1/api/spec.md new file mode 100644 index 000000000..0fd5f5cfa --- /dev/null +++ b/website/versioned_docs/version-2.1/api/spec.md @@ -0,0 +1,596 @@ +--- +id: spec +sidebar_label: Overview +title: API Overview (2.1) +--- + +The role of FDC3 API is to establish a baseline interface for interoperability between applications. Because FDC3 is largely an agreement between existing platforms and applications, standards should be optimized for ease of adoption rather than functional completeness. Functionality absent from a FDC3 specification is in no way a commentary on its importance. + +The following sections examine the API's use-cases and core concepts. The APIs a fully defined in both subsequent pages of this Part and a full set of TypeScript definitions in the [src](https://github.com/finos/FDC3/tree/master/src/api) directory of the [FDC3 GitHub repository](https://github.com/finos/FDC3/). + +## Components + +### Desktop Agent + +A Desktop Agent is a desktop component (or aggregate of components) that serves as a launcher and message router (broker) for applications in its domain. A Desktop Agent can be connected to one or more App Directories and will use directories for application identity and discovery. Typically, a Desktop Agent will contain the proprietary logic of a given platform, handling functionality like explicit application interop workflows where security, consistency, and implementation requirements are proprietary. + +Examples of Desktop Agents include: + +- Autobahn +- Finsemble +- Glue42 +- OpenFin +- Refinitiv Eikon + +An FDC3-compliant Desktop Agent exposes an FDC3 Standard API to applications they have launched. When an App is launched by a Desktop Agent and is given access to the Agent's API to interoperate, it is running in that Desktop Agent's *context*. + +### Application + +An application is any endpoint on the desktop that is: + +- Registered with/known by a Desktop Agent +- Launchable by a Desktop Agent +- Addressable by a Desktop Agent + +Examples of endpoints include: + +- Native Applications +- Web Applications +- Headless “services” running on the desktop + +## Desktop Agent Implementation + +The FDC3 API specification consists of interfaces. It is expected that each Desktop Agent will implement these interfaces. A Desktop Agent MUST provide implementations for the following interfaces: + +- [`DesktopAgent`](ref/DesktopAgent) +- [`Channel`](ref/Channel) +- [`PrivateChannel`](ref/PrivateChannel) +- [`Listener`](ref/Types#listener) + +Other interfaces defined in the spec are not critical to define as concrete types. Rather, the Desktop Agent should expect to have objects of the interface shape passed into or out of their library. + +### API Access + +The FDC3 API can be made available to an application through a number of different methods. In the case of web applications, a Desktop Agent MUST provide the FDC3 API via a global accessible as `window.fdc3`. Implementors MAY additionally make the API available through modules, imports, or other means. + +The global `window.fdc3` must only be available after the API is ready to use. To enable applications to avoid using the API before it is ready, implementors MUST provide a global `fdc3Ready` event that is fired when the API is ready for use. Implementations should first check for the existence of the FDC3 API and add a listener for this event if it is not found: + +```js +function fdc3Stuff() { + // Make fdc3 API calls here +} + +if (window.fdc3) { + fdc3Stuff(); +} else { + window.addEventListener('fdc3Ready', fdc3Stuff); +} +``` + +### Standards vs. Implementation + +![Desktop Agent - Standards Schematic](/assets/api-1.png) + +The surface area of FDC3 standardization (shown in *white* above) itself is quite small in comparison to the extent of a typical desktop agent implementation (in *grey*). + +For example: + +- workspace management +- user identity and SSO +- entitlements +- UX of application resolution + +Are all areas of functionality that any feature-complete desktop agent would implement, but are not currently areas considered for standardization under FDC3. + +### Inter-Agent Communication + +A goal of the FDC3 Standard is that applications running in different Desktop Agent contexts on the same desktop, or operated by the same user, would be able to interoperate and that one Desktop Agent context would be able to discover and launch an application in another Desktop Application context. As Desktop Agent interop is supported by common standards for APIs an app in one Desktop Agent context would not need to know a different syntax to launch or interact with an app in another Desktop Agent context. + +Inter-agent communication at the API layer may be achieved via the [Desktop Agent Bridging Part of the FDC3 Standard](../agent-bridging/spec) ([@experimental](../fdc3-compliance#experimental-features)), which defines an independent service that Desktop Agents may connect to, and a protocol for the exchange of messages relating to FDC3 API calls. Hence, by implementing support for Desktop Agent Bridging, a platform may extend interop across applications running in multiple Desktop Agent contexts. + +Desktop Agent Bridging provides message exchanges and a workflow for performing intent resolution across multiple agents. Hence, app discovery is supported across the agents connected to the bridge for intent-based workflows. Further, as channels are also supported by bridging, context sharing also works across multiple agents. + +There is currently no method of discovering all the apps supported by a Desktop Agent in the FDC3 API nor bridging. Hence, to support launching, via `fdc3.open` across the connected Desktop Agents, application details must be known in advance. This may be achieved by connecting Desktop Agents to the same App Directories. + +![Desktop Agent - Interop](/assets/api-2.png) + +### Desktop Agent API Standard Compliance + +An FDC3 Standard compliant Desktop Agent implementation **MUST**: + +- Provide the FDC3 API to web applications via a global accessible as [`window.fdc3`](#api-access). +- Provide a global [`fdc3Ready`](#api-access) event that is fired when the API is ready for use. +- Provide a method of resolving ambiguous intents (i.e. those that might be resolved by multiple applications) or unspecified intents (calls to `raiseIntentForContext` that return multiple options), such as a resolver UI. + - Intent resolution MUST take into account any specified input or return context types + - Requests for resolution to apps returning a channel MUST include any apps that are registered as returning a channel with a specific type. +- Return (JavaScript or platform appropriate) Error Objects with messages from the [`ChannelError`](ref/Errors#channelerror), [`OpenError`](ref/Errors#openerror), [`ResolveError`](ref/Errors#resolveerror) and [`ResultError`](ref/Errors#resulterror) enumerations as appropriate. +- Accept as input and return as output data structures that are compatible with the interfaces defined in this Standard. +- Include implementations of the following [Desktop Agent](ref/DesktopAgent) API functions, as defined in this Standard: + - [`addContextListener`](ref/DesktopAgent#addcontextlistener) + - [`addIntentListener`](ref/DesktopAgent#addintentlistener) + - [`broadcast`](ref/DesktopAgent#broadcast) + - [`createPrivateChannel`](ref/DesktopAgent#createprivatechannel) + - [`findInstances`](ref/DesktopAgent#findinstances) + - [`findIntent`](ref/DesktopAgent#findintent) + - [`findIntentsByContext`](ref/DesktopAgent#findintentsbycontext) + - [`getCurrentChannel`](ref/DesktopAgent#getcurrentchannel) + - [`getInfo`](ref/DesktopAgent#getinfo) + - [`getOrCreateChannel`](ref/DesktopAgent#getorcreatechannel) + - [`getUserChannels`](ref/DesktopAgent#getuserchannels) + - [`open`](ref/DesktopAgent#open) + - [`raiseIntent`](ref/DesktopAgent#raiseintent) + - [`raiseIntentForContext`](ref/DesktopAgent#raiseintentforcontext) +- Provide an ID for each [`PrivateChannel`](ref/PrivateChannel) created via [`createPrivateChannel`](ref/DesktopAgent#createprivatechannel) and prevent them from being retrieved via [`getOrCreateChannel`](ref/DesktopAgent#getorcreatechannel) by ID. +- Only require app directories that they connect to to have implemented only the minimum requirements specified in the [App Directory API Part](../app-directory/spec) of this Standard. +- Provide details of whether they implement optional features of the Desktop Agent API in the `optionalFeatures` property of the [`ImplementationMetadata`](ref/Metadata#implementationmetadata) object returned by the [`fdc3.getInfo()`](ref/DesktopAgent#getinfo) function. +- Allow, by default, at least a 15 second timeout for an application, launched via [`fdc3.open`](../api/ref/DesktopAgent#open), [`fdc3.raiseIntent`](../api/ref/DesktopAgent#raiseintent) or [`fdc3.raiseIntentForContext`](../api/ref/DesktopAgent#raiseintentforcontext) to add any context listener (via [`fdc3.addContextListener`](../api/ref/DesktopAgent#addcontextlistener)) or intent listener (via [`fdc3.addIntentListener`](../api/ref/DesktopAgent#addintentlistener)) necessary to deliver context or intent and context to it on launch. This timeout only applies to listeners needed to receive context on launch; further intent and context listeners not required on launch MAY be added later. + +An FDC3 Standard compliant Desktop Agent implementation **SHOULD**: + +- Support connection to one or more App Directories meeting the [FDC3 App Directory Standard](../app-directory/overview). +- Qualify `appId` values received from an app directory with the hostname of the app directory server (e.g. `myAppId@name.domain.com`) [as defined in the app directory standard](../app-directory/overview#application-identifiers). +- Allow applications to register an [`IntentHandler`](ref/Types#intenthandler) for particular Intent and Context type pairs by providing `interop.intents.listensFor` metadata in their AppD record. +- Adopt the [recommended set of User channel definitions](#recommended-user-channel-set). +- Ensure that context messages broadcast by an application on a channel are not delivered back to that same application if they are joined to the channel. +- Make metadata about each context message or intent and context message received (including the app that originated the message) available to the receiving application. +- Prevent external apps from listening or publishing on a [`PrivateChannel`](ref/PrivateChannel) that they did not request or provide. +- Enforce compliance with the expected behavior of intents (where Intents specify a contract that is enforceable by schema, for example, return object types) and return an error if the interface is not met. + +An FDC3 Standard compliant Desktop Agent implementation **MAY**: + +- Make the Desktop Agent API available through modules, imports, or other means. +- Support multiple routes for registration of an [`IntentHandler`](ref/Types#intenthandler) by an app to be considered during Intent resolution, including dynamic registration of apps at runtime. +- Implement the following OPTIONAL [Desktop Agent](ref/DesktopAgent) API functions: + - [`joinUserChannel`](ref/DesktopAgent#joinuserchannel) + - [`leaveCurrentChannel`](ref/DesktopAgent#leavecurrentchannel) + - [`getCurrentChannel`](ref/DesktopAgent#getcurrentchannel) +- Implement the following deprecated API functions: + - [`addContextListener`](ref/DesktopAgent#addcontextlistener-deprecated) (without a contextType argument) + - [`getSystemChannels`](ref/DesktopAgent#getsystemchannels-deprecated) (renamed getUserChannels) + - [`joinChannel`](ref/DesktopAgent#joinchannel-deprecated) (renamed joinUserChannel) + - [`open`](ref/DesktopAgent#open-deprecated) (deprecated version that addresses apps via `name` field) + - [`raiseIntent`](ref/DesktopAgent#raiseintent-deprecated) (deprecated version that addresses apps via `name` field) + - [`raiseIntentForContext`](ref/DesktopAgent#raiseintentforcontext-deprecated) (deprecated version that addresses apps via `name` field) + +For more details on FDC3 Standards compliance (including the versioning, deprecation and experimental features policies) please see the [FDC3 Compliance page](../fdc3-compliance). + +## Functional Use Cases + +### Open an Application + +Linking from one application to another is a critical basic workflow that the web revolutionized via the hyperlink. Supporting semantic addressing of applications across different technologies and platform domains greatly reduces friction in linking different applications into a single workflow. + +### Requesting Functionality From Another App + +Often, we want to link from one app to another to dynamically create a workflow. Enabling this without requiring prior knowledge between apps is a key goal of FDC3 and is implemented via the raising of [intents](../intents/spec), which represent a desired action, to be performed with a [context](../context/spec) supplied as input. + +Intents provide a way for an app to request functionality from another app and defer the discovery and launching of the destination app to the Desktop Agent. There are multiple models for interop that intents can support. + +- **Chain**: In this case the workflow is completely handed off from one app to another (similar to linking). Currently, this is the primary focus in FDC3. +- **Client-Service**: A Client invokes a Service via the Intent, the Service performs some function, then passes the workflow back to the Client. Typically, there is a data payload type associated with this intent that is published as the standard contract for the intent. +- **Remote API**: An app wants to remote an entire API that it owns to another App. In this case, the API for the App cannot be standardized. However, the FDC3 API can address how an App connects to another App in order to get access to a proprietary API. + +### Send/broadcast Context + +On the financial desktop, applications often want to broadcast [context](../context/spec) to any number of applications. Context sharing needs to support different groupings of applications, which is supported via the concept of 'channels', over which context is broadcast and received by other applications listening to the channel. + +In some cases, an application may want to communicate with a single application or service and to prevent other applications from participating in the communication. For single transactions, this can instead be implemented via a raised intent, which will be delivered to a single application that can, optionally, respond with data. Alternatively, it may instead respond with a [`Channel`](ref/Channel) or [`PrivateChannel`](ref/PrivateChannel) over which a stream of responses or a dialog can be supported. + +### Retrieve Metadata about the Desktop Agent implementation + +An application may wish to retrieve information about the version of the FDC3 Standard supported by a Desktop Agent implementation and the name of the implementation provider. + +Since version 1.2 of the FDC3 Standard it may do so via the [`fdc3.getInfo()`](ref/DesktopAgent#getinfo) function. The metadata returned can be used, for example, to vary the behavior of an application based on the version supported by the Desktop Agent, e.g.: + +```js +import {compareVersionNumbers, versionIsAtLeast} from '@finos/fdc3'; + +if (fdc3.getInfo && versionIsAtLeast(await fdc3.getInfo(), '1.2')) { + await fdc3.raiseIntentForContext(context); +} else { + await fdc3.raiseIntent('ViewChart', context); +} +``` + +The [`ImplementationMetadata`](ref/Metadata#implementationmetadata) object returned also includes the metadata for the calling application, according to the Desktop Agent. This allows the application to retrieve its own `appId`, `instanceId` and other details, e.g.: + +```js +let implementationMetadata = await fdc3.getInfo(); +let {appId, instanceId} = implementationMetadata.appMetadata; + +``` + +### Reference apps or app instance(s) and retrieve their metadata + +To construct workflows between applications, you need to be able to reference specific applications and instances of those applications. + +From version 2.0 of the FDC3 Standard, Desktop Agent functions that reference or return information about other applications do so via an [`AppIdentifier`](ref/Types#appidentifier) type. [`AppIdentifier`](ref/Types#appidentifier) references specific applications via an `appId` from an [App Directory](../app-directory/overview) record and instances of that application via an `instanceId` assigned by the Desktop Agent. + +Additional metadata for an application can be retrieved via the [`fdc3.getAppMetadata(appIdentifier)`](ref/DesktopAgent#getappmetadata) function, which returns an [`AppMetadata`](ref/Metadata#appmetadata) object. The additional metadata may include a title, description, icons, etc., which may be used for display purposes. + +Identifiers for instances of an application may be retrieved via the [`fdc3.findInstances(appIdentifier)`](ref/DesktopAgent#findinstances) function. + +## Raising Intents + +Raising an Intent is a method for an application to request functionality from another application and, if desired, defer the discovery and launching of the destination app to the Desktop Agent. + +### Intents and Context + +When raising an intent a specific context is provided as input. The type of the provided context may determine which applications can resolve the intent. + +A context type may also be associated with multiple intents. For example, an `fdc3.instrument` could be associated with `ViewChart`, `ViewNews`, `ViewAnalysis` or other intents. + +To raise an intent without a context, use the [`fdc3.nothing`](../context/ref/Nothing) context type. This type exists so that applications can explicitly declare that they support raising an intent without a context (when registering an `IntentHandler` or in an App Directory). + +As an alternative to raising a specific intent, you may also raise an unspecified intent with a known context allowing the Desktop Agent or the user (if the intent is ambiguous) to select the appropriate intent and then to raise it with the specified context for resolution. + +### Intent Results + +An optional [`IntentResult`](ref/Types#intentresult) may also be returned as output by an application handling an intent. Results maybe either a single `Context` object, or a `Channel` that may be used to send a stream of responses. The [`PrivateChannel`](ref/PrivateChannel) type is provided to support synchronization of data transmitted over returned channels, by allowing both parties to listen for events denoting subscription and unsubscription from the returned channel. `PrivateChannels` are only retrievable via [raising an intent](ref/DesktopAgent#raiseintent). + +For example, an application handling a `CreateOrder` intent might return a context representing the order and including an ID, allowing the application that raised the intent to make further calls using that ID. + +An optional result type is also supported when programmatically resolving an intent via [`findIntent`](ref/DesktopAgent#findintent) or [`findIntentByContext`](ref/DesktopAgent#findintentbycontext). + +### Resolvers + +Successful delivery of an intent depends first upon the Desktop Agent's ability to "resolve the intent" (i.e. map the intent to a specific App instance). Where the target application is ambiguous (because there is more than one application that could resolve the intent and context) Desktop Agents may resolve intents by any suitable methodology. A common method is to display a UI that allows the user to pick the desired App from a list of those that will accept the intent and context. Alternatively, the app issuing the intent may proactively handle resolution by calling [`findIntent`](ref/DesktopAgent#findintent) or [`findIntentByContext`](ref/DesktopAgent#findintentbycontext) and then raise the intent with a specific target application, e.g.: + +```js +// Find apps to resolve an intent to start a chat with a given contact +const appIntent = await fdc3.findIntent("StartChat", context); +// use the returned AppIntent object to target one of the returned +// chat apps or app instances using the AppMetadata object +await fdc3.raiseIntent("StartChat", context, appIntent.apps[0]); + +//Find apps to resolve an intent and return a specified context type +const appIntent = await fdc3.findIntent("ViewContact", context, "fdc3.contact"); +try { + const resolution = await fdc3.raiseIntent(appIntent.intent, context, appIntent.apps[0].name); + const result = await resolution.getResult(); + console.log(`${resolution.source} returned ${JSON.stringify(result)}`); +} catch(error) { + console.error(`${resolution.source} returned a result error: ${error}`); +} + +//Find apps to resolve an intent and return a channel +const appIntent = await fdc3.findIntent("QuoteStream", context, "channel"); +try { + const resolution = await fdc3.raiseIntent(appIntent.intent, context, appIntent.apps[0].name); + const result = await resolution.getResult(); + if (result && result.addContextListener) { + result.addContextListener(null, (context) => { + console.log(`received context: ${JSON.stringify(context)}`); + }); + } else { + console.log(`${resolution.source} didn't return a channel! Result: ${JSON.stringify(result)}`); + } +} catch(error) { + console.error(`${resolution.source} returned a result error: ${error}`); +} + +//Find apps that can perform any intent with the specified context +const appIntents = await fdc3.findIntentByContext(context); +//use the returned AppIntent array to target one of the returned apps +await fdc3.raiseIntent(appIntent[0].intent, context, appIntent[0].apps[0]); +``` + +Result context types requested are represented by their type name. A channel may be requested by passing the string `"channel"` or a channel that returns a specific type via the syntax `"channel"`, e.g. `"channel"`. Requesting intent resolution to an app returning a channel MUST include apps that are registered as returning a channel with a specific type. + +### Intent Resolution + +Raising an intent will return a Promise-type object that will resolve/reject based on a number of factors. + +#### Resolve + +- Intent was resolved unambiguously and the receiving app was launched successfully (if necessary). +- Intent was ambiguous, a resolution was chosen by the end user, and the chosen application was launched successfully. + +#### Reject + +- No app matching the intent and context (if specified) was found. +- A match was found, but the receiving app failed to launch. +- The intent was ambiguous and the resolver experienced an error. + +#### Resolution Object + +If the raising of the intent resolves (or rejects), a standard [`IntentResolution`](ref/Metadata#intentresolution) object will be passed into the resolver function with details of the application that resolved the intent and the means to access any results subsequently returned. + +For example, to raise a specific intent: + +```js +try { + const resolution = await fdc3.raiseIntent('StageOrder', context); +} +catch (err){ ... } +``` + +or to raise an unspecified intent for a specific context, where the user may select an intent from a resolver dialog: + +```js +try { + const resolution = await fdc3.raiseIntentForContext(context); + if (resolution.data) { + const orderId = resolution.data.id; + } +} +catch (err){ ... } +``` + +Use metadata about the resolving app instance to target a further intent + +```js +try { + const resolution = await fdc3.raiseIntent('StageOrder', context); + ... + + //some time later + await agent.raiseIntent("UpdateOrder", context, resolution.source); +} +catch (err) { ... } +``` + +Raise an intent and retrieve either data or a channel from the IntentResolution: + +```js +let resolution = await agent.raiseIntent("intentName", context); +try { + const result = await resolution.getResult(); + /* Detect whether the result is Context or a Channel by checking for properties unique to Channels. */ + if (result && result.broadcast) { + console.log(`${resolution.source} returned a channel with id ${result.id}`); + } else if (result){ + console.log(`${resolution.source} returned data: ${JSON.stringify(result)}`); + } else { + console.error(`${resolution.source} didn't return anything`); + } +} catch(error) { + console.error(`${resolution.source} returned a data error: ${error}`); +} +``` + +### Register an Intent Handler + +Applications need to let the system know the intents they can support. Typically, this SHOULD be done via registration with an [App Directory](../app-directory/spec) by providing `interop.intents.listensFor` metadata. However, Desktop Agent implementations MAY support dynamic registration of an [`IntentHandler`](ref/Types#intenthandler) by an app at runtime (for example, when they add an `IntentListener` via the API) to allow for ad-hoc registration which may be helpful at development time. Although dynamic registration is not part of this specification, a Desktop Agent agent MAY choose to support any number of registration paths. + +When an instance of an application is launched, it is expected to add an [`IntentHandler`](ref/Types#intenthandler) function to the Desktop Agent for each intent it has registered by calling the [`fdc3.addIntentListener`](ref/DesktopAgent#addintentlistener) function of the Desktop Agent. Doing so allows the Desktop Agent to pass incoming intents and contexts to that instance of the application. Hence, if the application instance was spawned in response to the raised intent, then the Desktop Agent must wait for the relevant intent listener to be added by that instance before it can deliver the intent and context to it. In order to facilitate accurate error responses, calls to `fdc3.raiseIntent` should not return an `IntentResolution` until the intent handler has been added and the intent delivered to the target app. + +Intent handlers SHOULD be registered via [`fdc3.addIntentListener`](ref/DesktopAgent#addintentlistener) within 15 seconds of the application launch (the minimum timeout Desktop Agents are required to provide) in order to be widely compatible with Desktop Agent implementations. Individual Desktop Agent implementations MAY support longer timeouts or configuration to control or extend timeouts. + +### Originating App Metadata + +Optional metadata about each intent & context message received, including the app that originated the message, SHOULD be provided by the desktop agent implementation to registered intent handlers. As this metadata is optional, apps making use of it MUST handle cases where it is not provided. + +### Compliance with Intent Standards + +Intents represent a contract with expected behavior if an app asserts that it supports the intent. Where this contract is enforceable by schema (for example, return object types), the FDC3 API implementation SHOULD enforce compliance and return an error if the interface is not met. + +It is expected that App Directories SHOULD also curate listed apps and ensure that they are complying with declared intents. + +## Context Channels + +Context channels allows a set of apps to share a stateful piece of data between them, and be alerted when it changes. Use cases for channels include color linking between applications to automate the sharing of context and topic based pub/sub such as theme. + +### Types of Channel + +There are three types of channels, which have different visibility and discoverability semantics: + +1. ***User channels***, which: + + - facilitate the creation of user-controlled context links between applications (often via the selection of a color channel), + - are created and named by the desktop agent, + - are discoverable (via the [`getUserChannels()`](ref/DesktopAgent#getuserchannels) API call), + - can be 'joined' (via the [`joinUserChannel()`](ref/DesktopAgent#joinuserchannel) API call). + + :::note + + Prior to FDC3 2.0, 'user' channels were known as 'system' channels. They were renamed in FDC3 2.0 to reflect their intended usage, rather than the fact that they are created by system (which could also create 'app' channels). + + ::: + + :::note + + Earlier versions of FDC3 included the concept of a 'global' system channel + which was deprecated in FDC3 1.2 and removed in FDC3 2.0. + + ::: + +2. ***App channels***, which: + + - facilitate developer controlled messaging between applications, + - are created and named by applications (via the [`getOrCreateChannel()`](ref/DesktopAgent#getorcreatechannel) API call), + - are not discoverable, + - are interacted with via the [Channel API](ref/Channel) (accessed via the desktop agent [`getOrCreateChannel`](ref/DesktopAgent#getorcreatechannel) API call) + +3. ***Private*** channels, which: + + - facilitate private communication between two parties, + - have an auto-generated identity and can only be retrieved via a raised intent. + +Channels are interacted with via `broadcast` and `addContextListener` functions, allowing an application to send and receive Context objects via the channel. For User channels, these functions are provided on the Desktop Agent, e.g. [`fdc3.broadcast(context)`](ref/DesktopAgent#broadcast), and apply to channels joined via [`fdc3.joinUserChannel`](ref/DesktopAgent#joinuserchannel). For App channels, a channel object must be retrieved, via [`fdc3.getOrCreateChannel(channelName)`](ref/DesktopAgent#getorcreatechannel), which provides the functions, i.e. [`myChannel.broadcast(context)`](ref/Channel#broadcast) and [`myChannel.addContextListener(context)`](ref/Channel#addcontextlistener). For `PrivateChannels`, a channel object must also be retrieved, but via an intent raised with [`fdc3.raiseIntent(intent, context)`](ref/DesktopAgent#raiseintent) and returned as an [`IntentResult`](ref/Types#intentresult). + +Channel implementations SHOULD ensure that context messages broadcast by an application on a channel are not delivered back to that same application if they are also listening on the channel. + +### Joining User Channels + +Apps can join *User channels*. An app can only be joined to one User channel at a time. + +When an app is joined to a User channel, calls to [`fdc3.broadcast`](ref/DesktopAgent#broadcast) will be routed to that channel and listeners added through [`fdc3.addContextListener`](ref/DesktopAgent#addcontextlistener) will receive context broadcasts from other apps also joined to that channel. If an app is not joined to a User channel [`fdc3.broadcast`](ref/DesktopAgent#broadcast) will be a no-op and handler functions added with [`fdc3.addContextListener`](ref/DesktopAgent#addcontextlistener) will not receive any broadcasts. However, apps can still choose to listen and broadcast to specific channels (both User and App channels) via the methods on the [`Channel`](ref/Channel) class. + +When an app joins a User channel, or adds a context listener when already joined to a channel, it will automatically receive the current context for that channel. + +It is possible that a call to join a User channel could be rejected. If for example, the desktop agent wanted to implement controls around what data apps can access. + +Joining channels in FDC3 is intended to be a behavior initiated by the end user. For example: by color linking or apps being grouped in the same workspace. Most of the time, it is expected that apps will be joined to a channel by mechanisms outside of the app. To support programmatic management of joined channels and the implementation of channel selector UIs other than those provided outside of the app, Desktop Agent implementations MAY provide [`fdc3.joinChannel()`](ref/DesktopAgent#joinchannel), [`fdc3.getCurrentChannel()`](ref/DesktopAgent#getcurrentchannel) and [`fdc3.leaveCurrentChannel()`](ref/DesktopAgent#leavecurrentchannel) functions and if they do, MUST do so as defined in the [Desktop Agent API reference](ref/DesktopAgent). + +There SHOULD always be a clear UX indicator of what channel an app is joined to. + +#### Examples + +To find a User channel, one calls: + +```js +// returns an array of channels +const allChannels = await fdc3.getUserChannels(); +const redChannel = allChannels.find(c => c.id === 'red'); +``` + +To join a User channel, one calls: + +```js +fdc3.joinUserChannel(redChannel.id); +``` + +Calling `fdc3.broadcast` will now route context to the joined channel. + +Channel implementations SHOULD ensure that context messages broadcast by an application on a channel are not delivered back to that same application if they are joined to the channel. + + > Prior to FDC3 2.0, 'user' channels were known as 'system' channels. They were renamed in FDC3 2.0 to reflect their intended usage, rather than the fact that they are created by system (which could also create 'app' channels). The `joinChannel` function was also renamed to `joinUserChannel` to clarify that it is only intended to be used to join 'user', rather than 'app', channels. + +### Recommended User Channel Set + +Desktop Agent implementations SHOULD use the following set of channels, to enable a consistent user experience across different implementations. Desktop Agent implementation MAY support configuration of the user channels. + +:::note +Future versions of the FDC3 Standard may support connections between desktop agents, where differing user channel sets may cause user experience issues. +::: + +```javascript +const recommendedChannels = [ + { + id: 'fdc3.channel.1', + type: 'user', + displayMetadata: { + name: 'Channel 1', + color: 'red', + glyph: '1', + }, + }, + { + id: 'fdc3.channel.2', + type: 'user', + displayMetadata: { + name: 'Channel 2', + color: 'orange', + glyph: '2', + }, + }, + { + id: 'fdc3.channel.3', + type: 'user', + displayMetadata: { + name: 'Channel 3', + color: 'yellow', + glyph: '3', + }, + }, + { + id: 'fdc3.channel.4', + type: 'user', + displayMetadata: { + name: 'Channel 4', + color: 'green', + glyph: '4', + }, + }, + { + id: 'fdc3.channel.5', + type: 'user', + displayMetadata: { + name: 'Channel 5', + color: 'cyan', + glyph: '5', + }, + }, + { + id: 'fdc3.channel.6', + type: 'user', + displayMetadata: { + name: 'Channel 6', + color: 'blue', + glyph: '6', + }, + }, + { + id: 'fdc3.channel.7', + type: 'user', + displayMetadata: { + name: 'Channel 7', + color: 'magenta', + glyph: '7', + }, + }, + { + id: 'fdc3.channel.8', + type: 'user', + displayMetadata: { + name: 'Channel 8', + color: 'purple', + glyph: '8', + }, + }, +]; +``` + +### Direct Listening and Broadcast on Channels + +While joining User channels (using [`fdc3.joinUserChannel`](ref/DesktopAgent#joinuserchannel)) automates a lot of the channel behavior for an app, it has the limitation that an app can only be 'joined' to one channel at a time. However, an app may instead retrieve an App [`Channel`](ref/Channel) Object via the [`fdc3.getOrCreateChannel`](ref/DesktopAgent#getorcreatechannel) API, create a [`PrivateChannel`](ref/PrivateChannel) via the [`fdc3.createPrivateChannel`](ref/DesktopAgent#createprivatechannel) API, or by raising an intent that returns a channel created by another app. The `Channel` object may then be used to listen to and broadcast on that channel directly using the [`Channel.addContextListener`](ref/Channel#addcontextlistener) and the [`Channel.broadcast`](ref/Channel#broadcast) APIs. FDC3 imposes no restriction on adding context listeners or broadcasting to multiple channels. + +### App Channels + +App Channels are topics dynamically created by applications connected via FDC3. For example, an app may create a named App Channel to broadcast data or status that is specific to that app to other apps that know to connect to the channel with that name. + +To get (or create) a [`Channel`](ref/Channel) reference, then interact with it: + +```js +const appChannel = await fdc3.getOrCreateChannel('my_custom_channel'); +// get the current context of the channel +const current = await appChannel.getCurrentContext(); +// add a listener +await appChannel.addContextListener(null, context => {...}); +// broadcast to the channel +await appChannel.broadcast(context); +``` + +An app can still explicitly receive context events on any [`Channel`](ref/Channel), regardless of the channel it is currently joined to. + +```js +// check for current fdc3 channel +let joinedChannel = await fdc3.getCurrentChannel() +//current channel is null, as the app is not currently joined to a channel + +//add a context listener for channels we join +const listener = await fdc3.addContextListener(null, context => { ... }); + +//retrieve an App channel and add a listener that is specific to that channel +const myChannel = await fdc3.getOrCreateChannel('my_custom_channel'); +const myChannelListener = await myChannel.addContextListener(null, context => { ... }); + +fdc3.joinChannel('blue') +joinedChannel = await fdc3.getCurrentChannel() +//current channel is now the 'blue' channel +``` + +if another application broadcasts to "my_custom_channel" (by retrieving it and broadcasting to it via `myChannel.broadcast()`) then the broadcast will be received by the specific listener (`myChannelListener`) but NOT by the listener for joined channels (`listener`). + +### Private Channels + +A [`PrivateChannel`](ref/PrivateChannel) is created to support the return of a stream of responses from a raised intent, or private dialog between two applications. + +It is intended that Desktop Agent implementations: + +- SHOULD restrict external apps from listening or publishing on this channel. +- MUST prevent `PrivateChannels` from being retrieved via `fdc3.getOrCreateChannel`. +- MUST provide the `id` value for the channel as required by the `Channel` interface. + +The `PrivateChannel` type also supports synchronization of data transmitted over returned channels. They do so by extending the `Channel` interface with event handlers which provide information on the connection state of both parties, ensuring that desktop agents do not need to queue or retain messages that are broadcast before a context listener is added and that applications are able to stop broadcasting messages when the other party has disconnected. + +### Broadcasting and listening for multiple context types + +The [Context specification](../context/spec#assumptions) recommends that complex context objects are defined using simpler context types for particular fields. For example, a `Position` is composed of an `Instrument` and a holding amount. This leads to situations where an application may be able to receive or respond to context objects that are embedded in a more complex type, but not the more complex type itself. For example, a pricing chart might respond to an `Instrument` but doesn't know how to handle a `Position`. + +To facilitate context linking in such situations it is recommended that applications `broadcast` each context type that other apps (listening on a User Channel or App Channel) may wish to process, starting with the simpler types, followed by the complex type. Doing so allows applications to filter the context types they receive by adding listeners for specific context types - but requires that the application broadcasting context make multiple broadcast calls in quick succession when sharing its context. + +### Originating App Metadata + +Optional metadata about each context message received, including the app that originated the message, SHOULD be provided by the desktop agent implementation to registered context handlers on all types of channel. As this metadata is optional, apps making use of it MUST handle cases where it is not provided. diff --git a/website/versioned_docs/version-2.1/app-directory/overview.md b/website/versioned_docs/version-2.1/app-directory/overview.md new file mode 100644 index 000000000..285448565 --- /dev/null +++ b/website/versioned_docs/version-2.1/app-directory/overview.md @@ -0,0 +1,175 @@ +--- +id: overview +sidebar_label: Overview +title: App Directory Overview (2.1) +--- + +An application directory (appD) is a structured repository of information about apps that can be used in an FDC3-enabled desktop. In other words, it’s a convenient way of storing and managing metadata about apps in your ecosystem. + +The application metadata stored in appD records may include: the app name, type, details about how to run the application, its icons, publisher, support contact details and so on. It may also include links to or embed manifest formats defined elsewhere, such as proprietary manifests for launching the app in a container product or a Web Application Manifest (as [defined by the W3C](https://www.w3.org/TR/appmanifest/)). + +All this information is readily available in one place and can be used both to populate a launcher or app catalog UI for your users, and by the Desktop Agent managing the apps on your desktop. In fact, if your desktop platform supports the FDC3 standard, appD is the primary way that the FDC3 Desktop Agent implementation should receive the details about apps available to run on your desktop. Conversely, if an app is not listed in appD, the Desktop Agent can’t ensure its participation in context sharing or use it to resolve intents. + +## Advantages + +Using appD offers many advantages both for financial institutions running an FDC3-enabled desktop container and for vendors that provide FDC3-compliant apps: + +### For the user + +#### Easier to Find App Info + +Your appD is the one place to collect all the information about apps. The more apps you have, the more you’ll appreciate the convenience of not having to chase down details about each. This is particularly important for large institutions with multiple desks. + +#### Human Readable + +AppD has two types of users. One is the Desktop Agent, but the other is humans administrating and using the smart desktop at your organization. Hence, an appD contains information about apps in both machine- and human-readable forms. For example, it includes both unique identifiers for apps that are used to refer to them in code and human-friendly app names, icons, descriptions and tooltips necessary to populate a launcher menu or app catalog user interface for your users. + +#### Apps are Discoverable + +For large institutions, it can be difficult to keep track of all the apps (developed both in-house and by vendors), since a typical desktop could have many. Users can search appD to discover the apps they need. An app might already reside on their system or be available to them over the internet, but if they don’t have a way to search the apps available to them, they won’t be able to find it. An appD provides a way for users to discover the apps they need. + +An appD makes it possible to discover info about apps that reside on various domains, not just the one domain the appD itself is hosted on. In addition, you can find details about how to launch the apps in multiple, diverse environments. This is a different use-case to, for example, the [W3C's Web App Manifest](https://www.w3.org/TR/appmanifest/), which is hosted on the same domain as the app, is limited to web apps, and is generally used to 'install' an app that the user has already accessed. + +#### Updating Apps + +Typically, software evolves over time. The app versions you are running today will not be the same ones you need tomorrow. Therefore, you will need to upgrade apps periodically. Very few people look forward to upgrading, but appD and web deployment can make it easier for you. To roll out a new version of your app, either update the existing entry for it in appD or add a new entry for that version (allowing users to select the version they will use). + +#### Agent-agnostic + +As a part of the FDC3 standard, appD isn't tied to any specific vendor. This is important, as it allows you more flexibility in that you are not tied to any specific container or Desktop Agent implementation. If at any point you want to switch to a different Desktop Agent, the process won’t be prohibitively difficult. The existing appD will work without any additional effort from you, as long as your new Desktop Agent is also FDC3-compliant. This is in contrast with proprietary solutions, where you would have to produce a new configuration and integration for every application. + +AppD reduces fragmentation in the market and allows end-users more flexibility in what applications can be included in their desktop. + +#### Intent Resolution + +AppD provides information to the Desktop Agent on which applications can handle particular [intents](../intents/spec) and the context types they support as input to them. This allows the Desktop Agent to implement an [intent resolver](../api/spec#resolvers) that can launch applications and pass the intent and context to them to operate on, supporting workflows between applications that didn't require prior bilateral agreements between the application providers. + +### For an Application Provider + +Until now, we've looked at appD from the perspective of a desktop owner and user. But appD also offers advantages to vendors who develop apps for the financial services desktop. + +#### Apps Work Well Together Out-of-the-box + +When your customers add your FDC3-compliant app to their desktop via an appD record accurately describing it, you can be sure that your app will interoperate with other apps that follow the FDC3 standard. You don’t have to do anything special, or arrange a bilateral agreement with anyone else. The benefit of the open standard is that any app that follows it will work well with any other compliant app. + +#### Easy Updates + +As a vendor, you prefer for all your customers to run your latest software. However, many customers will postpone upgrades, sometimes for a long time, because upgrading can be a pain. An advantage of a vendor-hosted appD is that the configuration of an app can be updated at any time and, if your customers need to choose when to upgrade, multiple versions of it can be made available, each with their own configuration. By making it easier for customers to update, you can drive better adoption. + +### For the Industry + +By hosting our own appD we can easily combine applications from various providers into one cohesive directory. Alternatively, we can connect to directories from multiple providers (in standardized format) and provide a single view over them. This reduces fragmentation in the market, allows end-users more flexibility in what apps to include in their smart desktop, and obviates the need for vendors to provide application details in diverse formats or for their customers to work out these details for themselves. + +## Relationship to Other Standards + +The App Directory's application record is similar to application manifests defined in other standards, in particular the W3C's [Web Application Manifest](https://www.w3.org/TR/appmanifest/). However, the App Directory, and by extension the application record, serve a different set of use-cases specific to application interoperability on financial services desktops, which other standards do not fully address. + +Wherever possible, FDC3 seeks to draw inspiration from, align itself with and reference other standards - ensuring that conventions and best practices developed by those standards are reused, along with the standard itself (e.g. data formats in ISO standard formats, external links to technology-specific manifest file formats etc.). For a list of standards that FDC3 references, see the [References](../references) page. + +## Use Cases + +An application directory provides information about an application's identifiers, publisher details, intents that it supports, and metadata necessary to launch and integrate the application in a Desktop Agent. + +The following provides a summary of use cases. + +### Launcher + +A Desktop Agent will usually include a user interface allowing the user to select from a set of launchable applications and then allow them to manually launch one. It is also responsible for launching applications necessary to resolve a raised intent. However, it must first retrieve the necessary metadata about the available applications. An app directory provides an endpoint to retrieve a list of the available applications along with their metadata, which may include or link to additional information necessary to launch the application in a specific Desktop Agent. + +A launcher will usually be configured with the locations of one or more AppD servers (which is necessary to implement intent resolution), however, as described in the [Service Discovery](#service-discovery) section, a fully qualified application identifier (e.g. `app1@host.appd.com`) may also be used to both locate the appD service and to retrieve the specific application data. + +![img](/assets/appd_launcher_embedded.png) + +### Aggregated View + +There could be many different appD service instances in the world providing application data zoned to the provider or enterprise deployment. The appD specification allows for unique instances of the service with no requirement to aggregate data or define a structured hierarchy. With this said, a launcher might want to construct an aggregated view of applications from one or more appD instances. In this case, the launcher would be required to retrieve multiple application definitions from one or more appD instances providing a consolidated view of all applications required. + +Today, there is no intention to create a single registry of known AppD instances, so there is an assumption that the launcher will have prior +knowledge of the AppD instance location. + +![img](/assets/appd_launcher_aggregated.png) + +### Authentication and Entitlements + +The AppD API specification defines the optional use of an access token to identify the requesting user/launcher and implement authorizations which may affect appD API responses. For example, different subsets of the full list of applications may be returned for different users depending on their role in an organization. + +The specification does not define or make mandatory any authorizations or roles that a provider or enterprise can define. + +## Application Identifiers + +Application Records served by an app directory are each labelled with an identifier, `appId`, which should be unique within the app directory instance and may be used to refer to or retrieve the application's record via the [app directory API](spec). This identifier may be made globally unique through a nested namespace approach and email address construction (`appId@fqdn`) where `@` followed by the app directory instance's host name is appended to it. The resulting globally unique identifier is known as a 'fully qualified application identifier'. + +Fully qualified appIds may be used to locate the appD instance hosting the application's record. See the [Service Discovery](#service-discovery) section for details. + +### Shrinking the URI + +Although the concept of fully qualified application IDs are useful in resolving the actual host of the application directory, there is no requirement for an application directory to use this fully qualified application ID as the resolver for a record. An application ID is unique to given application directory, but there is no requirement to use the fully qualified representation when querying an interface. Taking the prior example, the fully qualified application ID `app1@appd.foo.com` is represented as `app1` within the application directory. As a result a launcher can use a shortened URI construct `https://appd.foo.com/api/appd/v2/apps/app1` to resolve the application data vs `https://appd.foo.com/api/appd/v2/apps/app1@appd.foo.com`. + +## Service Discovery + +In order to support the discovery of applications that can be used with a Desktop Agent, it is necessary to access data stored in one or more app directory instances. + +![img](/assets/appd_service_distribution.png) + +However, in order to do so, you must first discover the location of an app directory service, which you may then use to generate URIs (e.g. `https://appd.foo.com/api/appd/v2/apps/app1@appd.foo.com`) to query a given directory instance for data. In order to construct a URI, the host location and port of a given AppD service instance is required. + +Three methods for discovering app directory services are defined in this Standard: + + 1. **Static configuration:** Statically defined URI records for use within client applications (typically a Desktop Agent implementation) directly. + 2. **Fully-qualified appID namespace syntax host resolution:** Discovery of the appD location using a fully qualified application ID (appId) domain name. + 3. **DNS lookup by domain name:** Discovery of the appD location using a domain name to lookup DNS SRV records identifying the host server location and TCP port. ([RFC2782](https://tools.ietf.org/html/rfc2782)) + +App directory service host discovery implementations SHOULD support each of these methods and MUST support at least static configuration. + +### Static configuration + +As the name implies, a static configuration for an appD service location is defined within a Desktop Agent or launcher application. This is the simplest and most common approach to app directory and application data discovery. + +![img](/assets/appd_static_config.png) + +### Fully-qualified appID namespace syntax host resolution + +An app directory URI can be constructed using a [fully qualified application ID](spec#applicationidentifiers) (email address syntax) by using fqdn part of the ID as the host location and the name part as the application name. Given an application id `app1` with a fully qualified identifier of `app1@appd.foo.com` an application directory host location can be derived by simply extracting the fqdn "appd.foo.com" from the email syntax. The extracted fqdn "app.foo.com" MUST resolve to the actual host location where the application directory is running. + +A launcher can then easily construct a URI by: + +1. URI protocol is defaulted to `https`, but can be overridden by the launcher. +2. URI hostname is the fully qualified domain of the application ID. +3. URI port is default `https/443`, but can be overridden by the launcher +4. URI url is by default `/api/appd/(version)/apps` . Calls that are made without version MUST automatically default to latest, i.e. `/api/appd/apps/app1` should return the same result as `/api/appd/v2/apps/app1". + +The resulting URI to retrieve application data for `app1` would be + +### DNS/SRV Records + +Another approach to support app directory service discovery (resolution) is through use of existing domain name service (DNS) implementations that are broadly used on the Internet today (see: [RFCs](https://www.isc.org/community/rfcs/dns/)). Name service implementations can be considered critical infrastructure and are proven stable with over twenty years of use. Name services can be used both through public Internet or locally deployed intranet, which provides optionality to deployment schemes. + +More specifically, resolution of an appD service instance (host location) can be implemented using DNS "service records" (SRV) providing the host instance, protocol and associated port. The following is a well-known description of a SRV record ([RFC2782](https://tools.ietf.org/html/rfc2782)): + +```text +zone name { _service._proto.name. TTL class SRV priority weight port target.} +``` + +- *`service`*: the symbolic name of the desired service. For AppD service, this must be identified as **`_appd`** +- *`proto`*: the transport protocol of the desired service; this is usually either [TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) or [UDP](https://en.wikipedia.org/wiki/User_Datagram_Protocol). For AppD service **_tcp** must be used. +- *`name`*: the domain name for which this record is valid, ending in a dot. For AppD service, the name should directly map to the application identifier domain. +- *`TTL`*: standard DNS [time to live](https://en.wikipedia.org/wiki/Time_to_live) field. +- *`class`*: standard DNS class field (this is always *IN*). +- *`priority`*: the priority of the target host, lower value means more preferred. +- *`weight`*: A relative weight for records with the same priority, higher value means more preferred. +- *`port`*: the TCP or UDP port on which the service is to be found. For AppD service, TCP should always be used. +- *`target`*: the canonical hostname of the machine providing the service, ending in a dot. This would be the host where the AppD service is running. + +For AppD Service the SRV record MUST use the following definitions: + +- `service` = **`_appd`** +- `proto` = **`_tcp`** +- `name` = must map to the domain of the application identifier . Example: the `name` for application identifier `app1@appd.foo.com` would be `appd.foo.com` + +*AppD service through DNS / SRV records:* + +![img](/assets/appd_dns.png) + +#### Known domains + +Although SRV records provide the means of resolving the location of an app directory service for a specific domain, there could be a need to know what domains exist in the universe. This would be a list of domains representing all known directory instances. It is recommended that the FDC3/FINOS organization publish a list of known domains which support AppD services. This publication can be handled in multiple ways, such as structured files or API endpoints. This proposal shall not provide a qualified solution to achieve this, but rather draw attention to a potential requirement. diff --git a/website/versioned_docs/version-2.1/app-directory/spec.md b/website/versioned_docs/version-2.1/app-directory/spec.md new file mode 100644 index 000000000..727824800 --- /dev/null +++ b/website/versioned_docs/version-2.1/app-directory/spec.md @@ -0,0 +1,51 @@ +--- +id: spec +sidebar_label: API +title: App Directory API (2.1) +--- + +View the [full specification][1] in [OpenAPI v3.0][2] format (generated with [ReDoc][3]), +or explore with the [Swagger Editor][4]. + +[1]: pathname:///schemas/2.1/app-directory.html +[2]: https://www.openapis.org/ +[3]: https://github.com/Redocly/redoc/ +[4]: https://editor.swagger.io/?url=https://fdc3.finos.org/schemas/2.1/appd.schema.json + +## Endpoints + + Endpoint | Method | Description + ------------------ | ------ | ----------- + `/v2/apps` | GET | Retrieve all application definitions + `/v2/apps/{appId}` | GET | Retrieve an application definition + `/v1/apps` | POST | (deprecated v1 API version) Create a new application definition + `/v1/apps/{appId}` | GET | (deprecated v1 API version) Retrieve an application definition + `/v1/apps/search` | GET | (deprecated v1 API version) Retrieve a list of applications + +App Directory implementations MAY extend the list of endpoints to provide other necessary functionality. However, FDC3 Desktop Agent implementations that connect to app directories MUST support connection to app directories that only provide the minimum endpoints listed here. + +## App Directory Standard Compliance + +An FDC3 Standard compliant App Directory implementation **MUST**: + +- Implement the specified `/v2` endpoints for retrieving app definitions as defined in the [app directory OpenAPI specification](pathname:///schemas/2.1/app-directory.html#tag/Application): + - `/v2/apps` (GET) + - `/v2/apps/{appId}` (GET) +- Ensure that `appId` field values assigned to applications are unique within the directory. +- Ensure that app directory records served meet the minimum requirements specified in the [app directory OpenAPI specification](pathname:///schemas/2.1/app-directory.html#tag/Application) +- Support retrieval of app directory records via either the raw `appId` (e.g. `myAppId`) or fully-qualified appId (e.g. `myAppId@host.domain.com`) as defined in the [app directory overview](overview#shrinking-the-uri). + +An FDC3 Standard compliant App Directory implementation **SHOULD**: + +- Support authentication (where required) via the HTTP Authorization header and Bearer authentication schema (implemented via JWT tokens) +- Select any `categories` field values from the recommended list. +- Encourage the use of the `lang` and `localizedVersions` fields in appD records to support localization and accessibility. + +An FDC3 Standard compliant App Directory implementation **MAY**: + +- Support filtering of application records returned by user entitlement, where authentication is enabled. +- Implement the deprecated `/v1` endpoints provided for backwards compatibility with prior version of the standard: + - `/v1/apps` (POST) + - `/v1/apps/{appId}` (GET) + - `/v1/apps/search` (GET) +- Extend the implementation with additional endpoints. diff --git a/website/versioned_docs/version-2.1/context/ref/Action.md b/website/versioned_docs/version-2.1/context/ref/Action.md new file mode 100644 index 000000000..982fa8177 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Action.md @@ -0,0 +1,74 @@ +--- +id: Action +sidebar_label: Action +title: Action +hide_title: true +--- +# `Action` + +A representation of an FDC3 Action (specified via a Context or Context & Intent) that can be inserted inside another object, for example a chat message. + +The action may be completed by calling `fdc3.raiseIntent()` with the specified Intent and Context, or, if only a context is specified, by calling `fdc3.raiseIntentForContext()` (which the Desktop Agent will resolve by presenting the user with a list of available Intents for the Context). + +Accepts an optional `app` parameter in order to specify a specific app. + +## Type + +`fdc3.action` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------------|-------------------------------------------|----------|-------------------------| +| `type` | string | Yes | `'fdc3.action'` | +| `title` | string | Yes | `'Click to view Chart'` | +| `intent` | string | No | `'ViewChart'` | +| `context` | string | Yes | See Below | +| `app` | object | No | `'myApp'` | +| `app.appId` | string | Yes | `'app1'` | +| `app.instanceId` | string | No | `'instance1'` | + +## Example + +```js +const action = { + type: 'fdc3.action', + title: 'Click to view Chart', + intent: 'ViewChart', + context { + type: 'fdc3.chart', + instruments: [ + { + type: 'fdc3.instrument', + id: { + ticker: 'EURUSD' + } + } + ], + range: { + type: 'fdc3.dateRange', + starttime: '2020-09-01T08:00:00.000Z', + endtime: '2020-10-31T08:00:00.000Z' + }, + style: 'candle' + }, + app { + appId: 'MyChartViewingApp', + instanceId: 'instance1' + } +} +``` + +## See Also + +Other Types + +- [Message](Message) + +Intents + +- [StartChat](../../intents/ref/StartChat) diff --git a/website/versioned_docs/version-2.1/context/ref/Chart.md b/website/versioned_docs/version-2.1/context/ref/Chart.md new file mode 100644 index 000000000..dadc54bd3 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Chart.md @@ -0,0 +1,99 @@ +--- +id: Chart +sidebar_label: Chart +title: Chart +hide_title: true +--- +# `Chart` + +A context type representing details of a Chart, which may be used to request plotting of a particular chart or to otherwise share details of its composition, such as: + +- A list of instruments for comparison +- The time period to plot the chart over +- The style of chart (line, bar, mountain, candle etc.) +- Other settings such as indicators to calculate, or data representing drawings and annotations + +In addition to handling requests to plot charts, a charting application may use this type to output a representation of what it is currently displaying so that it can be recorded by another application. + +## Type + +`fdc3.chart` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|------------------|-----------------|----------|----------------------| +| `type` | string | Yes | `'fdc3.chart'` | +| `instruments` | Instrument[] | Yes |
[
  {
    "type": "fdc3.instrument",
    "id": {
      "ticker": "AAPL"
    }
  },
  {
    "type": "fdc3.instrument",
    "id": {
      "ticker": "MSFT"
    }
  }
]
| +| `range` | TimeRange | No |
{
  "type": "fdc3.timerange",
  "startTime": "2022-03-30T15:44:44+00:00",
  "endTime": "2022-04-30T23:59:59+00:00"
}
| +| `style` | string | No | one of: `'line'`, `'bar'`, `'stacked-bar'`, `'mountain'`, `'candle'`, `'pie'`, `'scatter'`, `'histogram'`, `'heatmap'`, `'custom'` | +| `otherConfig`* | array | No | `[ {/* additional config context objects */} ]` | + +::: info + +It is common for charts to support other configuration, such as indicators, annotations etc., which do not have standardized formats, but may be included in the `otherConfig` array as context objects. + +::: + +## Example + +```js +const chart = { + type: "fdc3.chart", + instruments: [ + { + type: "fdc3.instrument", + id: { + ticker: "AAPL" + } + }, + { + type: "fdc3.instrument", + id: { + ticker: "GOOG" + } + } + ], + range: { + type: "fdc3.timeRange", + startTime: "2020-09-01T08:00:00.000Z", + endTime: "2020-10-31T08:00:00.000Z" + }, + style: "line", + otherConfig: [ + { + type: "somevendor.someproduct.indicator", + name: "stddev", + parameters: { + period: 10, + matype: "exponential" + } + }, + { + type: "someothervendor.someotherproduct.formula", + formula: "standard-deviation", + fields: { + lookback: 10, + type: "ema" + } + } + ] +}; + +fdc3.raiseIntent("ViewChart", chart); +``` + +## See Also + +Other Types + +- [Instrument](Instrument) +- [TimeRange](TimeRange) + +Intents + +- [ViewChart](../../intents/ref/ViewChart) diff --git a/website/versioned_docs/version-2.1/context/ref/ChatInitSettings.md b/website/versioned_docs/version-2.1/context/ref/ChatInitSettings.md new file mode 100644 index 000000000..1dab98548 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/ChatInitSettings.md @@ -0,0 +1,105 @@ +--- +id: ChatInitSettings +sidebar_label: ChatInitSettings +title: ChatInitSettings +hide_title: true +--- + +# `ChatInitSettings` + +A collection of settings to start a new chat conversation + +## Type + +`fdc3.chat.initSettings` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +| ------------------------------ | ----------- | -------- | -------------------------------------------------------------------- | +| `type` | string | Yes | `'fdc3.chat.initSettings'` | +| `chatName` | string | No | `'Instrument XYZ'` | +| `members` | ContactList | No | ContactList - cf. below | +| `message` | Message | No | Message - cf. below | +| `options.groupRecipients` | boolean | No | `true`: if false a separate chat will be created for each member | +| `options.isPublic` | boolean | No | `true`: the room will be visible to everyone in the chat application | +| `options.allowHistoryBrowsing` | boolean | No | `true`: members will be allowed to browse past messages | +| `options.allowMessageCopy` | boolean | No | `true`: members will be allowed to copy/paste messages | +| `options.allowAddUser` | boolean | No | `true`: members will be allowed to add other members to the chat | + +If _members_ or _chatName_ are not provided, the application executing this +intent is expected to provide a means to enter such information. + +## Example + +```js +const initSettings = { + type: 'fdc3.chat.initSettings', + chatName: 'Chat ABCD', + members: { + type: 'fdc3.contactList', + contacts: [{ + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } + },{ + type: 'fdc3.contact', + name: 'John Doe', + id: { + email: 'john@mail.com' + }, + }] + }, + options: { + groupRecipients: true, // one chat with both contacts + isPublic: false, // private chat room + allowHistoryBrowsing: true, + allowMessageCopy: true + }, + message: { + type: 'fdc3.message', + text: { + 'text/plain': 'Hey all, can we discuss the issue together? I attached a screenshot' + }, + entities: { + '0': { + type: 'fdc3.fileAttachment', + data: { + name: 'myImage.png', + dataUri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII' + } + } + } + } +} + +const res = fdc3.raiseIntent('StartChat', initSettings); + +// Return a reference to the room +const chatRoom = await res.getResult(); +``` + +## See Also + +Other Types + +- [ChatRoom](ChatRoom) +- [ContactList](ContactList) +- [Message](Message) + +Intents + +- [StartChat](../../intents/ref/StartChat) +- [StartCall](../../intents/ref/StartCall) +- [SendChatMessage](../../intents/ref/StartChat) +- [ViewContact](../../intents/ref/ViewContact) + +FINOS Financial Objects + +- [Contact](https://fo.finos.org/docs/objects/contact) diff --git a/website/versioned_docs/version-2.1/context/ref/ChatMessage.md b/website/versioned_docs/version-2.1/context/ref/ChatMessage.md new file mode 100644 index 000000000..271047e26 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/ChatMessage.md @@ -0,0 +1,51 @@ +--- +id: ChatMessage +sidebar_label: ChatMessage +title: ChatMessage +hide_title: true +--- +# `ChatMessage` + +A context representing a chat message. Typically used to send the message or to pre-populate a message for sending. + +## Type + +`fdc3.chat.message` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------|---------|----------|-------------------| +| `type` | string | Yes | `'fdc3.chat.message'` | +| `chatRoom` | ChatRoom | Yes | `{ type: 'fdc3.chat.room', providerName: 'Symphony', id:{ streamId: 'j75xqXy25NBOdacUI3FNBH'} }` | +| `message` | [Message](https://fdc3.finos.org/schemas/2.1/message.schema.json) | Yes | `'A message to send'` | + +## Example + +```js +const chatMessage = { + type: "fdc3.chat.message", + chatRoom: { + type: 'fdc3.chat.room', + providerName: "Symphony", + id: { + streamId: "j75xqXy25NBOdacUI3FNBH" + } + }, + message: "A message to send" +} +``` + +## See Also + +Intents +- [StartChat](../../intents/ref/StartChat) +- [StartCall](../../intents/ref/StartCall) +- [SendChatMessage](../../intents/ref/SendChatMessage) + +FINOS Financial Objects +- [Contact](https://fo.finos.org/docs/objects/contact) diff --git a/website/versioned_docs/version-2.1/context/ref/ChatRoom.md b/website/versioned_docs/version-2.1/context/ref/ChatRoom.md new file mode 100644 index 000000000..9e1ff1b71 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/ChatRoom.md @@ -0,0 +1,64 @@ +--- +id: ChatRoom +sidebar_label: ChatRoom +title: Contact +hide_title: true +--- +# `ChatRoom` + +Reference to the chat room, which could be used later to send a message to the room. + +## Type + +`fdc3.chat.room` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------|---------|----------|-------------------| +| `type` | string | Yes | `'fdc3.chat.room'` | +| `providerName` | string | Yes | `'Symphony'` | +| `id` | object | Yes | `{ streamId: 'j75xqXy25NBOdacUI3FNBH', anyOtherKey: 'abcdef'}` | +| `url` | string | No | `'http://symphony.com/ref/room/j75xqXy25NBOdacUI3FNBH___pqSsuJRdA'` | +| `name` | string | No | `'My new room'` | + +The `url` is a universal url to access to the room. It could be opened from a browser, a mobile app, etc... + +## Example + +```js +const chatRoom = { + type: "fdc3.chat.room", + providerName: "Symphony", + id: { + streamId: "j75xqXy25NBOdacUI3FNBH" + } + url: "http://symphony.com/ref/room/j75xqXy25NBOdacUI3FNBH___pqSsuJRdA", + name: 'My new room' +}; + +//Chat rooms are returned by the StartChat intent as a result +const intentResolution = await fdc3.raiseIntent("StartChat", context); + +try { + const chatRooms = await intentResolution.getResult(): +} catch (error) { + //chat room were not created... +} +``` + +## See Also + +Other Types +* [ChatInitSettings](ChatInitSettings) + +Intents +- [StartChat](../../intents/ref/StartChat) +- [SendChatMessage](../../intents/ref/SendChatMessage) + +FINOS Financial Objects +- [Contact](https://fo.finos.org/docs/objects/contact) diff --git a/website/versioned_docs/version-2.1/context/ref/ChatSearchCriteria.md b/website/versioned_docs/version-2.1/context/ref/ChatSearchCriteria.md new file mode 100644 index 000000000..043019bf2 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/ChatSearchCriteria.md @@ -0,0 +1,64 @@ +--- +id: ChatSearchCriteria +sidebar_label: ChatSearchCriteria +title: ChatSearchCriteria +hide_title: true +--- +# `ChatSearchCriteria` + +A context type that represents a simple search criterion, based on a list of other context objects, that can be used to search or filter messages in a chat application. + +## Type + +`fdc3.chat.searchCriteria` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|------------------|-----------------|----------|----------------------| +| `type` | string | Yes | `'fdc3.chat.searchCriteria'` | +| `criteria` | (Instrument |
Contact |
Organization |
string)[] | Yes |
[
  {
    "type": "fdc3.instrument",
    "id": {
      "ticker": "AAPL"
    }
  },
  {
    "type": "fdc3.contact",
    "name":"Jane Doe",
    "id": {
      "email": "jane.doe@mail.com"
    }
  },
  {
    "type": "fdc3.organization",
    "name":"Symphony",
  },
  "#OrderID45788422",
]
| + +⚠️ Operators (and/or/not) are not defined in `fdc3.chat.searchCriteria`. It is up to the application that processes the FDC3 Intent to choose and apply the operators between the criteria. + +Empty search criteria can be supported to allow resetting of filters. + +## Example + +```js +const searchCriteria = { + type: "fdc3.chat.searchCriteria", + criteria: [ + { + type: "fdc3.instrument", + id: { + ticker: "AAPL" + } + }, + { + type: "fdc3.contact", + name: "Jane Doe", + id: { + email: "jane.doe@mail.com" + } + }, + { + type: "fdc3.organization", + name: "Symphony" + }, + "#OrderID45788422" + ] +} + +fdc3.raiseIntent('ViewMessages', searchCriteria); +``` + +## See Also + +Intents + +* [ViewMessages](../../intents/ref/ViewMessages) diff --git a/website/versioned_docs/version-2.1/context/ref/Contact.md b/website/versioned_docs/version-2.1/context/ref/Contact.md new file mode 100644 index 000000000..38a0d0ac9 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Contact.md @@ -0,0 +1,61 @@ +--- +id: Contact +sidebar_label: Contact +title: Contact +hide_title: true +--- +# `Contact` + +A person contact that can be engaged with through email, calling, messaging, CMS, etc. + +## Type + +`fdc3.contact` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------|---------|----------|-------------------| +| `type` | string | Yes | `'fdc3.contact'` | +| `name` | string | No | `'Jane Doe'` | +| `id.email` | string | No | `'jane@mail.com'` | +| `id.FDS_ID` | string | No | `'ABC123-E'` | + +## Example + +```js +const contact = { + type: "fdc3.contact", + name: "Jane Doe", + id: { + email: "jane.doe@mail.com" + } +} + + +fdc3.broadcast(contact) +``` + +## See Also + +Other Types + +- [ContactList](ContactList) + +Intents + +- [CreateInteraction](../../intents/ref/CreateInteraction) +- [StartChat](../../intents/ref/StartChat) +- [StartCall](../../intents/ref/StartCall) +- [ViewProfile](../../intents/ref/ViewProfile) +- [ViewResearch](../../intents/ref/ViewResearch) +- [ViewInteractions](../../intents/ref/ViewInteractions) +- [ViewOrders](../../intents/ref/ViewOrders) + +FINOS Financial Objects + +- [Contact](https://fo.finos.org/docs/objects/contact) diff --git a/website/versioned_docs/version-2.1/context/ref/ContactList.md b/website/versioned_docs/version-2.1/context/ref/ContactList.md new file mode 100644 index 000000000..138975778 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/ContactList.md @@ -0,0 +1,73 @@ +--- +id: ContactList +sidebar_label: ContactList +title: ContactList +hide_title: true +--- +# `ContactList` + +A collection of contacts, e.g. for chatting to or calling multiple contacts. + +Notes: + +- The contact list schema does not explicitly include identifiers in the `id` section, as there +is not a common standard for such identifiers. Applications can, however, populate +this part of the contract with custom identifiers if so desired. + +## Type + +`fdc3.contactList` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------|-----------|----------|------------------------| +| `type` | string | Yes | `'fdc3.contactList'` | +| `id` | object | No | `{ customId: '5576' }` | +| `name` | string | No | `'My address book'` | +| `contacts` | Contact[] | Yes | `[contact1, contact2]` | + +## Example + +```js +const contacts = { + type: "fdc3.contactList", + contacts: [ + { + type: "fdc3.contact", + name: "Jane Doe", + id: { + email: "jane.doe@mail.com" + } + }, + { + type: "fdc3.contact", + name: "John Doe", + id: { + email: "john.doe@mail.com" + } + }, + ] +} +fdc3.raiseIntent("StartChat", contacts) +``` + +## See Also + +Other Types + +- [Contact](Contact) + +Intents + +- [CreateInteraction](../../intents/ref/CreateInteraction) +- [StartChat](../../intents/ref/StartChat) +- [StartCall](../../intents/ref/StartCall) + +FINOS Financial Objects + +- [ContactList](https://fo.finos.org/docs/objects/contactlist) diff --git a/website/versioned_docs/version-2.1/context/ref/Context.md b/website/versioned_docs/version-2.1/context/ref/Context.md new file mode 100644 index 000000000..fbc6d48cf --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Context.md @@ -0,0 +1,80 @@ +--- +id: Context +sidebar_label: Context +title: Context +hide_title: true +--- +# `Context` + +The `fdc3.context` type defines the basic contract or "shape" for all data exchanged by FDC3 operations. As such, it is not +really meant to be used on its own, but is imported by more specific type definitions (standardised or custom) to provide +the structure and properties shared by all FDC3 context data types. + +The key element of FDC3 context types is their mandatory `type` property, which is used to identify what type of data the +object represents, and what shape it has. + +Notes: + +- The FDC3 context type, and all derived types, define the minimum set of fields a context data object of a particular type +can be expected to have, but this can always be extended with custom fields as appropriate. + +## Type + +`fdc3.context` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------|---------|----------|----------------------------------| +| `type` | string | Yes | `'fdc3.context'` | +| `name` | string | No | `'Display name'` | +| `id` | object | No | `{ id: 'value', 'id': 'value' }` | + +### `type` (required) + +The type property is the only _required_ part of the FDC3 context data schema. +The FDC3 [API](../../api/spec) relies on the `type` property being present to route shared context data appropriately. + +FDC3 [Intents](../../intents/spec) also register the context data types they support in an FDC3 [App Directory](../../app-directory/overview), used for intent discovery and routing. + +Standardized FDC3 context types have well-known `type` properties prefixed with the `fdc3` namespace, e.g. `fdc3.instrument`. +For non-standard types, e.g. those defined and used by a particular organization, the convention is to prefix them with an +organization-specific namespace, e.g. `blackrock.fund`. + +See the [Context Data Specification](../../context/spec) for more information about context data types. + +### `name` (optional) + +Context data objects may include a name property that can be used for more information, or display purposes. Some +derived types may require the name object as mandatory, depending on use case. + +### `id` (optional) + +Context data objects may include a set of equivalent key-value pairs that can be used to help applications +identify and look up the context type they receive in their own domain. The idea behind this design is that applications can provide as many equivalent identifiers to a target application as possible, e.g. an instrument may be represented by an ISIN, CUSIP or Bloomberg identifier. + +Identifiers do not make sense for all types of data, so the `id` property is therefore optional, but some derived types may choose to require at least one identifier. + +## See Also + +FDC3 Specifications + +- [Context Data](../../context/spec) +- [Intents](../../intents/spec) +- [API](../../api/spec) +- [App Directory](../../app-directory/spec) + +FDC3 Context Types + +- [Contact](Contact) +- [ContactList](ContactList) +- [Country](Country) +- [Instrument](Instrument) +- [InstrumentList](InstrumentList) +- [Organization](Organization) +- [Position](Position) +- [Portfolio](Portfolio) diff --git a/website/versioned_docs/version-2.1/context/ref/Country.md b/website/versioned_docs/version-2.1/context/ref/Country.md new file mode 100644 index 000000000..f606d1ff5 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Country.md @@ -0,0 +1,64 @@ +--- +id: Country +sidebar_label: Country +title: Country +hide_title: true +--- +# `Country` + +A country entity. + +Notes: + +- It is valid to include extra properties and metadata as part of the country payload, but the minimum requirement +is for at least one standardized identifier to be provided + - `COUNTRY_ISOALPHA2` SHOULD be preferred. + +- Try to only use country identifiers as intended and specified in the [ISO standard](https://en.wikipedia.org/wiki/ISO_3166-1). E.g. the `COUNTRY_ISOALPHA2` property must be a recognized value and not a proprietary two-letter code. If the identifier you want to share is not a standardized and recognized one, rather define a property that makes it clear what value it is. This makes it easier for target applications. + +## Type + +`fdc3.country` + +## Schema + + + + +## Details + +| Property | Type | Required | Example Value | +|--------------------------|---------|----------|----------------------| +| `type` | string | Yes | `'fdc3.country'` | +| `name` | string | No | `'Sweden'` | +| `id.COUNTRY_ISOALPHA2` | string | Yes | `'SE'` | +| `id.COUNTRY_ISOALPHA3` | string | No | `'SWE'` | +| `id.ISOALPHA2` * | string | No | `'SE'` | +| `id.ISOALPHA3` * | string | No | `'SWE'` | + +\* Field names deprecated in FDC3 2.0 in favour of the versions prefixed with `COUNTRY_`. + +**Example:** + +```js +const country = { + type: "fdc3.country", + name: "Sweden", + id: { + COUNTRY_ISOALPHA2: "SE" + } +} + +fdc3.broadcast(country) +``` + +## See Also + +Intents + +- [ViewNews](../../intents/ref/ViewNews) +- [ViewAnalysis](../../intents/ref/viewAnalysis) + +FINOS Financial Objects + +- [Country](https://fo.finos.org/docs/objects/country) diff --git a/website/versioned_docs/version-2.1/context/ref/Currency.md b/website/versioned_docs/version-2.1/context/ref/Currency.md new file mode 100644 index 000000000..9dd913815 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Currency.md @@ -0,0 +1,40 @@ +--- +id: Currency +sidebar_label: Currency +title: Currency +hide_title: true +--- + +# `Currency` + +A context representing an individual Currency. + +## Type + +`fdc3.currency` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------------------|---------|----------|-------------------| +| `type` | string | Yes | `'fdc3.currency'` | +| `name` | string | No | `'US Dollar'` | +| `id.CURRENCY_ISOCODE` * | string | Yes | `'USD'` | + +\* The `CURRENCY_ISOCODE` should conform to 3 character alphabetic codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). + +## Example + +```js +const currency = { + type: 'fdc3.currency', + name: 'US Dollar', + id: { + CURRENCY_ISOCODE: "USD" + } +} +``` diff --git a/website/versioned_docs/version-2.1/context/ref/Email.md b/website/versioned_docs/version-2.1/context/ref/Email.md new file mode 100644 index 000000000..e3291c1fd --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Email.md @@ -0,0 +1,57 @@ +--- +id: Email +sidebar_label: Email +title: Email +hide_title: true +--- +# `Email` + +A collection of information to be used to initiate an email with a Contact or ContactList + +## Type + +`fdc3.email` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------------|---------------------------------------|----------|---------------------| +| `type` | string | Yes | `'fdc3.email'` | +| `recipients` | fdc3.contact or fdc3.contactList | Yes | `{ type: "fdc3.contact", name: "John Doe", id: { "email": "john@sample.com" } }` | +| `subject` | string | No | `'The information you requested'` | +| `textBody` | string | No | `'Blah, blah, bah` | + +## Example + +```js +const email = { + type: 'fdc3.email', + recipients: { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@example.com' + } + }, + subject: 'The information you requested', + textBody: 'Blah, blah, blah ...' +} + + +fdc3.raiseIntent("StartEmail", email) +``` + +## See Also + +Other Types + +- [Contact](Contact) +- [ContactList](ContactList) + +Intents + +- [StartEmail](../../intents/ref/StartEmail) diff --git a/website/versioned_docs/version-2.1/context/ref/Instrument.md b/website/versioned_docs/version-2.1/context/ref/Instrument.md new file mode 100644 index 000000000..0d6f70cf6 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Instrument.md @@ -0,0 +1,97 @@ +--- +id: Instrument +sidebar_label: Instrument +title: Instrument +hide_title: true +--- +# `Instrument` + +A financial instrument from any asset class. + +Any combination of instrument identifiers can be used together to resolve ambiguity, or for a better match. + +Notes: + +- Not all applications will use the same instrument identifiers, which is why FDC3 allows for multiple to be specified. +In general, the more identifiers an application can provide, the easier it will be to achieve interoperability. + +- The `market` map can be used to further specify the instrument and help achieve interoperability between disparate data sources. This is especially useful when using an `id` field that is not globally unique. + +- It is valid to include extra properties and metadata as part of the instrument payload, but the minimum requirement +is for at least one instrument identifier to be provided. + +- Try to only use instrument identifiers as intended. E.g. the `ticker` property is meant for tickers as used by an exchange. +If the identifier you want to share is not a ticker or one of the other standardized fields, define +a property that makes it clear what value represents. Doing so will make interpretation easier for the developers of target applications. + +## Type + +`fdc3.instrument` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | More Info | +|-----------------------------|---------|----------|--------------------------|--------------------------------------------------------| +| `type` | string | Yes | `"fdc3.instrument"` | | +| `name` | string | No | `"Microsoft"` | | +| `id.ticker` | string | No | `"MSFT"` | | +| `id.BBG` | string | No | `"MSFT:US"` | | +| `id.CUSIP` | string | No | `"594918104"` | | +| `id.FDS_ID` | string | No | `"P8R3C2-R"` | | +| `id.FIGI` | string | No | `"BBG000BPH459"` | | +| `id.ISIN` | string | No | `"US5949181045"` | | +| `id.PERMID` | string | No | `"4295907168"` | | +| `id.RIC` | string | No | `"MSFT.OQ"` | | +| `id.SEDOL` | string | No | `"2588173"` | | +| `market.MIC` | string | No | `"XNAS"` | | +| `market.name` | string | No | `"NASDAQ - All Markets"` | | +| `market.COUNTRY_ISOALPHA2` | string | No | `"US"` | | +| `market.BBG` | string | No | `"US"` | | + +## Example + +```js +const instrument = { + type: "fdc3.instrument", + name: "Microsoft", + id: { + ticker: "MSFT", + RIC: "MSFT.OQ", + ISIN: "US5949181045" + }, + market: { + MIC: "XNAS" + } +} + +fdc3.joinUserChannel('Channel 1') +fdc3.broadcast(instrument) +``` + +## See Also + +Other Types + +- [InstrumentList](InstrumentList) +- [Chart](Chart) +- [Position](Position) +- [Portfolio](Portfolio) + +Intents + +- [ViewAnalysis](../../intents/ref/ViewAnalysis) +- [ViewChart](../../intents/ref/ViewChart) +- [ViewInstrument](../../intents/ref/ViewInstrument) +- [ViewNews](../../intents/ref/ViewNews) +- [ViewQuote](../../intents/ref/ViewQuote) +- [ViewResearch](../../intents/ref/ViewResearch) +- [ViewInteractions](../../intents/ref/ViewInteractions) +- [ViewOrders](../../intents/ref/ViewOrders) + +FINOS Financial Objects + +- [Instrument](https://fo.finos.org/docs/objects/instrument) diff --git a/website/versioned_docs/version-2.1/context/ref/InstrumentList.md b/website/versioned_docs/version-2.1/context/ref/InstrumentList.md new file mode 100644 index 000000000..7f2e3bc0c --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/InstrumentList.md @@ -0,0 +1,82 @@ +--- +id: InstrumentList +sidebar_label: InstrumentList +title: InstrumentList +hide_title: true +--- +# `InstrumentList` + +A collection of instruments. Use this type for use cases that require not just a single instrument, but multiple (e.g. to populate a watchlist). + +When holding information for each instrument is required, it is recommended to use the [Portfolio](Portfolio) type, though. + +Notes: + +- The instrument list schema does not explicitly include identifiers in the `id` section, as there +is not a common standard for such identifiers. Applications can, however, populate +this part of the contract with custom identifiers if so desired. + +## Type + +`fdc3.instrumentList` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|---------------|--------------|----------|--------------------------------| +| `type` | string | Yes | `'fdc3.instrumentList'` | +| `name` | string | No | `'Interesting instruments...'` | +| `id` | object | No | `{ customId: '5464' }` | +| `instruments` | Instrument[] | Yes | `[instrument1, instrument2]` | + +## Example + +```js +const instruments = { + type: "fdc3.instrumentList", + instruments: [ + { + type: "fdc3.instrument", + id: { + ticker: "AAPL" + }, + market: { + MIC: "XNAS" + } + }, + { + type: "fdc3.instrument", + id: { + ISIN: "US5949181045" + } + }, + ] +} + +fdc3.joinUserChannel('Channel 1') +fdc3.broadcast(instruments) +``` + +## See Also + +Other Types + +- [Instrument](Instrument) +- [Position](Position) +- [Portfolio](Portfolio) + +Intents + +- [ViewAnalysis](../../intents/ref/ViewAnalysis) +- [ViewChart](../../intents/ref/ViewChart) +- [ViewInstrument](../../intents/ref/ViewInstrument) +- [ViewNews](../../intents/ref/ViewNews) +- [ViewQuote](../../intents/ref/ViewQuote) + +FINOS Financial Objects + +- [InstrumentList](https://fo.finos.org/docs/objects/instrumentlist) diff --git a/website/versioned_docs/version-2.1/context/ref/Interaction.md b/website/versioned_docs/version-2.1/context/ref/Interaction.md new file mode 100644 index 000000000..fdb965944 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Interaction.md @@ -0,0 +1,96 @@ +--- +id: Interaction +sidebar_label: Interaction +title: Interaction +hide_title: true +--- +# `Interaction` + +An `Interaction` is a significant direct exchange of ideas or information between a number of participants, e.g. a Sell Side party and one or more Buy Side parties. An `Interaction` might be a call, a meeting (physical or virtual), an IM or the preparation of some specialist data, such as financial data for a given company or sector. + +Notes: + +- `interactionType` SHOULD be one of `'Instant Message'`, `'Email'`, `'Call'`, or `'Meeting'` although other string values are permitted. +- `origin` is used to represent the application or service that the interaction was created from to aid in tracing the source of an interaction. +- `id` does not need to be populated by the originating application, however the target application could store it for future reference and SHOULD return it in a `TransactionResult`. +- `id` can be used by a target application to pass an identifier back to the originating application after an interaction record has been created, updated or deleted. +- `id.URI` can be used by a target application to pass a record's link back to the originating application. This offers the originating application a way to open the record for a user to view. + +## Type + +`fdc3.interaction` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|--------------------|------------------|-----------|-------------------------------------------------| +| `type` | string | Yes | `fdc3.interaction` | +| `participants` | fdc3.contactList | Yes | See below | +| `timeRange` | fdc3.timeRange | Yes | See below | +| `interactionType` | string | Yes | `Instant Message` | +| `description` | string | Yes | `Blah, blah, blah` | +| `initiator` | fdc3.contact | No | See below | +| `origin` | string | No | `Outlook` | +| `id.SINGLETRACK` | string | No | `a0S8d000000uO05EAE` | +| `id.SALESFORCE` | string | No | `a0S8d000000uO05EAE` | +| `id.URI` | string | No | `https://example.com/record/a0S8d000000uO05EAE` | + + +## Example + +```js +const interaction = { + type: 'fdc3.interaction', + participants: { + type: 'fdc3.contactList', + contacts: [ + { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@mail.com' + } + }, + { + type: 'fdc3.contact', + name: 'John Doe', + id: { + email: 'john.doe@mail.com' + } + }, + ] + }, + interactionType: 'Instant Message', + timeRange: { + type: 'fdc3.timeRange', + startTime: '2022-02-10T15:12:00Z' + }, + description: 'Laboris libero dapibus fames elit adipisicing eu, fermentum, dignissimos laboriosam, erat, risus qui deserunt. Praesentium! Reiciendis. Hic harum nostrud, harum potenti amet? Mauris. Pretium aliquid animi, eget eiusmod integer proident. Architecto ipsum blandit ducimus, possimus illum sunt illum necessitatibus ab litora sed, nonummy integer minus corrupti ducimus iste senectus accumsan, fugiat nostrud? Pede vero dictumst excepturi, iure earum consequuntur voluptatum', + initiator: { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@mail.com' + } + }, + origin: 'Outlook' +} + +fdc3.raiseIntent('CreateInteraction', interaction) +``` + +## See Also + +Other Types +- [Contact](Contact) +- [ContactList](ContactList) +- [TimeRange](TimeRange) +- [TransactionResult](TransactionResult) + +Intents +- [CreateInteraction](../../intents/ref/CreateInteraction) +- [ViewInteractions](../../intents/ref/ViewInteractions) \ No newline at end of file diff --git a/website/versioned_docs/version-2.1/context/ref/Message.md b/website/versioned_docs/version-2.1/context/ref/Message.md new file mode 100644 index 000000000..05c25e1c0 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Message.md @@ -0,0 +1,77 @@ +--- +id: Message +sidebar_label: Message +title: Message +hide_title: true +--- +# `Message` + +A chat message to be sent through an instant messaging application. Can contain one or several text bodies (organised by mime-type, plaintext or markdown), +as well as attached entities (either arbitrary file attachments or FDC3 actions to be embedded in the message). To be put inside a ChatInitSettings object. + +## Type + +`fdc3.message` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------------|-------------------------------------------|----------|-------------------------| +| `type` | string | Yes | `'fdc3.message'` | +| `text` | map of string mime-type to string content | No | { text/plain: 'Hello' } | +| `entities` | map of json entity to string id | No | See Below | + +## Example + +```js +const message = { + type: 'fdc3.message', + text: { + 'text/plain': 'Hey all, can we discuss the issue together? I attached a screenshot and a link to the current exchange rate' + }, + entities: { + 'picture1': { + type: 'fdc3.fileAttachment', + data: { + name: 'myImage.png', + dataUri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII' + } + }, + 'eurusd_action': { + type: 'fdc3.action', + title: 'Click to view Chart', + intent: 'ViewChart', + context: { + type: 'fdc3.chart', + instruments: [ + { + type: 'fdc3.instrument', + id: { + ticker: 'EURUSD' + } + } + ], + range: { + type: 'fdc3.dateRange', + starttime: '2020-09-01T08:00:00.000Z', + endtime: '2020-10-31T08:00:00.000Z' + }, + style: 'candle' + } + } + } +} +``` + +## See Also + +Other Types +* [ChatInitSettings](ChatInitSettings) +* [Action](Action) + +Intents +* [StartChat](../../intents/ref/StartChat) diff --git a/website/versioned_docs/version-2.1/context/ref/Nothing.md b/website/versioned_docs/version-2.1/context/ref/Nothing.md new file mode 100644 index 000000000..f31822dc1 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Nothing.md @@ -0,0 +1,39 @@ +--- +id: Nothing +sidebar_label: Nothing +title: Nothing +hide_title: true +--- +# `Nothing` + +A type that explicitly represents a lack of context. + +Notes: + +- Intended to be used in situations where no context is desired. +- For example: + - Raising an intent without context (e.g. opening a blank order form, or chat + interface without a contact selected). + - Resetting context on a channel (e.g. when context is used to set a filter in + other applications a null context might release the filter). +- An explicit representation of a Null or empty context allows apps to declare support for + a lack of context, for example in their intent metadata in an app directory. + +## Type + +`fdc3.nothing` + +## Schema + + + +## Example + +```js +const nullContext = { + type: 'fdc3.nothing' +} + +fdc3.joinUserChannel('groupA') +fdc3.broadcast(nullContext) +``` diff --git a/website/versioned_docs/version-2.1/context/ref/Order.md b/website/versioned_docs/version-2.1/context/ref/Order.md new file mode 100644 index 000000000..c00fa3b4e --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Order.md @@ -0,0 +1,72 @@ +--- +id: Order +sidebar_label: Order +title: Order +hide_title: true +--- +# `Order` + +[`@experimental`](/docs/fdc3-compliance#experimental-features) context type representing an order. To be used with OMS and EMS systems. + +This type currently only defines a required `id` field, which should provide a reference to the order in one or more systems, an optional human-readable `name` field to be used to summarize the order, and an optional `details` field that may be used to provide additional detail about the order, including a Context representing a `product`, which may be extended with arbitrary properties. The `details.product` field is currently typed as an unspecified Context type, but both `details` and `details.product` are expected to be standardized in the future. + +## Type + +`fdc3.order` + +## Schema + + + +## Details + +| Property | Type | Required | Details | +|-------------------|------------|----------|---------------------------| +| `type` | string | Yes | `'fdc3.order'` | +| `id` | object | Yes | One or more identifiers that refer to the order in an OMS, EMS or related system. Specific key names for systems are expected to be standardized in future. E.g.:`{ myOMS: '12345' }` | +| `name` | string | No | An optional human-readable summary of the order. | +| `details` | object | No | Optional additional details about the order, which may include a product element that is an, as yet undefined but extensible, Context | +| `details.product` | Product | No | The product that the order relates to | + +## Examples + +```js +const order1 = { + "type": "fdc3.order", + "name": "...", + "id": { + "myOMS": "12345" + }, + "details": { + "product": { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } + } +}; +``` + +```js +const order2 = { + "type": "fdc3.order", + "id": { + "myOMS": "ABC123" + } +}; +``` + +## See Also + +Other Types + +- [OrderList](OrderList) +- [Product](Product) +- [Trade](Trade) diff --git a/website/versioned_docs/version-2.1/context/ref/OrderList.md b/website/versioned_docs/version-2.1/context/ref/OrderList.md new file mode 100644 index 000000000..4ff9eb49e --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/OrderList.md @@ -0,0 +1,58 @@ +--- +id: OrderList +sidebar_label: OrderList +title: OrderList +hide_title: true +--- +# `OrderList` + +[`@experimental`](/docs/fdc3-compliance#experimental-features) A list of orders. Use this type for use cases that require not just a single order, but multiple. + +Notes: + +- The OrderList schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired. + +## Type + +`fdc3.orderList` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|--------------|------------|----------|---------------------------| +| `type` | string | Yes | `'fdc3.orderList'` | +| `id` | object | No | `{ listId: '1234' }` | +| `name` | string | No | `'Today's orders'` | +| `orders` | Trade[] | Yes | `[order1, order2]` | + +## Example + +```js +const orderList = { + type: "fdc3.orderList", + orders: [ + { + "type": "fdc3.order", + "id": { + "myOMS": "ABC123" + } + }, + { + "type": "fdc3.order", + "id": { + "myOMS": "DEF456" + } + } + ] +}; +``` + +## See Also + +Other Types + +- [Order](Order) diff --git a/website/versioned_docs/version-2.1/context/ref/Organization.md b/website/versioned_docs/version-2.1/context/ref/Organization.md new file mode 100644 index 000000000..86a355046 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Organization.md @@ -0,0 +1,66 @@ +--- +id: Organization +sidebar_label: Organization +title: Organization +hide_title: true +--- +# `Organization` + +An entity that can be used when referencing private companies and other organizations where a specific instrument is not available or desired e.g. CRM and News workflows. + +Notes: + +- It is valid to include extra properties and metadata as part of the organization payload, but the minimum requirement +is for at least one specified identifier to be provided. + +## Type + +`fdc3.organization` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------|---------|----------|---------------------------| +| `type` | string | Yes | `'fdc3.organization'` | +| `name` | string | No | `'Cargill, Incorporated'` | +| `id.LEI` | string | No | `'QXZYQNMR4JZ5RIRN4T31'` | +| `id.PERMID` | string | No | `'4296555324'` | +| `id.FDS_ID` | string | No | `'00161G-E'` | + +## Example + +```js +const organization = { + type: "fdc3.organization", + name: "Cargill, Incorporated", + id: { + LEI: "QXZYQNMR4JZ5RIRN4T31", + FDS_ID: "00161G-E" + } +} + +fdc3.broadcast(organization) +``` + +## See Also + +Other Types + +- [Instrument](Instrument) + +Intents + +- [ViewNews](../../intents/ref/ViewNews) +- [ViewAnalysis](../../intents/ref/viewAnalysis) +- [ViewProfile](../../intents/ref/ViewProfile) +- [ViewResearch](../../intents/ref/ViewResearch) +- [ViewInteractions](../../intents/ref/ViewInteractions) +- [ViewOrders](../../intents/ref/ViewOrders) + +FINOS Financial Objects + +- [Organization](https://fo.finos.org/docs/objects/organization) diff --git a/website/versioned_docs/version-2.1/context/ref/Portfolio.md b/website/versioned_docs/version-2.1/context/ref/Portfolio.md new file mode 100644 index 000000000..6fcf3b787 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Portfolio.md @@ -0,0 +1,100 @@ +--- +id: Portfolio +sidebar_label: Portfolio +title: Portfolio +hide_title: true +--- +# `Portfolio` + +A financial portfolio made up of multiple positions (holdings) in several instruments. Contrast this +with e.g. the [InstrumentList](InstrumentList) type, which is just a list of instruments. + +This is a good example of how types can be composed and extended with extra properties to define more complex types. + +The [Portfolio](Portfolio) type consists of an array of [Position](Position) types, each of which +refers to a single [Instrument](Instrument) and a holding amount for that instrument. + +Notes: + +- Like all other FDC3 context types, extra properties for the portfolio can be added, the schema just +specifies the minimum contract. + +- The portfolio schema does not explicitly include identifiers in the `id` section, as there +is not a common standard for such identifiers. Applications can, however, populate +this part of the contract with custom identifiers if so desired. + +## Type + +`fdc3.portfolio` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|--------------|------------|----------|---------------------------| +| `type` | string | Yes | `'fdc3.portfolio'` | +| `id` | object | No | `{ portfolioId: '7381' }` | +| `name` | string | No | `'My share portfolio'` | +| `positions` | Position[] | Yes | `[position1, position2]` | + +## Example + +```js +const portfolio = { + type: "fdc3.portfolio", + positions: [ + { + type: "fdc3.position", + instrument: { + type: "fdc3.instrument", + id: { + ticker: "AAPL" + } + }, + holding: 2000000 + }, + { + type: "fdc3.position", + instrument: { + type: "fdc3.instrument", + id: { + ticker: "MSFT" + } + }, + holding: 1500000 + }, + { + type: "fdc3.position", + instrument: { + type: "fdc3.instrument", + id: { + ticker: "IBM" + } + }, + holding: 3000000 + } + ] +} +fdc3.raiseIntent("ViewAnalysis", portfolio) +``` + +## See Also + +Other Types + +- [Instrument](Instrument) +- [InstrumentList](InstrumentList) +- [Position](Position) + +Intents + +- [ViewAnalysis](../../intents/ref/ViewAnalysis) +- [ViewChart](../../intents/ref/ViewChart) +- [ViewNews](../../intents/ref/ViewNews) + +FINOS Financial Objects + +- [Position](https://fo.finos.org/docs/objects/portfolio) diff --git a/website/versioned_docs/version-2.1/context/ref/Position.md b/website/versioned_docs/version-2.1/context/ref/Position.md new file mode 100644 index 000000000..82f8481ec --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Position.md @@ -0,0 +1,76 @@ +--- +id: Position +sidebar_label: Position +title: Position +hide_title: true +--- +# `Position` + +A financial position made up of an instrument and a holding in that instrument. This type is a good +example of how new context types can be composed from existing types. + +In this case, the instrument and the holding amount for that instrument are required values. + +The [Position](Position) type goes hand-in-hand with the [Portfolio](Portfolio) type, which represents +multiple holdings in a combination of instruments. + +Notes: + +- Like all other FDC3 context types, extra properties for the position can be added, the schema just +specifies the minimum contract. + +- The position schema does not explicitly include identifiers in the `id` section, as there +is not a common standard for such identifiers. Applications can, however, populate +this part of the contract with custom identifiers if so desired. + +## Type + +`fdc3.position` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|--------------|------------|----------|------------------------------------| +| `type` | string | Yes | `'fdc3.position'` | +| `id` | object | No | `{ positionId: '6475' }` | +| `name` | string | No | `'My Apple shares'` | +| `holding` | number | Yes | `2000000` | +| `instrument` | Instrument | Yes | `{ type: 'fdc3.instrument', ... }` | + +## Example + +```js +const position = { + type: "fdc3.position", + instrument: { + type: "fdc3.instrument", + id: { + ticker: "AAPL" + } + }, + holding: 2000000 +} + +fdc3.raiseIntent("ViewChart", position) +``` + +## See Also + +Other Types + +- [Instrument](Instrument) +- [Portfolio](Portfolio) + +Intents + +- [ViewAnalysis](../../intents/ref/ViewAnalysis) +- [ViewChart](../../intents/ref/ViewChart) +- [ViewNews](../../intents/ref/ViewNews) + +FINOS Financial Objects + +- [Position](https://fo.finos.org/docs/objects/position) diff --git a/website/versioned_docs/version-2.1/context/ref/Product.md b/website/versioned_docs/version-2.1/context/ref/Product.md new file mode 100644 index 000000000..21bc6abc2 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Product.md @@ -0,0 +1,55 @@ +--- +id: Product +sidebar_label: Product +title: Product +hide_title: true +--- +# `Product` + +[`@experimental`](/docs/fdc3-compliance#experimental-features) context type representing a tradable product. To be used with OMS and EMS systems. This type is currently only loosely defined as an extensible context object, with an optional instrument field. + +Notes: + +- The Product schema does not explicitly include identifiers in the `id` section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired. + +## Type + +`fdc3.product` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|--------------|------------|----------|---------------------------| +| `type` | string | Yes | `'fdc3.product'` | +| `id` | object | Yes | One or more identifiers that refer to the product. Specific key names for systems are expected to be standardized in future. | +| `name` | string | No | A human-readable summary of the product. | +| `instrument` | Instrument | No | A financial instrument that relates to the definition of this product. | + +## Example + +```js +const product = { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } +}; +``` + +## See Also + +Other Types + +- [Instrument](Instrument) +- [Order](Order) +- [Trade](Trade) diff --git a/website/versioned_docs/version-2.1/context/ref/TimeRange.md b/website/versioned_docs/version-2.1/context/ref/TimeRange.md new file mode 100644 index 000000000..9477a608a --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/TimeRange.md @@ -0,0 +1,85 @@ +--- +id: TimeRange +sidebar_label: TimeRange +title: TimeRange +hide_title: true +--- +# `TimeRange` + +A context representing a period of time. Any user interfaces that represent or visualize events or activity over time can be filtered or focused on a particular time period, e.g.: + +- A pricing chart +- A trade blotter +- A record of client contact/activity in a CRM + +Example use cases: + +- User may want to view pricing/trades/customer activity for a security over a particular time period, the time range might be specified as the context for the `ViewChart` intent OR it might be embedded in another context (e.g. a context representing a chart to plot). +- User filters a visualization (e.g. a pricing chart) to show a particular period, the `TimeRange` is broadcast and other visualizations (e.g. a heatmap of activity by instrument, or industry sector etc.) receive it and filter themselves to show data over the same range. + +Notes: + +- A `TimeRange` may be closed (i.e. `startTime` and `endTime` are both known) or open (i.e. only one of `startTime` or `endTime` is known). + +- Ranges corresponding to dates (e.g. `2022-05-12` to `2022-05-19`) should be specified using times as this prevents issues with timezone conversions and inclusive/exclusive date ranges. + +- String fields representing times are encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html). + - A timezone indicator should be specified, e.g. `"2022-05-12T15:18:03Z"` or `"2022-05-12T16:18:03+01:00"` + - Times MAY be specified with millisecond precision, e.g. `"2022-05-12T15:18:03.349Z"` + +## Type + +`fdc3.timerange` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|-------------|-----------|----------|-------------------------------| +| `type` | string | Yes | `"fdc3.timeRange"` | +| `startTime` | string * | No ** | `"2022-03-30T15:44:44Z"` | +| `endTime` | string * | No ** | `"2022-04-30T23:59:59+00:00"` | + +\* Fields representing time SHOULD be string encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator included. + +\*\* One of `startTime` or `endTime` MUST be specified. + +## Example + +A closed range: + +```js +const timeRange = { + type: "fdc3.timeRange", + startTime: "2022-03-30T15:44:44Z", + endTime: "2022-04-30T23:59:59ZS" +} +``` + +Open ranges: + +```js +const timeRange = { + type: "fdc3.timeRange", + startTime: "2022-03-30T15:44:44+00:00" +} +``` + +```js +const timeRange = { + type: "fdc3.timeRange", + endTime: "2022-03-30T16:44:44.123Z" +} +``` + +## See Also + +Other Types + +- [Chart](Chart) + +Intents +- [CreateInteraction](../../intents/ref/CreateInteraction) \ No newline at end of file diff --git a/website/versioned_docs/version-2.1/context/ref/Trade.md b/website/versioned_docs/version-2.1/context/ref/Trade.md new file mode 100644 index 000000000..767aff36f --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Trade.md @@ -0,0 +1,63 @@ +--- +id: Trade +sidebar_label: Trade +title: Trade +hide_title: true +--- +# `Trade` + +[`@experimental`](/docs/fdc3-compliance#experimental-features) context type representing a trade. To be used with execution systems. + +This type currently only defines a required `id` field, which should provide a reference to the trade in one or more systems, an optional human readable `name` field to be used to summarize the trade and a required `product` field that may be used to provide additional detail about the trade, which is currently typed as an unspecified Context type, but `product` is expected to be standardized in future. + +Notes: + +- The Trade schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired. + +## Type + +`fdc3.trade` + +## Schema + + + +## Details + +| Property | Type | Required | Details | +|--------------|------------|----------|---------------------------| +| `type` | string | Yes | `'fdc3.trade'` | +| `id` | object | Yes | One or more identifiers that refer to the trade in an OMS, EMS or related system. Specific key names for systems are expected to be standardized in future. | +| `name` | string | No | A human-readable summary of the trade, e.g. `'100 TSLA @ 290.85 USD'` | +| `product` | Product | Yes | A tradeable product | + +## Example + +```js +const trade = { + "type": "fdc3.trade", + "name": "...", + "id": { + "myEMS": "12345" + }, + "product": { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } +}; +``` + +## See Also + +Other Types + +- [Product](Product) +- [TradeList](TradeList) diff --git a/website/versioned_docs/version-2.1/context/ref/TradeList.md b/website/versioned_docs/version-2.1/context/ref/TradeList.md new file mode 100644 index 000000000..592966b2f --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/TradeList.md @@ -0,0 +1,83 @@ +--- +id: TradeList +sidebar_label: TradeList +title: TradeList +hide_title: true +--- +# `TradeList` + +[`@experimental`](/docs/fdc3-compliance#experimental-features) A list of trades. Use this type for use cases that require not just a single trade, but multiple. + +Notes: + +- The TradeList schema does not explicitly include identifiers in the id section, as there is not a common standard for such identifiers. Applications can, however, populate this part of the contract with custom identifiers if so desired. + +## Type + +`fdc3.tradeList` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|--------------|------------|----------|---------------------------| +| `type` | string | Yes | `'fdc3.tradeList'` | +| `id` | object | No | `{ listId: '1234' }` | +| `name` | string | No | `'Today's trades'` | +| `trades` | Trade[] | Yes | `[trade1, trade2]` | + +## Example + +```js +const tradeList = { + type: "fdc3.tradeList", + trades: [ + { + "type": "fdc3.trade", + "name": "...", + "id": { + "myEMS": "12345" + }, + "product": { + "type": "fdc3.product", + "id": { + "productId": "ABC123" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "MSFT" + } + } + } + }, + { + "type": "fdc3.trade", + "id": { + "myEMS": "67890" + }, + "product": { + "type": "fdc3.product", + "id": { + "productId": "DEF456" + }, + "instrument": { + "type": "fdc3.instrument", + "id": { + "ticker": "TSLA" + } + } + } + } + ] +}; +``` + +## See Also + +Other Types + +- [Trade](Trade) diff --git a/website/versioned_docs/version-2.1/context/ref/TransactionResult.md b/website/versioned_docs/version-2.1/context/ref/TransactionResult.md new file mode 100644 index 000000000..308721902 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/TransactionResult.md @@ -0,0 +1,59 @@ +--- +id: TransactionResult +sidebar_label: TransactionResult +title: TransactionResult +hide_title: true +--- +# `TransactionResult` + +A context type representing the result of a transaction initiated via FDC3, which SHOULD be returned as an [`IntentResult`](../../api/ref/Types#intentresult) by intents that create, retrieve, update or delete content or records in another application. Its purpose is to provide a status and message (where needed) for the transaction and MAY wrap a returned context object. + +## Type + +`fdc3.transactionResult` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|------------|---------|----------|-------------------| +| `type` | string | Yes | 'fdc3.transactionResult' | +| `status` | string | Yes | `"Created" \| "Deleted" \| "Updated" \| "Failed"` | +| `context` | Context | No | See Below | +| `message` | string | No | See Below | + +## Example + +```js +const contact = { + type: "fdc3.contact", + name: "Jane Doe", + id: { + email: "jane.doe@mail.com" + } +} + +const resolution = await window.fdc3.raiseIntent('CreateOrUpdateProfile', contact); +const result = await resolution.getResult(); +console.log(JSON.stringify(result)); +``` + +Console log will display: + +```json +{ + "type": "fdc3.transactionResult", + "status": "Updated", + "context": { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@mail.com" + } + }, + "message": "record with id 'jane.doe@mail.com' was updated" +} +``` diff --git a/website/versioned_docs/version-2.1/context/ref/Valuation.md b/website/versioned_docs/version-2.1/context/ref/Valuation.md new file mode 100644 index 000000000..4ba83e10c --- /dev/null +++ b/website/versioned_docs/version-2.1/context/ref/Valuation.md @@ -0,0 +1,44 @@ +--- +id: Valuation +sidebar_label: Valuation +title: Valuation +hide_title: true +--- +# `Valuation` + +A context type representing the price and value of a holding. + +## Type + +`fdc3.valuation` + +## Schema + + + +## Details + +| Property | Type | Required | Example Value | +|----------------------|---------|----------|-------------------------------| +| `type` | string | Yes | `'fdc3.valuation'` | +| `value` | number | Yes | `500.0` | +| `price` | number | No | `5.0` | +| `CURRENCY_ISOCODE` * | string | Yes | `GBP` | +| `valuationTime` ** | string | No | `"2022-05-12T16:16:24.815Z"` | +| `expiryTime` ** | string | No | `"2022-05-13T16:16:24+01:00"` | + +\* The `CURRENCY_ISOCODE` should conform to 3 character alphabetic codes defined in [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html). + +\*\* Time fields SHOULD conform to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator included. + +## Example + +```js +const valuation = { + type: 'fdc3.valuation', + value: 500.0, + price: 5.0, + CURRENCY_ISOCODE: 'USD', + expiryTime: "2022-05-13T16:16:24+01:00" +} +``` diff --git a/website/versioned_docs/version-2.1/context/spec.md b/website/versioned_docs/version-2.1/context/spec.md new file mode 100644 index 000000000..a49590c37 --- /dev/null +++ b/website/versioned_docs/version-2.1/context/spec.md @@ -0,0 +1,311 @@ +--- +id: spec +sidebar_label: Overview +title: Context Data (2.1) +--- + +To interoperate, apps need to exchange commonly recognized context structures that can indicate topic with any number of identifiers or mappings to different systems. FDC3 Context Data defines a standard for passing common identifiers and data, encoded in JSON, between apps to create a seamless workflow. FDC3 Context Data is not a symbology solution and is not specifically focused on modeling financial objects. The focus is on providing a standard JSON payload structure that can be used to establish a lowest common denominator for interoperability. + +Context objects are used when raising [intents](../intents/spec) and when broadcasting context to other applications. + +There are two main use cases for exchanging context data: + +- **Transmitting reference data between applications.** + The source application will send as many known identifiers as possible, and the target application will try to match the entity based on the identifiers. It may then choose to map to its own internal domain representation for rendering purposes. + + An example of this is sending an instrument or contact, when only an ISIN or email is required to reference the same data in another application. + +- **Transferring information between applications.** + The source application may have data required to compose a workflow with another application, e.g. a list of contacts that have been selected, or a complex object representing an RFQ request. + + In many such cases there aren't any sensible reference identifiers that can be shared, it is instead the data itself being transferred. + +## Assumptions + +1. Context data objects are identified and routed according to their type, which is unique. +2. Any names, identifiers or extra properties are optional. +3. More complex objects can be composed from simpler objects by defining a new type, e.g a position from an instrument and a holding amount. +4. If multiple pieces of data need to be sent, an embedded array can be used, identified as a collection type, e.g. "contactList" or "portfolio". This allows for additional metadata and data relationships to be expressed. +5. There needs to be a way to reference or look up the structure of well-known context types, e.g. from a directory. + +## Other Standards + +FDC3 recognizes that there are other object definitions for providing context between applications. Most, if not all of these definitions though are platform-specific. FDC3, as a rule, sets out to be platform-agnostic and focused on creating bridges between the various walled gardens on the financial desktop. + +### Context Schemas + +FDC3 Context data is primarily encoded in JSON, but may also be encoded in language specific formats for use with FDC3 API implementations in those languages, although it is advisable to ensure that they can be converted to and from JSON. + +Each Standardized context type defined by the FDC3 Standard has an associated [JSON Schema](https://json-schema.org/) definition that should be considered the 'source of truth' for the context definition, although examples in documentation may also be given in TypeScript or JavaScript. The TypeScript definitions distributed in the FDC3 NPM module are generated from the JSON Schema files using [quicktype](https://quicktype.io/). Both documentation for fields defined (in the form of a `title` and `description` entry for each field defined) and examples SHOULD be included in JSON Schema definitions for Context types to ensure that the schema file can serve as a single source of truth, and that code generated from the schema files can also include that documentation. + +## The Context Interface + +Context can be summarized as: + +- Having a unique _type_ identifier, used for routing. +- Optionally providing a name. +- Optionally providing a map of equivalent identifiers. +- Any other properties or metadata. + +Hence, the Context Interface can be represented in TypeScript as: + +```typescript +interface Context { + type: string; + name?: string; + id?: { + [x:string]: string; + }, + [x: string]: any; +} +``` + +or in JSON Schema as: + +```JSON +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://fdc3.finos.org/schemas/2.1/context/context.schema.json", + "type": "object", + "title": "Context", + "description": "The `fdc3.context` type defines the basic contract or \"shape\" for all data exchanged by FDC3 operations. As such, it is not really meant to be used on its own, but is imported by more specific type definitions (standardized or custom) to provide the structure and properties shared by all FDC3 context data types.\n\nThe key element of FDC3 context types is their mandatory `type` property, which is used to identify what type of data the object represents, and what shape it has.\n\nThe FDC3 context type, and all derived types, define the minimum set of fields a context data object of a particular type can be expected to have, but this can always be extended with custom fields as appropriate.", + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "id": { + "type": "object", + "unevaluatedProperties": { + "type": "string" + } + } + }, + "additionalProperties": true, + "required": [ + "type" + ] +} +``` + +### Namespacing + +All well-known types at FDC3 level should be prefixed with `fdc3`. For private type definitions, or type definitions issued by other organizations, different namespaces can be used, e.g. `blackrock.fund`, etc. + +### Versioning + +The specification recognizes that evolving context data definitions over time, and helping applications to deal with changes to types, are very important. + +It may be as simple as adding an optional `$version` property to types, but it could also be a set of guidelines for adding new properties, without removing or changing existing ones. For example, web technologies like REST or GraphQL do not take a particular opinion about versioning. + +### Field Type Conventions + +This Standard defines a number of conventions for the fields of context types that all context objects SHOULD adhere to in order to reduce or prevent competing conventions from being established in both standardized types and proprietary types created by app developers. + +#### Identifiers + +An `id` field with type `object` is defined in the base [fdc3.context](ref/Context) type, from which all other context objects are derived, and SHOULD be used to encapsulate identifiers. Specific context types may define subfields for specific identifiers as needed. + +Where an identifier is the name of an existing standard, external to FDC3, it is represented in all caps. For example: FIGI, PERMID, CUSIP, ISO-2. When an identifier is a more general concept, it is represented in all lower case. For example: ticker, name, geocode, email. + +All standard identifier names are reserved names. Applications may use their own identifiers ad hoc. For example: + +```json +"id": { + "CUSIP":"037833100", + "foo":"bar" +} +``` + +The identifier "foo" is proprietary, an application that can use it is free to do so. However, since multiple applications may want to use the "foo" name and may use it to mean different things, there is a need for applications to ensure that their identifiers use naming conventions that will avoid collision. The recommended approach here is to prefix the identifier name with a namespace. For example: + +```json +"id": { + "CUSIP":"037833100", + "com.company.foo": "000C7F-E" +} +``` + +#### Times + +Fields representing a point in time SHOULD be string encoded according to [ISO 8601-1:2019](https://www.iso.org/standard/70907.html) with a timezone indicator included, e.g.: + +- Time in UTC: `"2022-03-30T15:44:44Z"` +- Also time in UTC: `"2022-03-30T15:44:44+00:00"` +- Same time in EDT: `"2022-03-30T11:44:44-04:00"` + +Times MAY be expressed with millisecond precision, e.g.: + +- `"2022-03-30T11:44:44.123-04:00"` +- `"2022-03-30T11:44:44.123Z"` + +Parsing in JavaScript: + +```javascript +let aDate = new Date("2022-03-30T11:44:44.123-04:00") +``` + +#### Dates + +Fields representing a point in time SHOULD be string encoded using the `YYYY-MM-DD` date format from [ISO 8601-1:2019](https://www.iso.org/standard/70907.html). + +E.g. `"2022-03-30"` + +Parsing in JavaScript: + +```javascript +let aDate = new Date("2022-03-30") +``` + +#### Country codes + +Fields representing a country SHOULD be string encoded using the Alpha-2-codes from [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) and field name `COUNTRY_ISOALPHA2`. The Alpha-3-codes from [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) MAY be used in addition to the Alpha-2-code with the field name `COUNTRY_ISOALPHA3`. + +E.g. `"COUNTRY_ISOALPHA2": "GB"` + +#### Currency codes + +Fields representing a currency SHOULD be string encoded using the Alphabetic code from [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) with the field name `CURRENCY_ISOCODE`. + +E.g. `"CURRENCY_ISOCODE": "GBP"` + +:::note +ISO 4217 only includes major currency codes, conversions to minor currencies is the responsibility of the consuming system (where required). +::: + +## Context Data Standard Compliance + +An FDC3 Standard compliant application that supports the use of context data **MUST**: + +- Ensure that any FDC3-defined standard context types used meet the interface defined for that type of context data. +- Where an app is intended to receive context from [`fdc3.open`](../api/ref/DesktopAgent#open) calls, use the [`fdc3.addContextListener`](../api/ref/DesktopAgent#addcontextlistener) API call to set up appropriate handlers. +- Where App or Private channels are supported, use the [`Channel.addContextListener`](../api/ref/Channel#addcontextlistener) API call to set up appropriate handlers. + +An FDC3 Standard compliant application that supports the use of context data **SHOULD**: + +- Prefer FDC3-defined standard context types over proprietary contexts, where a suitable FDC3-defined standard context type is available. +- Ensure that any proprietary context data types defined follow any the recommended [namespacing](#namespacing) and [field type conventions](#field-type-conventions) in the specification. +- Where an app is intended to receive context from [`fdc3.open`](../api/ref/DesktopAgent#open) calls, use the [`fdc3.addContextListener`](../api/ref/DesktopAgent#addcontextlistener) API call to set up appropriate handlers within 15 seconds of the application launch (the minimum timeout Desktop Agents are required to provide) in order to be widely compatible with Desktop Agent implementations. + +An FDC3 Standard compliant application that supports the use of context data **MAY**: + +- Define proprietary context data types to support use cases not currently supported via FDC3-defined standard context types. + +For more details on FDC3 Standards compliance (including the versioning, deprecation and experimental features policies) please see the [FDC3 Compliance page](../fdc3-compliance). + +## Standard Context Types + +The following are standard FDC3 context types: + +- [`fdc3.action`](ref/Action) ([schema](/schemas/2.1/context/action.schema.json)) +- [`fdc3.chart`](ref/Chart) ([schema](/schemas/2.1/context/chart.schema.json)) +- [`fdc3.chat.initSettings`](ref/ChatInitSettings) ([schema](/schemas/2.1/context/chatInitSettings.schema.json)) +- [`fdc3.chat.message`](ref/ChatMessage) ([schema](/schemas/2.1/context/chatMessage.schema.json)) +- [`fdc3.chat.room`](ref/ChatRoom) ([schema](/schemas/2.1/context/chatRoom.schema.json)) +- [`fdc3.chat.searchCriteria`](ref/ChatSearchCriteria) ([schema](/schemas/2.1/context/chatSearchCriteria.schema.json)) +- [`fdc3.contact`](ref/Contact) ([schema](/schemas/2.1/context/contact.schema.json)) +- [`fdc3.contactList`](ref/ContactList) ([schema](/schemas/2.1/context/contactList.schema.json)) +- [`fdc3.country`](ref/Country) ([schema](/schemas/2.1/context/country.schema.json)) +- [`fdc3.currency`](ref/Currency) ([schema](/schemas/2.1/context/currency.schema.json)) +- [`fdc3.email`](ref/Email) ([schema](/schemas/2.1/context/email.schema.json)) +- [`fdc3.instrument`](ref/Instrument) ([schema](/schemas/2.1/context/instrument.schema.json)) +- [`fdc3.instrumentList`](ref/InstrumentList) ([schema](/schemas/2.1/context/instrumentList.schema.json)) +- [`fdc3.interaction`](ref/Interaction) ([schema](/schemas/2.1/context/interaction.schema.json)) +- [`fdc3.message`](ref/Message) ([schema](/schemas/2.1/context/message.schema.json)) +- [`fdc3.organization`](ref/Organization) ([schema](/schemas/2.1/context/organization.schema.json)) +- [`fdc3.portfolio`](ref/Portfolio) ([schema](/schemas/2.1/context/portfolio.schema.json)) +- [`fdc3.position`](ref/Position) ([schema](/schemas/2.1/context/position.schema.json)) +- [`fdc3.nothing`](ref/Nothing) ([schema](/schemas/2.1/context/nothing.schema.json)) +- [`fdc3.timerange`](ref/TimeRange) ([schema](/schemas/2.1/context/timerange.schema.json)) +- [`fdc3.transactionResult`](ref/TransactionResult) ([schema](/schemas/2.1/context/transactionresult.schema.json)) +- [`fdc3.valuation`](ref/Valuation) ([schema](/schemas/2.1/context/valuation.schema.json)) + +The following are [`@experimental`](/docs/fdc3-compliance#experimental-features) types, which are in the process of being defined: + +- [`fdc3.order`](ref/Order) ([schema](/schemas/2.1/context/order.schema.json)) +- [`fdc3.orderList`](ref/OrderList) ([schema](/schemas/2.1/context/orderList.schema.json)) +- [`fdc3.product`](ref/Product) ([schema](/schemas/2.1/context/product.schema.json)) +- [`fdc3.trade`](ref/Trade) ([schema](/schemas/2.1/context/trade.schema.json)) +- [`fdc3.tradeList`](ref/TradeList) ([schema](/schemas/2.1/context/tradeList.schema.json)) + +### Examples + +The below examples show how the base context data interface can be used to define specific context data objects. + +#### Contact + +```json +{ + "type": "fdc3.contact", + "name": "John Smith", + "id":{ + "email": "john.smith@company.com", + } +} +``` + +#### Email + +```json +{ + "type": "fdc3.email", + "recipients": { + "type": "fdc3.contact", + "name": "Jane Doe", + "id": { + "email": "jane.doe@example.com" + } + }, + "subject": "The information you requested", + "textBody": "Blah, blah, blah ..." +} +``` + +#### Instrument + +```json +{ + "type" : "fdc3.instrument", + "name" : "Apple", + "id" : + { + "ticker" : "aapl", + "ISIN" : "US0378331005", + "CUSIP" : "037833100", + "FIGI" : "BBG000B9XRY4", + } +} +``` + +#### TypeScript definition + +The `Instrument` type is derived from the `Context` type (note that the name becomes a required field, the type is fixed and optional `id` subfields are defined): + +```typescript +interface Instrument extends Context { + type: 'fdc3.instrument', + name: string; + id: { + ticker?: string; + ISIN?: string; + CUSIP?: string; + } +} +``` + +e.g. as a JSON payload: + +```json +{ + "type" : "fdc3.instrument", + "name" : "Apple", + "id" : + { + "ticker" : "aapl", + "ISIN" : "US0378331005", + "CUSIP" : "037833100" + }, +} +``` diff --git a/website/versioned_docs/version-2.1/fdc3-charter.md b/website/versioned_docs/version-2.1/fdc3-charter.md new file mode 100644 index 000000000..055e1aa59 --- /dev/null +++ b/website/versioned_docs/version-2.1/fdc3-charter.md @@ -0,0 +1,66 @@ +--- +id: fdc3-charter +title: FDC3 Charter +--- + +## Scope + +Financial desktop applications include any app used in common financial workflows: + +- Traditional native applications implemented in C++, .NET, Java, Python, etc. +- Hybrid web/native applications - stand-alone native apps embedding Chromium (e.g. a .NET application embedding WebView using CEF or WebView2) +- Desktop web applications - Web applications running in a desktop container (e.g. OpenFin, Finsemble, Glue42, Electron, FDC3-Sail) +- Common desktop applications not specific to finance, but critical to workflows - such as Excel, Outlook, etc. +- PWAs & Web applications running in a commercial browser + +This Standard is focused specifically on the desktop. Activities of the desktop interoperability group do not include: + +- Defining financial objects - where existing standards are well established +- Interoperability between mobile apps +- Interoperability via REST or other client to server communication + +:::note +While these areas are out of scope, compatibility with Mobile and/or REST are still valid points of consideration for FDC3. +::: + +### Success Criteria + +- Commitment from major banks and application vendors to support the standards set out by the FDC3 +- Workflow integrations in the wild leveraging the standards + +### Deliverables + +- Define criteria and mechanics for secure communication between apps +- Define key functions that require specific standards for interoperability +- Create an agreed taxonomy for common app “intents” within financial desktop workflows +- Create an agreed taxonomy for common data to be shared across apps within financial desktop workflows +- Provide reference implementations of all standards +- Maintain the above standards and reference implementations + +## Participation + +To be successful, the maintenance and evolution of this Standard needs to have a critical mass of active participants for its duration. Effective participation in FDC3 means participation in the form of research, authoring, editing, and development activities outside the scope of attending regular meetings. + +## Licensing + +Version 1.0 of the FDC3 specification is licensed under the [FDC3 1.0 Final Specification License](https://github.com/finos/FDC3/blob/17892008c26a73ff1fd9f6e40ceb8c8bfd58c610/PATENTS-FDC3-1.0.md). + +Subsequent FDC3 specifications and draft specifications are subject to the [FINOS IP Policy](https://github.com/finos/community/blob/master/website/static/governance-docs/IP-Policy.pdf)), which authorizes implementation of FDC3 specifications without charge, on a [RAND basis](https://en.wikipedia.org/wiki/Reasonable_and_non-discriminatory_licensing), subject to the terms of the policy. For details of the IP commitments made by contributors to FDC3, please refer to the policy. + +Reference implementations and other software contained in FDC3 repositories is licensed under the [Apache License, Version 2.0](https://github.com/finos/FDC3/blob/17892008c26a73ff1fd9f6e40ceb8c8bfd58c610/LICENSE) unless otherwise noted. SPDX-License-Identifier: [Apache-2.0](https://spdx.org/licenses/Apache-2.0). + +### Intellectual Property Claims + +Recipients of this document are requested to submit, with their comments, notification of +any relevant patent claims or other intellectual property rights of which they may be aware that +might be infringed by any implementation of the standard set forth in this document, and to provide +supporting documentation. + +THIS STANDARD IS BEING OFFERED WITHOUT ANY WARRANTY +WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NON-INFRINGEMENT IS +EXPRESSLY DISCLAIMED. ANY USE OF THIS STANDARD SHALL BE MADE +ENTIRELY AT THE IMPLEMENTER'S OWN RISK, AND NEITHER THE FOUNDATION, +NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY +WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF +ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE +OF THIS STANDARD. diff --git a/website/versioned_docs/version-2.1/fdc3-compliance.md b/website/versioned_docs/version-2.1/fdc3-compliance.md new file mode 100644 index 000000000..af2080f8b --- /dev/null +++ b/website/versioned_docs/version-2.1/fdc3-compliance.md @@ -0,0 +1,87 @@ +--- +id: fdc3-compliance +title: Compliance +--- + +FDC3 standards follow the IETF best practices for keywords to Indicate Requirement levels: [RFC 2119](https://tools.ietf.org/html/rfc2119). Documentation should be updated as needed to reflect this. + +In general, the ratified FDC3 specs represent a lowest common denominator interface for interoperability. So, unless a particular item in a spec is marked with keywords such as OPTIONAL, MAY, SHOULD, or SHOULD NOT, it should be treated as REQUIRED. Since FDC3 itself is primarily concerned with establishing the baseline requirements for interoperation, this is consistent with the IETF Guidance: + +>6. **Guidance in the use of these Imperatives** +> +> Imperatives of the type defined in this memo must be used with care +> and sparingly. In particular, they MUST only be used where it is +> actually required for interoperation or to limit behavior which has +> potential for causing harm (e.g., limiting retransmissions) For +> example, they must not be used to try to impose a particular method +> on implementors where the method is not required for +> interoperability. + +These rules would apply only to standards work within FDC3. Today, this covers the API, App Directory, Context Data, and Intents specifications. + +## Personas + +FDC3 implementors generally fall into 2 categories: platform providers, and application providers. A platform provider supplies an implementation(s) of the FDC3 APIs (The Desktop Agent API and Application Directory) for applications to use. + +An application provider is largely a downstream consumer of FDC3 standards. It MAY use the API, it MAY use Context Data, it MAY use Intents. Application providers are only required to comply with the standards they make use of. + +Depending on persona, implementation compliance with FDC3 will mean different things. + +### Platform Provider + +For platform providers FDC3 compliance requires that they meet the requirements of the APIs that they implement: + +- [Desktop Agent API compliance requirements](api/spec#desktop-agent-api-standard-compliance). +- [App Directory compliance requirements](app-directory/spec#app-directory-standard-compliance). + +### Application Provider + +For application providers FDC3 compliance requires that they interact with the FDC3 APIs as intended and meet the requirements of the Intents and Context Data Standards. Specifically: + +- [Intents Standard compliance requirements](intents/spec#intents-standard-compliance) +- [Context Data Standard compliance requirements](context/spec#context-data-standard-compliance) + +## Versioning + +Typically, a Standard that has marketplace relevance is revised from time to time, to correct errors and/or to add functionality to support new use cases. Hence, there exist multiple versions of the standard. As FDC3 is a standards project, we don't follow semver, which is meant for libraries. We use the versioning scheme `.`, e.g. `1.1` or `2.3`. + +## Deprecation Policy + +Over time, it is not uncommon for certain things in a standard to be marked for removal in a future version, possibly being replaced by an alternative. That is, they are deprecated. Often, they are retained in the standard because of their widespread use, but their use in new projects is discouraged. + +FDC3 adopts the following deprecation policy: + +1. A feature can be deprecated by any major or minor version. Newly deprecated features will be described in the [Changelog](https://github.com/finos/FDC3/blob/master/CHANGELOG.md). +2. A feature shall only be removed by a major version. Newly removed features will be described in the [Changelog](https://github.com/finos/FDC3/blob/master/CHANGELOG.md). +3. Deprecated features are clearly marked with an `@deprecated` tag and comment in both the documentation and jsDocs applied to the TypeScript sources. +4. Where possible, changes to the behavior of an existing feature should be avoided; consider deprecating it and replacing it with something with a different name/syntax. +5. Breaking change should only be made in a major version of the Standard. + +## Experimental Features + +Occasionally, a change to FDC3 may be proposed where the design is tentative, and because of this, we need feedback from the community to finalize its inclusion in the Standard. In such cases, a feature may be designated as _experimental_ to indicate that its design may change in future and that it is exempted from the normal versioning and deprecation polices in order to facilitate that change. However, designating a feature as experimental is likely to reduce its uptake by the community, hence, this designation should be used sparingly. + +FDC3 adopts the following experimental features policy: + +1. A feature may be designated as experimental where feedback is needed to confirm the final design of that feature, with the goal of including it as a full part of the Standard without the experimental label. +2. A feature should only be designated as experimental where there is a reasonable chance that breaking changes to its design may be applied, based on feedback received; non-breaking changes (refinements) may already be applied to features defined in the Standard without the experimental designation. +3. Experimental features are clearly marked with an `@experimental` tag and comment in both the documentation and docs applied to the TypeScript sources. +4. Unless otherwise stated, experimental features should be considered optional for compliance purposes, but recommended for implementation (i.e. the SHOULD keyword is implied). +5. Experimental features are exempted from the normal versioning and deprecation policies that govern changes to FDC3. I.e. breaking changes may be made to experimental features between versions of the Standard without a major version release. +6. The experimental designation may be removed from a feature in a minor version release (as this will be considered an additive change). + +## Intellectual Property Claims + +Recipients of this document are requested to submit, with their comments, notification of +any relevant patent claims or other intellectual property rights of which they may be aware that +might be infringed by any implementation of the standard set forth in this document, and to provide +supporting documentation. + +THIS STANDARD IS BEING OFFERED WITHOUT ANY WARRANTY +WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NON-INFRINGEMENT IS +EXPRESSLY DISCLAIMED. ANY USE OF THIS STANDARD SHALL BE MADE +ENTIRELY AT THE IMPLEMENTER'S OWN RISK, AND NEITHER THE FOUNDATION, +NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY +WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF +ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE +OF THIS STANDARD. diff --git a/website/versioned_docs/version-2.1/fdc3-glossary.md b/website/versioned_docs/version-2.1/fdc3-glossary.md new file mode 100644 index 000000000..6fa5a970c --- /dev/null +++ b/website/versioned_docs/version-2.1/fdc3-glossary.md @@ -0,0 +1,42 @@ +--- +id: fdc3-glossary +title: Glossary of Terms +sidebar_label: Glossary +--- + +For the purposes of this Standard, the following definitions apply. Other terms are defined when first used, at which place they appear in bold and italic type. Terms explicitly defined in this Standard are not to be presumed to refer implicitly to similar terms defined elsewhere. Terms not defined are assumed to be well-known in the financial services or software industries. + +- **Agent Bridge**: Shorthand for Desktop Agent Bridge. +- **app**: Shorthand for application. +- **app directory**: A repository of application metadata supporting discovery, for example via name or intent, and retrieval of metadata necessary to launch an application. +- **app directory record**: Metadata relating to a single application, encoded in JSON. +- **appD**: Shorthand for app directory. +- **appD record**: Shorthand for app directory record. +- **application**: Any endpoint on the desktop that is registered with/known by a Desktop Agent, launchable by a Desktop Agent, addressable by a Desktop Agent or otherwise able to interact with the Desktop Agent. +- **application, hybrid**: Any web application running within the context of a standalone native application that embeds a web view, typically based on Chromium. +- **application, native**: A non-web-based application; i.e., one that runs outside the context of web browser, web view or web container. A user-written program, typically implemented in a language such as C++, C#, Java, or Python, rather than JavaScript or TypeScript. +- **application, web**: An application written in TypeScript or JavaScript, HTML and CSS, which runs within the context of a web browser or a web container. +- **Application Provider**: A downstream consumer of FDC3 Standards that can understand and use the FDC3 API (supplied by a Platform Provider), context data, and/or intents. +- **application-specific intent**: A custom intent defined by an application or applications, independent of the Standard. +- **Bridge**: Shorthand for Desktop Agent Bridge. +- **bridging**: Shorthand for the exchange of messages across a Desktop Agent Bridge for the purposes of extending interop between apps managed by different Desktop Agents. +- **Channel**: A grouping of apps for the purposes of sharing stateful pieces of data. A secondary interface of the FDC3 API. +- **context channels**: A mechanism to allow sets of apps to share stateful pieces of data among themselves, and to be alerted when that data changes. +- **context**: Shorthand for context data. +- **context data**: Objects encoding common identifiers and data in a standardized format that can be passed between apps via context channels or used in conjunction with intents to invoke actions creating a seamless cross-application workflow. Diverse context data types are created to encode different types of data, each having their own _type_ field and unique set of data fields. +- **DAB**: Acronym of Desktop Agent Bridge. +- **Desktop Agent**: A desktop component (or aggregate of components) that serves as a launcher and message router (broker) for applications in its domain. The primary interface of the FDC3 API. +- **Desktop Agent Bridge**: An independent service that Desktop Agents connect to which allows them to relay requests to other Desktop Agents also connected to the bridge, allowing FDC3-based interop to extend across multiple Desktop Agents and machines. +- **FDC3 API**: A baseline, consistent developer interface for interoperability between applications. +- **GUID**: Globally Unique IDentifier, synonymous with UUID. Defined by [IETF RFC4122](references). +- **interop**: Shorthand for interoperability. +- **interoperability**: the ability of software applications to exchange and make use of information and invoke specified actions. +- **intent**: A verb, with a pre-agreed meaning (expected behavior), used to invoke an action between applications. A set of such verbs can, in conjunction with Context Data acting as nouns, be used to put together common cross-application workflows on the financial desktop. +- **Listener**: API interface which allows unsubscribing from Intents or Context Channels. +- **Originating App**: The application that sent a particular context message or raised an intent. +- **Platform Provider**: An environment that provides an implementation of the FDC3 API that applications can use. +- **raising an intent**: The act of requesting, via the FDC3 API/Desktop Agent that a specified action be performed by another application, using specified context data as input. +- **resolver**: A facility of a Desktop Agent used to map a raised intent and associated context object to an application that will perform the action represented by the intent, using the context object as input. Where multiple applications can resolve the intent, a resolver will often display a user-interface allowing a user to pick from the available applications that support the intent and type of context supplied. +- **resolving an intent**: The act of mapping a specified intent and context object to an application. +- **standard intent**: An intent defined by this Standard. +- **UUID**: Universally Unique IDentifier, synonymous with GUID. Defined by [IETF RFC4122](references). diff --git a/website/versioned_docs/version-2.1/fdc3-intro.md b/website/versioned_docs/version-2.1/fdc3-intro.md new file mode 100644 index 000000000..e7a254877 --- /dev/null +++ b/website/versioned_docs/version-2.1/fdc3-intro.md @@ -0,0 +1,52 @@ +--- +id: fdc3-intro +title: Welcome to FDC3 2.1 +sidebar_label: Introduction +--- + +The mission of the Financial Desktop Connectivity and Collaboration Consortium (FDC3) is to develop specific protocols and taxonomies to advance the ability of desktop applications in financial workflows to interoperate in a plug-and-play fashion, without prior bi-lateral agreements. + +FDC3 provides an **open standard for interoperability** between applications on the financial desktop. + +This includes standardized verbs to invoke actions between applications (**intents**), a standardized **context data** format, a REST-based **App Directory** standard, and standardized API operations for a **Desktop Agent**. + +## Motivation + +FDC3 codifies standard patterns that application developers have been using for cross-application workflows between web and native applications in the financial industry. + +For more information, see [Why FDC3?](why-fdc3) + +## Parts of the Standard + +The [Standard](fdc3-standard) currently consists of five complementary parts: + +- [API](api/spec) +- [Intents](intents/spec) +- [Context Data](context/spec) +- [App Directory](app-directory/spec) +- [Agent Bridging](agent-bridging/spec) + +## Use Cases + +From its inception, the standards have been informed by real-world [business use cases](use-cases/overview), which you can view on this website, and form an important part of FDC3. + +## Who is using FDC3? + +The Financial Desktop Connectivity and Collaboration Consortium (FDC3) standards are created and used by [leading organizations across the financial industry](/users). For more detail on who's using FDC3, developer tools, training and examples, see the [community page](/community). + +## How is FDC3 governed? + +FDC3 is hosted within, and governed by the policies of, the [Fintech Open Source Foundation](http://finos.org/) (FINOS). FINOS is an independent nonprofit organization focused on promoting open innovation within financial services. + +- See the [FDC3 Governance document](https://github.com/finos/FDC3/blob/master/GOVERNANCE.md) for details of how FDC3 is governed. +- See the [FDC3 Contribution Guide](https://github.com/finos/FDC3/blob/master/CONTRIBUTING.md) for details of how to contribute to FDC3. +- See the [FDC3 Charter](fdc3-charter#licensing) for details of how deliverables are licensed. + +## Where should I go next? + +- Have a look at the [supported platforms](supported-platforms) or [common use cases](use-cases/overview). +- Visit FDC3 [on GitHub](https://github.com/finos/FDC3). +- Download and install our [npm package](https://www.npmjs.com/package/@finos/fdc3). +- Try out an FDC3-compliant implementation, e.g. this [browser extension](https://github.com/finos/fdc3-desktop-agent). +- Join us in the [mailing list](mailto:fdc3+subscribe@finos.org) or on [Slack](https://app.slack.com/client/T01E7QRQH97/C01R0P7H5LH). +- [Participate](https://github.com/finos/FDC3#getting-involved) in the evolution of the standard. diff --git a/website/versioned_docs/version-2.1/fdc3-standard.md b/website/versioned_docs/version-2.1/fdc3-standard.md new file mode 100644 index 000000000..8b943bdce --- /dev/null +++ b/website/versioned_docs/version-2.1/fdc3-standard.md @@ -0,0 +1,41 @@ +--- +id: fdc3-standard +title: FDC3 2.1 +sidebar_label: Abstract +--- + +**Status:** Current +_**adopted:** 31st August 2023_ +_**released:** 14th September 2023_ + +## Abstract + +FDC3 aims to provide an open standard for interoperability on the financial desktop. This includes standardized verbs to invoke actions between applications (called "intents"), a standardized data format, an OpenAPI app directory standard, and standardized API operations. + +The specifications are informed by agreed business [use cases](use-cases/overview), and implemented and used by leading [financial industry participants](../../users). + +The standard currently consists of five complementary parts: + +- **[Desktop Agent API](api/spec)**: An API interface for working with a Desktop agent, which acts as launcher and message router (broker) for applications in its domain. +- **[Intents](intents/spec)**: A set of verbs that, in conjunction with context data acting as nouns, can be used to put together common cross-application workflows on the financial desktop. +- **[Context Data](context/spec)**: A message format for passing common identifiers and data between apps to create a seamless workflow. +- **[App Directory](app-directory/spec)**: A structured repository of information about apps that can be used in an FDC3-enabled desktop. +- **[Agent Bridging](agent-bridging/spec)**: An [@experimental](fdc3-compliance#experimental-features) API interface for the interconnection of Desktop Agents (DAs) such that apps running under different Desktop Agents can interoperate. + +## Versioning + +This Standard defines FDC3 Version 2.1. The differences between this version and earlier ones can be found in the [Changelog](https://github.com/finos/FDC3/blob/master/CHANGELOG.md). + +For more details on FDC3's versioning, deprecation and experimental features policies see the [Compliance page](./fdc3-compliance#versioning). + +## Table of Contents + +- [Compliance information](fdc3-compliance) +- [Glossary](fdc3-glossary) +- [References](references) +- [Supported Platforms](supported-platforms) +- [API Part](api/spec) +- [Intents Part](intents/spec) +- [Context Data Part](context/spec) +- [App Directory Part](app-directory/spec) +- [Agent Bridging Part](agent-bridging/spec) diff --git a/website/versioned_docs/version-2.1/guides/submit-new-intent.md b/website/versioned_docs/version-2.1/guides/submit-new-intent.md new file mode 100644 index 000000000..5e9f4f39e --- /dev/null +++ b/website/versioned_docs/version-2.1/guides/submit-new-intent.md @@ -0,0 +1,62 @@ +--- +id: SubmitNewIntent +sidebar_label: How To Submit New Intent +title: How to Submit a New Intent PR +--- + +## Getting Started + +Prepare to submit a patch as described in [How to Contribute a Patch](https://github.com/finos/FDC3/blob/master/CONTRIBUTING.md#3how-to-contribute-a-patch) in CONTRIBUTING.md. Use the issue number and issue title as the branch name, e.g. + +```git checkout -b 587-intent-proposal-view-research``` + +To install all the necessary packages to run the website locally, change to the website directory and run yarn + +```bash +cd website +yarn +``` + +To run the website locally + +```yarn start``` + +This will open the home page or browse to + +Note that the page opens on the current release version of the docs and you will be changing the latest version. Click the version selector in the top left hand corner + +![Version Selector](/assets/version_selector.png) + +and then select 'Documentation' under 'Latest Version' + +![Latest Version Selector](/assets/latest_version_selector.png) + +The 'next' version will be indicated in the header: + +![Next Version](/assets/next_version.png) + +## Create Intent File + +Add the new intent markdown file to docs/intents/ref. Use one of the existing intent markdown files as a template. E.g. the [ViewResearch](../intents/ref/ViewResearch) intent was created using [ViewProfile](../intents/ref/ViewProfile) as an example: + +![View Research](/assets/view_research.png) + +## Link to Intent File + +Add links to your Intent File to the following: + +- [src/intents/Intents.ts](https://github.com/finos/FDC3/blob/master/src/intents/Intents.ts) +- [src/intents/standard intents.json](https://github.com/finos/FDC3/blob/master/src/intents/standard%20intents.json) +- [website/sidebars.json](https://github.com/finos/FDC3/blob/master/website/sidebars.json) (look for the 'Intents' property and the 'ids' property within it) + +At this point your new Intent should appear on the sidebar (you may need to restart yarn to get this). + +Also add to: + +- [docs/intents/spec.md](https://github.com/finos/FDC3/blob/master/docs/intents/spec.md) in the 'Standard Intents' section (also add the summary from your Intent page) +- Any of the Context documents in [docs/context/ref](https://github.com/finos/FDC3/blob/master/docs/context/ref) that are utilized by the Intent (e.g. for the [ViewResearch](../intents/ref/ViewResearch) intent, each of the [Contact](../context/ref/Contact), [Instrument](../context/ref/Instrument) and [Organization](../context/ref/Organization) Contexts are valid and so links were added to their Context pages) +- Any of the Intents documents in [docs/intents/ref](https://github.com/finos/FDC3/blob/master/docs/intents/ref) that are related or relevant to the new Intent (e.g. for the [ViewResearch](../intents/ref/ViewResearch) intent a link was added to the [ViewAnalysis](../intents/ref/ViewAnalysis) document) + +## Finishing Off + +Commit your changes and push as described in [How to Contribute a Patch](https://github.com/finos/FDC3/blob/master/CONTRIBUTING.md#3how-to-contribute-a-patch). Then submit the branch as a Pull Request (in github, go to the Branches tab and click 'New Pull Request') diff --git a/website/versioned_docs/version-2.1/intents/ref/CreateInteraction.md b/website/versioned_docs/version-2.1/intents/ref/CreateInteraction.md new file mode 100644 index 000000000..041b663a4 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/CreateInteraction.md @@ -0,0 +1,126 @@ +--- +id: CreateInteraction +sidebar_label: CreateInteraction +title: CreateInteraction +hide_title: true +--- +# `CreateInteraction` + +Create a record documenting an interaction (calls, meetings, etc.) between a list of contacts. + +## Intent Name + +`CreateInteraction` + +## Display Name + +`Create Interaction` + +## Possible Contexts + +* [ContactList](../../context/ref/ContactList) +* [Interaction](../../context/ref/Interaction) + +SHOULD return context as a result: + +* [TransactionResult](../../context/ref/TransactionResult) + +## Example + +```js +const interaction = { + type: 'fdc3.interaction', + participants: { + type: 'fdc3.contactList', + contacts: [ + { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@mail.com' + } + }, + { + type: 'fdc3.contact', + name: 'John Doe', + id: { + email: 'john.doe@mail.com' + } + }, + ] + }, + interactionType: 'Instant Message', + timeRange: { + type: 'fdc3.timeRange', + startTime: '2022-02-10T15:12:00Z' + }, + description: 'Laboris libero dapibus fames elit adipisicing eu, fermentum, dignissimos laboriosam, erat, risus qui deserunt. Praesentium! Reiciendis. Hic harum nostrud, harum potenti amet? Mauris. Pretium aliquid animi, eget eiusmod integer proident. Architecto ipsum blandit ducimus, possimus illum sunt illum necessitatibus ab litora sed, nonummy integer minus corrupti ducimus iste senectus accumsan, fugiat nostrud? Pede vero dictumst excepturi, iure earum consequuntur voluptatum', + initiator: { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@mail.com' + } + }, + origin: 'Outlook' +} + +const intentResolution = await fdc3.raiseIntent('CreateInteraction', interaction); +const result = await intentResolution.getResult(); +console.log(result); +``` + +Console log will display: + +```js +{ + type: 'fdc3.transactionResult', + status: 'Created', + context: { + type: 'fdc3.interaction', + participants: { + type: 'fdc3.contactList', + contacts: [ + { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@mail.com' + } + }, + { + type: 'fdc3.contact', + name: 'John Doe', + id: { + email: 'john.doe@mail.com' + } + }, + ] + }, + interactionType: 'Instant Message', + timeRange: { + type: 'fdc3.timeRange', + startTime: '2022-02-10T15:12:00Z' + }, + description: 'Laboris libero dapibus fames elit adipisicing eu, fermentum, dignissimos laboriosam, erat, risus qui deserunt. Praesentium! Reiciendis. Hic harum nostrud, harum potenti amet? Mauris. Pretium aliquid animi, eget eiusmod integer proident. Architecto ipsum blandit ducimus, possimus illum sunt illum necessitatibus ab litora sed, nonummy integer minus corrupti ducimus iste senectus accumsan, fugiat nostrud? Pede vero dictumst excepturi, iure earum consequuntur voluptatum', + initiator: { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@mail.com' + } + }, + origin: 'Outlook' + id: { + Singletrack: 'a0S8d000000uO05EAE' + } + }, + message: 'record with id "a0S8d000000uO05EAE" was created' +} +``` + +## See Also + +Context +- [Interaction](../../context/ref/Interaction) +- [TransactionResult](../../context/ref/TransactionResult) \ No newline at end of file diff --git a/website/versioned_docs/version-2.1/intents/ref/SendChatMessage.md b/website/versioned_docs/version-2.1/intents/ref/SendChatMessage.md new file mode 100644 index 000000000..e34673333 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/SendChatMessage.md @@ -0,0 +1,50 @@ +--- +id: SendChatMessage +sidebar_label: SendChatMessage +title: SendChatMessage +hide_title: true +--- +# `SendChatMessage` + +Send a message to an existing chat room. + +## Intent Name + +`SendChatMessage` + +## Display Name + +`Send Chat Message` + +## Possible Contexts + +* [ChatMessage](../../context/ref/ChatMessage) + +## Example + +```js +// Start a chat and retrieve a reference to the chat room created +const intentResolution = await fdc3.raiseIntent("StartChat", context); +const chatRoom = intentResolution.getResult(); + +//Some time later + +let chatMessage: ChatMessage = { + type: "fdc3.chat.message", + chatRoom, + message: "Another message to send in the room" +} + +await fdc3.raiseIntent("SendChatMessage", context, intentResolution.source); +``` + +## See Also + +Context +- [ChatMessage](../../context/ref/ChatMessage) +- [ChatRoom](../../context/ref/ChatRoom) + +Intents +* [StartChat](StartChat) +* [StartCall](StartCall) +* [StartEmail](StartEmail) diff --git a/website/versioned_docs/version-2.1/intents/ref/StartCall.md b/website/versioned_docs/version-2.1/intents/ref/StartCall.md new file mode 100644 index 000000000..78689b0ab --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/StartCall.md @@ -0,0 +1,48 @@ +--- +id: StartCall +sidebar_label: StartCall +title: StartCall +hide_title: true +--- +# `StartCall` + +Initiate a call with a contact or list of contacts. + +## Intent Name + +`StartCall` + +## Display Name + +`Start a Call` + +## Possible Contexts + +- [Contact](../../context/ref/Contact) +- [ContactList](../../context/ref/ContactList) + +## Example + +```js +const contact = { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } +} + +fdc3.raiseIntent('StartCall', contact) +``` + +## See Also + +Context + +- [Contact](../../context/ref/Contact) +- [ContactList](../../context/ref/ContactList) + +Intents + +- [StartChat](StartChat) +- [StartEmail](StartEmail) diff --git a/website/versioned_docs/version-2.1/intents/ref/StartChat.md b/website/versioned_docs/version-2.1/intents/ref/StartChat.md new file mode 100644 index 000000000..344263076 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/StartChat.md @@ -0,0 +1,100 @@ +--- +id: StartChat +sidebar_label: StartChat +title: StartChat +hide_title: true +--- +# `StartChat` + +Initiate a chat with a contact, a list of contacts or detailed initialization settings. This could be launched from within another application. For example initiating a chat from a research or OMS application. + +## Intent Name + +`StartChat` + +## Display Name + +`Start a Chat` + +## Possible Contexts + +- [Contact](../../context/ref/Contact) +- [ContactList](../../context/ref/ContactList) +- [ChatInitSettings](../../context/ref/ChatInitSettings) + +## Example + +```js +const contact = { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } +} + +fdc3.raiseIntent('StartChat', contact) + +// chat with initialization settings +const initSettings = { + type: 'fdc3.chat.initSettings', + chatName: 'Chat ABCD', + members: { + type: 'fdc3.contactList', + contacts: [{ + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } + },{ + type: 'fdc3.contact', + name: 'John Doe', + id: { + email: 'john@mail.com' + }, + }] + }, + options: { + groupRecipients: true, // one chat with both contacts + isPublic: false, // private chat room + allowHistoryBrowsing: true, + allowMessageCopy: true + } + message: { + type: 'fdc3.message', + text: { + 'text/plain': 'Hey all, can we discuss the issue together? I attached a screenshot' + }, + entities: { + '0': { + type: 'fdc3.fileAttachment', + data: { + name: 'myImage.png', + dataUri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII' + } + } + } + } +} + +const resolution = fdc3.raiseIntent('StartChat', initSettings); + +// Return a reference to the room +const chatRoom = await resolution.getResult(); +``` + +## See Also + +Context + +- [ChatRoom](../../context/ref/ChatRoom) +- [Contact](../../context/ref/Contact) +- [ContactList](../../context/ref/ContactList) +- [ChatInitSettings](../../context/ref/ChatInitSettings) + +Intents + +- [SendChatMessage](SendChatMessage) +- [StartCall](StartCall) +- [StartEmail](StartEmail) diff --git a/website/versioned_docs/version-2.1/intents/ref/StartEmail.md b/website/versioned_docs/version-2.1/intents/ref/StartEmail.md new file mode 100644 index 000000000..90876a92a --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/StartEmail.md @@ -0,0 +1,49 @@ +--- +id: StartEmail +sidebar_label: StartEmail +title: StartEmail +hide_title: true +--- +# `StartEmail` + +Initiate an email with a contact or list of contacts provided as part of an Email context. + +## Intent Name + +`StartEmail` + +## Display Name + +`Start Email` + +## Possible Contexts + +- [Email](../../context/ref/Email) + +## Example + +```js +window.fdc3.raiseIntent('fdc3.StartEmail', { + type: 'fdc3.email', + recipients: { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@example.com' + } + }, + subject: 'The information you requested', + textBody: 'Blah, blah, blah ...' +}) +``` + +## See Also + +Context + +- [Email](../../context/ref/Email) + +Intents + +- [StartCall](StartCall) +- [StartChat](StartChat) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewAnalysis.md b/website/versioned_docs/version-2.1/intents/ref/ViewAnalysis.md new file mode 100644 index 000000000..b39548f30 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewAnalysis.md @@ -0,0 +1,51 @@ +--- +id: ViewAnalysis +sidebar_label: ViewAnalysis +title: ViewAnalysis +hide_title: true +--- +# `ViewAnalysis` + +Display analysis on the provided context. + +## Intent Name + +`ViewAnalysis` + +## Display Name + +`View Analysis` + +## Possible Contexts + +- [Instrument](../../context/ref/Instrument) +- [Organization](../../context/ref/Organization) +- [Portfolio](../../context/ref/Portfolio) + +## Example + +```js +const instrument = { + type: 'fdc3.instrument', + name: 'International Business Machines', + id: { + ticker: 'ibm' + } +} + +fdc3.raiseIntent('ViewAnalysis', instrument) +``` + +## See Also + +Context + +- [Instrument](../../context/ref/Instrument) +- [Organization](../../context/ref/Organization) +- [Portfolio](../../context/ref/Portfolio) +- [Position](../../context/ref/Position) + +Intents + +- [ViewChart](ViewChart) +- [ViewResearch](ViewResearch) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewChart.md b/website/versioned_docs/version-2.1/intents/ref/ViewChart.md new file mode 100644 index 000000000..327c39f45 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewChart.md @@ -0,0 +1,99 @@ +--- +id: ViewChart +sidebar_label: ViewChart +title: ViewChart +hide_title: true +--- +# `ViewChart` + +Display a chart for the provided context. + +## Intent Name + +`ViewChart` + +## Display Name + +`View Chart` + +## Possible Contexts + +- [Chart](../../context/ref/Chart) +- [Instrument](../../context/ref/Instrument) +- [InstrumentList](../../context/ref/InstrumentList) +- [Portfolio](../../context/ref/Portfolio) +- [Position](../../context/ref/Position) + +## Example + +Request a chart for an instrument: + +```js +const instrument = { + type: 'fdc3.instrument', + name: 'International Business Machines', + id: { + ticker: 'ibm' + } +} + +fdc3.raiseIntent('ViewChart', instrument) +``` + +Request a specific chart: + +```js +const chart = { + type: "fdc3.chart", + instruments: [ + { + type: "fdc3.instrument", + id: { + ticker: "AAPL" + } + }, + { + type: "fdc3.instrument", + id: { + ticker: "GOOG" + } + } + ], + range: { + type: "fdc3.timeRange", + startTime: "2020-09-01T08:00:00.000Z", + endTime: "2020-10-31T08:00:00.000Z" + }, + style: "line", + otherConfig: { + indicators: [ + { + name: "ma", + parameters: { + period: 14, + type: "ema" + } + }, + { + name: "volume" + } + ] + } +}; + +fdc3.raiseIntent("ViewChart", chart); +``` + +## See Also + +Context + +- [Chart](../../context/ref/Chart) +- [Instrument](../../context/ref/Instrument) +- [InstrumentList](../../context/ref/InstrumentList) +- [Portfolio](../../context/ref/Portfolio) +- [Position](../../context/ref/Position) + +Intents + +- [ViewQuote](ViewQuote) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewChat.md b/website/versioned_docs/version-2.1/intents/ref/ViewChat.md new file mode 100644 index 000000000..4a6973bd6 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewChat.md @@ -0,0 +1,103 @@ +--- +id: ViewChat +sidebar_label: ViewChat +title: ViewChat +hide_title: true +--- +# `ViewChat` + +Open an existing chat room. + +## Intent Name + +`ViewChat` + +## Display Name + +`View Chat` + +## Possible Contexts + +* [ChatRoom](../../context/ref/ChatRoom) +* [Contact](../../context/ref/Contact): It will open the **direct** chat where there is the current user and the contact +* [ContactList](../../context/ref/ContactList): It will open the **room** where there is the current user and the listed contacts. Contact List may need to display search results if there are multiple matches. + +## Output + +This intent returns as output: +* If the chat doesn't exist, will display a modal to create a chat +* if the chat gets created, return its ChatRoom context +* if none is created return void + +## Example: ChatRoom + +```js +const chatRoom = { + type: 'fdc3.chat.room', + providerName: "Symphony", + id: { + streamId: "j75xqXy25NBOdacUI3FNBH" + } +} + +const intentResolution = await fdc3.raiseIntent('ViewChat', chatRoom); + +const chatRoom = intentResolution.getResult(): // A chatRoom will be returned as context if the room was found +``` + +## Example: Contact + +```js +const contact = { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } +} + +const intentResolution = await fdc3.raiseIntent('ViewChat', contact); + +const chatRoom = intentResolution.getResult(): // A chatRoom will be returned as context if the direct chat was found +``` + +## Example: ContactList + +```js +const contacts = { + type: 'fdc3.contactList', + contacts: [ + { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane.doe@mail.com' + } + }, + { + type: 'fdc3.contact', + name: 'John Doe', + id: { + email: 'john.doe@mail.com' + } + }, + ] +} + + +const intentResolution = await fdc3.raiseIntent('ViewChat', contacts); + +const chatRoom = intentResolution.getResult(): // A chatRoom will be returned as context if the room was found +``` + +## See Also + +Context + +* [ChatRoom](../../context/ref/ChatRoom) +* [Contact](../../context/ref/Contact) +* [ContactList](../../context/ref/ContactList) + +Intents + +* [StartChat](StartChat) \ No newline at end of file diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewContact.md b/website/versioned_docs/version-2.1/intents/ref/ViewContact.md new file mode 100644 index 000000000..8ae0044f0 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewContact.md @@ -0,0 +1,49 @@ +--- +id: ViewContact +sidebar_label: ViewContact (deprecated) +title: ViewContact +hide_title: true +--- +# `ViewContact` + +:::caution +ViewContact has been deprecated in FDC3 2.0 in favour of the more general [ViewProfile](ViewProfile) intent. +::: + +View details for a contact. + +## Intent Name + +`ViewContact` + +## Display Name + +`View Contact Details` + +## Possible Contexts + +- [Contact](../../context/ref/Contact) + +## Example + +```js +const contact = { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } +} + +fdc3.raiseIntent('ViewContact', contact) +``` + +## See Also + +Context + +- [Contact](../../context/ref/Contact) + +Intents + +- [StartChat](StartChat) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewHoldings.md b/website/versioned_docs/version-2.1/intents/ref/ViewHoldings.md new file mode 100644 index 000000000..3cd948b54 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewHoldings.md @@ -0,0 +1,51 @@ +--- +id: ViewHoldings +sidebar_label: ViewHoldings +title: ViewHoldings +hide_title: true +--- +# `ViewHoldings` + +Display any holdings for the provided instrument, list of instruments, or organization. + +## Intent Name + +`ViewHoldings` + +## Display Name + +`View Holdings` + +## Possible Contexts + +- [Instrument](../../context/ref/Instrument) +- [InstrumentList](../../context/ref/InstrumentList) +- [Organization](../../context/ref/Organization) + +## Example + +```js +const instrument = { + type: 'fdc3.instrument', + name: 'Tesla, Inc.', + id: { + ticker: 'TSLA' + } +} + +fdc3.raiseIntent('ViewHoldings', instrument) +``` + +## See Also + +Context + +- [Instrument](../../context/ref/Instrument) +- [InstrumentList](../../context/ref/InstrumentList) +- [Organization](../../context/ref/Organization) + +Intents + +- [ViewInstrument](ViewInstrument) +- [ViewAnalysis](ViewAnalysis) +- [ViewOrders](ViewOrders) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewInstrument.md b/website/versioned_docs/version-2.1/intents/ref/ViewInstrument.md new file mode 100644 index 000000000..b7d143f6f --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewInstrument.md @@ -0,0 +1,46 @@ +--- +id: ViewInstrument +sidebar_label: ViewInstrument +title: ViewInstrument +hide_title: true +--- +# `ViewInstrument` + +Display details for the provided instrument. + +## Intent Name + +`ViewInstrument` + +## Display Name + +`View Instrument Details` + +## Possible Contexts + +- [Instrument](../../context/ref/Instrument) + +## Example + +```js +const instrument = { + type: 'fdc3.instrument', + name: 'International Business Machines', + id: { + ticker: 'ibm' + } +} + +fdc3.raiseIntent('ViewInstrument', instrument) +``` + +## See Also + +Context + +- [Instrument](../../context/ref/Instrument) + +Intents + +- [ViewChart](ViewChart) +- [ViewOrders](ViewOrders) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewInteractions.md b/website/versioned_docs/version-2.1/intents/ref/ViewInteractions.md new file mode 100644 index 000000000..6858e35ff --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewInteractions.md @@ -0,0 +1,50 @@ +--- +id: ViewInteractions +sidebar_label: ViewInteractions +title: ViewInteractions +hide_title: true +--- +# `ViewInteractions` + +Display interactions (calls, meetings, etc.) related to an individual, an instrument or organization provided as context. + +## Intent Name + +`ViewInteractions` + +## Display Name + +`View Interactions` + +## Possible Contexts + +- [Contact](../../context/ref/Contact) +- [Instrument](../../context/ref/Instrument) +- [Organization](../../context/ref/Organization) + +## Example + +```js +const contact = { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } +} + +fdc3.raiseIntent('ViewInteractions', contact) +``` + +## See Also + +Context + +- [Contact](../../context/ref/Contact) +- [Instrument](../../context/ref/Instrument) +- [Organization](../../context/ref/Organization) + +Intents + +- [ViewProfile](ViewProfile) +- [ViewResearch](ViewResearch) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewMessages.md b/website/versioned_docs/version-2.1/intents/ref/ViewMessages.md new file mode 100644 index 000000000..fa3c28459 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewMessages.md @@ -0,0 +1,124 @@ +--- +id: ViewMessages +sidebar_label: ViewMessages +title: ViewMessages +hide_title: true +--- +# `ViewMessages` + +Search and display a list of messages (for example in a chat application or CRM) to the user. + +## Intent Name + +`ViewMessages` + +## Display Name + +`View Messages` + +## Possible Contexts + +* [ChatSearchCriteria](../../context/ref/ChatSearchCriteria) + +## Example + +Request display of messages relating to a specific `fdc3.instrument` (representing a ticker): +```js +const searchCriteria = { + type: "fdc3.chat.searchCriteria", + criteria: [ + { + type: "fdc3.instrument", + id: { + ticker: "AAPL" + } + } + ] +} + +fdc3.raiseIntent('ViewMessages', searchCriteria); +``` + +Request display of messages relating to a specific `fdc3.contact`: + +```js +const searchCriteria = { + type: "fdc3.chat.searchCriteria", + criteria: [ + { + type: "fdc3.contact", + name: "Jane Doe", + id: { + email: "jane.doe@mail.com" + } + } + ] +} + +fdc3.raiseIntent('ViewMessages', searchCriteria); +``` + +Request display of messages relating to a specific `fdc3.organization`: + +```js +const searchCriteria = { + type: "fdc3.chat.searchCriteria", + criteria: [ + { + type: "fdc3.organization", + name: "Symphony" + } + ] +} + +fdc3.raiseIntent('ViewMessages', searchCriteria); +``` + +Request display of messages relating to a specific **phrase**: + +```js +const searchCriteria = { + type: "fdc3.chat.searchCriteria", + criteria: [ + "#OrderID45788422" + ] +} + +fdc3.raiseIntent('ViewMessages', searchCriteria); +``` + +Request display of messages matching _multiple_ criteria: +```js +const searchCriteria = { + type: "fdc3.chat.searchCriteria", + criteria: [ + { + type: "fdc3.contact", + name: "Jane Doe", + id: { + email: "jane.doe@mail.com" + } + }, + { + type: "fdc3.organization", + name: "Symphony" + }, + "#OrderID45788422" + ] +} + +fdc3.raiseIntent('ViewMessages', searchCriteria); +``` + +## See Also + +Context + +* [ChatSearchCriteria](../../context/ref/ChatSearchCriteria) +* [Instrument](../../context/ref/Instrument) +* [Contact](../../context/ref/Contact) +* [Organization](../../context/ref/Organization) + +Intents + +* [ViewChat](ViewChat) \ No newline at end of file diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewNews.md b/website/versioned_docs/version-2.1/intents/ref/ViewNews.md new file mode 100644 index 000000000..6c0cb543b --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewNews.md @@ -0,0 +1,57 @@ +--- +id: ViewNews +sidebar_label: ViewNews +title: ViewNews +hide_title: true +--- +# `ViewNews` + +Display news stories for the provided context. + +## Intent Name + +`ViewNews` + +## Display Name + +`View News` + +## Possible Contexts + +- [Country](../../context/ref/Country) +- [Instrument](../../context/ref/Instrument) +- [InstrumentList](../../context/ref/InstrumentList) +- [Organization](../../context/ref/Organization) +- [Portfolio](../../context/ref/Portfolio) + +## Example + +```js +const instrument = { + type: 'fdc3.instrument', + name: 'International Business Machines', + id: { + ticker: 'IBM' + }, + market: { + MIC: "XNYS" + } +} + +fdc3.raiseIntent('ViewNews', instrument) +``` + +## See Also + +Context + +- [Country](../../context/ref/Country) +- [Instrument](../../context/ref/Instrument) +- [InstrumentList](../../context/ref/InstrumentList) +- [Organization](../../context/ref/Organization) +- [Portfolio](../../context/ref/Portfolio) +- [Position](../../context/ref/Position) + +Intents + +- [ViewAnalysis](ViewAnalysis) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewOrders.md b/website/versioned_docs/version-2.1/intents/ref/ViewOrders.md new file mode 100644 index 000000000..6ccdf141f --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewOrders.md @@ -0,0 +1,50 @@ +--- +id: ViewOrders +sidebar_label: ViewOrders +title: ViewOrders +hide_title: true +--- +# `ViewOrders` + +Display any orders related to the provided contact, instrument, or organization. + +## Intent Name + +`ViewOrders` + +## Display Name + +`View Orders` + +## Possible Contexts + +- [Contact](../../context/ref/Contact) +- [Instrument](../../context/ref/Instrument) +- [Organization](../../context/ref/Organization) + +## Example + +```js +const instrument = { + type: 'fdc3.instrument', + name: 'Tesla, Inc.', + id: { + ticker: 'TSLA' + } +} + +fdc3.raiseIntent('ViewOrders', instrument) +``` + +## See Also + +Context + +- [Contact](../../context/ref/Contact) +- [Instrument](../../context/ref/Instrument) +- [Organization](../../context/ref/Organization) + +Intents + +- [ViewHoldings](ViewHoldings) +- [ViewInstrument](ViewInstrument) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewProfile.md b/website/versioned_docs/version-2.1/intents/ref/ViewProfile.md new file mode 100644 index 000000000..8859e1518 --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewProfile.md @@ -0,0 +1,48 @@ +--- +id: ViewProfile +sidebar_label: ViewProfile +title: ViewProfile +hide_title: true +--- +# `ViewProfile` + +Display basic profile information for the individual or organization provided as context. + +## Intent Name + +`ViewProfile` + +## Display Name + +`View Profile` + +## Possible Contexts + +- [Contact](../../context/ref/Contact) +- [Organization](../../context/ref/Organization) + +## Example + +```js +const contact = { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } +} + +fdc3.raiseIntent('ViewProfile', contact) +``` + +## See Also + +Context + +- [Contact](../../context/ref/Contact) +- [Organization](../../context/ref/Organization) + +Intents + +- [ViewHoldings](ViewHoldings) +- [ViewInteractions](ViewInteractions) diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewQuote.md b/website/versioned_docs/version-2.1/intents/ref/ViewQuote.md new file mode 100644 index 000000000..8da52d9be --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewQuote.md @@ -0,0 +1,45 @@ +--- +id: ViewQuote +sidebar_label: ViewQuote +title: ViewQuote +hide_title: true +--- +# `ViewQuote` + +Display pricing for an [Instrument](../../context/ref/Instrument). + +## Intent Name + +`ViewQuote` + +## Display Name + +`View Quote` + +## Possible Contexts + +- [Instrument](../../context/ref/Instrument) + +## Example + +```js +const instrument = { + type: 'fdc3.instrument', + name: 'International Business Machines', + id: { + ticker: 'ibm' + } +} + +fdc3.raiseIntent('ViewQuote', instrument) +``` + +## See Also + +Context + +- [Instrument](../../context/ref/Instrument) + +Intents + +- [ViewChart](ViewChart) \ No newline at end of file diff --git a/website/versioned_docs/version-2.1/intents/ref/ViewResearch.md b/website/versioned_docs/version-2.1/intents/ref/ViewResearch.md new file mode 100644 index 000000000..ff816669b --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/ref/ViewResearch.md @@ -0,0 +1,49 @@ +--- +id: ViewResearch +sidebar_label: ViewResearch +title: ViewResearch +hide_title: true +--- +# `ViewResearch` + +Show research related to an instrument, an individual or organization provided as context. + +## Intent Name + +`ViewResearch` + +## Display Name + +`View Research` + +## Possible Contexts + +- [Contact](../../context/ref/Contact) +- [Instrument](../../context/ref/Instrument) +- [Organization](../../context/ref/Organization) + +## Example + +```js +const contact = { + type: 'fdc3.contact', + name: 'Jane Doe', + id: { + email: 'jane@mail.com' + } +} + +fdc3.raiseIntent('ViewResearch', contact) +``` + +## See Also + +Context + +- [Contact](../../context/ref/Contact) +- [Instrument](../../context/ref/Instrument) +- [Organization](../../context/ref/Organization) + +Intents + +- [ViewAnalysis](ViewAnalysis) diff --git a/website/versioned_docs/version-2.1/intents/spec.md b/website/versioned_docs/version-2.1/intents/spec.md new file mode 100644 index 000000000..731ff622f --- /dev/null +++ b/website/versioned_docs/version-2.1/intents/spec.md @@ -0,0 +1,194 @@ +--- +id: spec +sidebar_label: Overview +title: Intents Overview (2.1) +--- + +FDC3 Intents define a standard set of verbs that, in conjunction with context data acting as nouns, can be used to put together common cross-application workflows on the financial desktop. + +- Applications register the intents and [context data](../context/spec) combinations they support in the [App Directory](../app-directory/spec). +- The App Directory supports application discovery by intents and/or context data. +- Intents are not full RPC, apps don’t need to enumerate every function with an intent. +- FDC3 standard intents are a limited set, organizations can create their own intents. + +## Naming Conventions + +Naming of Intents SHOULD follow the below guidelines: + +- Intent names should be free of non-alphanumeric characters. +- ‘.’ will be used to namespace the intent (see below). +- Intent names should be in UpperCamelCase. + +:::note +The naming guidelines should be adhered to when creating future Intents. This is to ensure they meet the criteria for addition to the FDC3 standard and to provide a consistent user experience. +::: + +### Characteristics + +When creating Intents they should be: + +- Recognizable + - Generally self-evident what the thing is +- Repeatable + - Many instances across the industry +- Stateless + - Workflows should not require callbacks or endpoints to maintain references to each other. Once an Intent is passed to an endpoint - it controls the rest of that workflow. +- Specific + - Terms should not be so open-ended that one endpoint could fulfill the Intent in a completely different way than another +- Distinct + - Granular enough that Intent handlers can communicate key functional differences + +### Namespaces + +All standard intent names are reserved. Applications may use their own intents ad hoc. +However, there is occasionally a need for applications to ensure that their intents avoid collision, for example, where a workflow is highly specific to or internal to an application. The recommended approach is to namespace the intent with the application name. For example, the ‘myChart’ App may expose the ‘ViewChart’ intent and the ‘myChart.Foo’ proprietary intent. + +### Intent Name Prefixes + +Early versions of the FDC3 standard included 8 intents, which used one of two different prefixes ( `View___` and `Start___`) that are focused on UI interactions. The prefixes are used to help define the expected behavior of an app when resolving an intent with that prefix. The list of intent name prefixes was expanded in FDC3 2.0 to include prefixes that indicate that CRUD operations should be performed on data. + +#### `View___` + +- Expected behavior: Content should be displayed to the user. + +#### `Start___` + +- Expected behavior: An interaction, such as a chat room or email thread, should be initiated. + +As more use cases were identified it was clear further Intents were required. FDC3 2.0 expanded this set to include the following: + +#### `Create___` + +- Expected behavior: A new record or entity should be created. The operation should fail if it already exists. + +#### `Update___` + +- Expected behavior: An existing record or entity should be updated. The operation should fail if it does not exist. + +#### `CreateOrUpdate___` + +- Expected behavior: A new record or entity should be created, or an existing one updated if it exists. + +#### `Delete___` + +- Expected behavior: An existing record or entity should be deleted. The operation should fail if it does not exist. + +#### `Get___` + +- Expected behavior: A record or entity should be retrieved and returned as an intent result. The operation should fail if the record does not exist. + +#### `Share___` + +- Expected behavior: A record or entity should shared. The operation should fail if it does not exist + +## Using Intents + +Combined with [context data](../context/spec) and [App Directory](../app-directory/overview) standards, intents enable rich service discovery on the desktop. For example: + +### Ask for a chart to be displayed + +```javascript +const result = await fdc3.raiseIntent("ViewChart", { + type: "fdc3.instrument", + name: "IBM", + id: { + ticker:"ibm" + } +}); +``` + +### Ask a specific application to display a chart + +```javascript +const result = await fdc3.raiseIntent("ViewChart", { + type: "fdc3.instrument", + name: "IBM", + id: { + ticker:"ibm" + } +}, "market-data-app"); +``` + +### Find applications that can start a chat + +```javascript +const intentApps = await fdc3.findIntent("StartChat"); +``` + +### Find available intents for a contact + +```javascript +const intentsAndApps = await fdc3.findIntentsByContext({ + type: "fdc3.contact", + name: "Jane Doe", + id: { + email:"jane@doe.com" + } +}); +``` + +## Intents that return data + +From FDC3 2.0, intents raised through the Desktop Agent API may return results in the form of a `Context` object or a `Channel`. Where an intent implements a transaction with another application, for example for a CRUD operation, the [`fdc3.transactionResult` context type](../context/ref/TransactionResult) SHOULD be used to provide a result status for the transaction and may wrap a context object that would otherwise be returned. + +For more details on retrieving a result from a raised intent, see the [documentation for `raiseIntent`](../api/ref/DesktopAgent#raiseintent). + +## Intents Standard Compliance + +An FDC3 Standard compliant application that supports intents **MUST**: + +- Meet the expected context and behavior defined for any FDC3-defined standard intents used. +- Where an app is intended to be launched in order to resolve a raised intent, use the [`fdc3.addIntentListener`](../api/ref/DesktopAgent#addintentlistener) API call to set up the necessary handler function(s) after it is launched. This facilitates delivery of raised intents to the application. + +An FDC3 Standard compliant application that supports intents **SHOULD**: + +- Prefer FDC3-defined standard intents over proprietary intents, where a suitable standardized intent is available. +- Ensure that proprietary intents follow the recommended naming conventions in the specification. +- Apply [namespacing](#namespaces) to proprietary intent names, where it is necessary to avoid collision with those created by other applications. +- Where an app is intended to be launched in order to resolve a raised intent, use the [`fdc3.addIntentListener`](../api/ref/DesktopAgent#addintentlistener) API call to set up the necessary handler function(s) within 15 seconds of the application launch (the minimum timeout Desktop Agents are required to provide) in order to be widely compatible with Desktop Agent implementations. +- Use the `fdc3.transactionResult` context type to return a status for any transactions relating to CRUD operations. + +An FDC3 Standard compliant application that supports intents **MAY**: + +- Define proprietary intents to support use cases not currently supported via FDC3-defined standard intents. + +For more details on FDC3 Standards compliance (including the versioning, deprecation and experimental features policies) please see the [FDC3 Compliance page](../fdc3-compliance). + +## Standard Intents + +A list of standardized intents are defined in the following pages: + +* [`CreateInteraction`](ref/CreateInteraction) +* [`StartCall`](ref/StartCall) +* [`StartChat`](ref/StartChat) +* [`StartEmail`](ref/StartEmail) +* [`ViewAnalysis`](ref/ViewAnalysis) +* [`ViewChat`](ref/ViewChat) +* [`ViewChart`](ref/ViewChart) +* [`ViewHoldings`](ref/ViewHoldings) +* [`ViewInstrument`](ref/ViewInstrument) +* [`ViewInteractions`](ref/ViewInteractions) +* [`ViewMessages`](ref/ViewMessages) +* [`ViewNews`](ref/ViewNews) +* [`ViewOrders`](ref/ViewOrders) +* [`ViewProfile`](ref/ViewProfile) +* [`ViewQuote`](ref/ViewQuote) +* [`ViewResearch`](ref/ViewResearch) + +### Deprecated Intents + +- [`ViewContact`](ref/ViewContact) + +## Using Intents without a context + +As the [Desktop Agent API](../api/ref/DesktopAgent) and [App Directory](../app-directory/overview) both require a context to be specified wherever intents are used, using an intent without a context is achieved through the use of the explicit `null` context type [`fdc3.nothing`](../context/ref/Nothing). By using an explicit type to represent an absence of context we allow applications to declare their support for an absence of context. + +```javascript +const intentsAndApps = await fdc3.findIntentsByContext({ + type: "fdc3.nothing", +}); + +const result = await fdc3.raiseIntent("StartChat", { + type: "fdc3.nothing" +}); +``` diff --git a/website/versioned_docs/version-2.1/references.md b/website/versioned_docs/version-2.1/references.md new file mode 100644 index 000000000..379c5342d --- /dev/null +++ b/website/versioned_docs/version-2.1/references.md @@ -0,0 +1,35 @@ +--- +id: references +title: References & Bibliography +sidebar_label: References +--- + + +The following normative documents contain provisions, which, through reference in this text, constitute provisions of this Standard. For dated references, subsequent amendments to, or revisions of, any of these publications do not apply. However, parties to agreements based on this Standard are encouraged to investigate the possibility of applying the most recent editions of the normative documents indicated below. For undated references, the latest edition of the normative document referred to applies: + +- **Apache 2.0 open-source license**, . +- **Community Specification license**, +- **ISO 3166-1**, _Codes for the representation of names of countries and their subdivisions – Part 1: Country codes_, . +- **ISO 8601-1:2019**, _Date and time — Representations for information interchange — Part 1: Basic rules_, +- **JSON Schema**, . +- **OpenAPI Standard v3.0**, . +- **quicktype**, . +- **RFC 2119**, _Keywords for use in RFCs to Indicate Requirement Levels, March 1997_, . +- **RFC 2782**, _A DNS RR for specifying the location of services (DNS SRV), February 2000_, . +- **RFC 4122**, _A Universally Unique IDentifier (UUID) URN Namespace, July 2005_, . +- **RFC 5646**, _Tags for Identifying Languages, September 2009_, . +- **TypeScript Programming Language**, . +- **Web Application Manifest**, _W3C Working Draft_, February 2022 + +The following documents may be useful in understanding certain aspects of this Standard; however, knowledge of them is not essential to the creation of a compliant implementation of this Standard: + +- **CUSIP**, _Committee on Uniform Security Identification Procedures_, . +- **FIGI**, _Financial Instrument Global Identifier_, . +- **ISIN**, _International Securities Identification Number_, +- **LEI**, _Legal Entity Identifier based on the ISO 17442 standard_, . +- **npm**, . +- **PermID**, _Permanent Identifiers_, . +- **pnpm**, . +- **REST**, , . +- **SEDOL**, _Stock Exchange Daily Official List_, . +- **yarn**, . diff --git a/website/versioned_docs/version-2.1/supported-platforms.md b/website/versioned_docs/version-2.1/supported-platforms.md new file mode 100644 index 000000000..eb12eda4f --- /dev/null +++ b/website/versioned_docs/version-2.1/supported-platforms.md @@ -0,0 +1,110 @@ +--- +id: supported-platforms +title: Supported Platforms +--- + +FDC3 is platform- and programming language-independent. An FDC3-capable platform requires a Desktop Agent that supports the FDC3 standard, and that agent is responsible for coordinating application interactions. + +There are two main categories of platform: web and native, both of which are described below. There exists a third category, hybrid, where a web application runs within the context of a standalone native application via a web view. + +## Web + +For a web application to be FDC3-enabled, it needs to run in the context of an environment or **_Platform Provider_** that makes the FDC3 API available to the application. This environment could be a browser extension, a web or native app, or a fully-fledged desktop container framework. + +### Usage + +There are two main ways FDC3 can be used from web applications: + +#### 1. Direct Usage + +Simply rely on the global object being made available by your desktop agent, and address the API directly: + +```javascript +function sendData() { + window.fdc3.broadcast({ + type: 'fdc3.instrument', + id: { ticker: 'AAPL' } + }) +} + +if (window.fdc3) { + sendData(); +} else { + window.addEventListener("fdc3Ready", sendData); +} +``` + +#### 2. NPM Wrapper + +FDC3 offers the [`@finos/fdc3` npm package](https://www.npmjs.com/package/@finos/fdc3) that can by used by web applications to target operations from the [API Specification](api/spec) in a consistent way. Each FDC3-compliant desktop agent that the application runs in, can then provide an implementation of the FDC3 API operations. + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +```bash +npm install @finos/fdc3 +``` + + + + +```bash +yarn add @finos/fdc3 +``` + + + + +```bash +pnpm install @finos/fdc3 +``` + + + + +The npm package provides a wrapper around FDC3, allowing you to use it with ES6 import syntax: + +```javascript +import * as fdc3 from '@finos/fdc3'; + +await fdc3.raiseIntent('ViewAnalysis', { + type: 'fdc3.instrument', + id: { ticker: 'AAPL' } +}); +``` + +It also includes a helper function you can use to wait for FDC3 to become available: + +```javascript +import { fdc3Ready, addIntentListener } from '@finos/fdc3' + +await fdc3Ready(); + +const listener = await addIntentListener('ViewAnalysis', instrument => { + // handle intent +}); +``` + +**See also:** + +- [`fdc3Ready() Function`](api/ref/Globals#fdc3ready-function) + +## Native + +The FDC3 Standard does not currently define wire formats for an app to communicate with a Desktop Agent, nor does it define language specific API bindings, other than JavaScript and TypeScript. Hence, for a native application to be FDC3-enabled, it needs to either: + +- Make use of a shared library (such as a .NET DLL or JAR file) that provides it with an implementation of the FDC3 API (which ties it to a specific desktop agent implementation). +- Model itself as a Desktop Agent (rather than just an app working with one) and use the Agent Bridging protocol to connect to a Desktop Agent Bridge and work through it to interoperate with apps managed by other Desktop Agents. + +## Hybrid + +In a hybrid application, a standalone native application incorporates a web view, within which a web application runs. This may be considered a special case of the web platform where all platform-provider requirements for web applications must be satisfied, but it is the responsibility of the associated native application, rather than a platform provider, to ensure they are fulfilled. This may be achieved, for example, by injecting an implementation of the DesktopAgent API and ensuring that it is accessible at the usual location, `window.fdc3`. + +## Compliance + +Support for each platform is optional and compliance with the FDC3 standard should be assessed for each platform implemented independently of any other, with the exception of ensuring that where applications running on multiple platforms are used together, communication between them still complies with the standard. + +The Web API binding is expressed using TypeScript syntax that defines the API interface (for both TypeScript and JavaScript). Adherence to the specific binding is required for Web application platforms. No specific API binding for native platforms is currently expressed in the Standard. Hence, native applications may be implemented with any programming language binding that supports the constructs required by the API specification, until such time that the FDC3 Standard introduces an appropriate language-specific binding. diff --git a/website/versioned_docs/version-2.1/trademarks.md b/website/versioned_docs/version-2.1/trademarks.md new file mode 100644 index 000000000..584d26e61 --- /dev/null +++ b/website/versioned_docs/version-2.1/trademarks.md @@ -0,0 +1,23 @@ +--- +id: trademarks +title: Trademarks +--- + +The trademarks, logos, and service marks not owned on behalf of FDC3 and FINOS and that are displayed on the Site are the registered and unregistered marks of their respective owners. No rights are granted by the FDC3 or FINOS to use such marks, whether by implication, estoppel, or otherwise. + +Trademarks used within this site and the FDC3 Standard include, but are not limited to: + +- Autobahn is a registered trademark of DEUTSCHE BANK AG, LONDON +- Chromium is a trademark of Google LLC +- Eikon is a registered trademark of Refinitiv +- FDC3 is a registered trademark and brand of The Linux Foundation +- Excel is a Microsoft Corporation product name +- Finsemble is a registered trademark and product name of Finsemble, Inc. +- Glue42 is a trademark of Tick42 +- Java is a registered trademark of Oracle America, Inc. +- JavaScript is a registered trademark of Oracle America, Inc. +- .NET is a trademark of Microsoft Corporation +- npm is a trademark of npm, Inc. +- OpenFin is a registered trademark of OpenFin Inc. +- Outlook is a registered trademark of Microsoft Corporation +- Python is a registered trademark of the Python Software Foundation diff --git a/website/versioned_docs/version-2.1/use-cases/001-equity-sell-side-trader.md b/website/versioned_docs/version-2.1/use-cases/001-equity-sell-side-trader.md new file mode 100644 index 000000000..f967ce96a --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/001-equity-sell-side-trader.md @@ -0,0 +1,36 @@ +--- +id: uc-1 +title: "Use Case 1: Equity sell side trader" +sidebar_label: 1. Equity sell side trader +layout: use_case +--- + +## Preconditions +On their desktop, this user has: +- Their firm's internal research & analytics platform containing liquidity tools and internal research. The product is running and the liquidity tool is open +- An installed chat application - product is running +- A third party market data terminal with 3 open applications. These applications are all 'linked' through a channel. + - A Watchlist + - An Order Book + - An Overview of pricing and fundamental data +- A third party Charting Application access via a browser window. This is not open. + +## Workflow 1 +The user receives a message in the chat application containing an instrument identifier for Tesla. They want to do some analysis on Tesla and so see what applications are available through right clicking on the identifier for Tesla. A menu will appear within the chat application showing applications that can be launched from the Messenger tool. The menu shows two apps, both for analysis; one in the internal platform, the other in the market data terminal. + +## Workflow 2 +The user wants to see his firm's internal research on Tesla and so decides to open the analysis app from his internal platform. The application is launched showing all internal research available for Tesla. + +## Workflow 3 +The user wants to do further analysis on Tesla and so they open (themselves) a new app in the market data terminal that has Tesla's financial statement and other calculated financial data (such as market capitalization, P/E ratio, growth rate, earnings margins, etc). The user sees the third party charting app listed in a menu in the market data terminal and decides to do some technical analysis using that app. They select the chart app, which opens in a browser window. + +## Workflow 4 +Having done technical analysis in the Chart app, the user wants to do the same analysis on BMW, and also use the open pricing and fundamental app. The user creates a link between the financial statement app, the pricing data app (both in the market data terminal) and the charting app. The user changes the instrument in the financial statement app and the other applications update to show information on BMW. + +## Workflow 5 +The user adds BMW and Tesla to a shared group of companies (aka a Watchlist) named "Automotive comparables" to a list within the open Watchlist. All linked applications update with the new companies. + +## Interoperability Points +- API +- Intents +- Context diff --git a/website/versioned_docs/version-2.1/use-cases/002-buy-side-portfolio-manager.md b/website/versioned_docs/version-2.1/use-cases/002-buy-side-portfolio-manager.md new file mode 100644 index 000000000..33e38db7f --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/002-buy-side-portfolio-manager.md @@ -0,0 +1,43 @@ +--- +id: uc-2 +title: "Use Case 2: Buy side Portfolio Manager" +sidebar_label: 2. Buy side Portfolio Manager +layout: use_case +--- + +## Preconditions +On their desktop, this user has: +- An installed full-service market data terminal with news, quotes, research management, etc. The application is open and FDC3 compatible. +- A third-party portfolio management system. The application is closed and not FDC3 compatible. +- An installed application for the chat tool used by the firm. The application is open and FDC3 compatible. It also has a proprietary integration to the portfolio management system. +- The default web browser for the OS. +- The default mail application for the OS. + +On their mobile device, this user has: +- The default mail application for the device. +- The default web browser for the device. +- The installed application from the market data provider. +- The installed application for the chat tool used at the firm. + +## Workflow 1 (non-desktop) +While using the mobile device (out of office), the user receives an email alert from his market data provider that a new research report has been posted which mentions a company that user is interested in. The user wants to read the report and clicks on the link in the email report. The market data application is launched and shows the research report. + +## Workflow 2 +Back in the office, the user wants to follow up on the report so he goes to his email client, finds the email and clicks the link. The market data application on the desktop displays the research report. + +## Workflow 3 +While reading the report the user wants to look up what the firm’s internal analysts have written about the company. The user hovers over the company identifier in the report and launches a tool within the terminal that shows the firm's internal research. A note from one analyst is intriguing so the user wants to know more. The user hovers over the name and launches the chat tool with a conversation with the analyst in focus and some details regarding the note is already posted to the chat. + +## Workflow 4 +During the chat, the analyst sends a link to a web site containing some further details regarding the company and the reason for the note posted. The user clicks on the link and the web browser opens. The user reads the article and continues to chat with the analyst. + +## Workflow 5 +During the chat, the analyst shares a chart with some important observations highlighted. The user clicks on the chart image in the chat and the terminal opens a live version of the chart with the observations highlighted. + +## Workflow 6 +During the chat, the user realizes that some changes should be done to their holdings in the company so hovers over the company identifier and launches the portfolio management system. While looking over the holdings the user also wants to contact the firm’s trader who is listed within the system. The user hovers over the name and launches the chat tool with a conversation with the trader in focus. +## Interoperability Points +- API +- Intents +- Context +- Financial Objects Program diff --git a/website/versioned_docs/version-2.1/use-cases/003-inhouse-cross-platform-launcher.md b/website/versioned_docs/version-2.1/use-cases/003-inhouse-cross-platform-launcher.md new file mode 100644 index 000000000..cc723cd61 --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/003-inhouse-cross-platform-launcher.md @@ -0,0 +1,52 @@ +--- +id: uc-3 +title: "Use Case 3: Inhouse Cross Platform Launcher" +sidebar_label: 3. Inhouse Cross Platform Launcher +layout: use_case +--- + +## Preconditions +The user wants a single launch pad / toolbar to access my applications and which can also provide the primary UI access point for notifications and alerts. +On the desktop this user will typically have: +- In house, container hosted, applications. +- 3rd party container hosted applications. +- In house applications written in .Net which are installed onto the user' desktops using inhouse installers. +- Applications from a 3rd parties including e-mail applications and Desktop terminal applications + + +## Workflow 1 +The launcher is started by the user, or automatically run after login, in order to provide access to Applications. + +The launcher may prompts the user to logon using the Enterprise's SSO system, which may be different to the Desktop login. + +The launcher has a list of Application Directory URLs it is configured to connect to, and passes the logged on user name and SSO identity/cookie of the logged in user to each App Directory as part of its sign on. +NB It is possible that some of the systems used may ignore the SSO login and may prompt for their own login identity, however by having a first login in the launcher and sharing those details the user may avoid multiple logins to the same Identity system. + + +The In-House app directory holding details of the in-house applications uses this identity and internal entitlement information to define what applications this user is permissioned to run. This is reflected in the list of applications the App Directory presents to the user. + +## Workflow 2 +When the Launcher runs an in-house application, the Launcher should provide details of the logged on user including the SSO identity/cookie to the apps as they are launched to avoid forcing the user to repeatedly sign on. + +NB The use case is not saying that SSO is part of the FDC3 interfaces but that mechanisms should be defined to allow any SSO information to be passed to App Directories and App Launchers who are free to use this information if appropriate. + +## Workflow 3 +The launcher starts a container based application using the container selected by the Enterprise. The selection of the container has been built into the Launcher design. + +## Workflow 4 +The Launcher starts a desktop exe. The exe has been defined by the one of the App Directories and includes the path to the installed application. + +There is no attempt to install desktop applications for which the user is permissioned but which have not been installed, instead the launcher may show a 'failed to start' error message of some kind. + +## Workflow 5 +The Launcher runs an application from a 3rd party vendor such as a Desktop terminal application. +NB These 'Desktop terminal applications' typically support tens or even hundreds of different window types which are referred to here as FDC3 Applications even when they are hosted in a single Desktop Application. + +## Workflow 6 +One or more FDC3 Platforms offer save and restore layout functions. The Layout save and restore functionality is available from the The Launcher. The Enterprise may also make 'standard' pre-built layouts available to users. The layouts made available depend on the user's role. + +## Workflow 7 +As a User with a sales focus, many of the applications I run are related to a client (aka a customer or prospect of my organisation) and I want to launch applications with a customer pre-selected, rather than being forced to select the customer (aka Client) in the application. Therefore the Launcher provides a Client search capability that allows selection of a customer or prospect from an in-house client databases and/or CRM system. + +## Workflow 8 +As a User with a trading focus, I have a similar requirement to Workflow 7, but instead I want to Select an Instrument. diff --git a/website/versioned_docs/version-2.1/use-cases/004-client-side-fx-trader.md b/website/versioned_docs/version-2.1/use-cases/004-client-side-fx-trader.md new file mode 100644 index 000000000..e96ecda70 --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/004-client-side-fx-trader.md @@ -0,0 +1,26 @@ +--- +id: uc-4 +title: "Use Case 4: Client-side FX Trader Credit Check" +sidebar_label: 4. Client-side FX Trader Credit Check +layout: use_case +--- + +## Preconditions + +- Running a client in-house proprietary application capable of conducting a user credit check +- Running third-party trading app (e.g. Autobahn FX) + +## Workflow 1 + +1. The FX Trader clicks button to book a trade in the third-party trading app (e.g. Autobahn FX) +1. The trading app executes an interop action to the client in-house proprietary credit check application to check the trader's credit limit. If this check indicates the limit has been reached, the trading app presents a rejection dialog as a standard error dialog box with an informational message which may be a standard message (e.g. "Credit Limit Reached") or may include an interop link/action (provided by the credit check application) to resolve the limit breach. + +![Use Case 4 Workflow](/assets/uc4.png) + +## Required Features + +- Point-to-point RPC invocation. Current FDC3 API proposal doesn't define response message for "open" and "send" methods as they both returns `Promise`: + +https://github.com/finos/FDC3/blob/master/src/api/interface.ts#L66 + +https://github.com/finos/FDC3/blob/master/src/api/interface.ts#L34 diff --git a/website/versioned_docs/version-2.1/use-cases/005-buy-side-treasurer.md b/website/versioned_docs/version-2.1/use-cases/005-buy-side-treasurer.md new file mode 100644 index 000000000..a89873911 --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/005-buy-side-treasurer.md @@ -0,0 +1,35 @@ +--- +id: uc-5 +title: "Use Case 5: Buy side Treasurer - client rates across providers" +sidebar_label: 5. Buy side Treasurer - client rates across providers +layout: use_case +--- + +## Preconditions + +- Several trading applications from different providers - all running +- UI which aggregates rates from different providers by entered parameters and allows to quickly execute trade with the most appropriate one + +## Workflow 1 + +1. A Corporate Treasurer enters or chooses the required trade parameters in an aggregator app which then sends requests to different providers to subscribe to rates updates +1. The aggregator app shows screen with all the rates received from the running provider apps and updates them in real-time as soon as provider sends new rate. + +![Use Case 5 Workflow](/assets/uc5.png) + + +## Workflow 2 + +1. The Treasurer chooses one option to execute from the list of rates shown in the aggregator app +1. The chosen provider app shows booking UI with pre-populated trade parameters + +## Workflow 3 + +1. The Treasurer closes the screen with aggregated rates +1. All the providers receive notification that listener has unsubscribed and they can stop providing updates + +## Required Features + +- Discovery +- Ability to get invocation response as stream. Current FDC3 API proposal doesn't define API to get stream of responses + diff --git a/website/versioned_docs/version-2.1/use-cases/009-call-transcription-to-crm.md b/website/versioned_docs/version-2.1/use-cases/009-call-transcription-to-crm.md new file mode 100644 index 000000000..e0a4e5ca0 --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/009-call-transcription-to-crm.md @@ -0,0 +1,48 @@ +--- +id: uc-9 +title: "Use Case 9: Call Transcription to CRM" +sidebar_label: 9. Call Transcription to CRM +layout: use_case +--- + +## Overview + +Voice calls contain important financial information which is trapped in the audio. These data are not easily searchable; human notetakers are prone to error; and post hoc call notes may miss crucial elements. + +Real-time transcribed audio data, saved to a CRM or other record keeping system, increases data accuracy and saves users valuable time. + +## Persona(s) + +Anyone who uses the phone to conduct business and needs to record contents. Examples include: + +1. an analyst calling into an earnings call +1. salesperson on a call with a customer +1. a meeting attendee capturing their notes + +## Workflows + +This transcription workflow consists of multiple workflows for gathering an audio stream. Each of these Alternate Inputs below could use traditional telephony, or a software client. The output of the finished transcription is sent to a CRM. + +### During live call + +1. During a live call, which might be a group call with multiple users, one user conferences in transcription service. +1. Parties converse as normal, while transcription service turns audio to text. +1. At conclusion of call, transcription service sends completed transcript and metadata to CRM + +### Post-call dictation + +1. After an event is concluded, the user initiates a dictation client (possibly a softphone) +1. User speaks their notes into a microphone. +1. Transcription service transcribes audio into text. +1. Transcription service sends completed transcript and metadata to CRM. + +## Interoperability Points + +Each of these 2 handoffs: client → transcription service → CRM , represent interoperability points for FDC3. All 3 may be from separate providers. + +The transcription service → CRM handoff may have an intermediary step where the user selects the 2nd party in their CRM as target for saving (this may potentially be automated with sufficiently rich metadata), or even which CRM or destination to save the data. + +## FDC3 Working groups affected + +- Intents Working Group +- Contexts Working Group diff --git a/website/versioned_docs/version-2.1/use-cases/010-realtime-trade-ticket-population.md b/website/versioned_docs/version-2.1/use-cases/010-realtime-trade-ticket-population.md new file mode 100644 index 000000000..6daa7a77f --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/010-realtime-trade-ticket-population.md @@ -0,0 +1,25 @@ +--- +id: uc-10 +title: "Use Case 10: Real-Time voice trades -> trade ticket population" +sidebar_label: "10. Real-Time voice trades -> trade ticket population" +layout: use_case +--- + +## Persona +- Salesperson / Trader / Broker negotiating a trade via voice (over the phone). + +## Workflow +1. User is on a call with a customer. +1. User conferences in Quote / Trade service. +1. DURING the call, user dictates trade/quote prefaced by key phrase (e.g. “Confirm…”) to distinguish final quote from negotiation. +1. Real-time quote/trade transcription service turns audio into structured data breakdown of trade. +1. Structured quote/trade data delivered to quote trade capture platform, displayed to user. +1. User may edit details, or correct errors. +1. User submits ticket to quote capture service. + +## Interoperability Points +The service which turns voice into structured text and metadata will need to send this data to a separate trade ticket service via FDC3 intents/contexts. + +## FDC3 Working groups affected +- Intents Working Group +- Contexts Working Group diff --git a/website/versioned_docs/version-2.1/use-cases/013-user-launches-multiple-apps-from-a-single-container.md b/website/versioned_docs/version-2.1/use-cases/013-user-launches-multiple-apps-from-a-single-container.md new file mode 100644 index 000000000..eb7f3f07c --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/013-user-launches-multiple-apps-from-a-single-container.md @@ -0,0 +1,33 @@ +--- +id: uc-13 +title: "Use Case 13: User launches multiple apps from a single container" +sidebar_label: 13. User launches multiple apps from a single container +layout: use_case +--- + +## Preconditions +On the desktop the user is running: +- Third party research & analytics platform +- Portfolio Management System + +## Workflow 1 +From a button next to a holding in the portfolio management system a user launches four applications from the research and analytics platform into the open workspace +The applications open within a single container and all show information on the holding + +## Workflow 2 +From a button next to a holding in the portfolio management system a user launches four applications from the research and analytics platform into the open workspace +The applications open within a single container and all show information on the holding +Selecting a different holding in the portfolio management system updates the launched layout automatically (it is linked when it is launched) + +## Workflow 3 +The user wants to open 4 apps from the research and analytics platform to find more information on a particular holding +A menu shows all the available apps that accept the holding in context that can be launched into the workspace +The user selects four and has the option to open as floating apps or within a single container +The user decides to launch them in a single container +An Eikon layout opens with the four apps that the user has selected showing information on the current holding + + +## Interoperability Points +- API +- Context data +- App Directory diff --git a/website/versioned_docs/version-2.1/use-cases/015-sales-floor-base-workflow.md b/website/versioned_docs/version-2.1/use-cases/015-sales-floor-base-workflow.md new file mode 100644 index 000000000..35ff2f1a9 --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/015-sales-floor-base-workflow.md @@ -0,0 +1,34 @@ +--- +id: uc-15 +title: "Use Case 15: Sales Floor Base Workflow" +sidebar_label: 15. Sales Floor Base Workflow +layout: use_case +--- + +## Overview +This use case focus on workflow efficiency and heavy reliant on better tools integration with central focus on a CRM. A CRM application with good analytics is central part in any sales business, enabling its integration with the traditional financial applications is key to make users life as easy as possible. + +## Workflow 1 +1. A phone contact happens, the user is in the office using a physical line (e.g. Turret); +1. The CRM automatically is setup in the page relevant to the customer (lets consider that the CRM is FDC3 compliant); +1. Relevant Analytical tools are automatically set based on the customer profile (this can include any type of analytics - products, customer history, etc.); +1. Relevant dealing tools, credit check tools, pricing tools are automatically set based on the customer profile; +1. A deal is agreed and the user uses the relevant tools to register the deal; +1. When the call ends a CRM call report popup form is shown prefilled with a NLP prepossessed call summary, call statistics (when, how much time, phone number, etc..) and deals registered; +>* While aware of the technical challenges for NLP in this scenario, that shouldn't make a huge difference for the FDC3 api layer if other path is chosen for this step. +1. The user edits if required and saves the call report. + +## Workflow 2 +1. A chat contact happens; +1. The CRM automatically is setup in the page relevant to the customer (lets consider that the CRM is FDC3 compliant); +1. Relevant Analytical tools are automatically set based on the customer profile (this can include any type of analytics - products, customer history, etc.); +1. While on the chat it triggers a request for analytics on a specific item delivered by another FDC3 compliant app (e.g. Bond, FX... ); +1. Relevant dealing tools, credit check tools, pricing tools are automatically set based on the customer profile; +1. A deal is agreed and the user uses the relevant tools to register the deal; +1. When the call ends, the user can trigger from the chat a CRM call report, a popup is shown prefilled with a NLP prepossessed chat summary and deals registered; +1. The user edits if required and saves the call report. + +## Interoperability Points +- API +- Context data +- App Directory diff --git a/website/versioned_docs/version-2.1/use-cases/016-quantifying-fdc3-interactions.md b/website/versioned_docs/version-2.1/use-cases/016-quantifying-fdc3-interactions.md new file mode 100644 index 000000000..0bcf46078 --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/016-quantifying-fdc3-interactions.md @@ -0,0 +1,50 @@ +--- +id: uc-16 +title: "Use Case 16: Quantifying FDC3 Interactions" +sidebar_label: 16. Quantifying FDC3 Interactions +layout: use_case +--- + +## Persona +A technologist enabling users to participate in FDC3 workflows, via a desktop, web, or mobile launcher. This persona could be business or technology focused. + +## User Goal +I would like to quantify the FDC3 interactions applications participate in, so that I can understand cross-application workflows and attribute these interactions to business outcomes. + +## Preconditions +The end-user's app ecosystem is typically comprised of: +- an app launcher +- multiple FDC3 compliant in-house applications, owned by different application development teams +- multiple FDC3-compliant vendor applications + +## Workflow 1 +For a given application, I can review all FDC3 events it has triggered and resolved, with their associated contexts. For example, intents fired, resolved, and contexts put on channels. + +## Workflow 2 +Subject to permissions, I can review the source applications for all FDC3 events my application is resolving, and I can review the resolving applications for all FDC3 events my application is triggering. This lets me attribute incoming and outgoing "traffic" to and from my application. + +## Workflow 3 +I can correlate FDC3 interactions across multiple applications, in order to understand how apps participate in a user workflow that led to an outcome. This includes all interactions from in-house and vendor apps. + +## Interoperability Points +- App Directory +- API + +NOTES +- Importance of uniquely identifying applications, across in-house and vendor apps, at scale (what do we think is the expected # of unique apps and interactions we will want to track?). +- Possibility of a hierarchy of apps where an intent can cascade to apps that are part of a group: + - Do we foresee this distinction being necessary? If so, would it suffice to know the app resolved the intent, and then 'lose' any cascading? Or would you expect the 'cascading' to itself be an intent with resolution? + - Ideally, we would be able to structure the reporting in such a way that consumers of the data could easily select the right level of granularity - ie grouping at different levels of hierarchy (ex: using namespacing?) +- In workflow 3 (but also consequently in 1, 2), we would we want to correlate interactions between applications or instances of applications? If we have more than one chart app open, for example, and context is passed to both or only one of them, would it be required to differentiate between the two cases? + - Same as above - ideally, we would be able to structure the reporting in such a way the consumer of the data could easily process select the right level of granularity + +## Adoption into the FDC3 Standard + +| Workflow # | Status Against 1.0 Standard | App Directory | Context & Intents | API | +| :---------: | ----- | ----- | ---------| --------- | +| 1 | New | - | - | - | +| 2 | New | - | - | - | +| 3 | New | - | - | - | + +## Adoption Metrics & Case Studies +*To be added: quantitative adoption metrics and qualitative measures of impact (case studies)* diff --git a/website/versioned_docs/version-2.1/use-cases/017-fine-tuning-interop-with-channels.md b/website/versioned_docs/version-2.1/use-cases/017-fine-tuning-interop-with-channels.md new file mode 100644 index 000000000..11df76f5f --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/017-fine-tuning-interop-with-channels.md @@ -0,0 +1,33 @@ +--- +id: uc-17 +title: "Use Case 17: Fine-tuning InterOp with Channels" +sidebar_label: 17. Fine-tuning InterOp with Channels +layout: use_case +--- + +## Persona +A user in a multi-monitor desktop environment with a fairly hectic, time-sensitive and unpredictable working day based on market movement and interactions with clients and colleagues. + +## User Goal +I want to be able to create "siloed" workflows on my desktop so that I can quickly switch context to serve a client or execute a trade while still keep an eye on the general market. + +## Preconditions +The end-user's app desktop environment consists of: +- an FDC3 compliant in-house application +- several FDC3-compliant vendor applications + +## Workflow 1 +The user's organisation maintains a coverage list in the in-house application. When selecting a company in there, the user wants a chart and a news component to update in vendor application 1, an options montage to update in vendor application 2. + +## Workflow 2 +In vendor application 1, the user maintains a personal watchlist. When selecting a company in there, the user wants a research portal in vendor application 3 to update as well as a trading screen in vendor application 4. + +## Workflow 3 +In vendor application 2, the user have a tool for ad-hoc company look ups. When selecting a company there, the user wants a chart and a news component in vendor application 1 to update (not the ones from WF 1), a detailed company report in vendor application 2 and a separate trading screen in vendor application 4 (not the one in WF2). + +![Use Case 17 Workflow](/assets/uc17.png) + +## Interoperability Points +- API +- Context +- Financial Objects Program diff --git a/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-01-16 uc-wg meeting notes.md b/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-01-16 uc-wg meeting notes.md new file mode 100644 index 000000000..64c21c2df --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-01-16 uc-wg meeting notes.md @@ -0,0 +1,55 @@ +--- + +--- +**Date**: 16 January 2020 + +**Attendees** + +| Name | Organization | GitHub ID | +| ------------- | ------------- | ------------- | +| Jonathan Teper | JP Morgan | jonathanteperJPMC | +| Johan Sandersson | Factset | donbasuno | + + +## Agenda +### 1. 2020 Move to GitHub - JT (15 min) +- Goal: manage all new UCWG content in GitHub in 2020 + +**Proposal:** how to manage the UCWG content +- Meeting Minutes + - legacy [keep them on confluence and link to them] AGREED - link to be added + - new [in github, [this folder](https://github.com/jonathanteperJPMC/FDC3/tree/master/docs/use-cases/meeting-minutes), we also could create a GitHub Issue template] AGREED - link to be updated +- Governance Docs [to be refreshed and moved to the [use cases intro](https://github.com/jonathanteperJPMC/FDC3/blob/master/docs/use-cases-intro.md) page] - AGREED to move to intro doc, but need to be reviewed and cleaned up. + - Ratifying use cases via GitHub PRs - voting done via GitHub (👍 / 👎 on an issue - see [UC 17](https://github.com/finos/FDC3/pull/153)) rather than Google Groups - AGREED +- Use Cases + - 1. In Review [will be managed via submitted pull requests - see [this](https://github.com/finos/FDC3/pulls?q=is%3Aopen+is%3Apr+label%3Ause-cases)] + - 2. Accepted [DONE - listed [here](https://github.com/jonathanteperJPMC/FDC3/tree/master/docs/use-cases)] + - 3. Rejected + - 4. Deleted + - 5. Backlog + - Use Case XX: Template [we can create this as a github issue type] - JT to try and prove this works +- Action Items + - to be reviewed and closed out. Relevant ones will be migrated. +- Process: + - One of the participants edits meeting minutes live on a screenshare during the call. All participants on the call review and approve the minutes at the end of the call. Once approved verbally on the call, the meeting minutes PR can be merged. + +### 2. UC 17 Vote - Johan (5 min) +- Voting directly on the PR: https://github.com/finos/FDC3/pull/153 +- APPROVED AND MERGED! + +### 3. UCWG Goals and Roadmap - JT (15 min) +- see proposal [here](https://github.com/jonathanteperJPMC/FDC3/blob/master/docs/fdc3-okrs.md#use-case-working-group) +- UCWG to review offline and comment + +### 4. AOB +- lean UCWG + new recruits +- clean up open action items in confluence + +## Decisions Made +- (see inline) + +## Action Items +- [ ] review and clean up governance docs +- [ ] action items on confluence to be closed or migrated to github +- [ ] goals and roadmaps to be reviewed offline +- [ ] JT to try creating a use case issue template diff --git a/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-02-20 uc-wg meeting notes.md b/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-02-20 uc-wg meeting notes.md new file mode 100644 index 000000000..e56d8c1ed --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-02-20 uc-wg meeting notes.md @@ -0,0 +1,30 @@ +--- + +--- + +**Date**: 16 January 2020 + +**Attendees** + +| Name | Organization | GitHub ID | +| ------------- | ------------- | ------------- | +| Jonathan Teper | JP Morgan | jonathanteperJPMC | +| Johan Sandersson | Factset | donbasuno | +| Leslie Spiro | Tick42 | | + + +## Agenda +### 1. + + +### 4. AOB +- + +## Decisions Made +- (see inline) + +## Action Items +- [ ] review and clean up governance docs +- [ ] action items on confluence to be closed or migrated to github +- [ ] goals and roadmaps to be reviewed offline +- [ ] JT to try creating a use case issue template diff --git a/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-03-19 uc-wg meeting notes.md b/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-03-19 uc-wg meeting notes.md new file mode 100644 index 000000000..3147322df --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/meeting-minutes/2020-03-19 uc-wg meeting notes.md @@ -0,0 +1,24 @@ +--- + +--- +**Meeting not held due to low attendance** + +**Date**: 19 March 2020 + +**Attendees** + +| Name | Organization | GitHub ID | +| ------------- | ------------- | ------------- | + +## Agenda +### 1. + + +### 4. AOB +- + +## Decisions Made +- (see inline) + +## Action Items + diff --git a/website/versioned_docs/version-2.1/use-cases/overview.md b/website/versioned_docs/version-2.1/use-cases/overview.md new file mode 100644 index 000000000..187162dc3 --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/overview.md @@ -0,0 +1,27 @@ +--- +id: overview +title: Use Cases Overview +hide_title: true +sidebar_label: Overview +layout: default +--- + +# Use Cases Overview + +## Goal + +Document and ratify business use cases that drive the standards created under the other FDC3 working groups: Intents Working Group, App Directory Working Group, Context Data Working Group, and API Working Group. + +## Charter + +The goal of FDC3 is to create standards for desktop application interoperability in the financial industry. For these standards to be successful we need ensure they satisfy a set of foundational use cases and requirements defined and validated by the program participants. These use cases must represent the interop needs of the 40+ members of FDC3 as a sample of the financial industry as a whole. The remaining working groups Context Data, App Directory, Intents and APIs should use the use cases as the basis for each set of standards. + +Until this point the existing working groups have focused on the functional requirements for interop standards with specifications based on assumptions of what is required. To ensure that the standards will enable the scalable interop interactions that we want, we need to validate these assumptions. This should not delay the work of the existing working groups, but happen in parallel with the requirements maintained as the program matures. + +Unlike the other working groups, 'Use Cases' should provide requirements only not solutions. The requirements and use cases defined should not be specific to a handful of products that are represented within the working group, but apply to the workflows present across the financial industry. + +![Use Cases diagram](/assets/use-cases.png) + + +## Join us +Join our mailing-lists and bi-weekly meetings on WebEx. Check the [Wiki documentation page](https://finosfoundation.atlassian.net/wiki/spaces/FDC3/pages/169738241/Use+Case+Working+Group) for details. \ No newline at end of file diff --git a/website/versioned_docs/version-2.1/use-cases/readme.md b/website/versioned_docs/version-2.1/use-cases/readme.md new file mode 100644 index 000000000..b0cc961de --- /dev/null +++ b/website/versioned_docs/version-2.1/use-cases/readme.md @@ -0,0 +1,37 @@ +--- + +--- +# Overview +Here are business use cases that have been documented and ratified by the Use Cases Working Group + +# Adoption of Use Cases into the FDC3 Standard + +**Use Cases Accepted onto Roadmap of Standards or Implemented** + +| Use Cases | Count | % | +| ------------- |:-------------:| :----: | +| 001-equity-sell-side-trader | 2 / 5 | 40% | +| 002-buy-side-portfolio-manager | 0 / 3 | 33% | +| 003-inhouse-cross-platform-launcher | 0 / 8 | 0% | +| 004-client-side-fx-trader | 0 / 1 | 0% | +| 005-buy-side-treasurer | 0 / 3 | 0% | +| 009-call-transcription-to-crm | 0 / 2 | 0% | +| 010-realtime-trade-ticket-population | 0 / 1 | 0% | +| 013-user-launches-multiple-apps-from-a-single-container | 0 / 3 | 0% | +| 015-sales-floor-base-workflow | 0 / 2 | 0% | +| 016-quantifying-fdc3-interactions | 0 / 3 | 0% | +| total | 2 / 31 | 6.5% | + + + +**Summary** + +| Status | Count | % | +| ------------- |:-------------:| :----: | +| New | 24 | 77.5% | +| Proposed | 5 | 16% | +| **Accepted onto Roadmap of Standard** | 0 | **0%** | +| **Implemented** | 2 | **6.5%** | +| Rejected | 0 | 0% | +| N/R | 3 | | +| Total (excl. N/R) | 31 | 100% | diff --git a/website/versioned_docs/version-2.1/why-fdc3.md b/website/versioned_docs/version-2.1/why-fdc3.md new file mode 100644 index 000000000..36aee7610 --- /dev/null +++ b/website/versioned_docs/version-2.1/why-fdc3.md @@ -0,0 +1,21 @@ +--- +id: why-fdc3 +sidebar_label: Why FDC3? +title: Why FDC3? +--- + +## Why look for FDC3-enabled applications? + +You want your business to move fast and use best of breed applications. Application integration has traditionally been a time consuming and costly exercise, meaning that once a set of applications supporting a workflow was established, changing parts of the workflow without very good reason was a no-go. + +The main goal of FDC3 is to standardize how applications communicate, without having defined inter-application workflows prior to being deployed. Applications that are FDC3-enabled can take part in a workflow on the desktop without any coding or manual integration, allowing you to replace one application with another application serving the same functions to the desktop (in FDC3 terms - supporting the same Intents and Context). + +## Why should I FDC3-enable my applications? + +There is a trend towards breaking up monolithic desktop applications, replacing them with adaptable workflows which involve the collaboration of multiple best-of-breed applications. Still, much of the integration on the desktop is done by the actual end-user; copy/paste between applications, exporting/importing CSV files etc.. + +Every application that has manual user input is a candidate for being FDC3-enabled, being able to demonstrate that your application can effectively take part in a workflow (without manual dual-entry or other tedious operations) is a easy route to happier users. Allowing your application to reach out to others is another way of extending the power of your offering; your app might not offer charting, but can let the end-user chart in an FDC3-enabled companion application based on context passed from your own app. + +## Why should my development team look at adopting FDC3? + +Deploying effective end-user workflows with as little development effort as possible, should be the goal for all internal/platform integration development teams. Implementing or developing on a platform that is FDC3-enabled, if done right, results in more bang for the buck. FDC3 is all about (re)usability and low-touch integration. With an [App directory](app-directory/overview) in place and a platform to develop on, each new enabled app broadens the value of the workflow offering. diff --git a/website/versioned_sidebars/version-2.1-sidebars.json b/website/versioned_sidebars/version-2.1-sidebars.json new file mode 100644 index 000000000..60904acb9 --- /dev/null +++ b/website/versioned_sidebars/version-2.1-sidebars.json @@ -0,0 +1,134 @@ +{ + "docs": { + "Getting Started": [ + "fdc3-intro", + "why-fdc3", + "fdc3-charter" + ], + "FDC3 Standard": [ + "fdc3-standard", + "fdc3-compliance", + "fdc3-glossary", + "references", + "supported-platforms", + { + "type": "category", + "label": "API Part", + "items": [ + "api/spec", + "api/ref/DesktopAgent", + "api/ref/Channel", + "api/ref/PrivateChannel", + "api/ref/Globals", + "api/ref/Types", + "api/ref/Metadata", + "api/ref/Errors" + ] + }, + { + "type": "category", + "label": "App Directory Part", + "items": [ + "app-directory/overview", + "app-directory/spec" + ] + }, + { + "type": "category", + "label": "Intents Part", + "items": [ + "intents/spec", + "intents/ref/CreateInteraction", + "intents/ref/StartCall", + "intents/ref/StartChat", + "intents/ref/StartEmail", + "intents/ref/SendChatMessage", + "intents/ref/ViewAnalysis", + "intents/ref/ViewChat", + "intents/ref/ViewChart", + "intents/ref/ViewHoldings", + "intents/ref/ViewInstrument", + "intents/ref/ViewInteractions", + "intents/ref/ViewMessages", + "intents/ref/ViewNews", + "intents/ref/ViewOrders", + "intents/ref/ViewProfile", + "intents/ref/ViewQuote", + "intents/ref/ViewResearch", + "intents/ref/ViewContact" + ] + }, + { + "type": "category", + "label": "Context Data Part", + "items": [ + "context/spec", + "context/ref/Context", + "context/ref/Action", + "context/ref/Chart", + "context/ref/ChatInitSettings", + "context/ref/ChatMessage", + "context/ref/ChatRoom", + "context/ref/ChatSearchCriteria", + "context/ref/Contact", + "context/ref/ContactList", + "context/ref/Country", + "context/ref/Currency", + "context/ref/Email", + "context/ref/Instrument", + "context/ref/InstrumentList", + "context/ref/Interaction", + "context/ref/Message", + "context/ref/Nothing", + "context/ref/Order", + "context/ref/OrderList", + "context/ref/Organization", + "context/ref/Portfolio", + "context/ref/Position", + "context/ref/Product", + "context/ref/TimeRange", + "context/ref/Trade", + "context/ref/TradeList", + "context/ref/TransactionResult", + "context/ref/Valuation" + ] + }, + { + "type": "category", + "label": "Agent Bridging Part", + "items": [ + "agent-bridging/spec", + "agent-bridging/ref/broadcast", + "agent-bridging/ref/findInstances", + "agent-bridging/ref/findIntent", + "agent-bridging/ref/findIntentsByContext", + "agent-bridging/ref/getAppMetadata", + "agent-bridging/ref/open", + "agent-bridging/ref/PrivateChannel.broadcast", + "agent-bridging/ref/PrivateChannel.eventListenerAdded", + "agent-bridging/ref/PrivateChannel.eventListenerRemoved", + "agent-bridging/ref/PrivateChannel.onAddContextListener", + "agent-bridging/ref/PrivateChannel.onDisconnect", + "agent-bridging/ref/PrivateChannel.onUnsubscribe", + "agent-bridging/ref/raiseIntent" + ] + } + ] + }, + "use-cases": { + "Use Cases": [ + "use-cases/overview", + "use-cases/uc-1", + "use-cases/uc-2", + "use-cases/uc-3", + "use-cases/uc-4", + "use-cases/uc-5", + "use-cases/uc-9", + "use-cases/uc-10", + "use-cases/uc-13", + "use-cases/uc-15", + "use-cases/uc-16", + "use-cases/uc-17" + ] + } +} diff --git a/website/versions.json b/website/versions.json index b7ba6b119..441ca11ef 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,4 +1,5 @@ [ + "2.1", "2.0", "1.2", "1.1",