Track and Trace Quick Start
Note: This quickstart uses a 4-node Uni configuration, which is not viable for Starter tier users given the node limits enforced. See full details on the Pricing page.
The management of risk within a supply chain is crucial to control cost and ensure customer commitments are met. Visibility into supply chain activities and inventory handling is paramount in identifying risks and opportunities. For example, manufacturers may wish to identify patterns in shipping activities that have previously damaged goods. When supply chain logistics extended beyond a single organization to include shippers, retails, and other parties, this visibility can only be enabled through the sharing of data. Vendia Unis provide a platform for sharing data and code with partners in real-time across geographies, cloud-accounts, and technology stacks.
In this Quick start, you will demonstrate how Vendia Unis can easily be implemented to track and trace goods in a supply chain as they move from manufacturer to shipper and ultimately to retailers.
By the end of this Quick start you will have:
- Created a Universal Application (Uni) with a pre-defined data-model
- Defined a network of business partners and on-boarded them to the Uni
- Used the automatically generated HTTPS GraphQL API to interact with the Uni
- Quickly performed an analysis of supply chain data to answer business questions
Prerequisites
This Quick start uses the Vendia share-cli
, a Command Line Interface (CLI) for creating and managing Unis. We will be using the share-cli
to deploy and manage our Uni.
Command Line Installation
The share-cli
can be installed using the nodeJS node Package Manager (NPM).
To install the CLI globally, run the following command:
npm install @vendia/share-cli -g
NOTE You can also install Vendia CLI inside a project (instead of globally).
For more information, please visit the @vendia/share-cli NPM package page or view the CLI commands list.
You will need to have a valid Vendia Share user in order to deploy this Quick start. Please sign up for Vendia Share if you have not already done so.
Step 1 - Prepare the Deployment Files for the Uni
In this Quick start, we have provided sample files including a data-model for your use that describes four collections of data:
Type | Description |
---|---|
Inventory | Inventory records provide information about products including their Name, SKU, Location, and Quantity on Hand. |
Shipment | Shipment records reflect the movement of products to and from locations in the supply chain. |
Order | Order records reflect a purchase of inventory from the manufacturer that will require a shipment for delivery to a retailer. |
Warehouse | Warehouse records detail the locations along the supply chain where partners may store goods throughout the manufacturing, shipping, and receiving activities. |
Save the Quick Start Files Below
The registration.json
, schema.json
, and initial-state.json
will be referenced by the CLI later. Please save these files locally by expanding each node and copying the contents.
Registration file - save as registration.json
The registration.json
file defines the Uni name, location of the schema, and the node configuration representing partners in the supply chain network. In this example, you will define a manufacturer, a shipper, and two retailers.
NOTES
- You will need to provide your Vendia Share
userId
when defining your nodes. For the quick start, please use your sameuserId
across all nodes. - Pick a unique
name
for your Uni that begins withtest-
- by default all Unis share a common namespace so here is your chance to get creative. - Starter tier users must (and Pro tier users may prefer to) continue with this example using only 2 of the nodes defined in the
registration.json
file below. See full details on the Pricing page.
{
"name": "test-track-and-trace",
"schema": "schema.json",
"initState": "initial-state.json",
"nodes": [{
"name": "manufacturer",
"userId": "me@domain.com",
"region": "us-east-2",
"csp": "aws"
},
{
"name": "shipper",
"userId": "me@domain.com",
"region": "us-east-2",
"csp": "aws"
},
{
"name": "retailer01",
"userId": "me@domain.com",
"region": "us-west-2",
"csp": "aws"
},
{
"name": "retailer02",
"userId": "me@domain.com",
"region": "us-west-2",
"csp": "aws"
}
]
}
Schema file - save as schema.json
The schema.json
file defines the data model for the Uni and is used to automatically generate the API that will be used later to interact with the system. This file defines the record types previously mentioned. Save it as schema.json
on your local workstation in the same directory as the registration.json
file you saved prior.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://vendia.com/schemas/demos/track-and-trace.json",
"title": "Track and Trace",
"description": "Track and trace shipments among a manufacturer, shipper, and retailer",
"type": "object",
"properties": {
"Inventory": {
"description": "Inventory information",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"description": "Product name",
"type": "string"
},
"sku": {
"description": "Product SKU",
"type": "string"
},
"warehouse": {
"description": "Manufacturer warehouse code",
"type": "string"
},
"availableInventory": {
"description": "Available inventory",
"type": "integer"
}
}
}
},
"Shipment": {
"description": "Shipment information",
"type": "array",
"items": {
"type": "object",
"properties": {
"originWarehouse": {
"description": "Shipment origin",
"type": "string"
},
"destinationWarehouse": {
"description": "Shipment destination",
"type": "string"
},
"orderId": {
"description": "Order ID",
"type": "string"
},
"created": {
"description": "When the order was placed",
"type": "string",
"format": "date-time"
},
"lastUpdated": {
"description": "When the order was last updated",
"type": "string",
"format": "date-time"
},
"location": {
"description": "Current Lat/long of the shipment",
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"uniqueItems": true
},
"delivered": {
"description": "Delivery status",
"type": "boolean"
}
}
}
},
"Order": {
"description": "Order information",
"type": "array",
"items": {
"type": "object",
"properties": {
"orderId": {
"description": "Order ID",
"type": "string"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sku": {
"description": "Product SKU in order",
"type": "string"
},
"quantity": {
"description": "Quantity of product in order",
"type": "integer"
}
}
}
},
"manufacturerWarehouseCode": {
"description": "Manufacturer warehouse that holds the inventory",
"type": "string"
},
"manufacturerWarehouseLocation": {
"description": "Lat/long of manufacturer warehouse",
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"uniqueItems": true
},
"retailerWarehouseCode": {
"description": "Retailer warehouse that placed the order",
"type": "string"
},
"retailerWarehouseLocation": {
"description": "Lat/long of retailer warehouse",
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"uniqueItems": true
},
"delivered": {
"description": "Order status",
"type": "boolean"
},
"created": {
"description": "When order was placed",
"type": "string",
"format": "date-time"
},
"updated": {
"description": "When order was last updated",
"type": "string",
"format": "date-time"
}
}
}
},
"Warehouse": {
"description": "Warehouse information",
"type": "array",
"items": {
"type": "object",
"properties": {
"companyName": {
"description": "Company name",
"type": "string"
},
"code": {
"description": "Warehouse code",
"type": "string"
},
"street1": {
"description": "Warehouse Street Address",
"type": "string"
},
"street2": {
"description": "Warehouse Warehouse Street Address Continued",
"type": "string"
},
"city": {
"description": "Warehouse City",
"type": "string"
},
"state": {
"description": "Warehouse State",
"type": "string"
},
"postalCode": {
"description": "Warehouse Postal Code",
"type": "string"
},
"country": {
"description": "Warehouse Country Code",
"type": "string"
},
"phone": {
"description": "Warehouse Phone Number",
"type": "string"
},
"fax": {
"description": "Warehouse Fax Number",
"type": "string"
},
"created": {
"description": "When the Warehouse record was created",
"type": "string",
"format": "date-time"
},
"updated": {
"description": "When Warehouse record was last updated",
"type": "string",
"format": "date-time"
}
}
}
}
}
}
Initial State file - save as initial-state.json
The initial-state.json
file allows for the population of pre-existing data when creating a Uni. In this example, the initial-state.json
file is pre-populated with Inventory, Warehouse, Order, and Shipment data.
Save this file as initial-state.json
in the same directory as the prior files.
{
"Inventory": [{
"name": "Widget 123 - 1 count",
"sku": "WMl237ABC",
"warehouse": "manufacturer",
"availableInventory": 100
},
{
"name": "Widget 123 - 5 count",
"sku": "WMl237DEF",
"warehouse": "manufacturer",
"availableInventory": 12
},
{
"name": "Widget 123 - 10 count",
"sku": "WMl237GHI",
"warehouse": "manufacturer",
"availableInventory": 83
},
{
"name": "Widget 123 - 50 count",
"sku": "WMl237JKL",
"warehouse": "manufacturer",
"availableInventory": 20
},
{
"name": "Widget 456 - 1 count",
"sku": "WMl237MNP",
"warehouse": "manufacturer",
"availableInventory": 10
},
{
"name": "Widget 456 - 5 count",
"sku": "WMl237QRS",
"warehouse": "manufacturer",
"availableInventory": 350
},
{
"name": "Widget 456 - 10 count",
"sku": "WMl237TUV",
"warehouse": "manufacturer",
"availableInventory": 1250
},
{
"name": "Widget 456 - 50 count",
"sku": "WMl237WXY",
"warehouse": "manufacturer",
"availableInventory": 49
}
],
"Warehouse": [{
"companyName": "Manufacturing Company",
"code": "manufacturer",
"street1": "3543 Queens Lane",
"city": "Keysville",
"state": "VA",
"postalCode": "23947",
"country": "US",
"phone": "4345553444",
"fax": "4345553445",
"created": "2020-12-01T14:10:02Z",
"updated": "2020-12-01T14:10:02Z"
},
{
"companyName": "Retailer Inc",
"code": "retailer01",
"street1": "558 Wilkinson Ct",
"street2": "ste 1402",
"city": "Maple Valley",
"state": "WA",
"postalCode": "98038",
"country": "US",
"phone": "4255551314",
"fax": "3605553213",
"created": "2020-12-01T14:10:02Z",
"updated": "2020-12-01T14:10:02Z"
},
{
"companyName": "Outlet Shops LLC",
"code": "retailer02",
"street1": "3449 Wolf Pen Rd",
"city": "San Francisco",
"state": "CA",
"postalCode": "94107",
"country": "US",
"phone": "6505559544",
"fax": "4155556254",
"created": "2020-12-01T14:10:02Z",
"updated": "2020-12-01T14:10:02Z"
}
],
"Order": [{
"orderId": "manufacturer-01",
"items": [{
"sku": "WMl237TUV",
"quantity": 10
}],
"manufacturerWarehouseCode": "manufacturer",
"manufacturerWarehouseLocation": [37.04827632907081, -78.48873356671945],
"retailerWarehouseCode": "retailer01",
"retailerWarehouseLocation": [47.37441523471446, -122.03460569672072],
"delivered": true,
"created": "2020-12-02T14:10:02Z",
"updated": "2020-12-02T14:10:02Z"
},
{
"orderId": "manufacturer-02",
"items": [{
"sku": "WMl237JKL",
"quantity": 6
}],
"manufacturerWarehouseCode": "manufacturer",
"manufacturerWarehouseLocation": [37.04827632907081, -78.48873356671945],
"retailerWarehouseCode": "retailer02",
"retailerWarehouseLocation": [37.72443674615711, -122.49047216194155],
"delivered": false,
"created": "2020-12-02T14:10:02Z",
"updated": "2020-12-02T14:10:02Z"
},
{
"orderId": "manufacturer-03",
"items": [{
"sku": "WMl237DEF",
"quantity": 2
},
{
"sku": "WMl237MNP",
"quantity": 4
}
],
"manufacturerWarehouseCode": "manufacturer",
"manufacturerWarehouseLocation": [37.04827632907081, -78.48873356671945],
"retailerWarehouseCode": "retailer02",
"retailerWarehouseLocation": [37.72443674615711, -122.49047216194155],
"delivered": false,
"created": "2020-12-02T14:10:02Z",
"updated": "2020-12-02T14:10:02Z"
}
],
"Shipment": [{
"originWarehouse": "manufacturer",
"destinationWarehouse": "retailer01",
"orderId": "manufacturer-01",
"created": "2020-12-02T14:10:02Z",
"lastUpdated": "2020-12-02T14:10:02Z",
"location": [47.37441523471446, -122.03460569672072],
"delivered": false
},
{
"originWarehouse": "manufacturer",
"destinationWarehouse": "retailer02",
"orderId": "manufacturer-02",
"created": "2020-12-02T14:10:02Z",
"lastUpdated": "2020-12-02T14:10:02Z",
"location": [40.20448090000001, -74.5759279],
"delivered": false
},
{
"originWarehouse": "manufacturer",
"destinationWarehouse": "retailer01",
"orderId": "manufacturer-03",
"created": "2020-12-02T14:10:02Z",
"lastUpdated": "2020-12-02T14:10:02Z",
"location": [40.19557037731903, -74.56602928070187],
"delivered": false
}
]
}
Step 2 - Command Line Deployment
Once the files are saved, deploy the Uni using the share-cli.
If not already logged in to the share service do so by running:
share login
The share uni create
command can be used to deploy our Uni.
share uni create --config registration.json
Check on Uni Status
The Uni deployment will take approximately 4 minutes. The status of the Uni deployment can be viewed by running the share get
command.
Note: Your Uni name should differ from the example. Set the value of the
--uni
argument accordingly to match thename
property in registration.json
share get --uni test-track-and-trace
Please refer to the Vendia Share CLI documentation for more detailed information.
Step 3 - Preparing to Interact with Uni Data
The easiest way to work with Uni data is via the Graphql API. You can access the GraphQL API with a web browser by visiting the GraphQL Explorer for your Uni.
Open the details page for your Uni and click on the GraphQL explorer
button for any node.
Remember, Uni data is available in real-time from any node, so you can explore the data from any node created in this quick start.
Run your first Query
The GraphQL Explorer window will be pre-populated with an example query. Delete this query and replace it with the sample below to list the pre-loaded inventory information. Run the query by pressing the play button and review the list of products.
query listInventory {
list_InventoryItems {
_InventoryItems {
_id
name
sku
availableInventory
warehouse
}
}
}
Step 4 - Track Products in the Supply Chain Network
Now that the Uni is operational and data has been loaded, the GraphQL Explorer can be used to further inspect the state of orders and shipments.
Where is My Delivery?
Imagine that Retailer Inc.
, represented by the code retailer01 in our network, has called regarding a delivery. The retailer provides the order id manufacturer-01
.
Using the following query in the GraphQL Explorer, determine the Delivery status and Location of the related shipment.
query manufacturing0102Shipment {
list_ShipmentItems(
filter: {
orderId: {eq: "manufacturer-01"}
}
) {
_ShipmentItems {
_id
orderId
delivered
originWarehouse
destinationWarehouse
location
created
lastUpdated
}
}
}
Example Output
{
"data": {
"list_ShipmentItems": {
"_ShipmentItems": [
{
"_id": "017d1206-7881-4279-995a-e4176d8f223a",
"orderId": "manufacturer-01",
"delivered": false,
"originWarehouse": "manufacturer",
"destinationWarehouse": "retailer01",
"location": [
47.3744,
-122.035
],
"created": "2020-12-02T14:10:02Z",
"lastUpdated": "2020-12-02T14:10:02Z"
}
]
}
}
}
A quick review of the results show the order was not delivered and was last reported at the location 47.3744, -122.035
.
Note the
_id
of the shipment record returned. That will be useful in the next step.
A quick review of the location on a map suggests this package may be irretrievably lost.
While the storage and retrieval of order data is useful, it may become necessary to review the history of the shipment data for deeper insights. For the purposes of this example, assume the package was retrieved from Lake Wilderness successfully and re-routed to its intended destination.
Progress the shipment by updating the shipment with new location data. Copy and paste the following mutation to update the shipment.
Important
As theid
of each record in the initial-state is generated by the Uni when we create it, you must update theid
value on line one to match the_id
of the shipment record you noted in the previous step. This value is specific to your Uni.
Note: While you can apply mutations from any node in the Uni in this quick start, each mutation will be written with metadata regarding its source. For demonstration purposes, imagine that you are acting on behalf of the Shipper and run the mutations from the Shipper node.
mutation UpdateShipment($shipmentId: ID!="YOUR ID HERE") {
update_Shipment(id: $shipmentId, input: {
created: "2020-12-02T14:10:02Z",
delivered: false,
destinationWarehouse: "retailer01",
lastUpdated: "2020-12-02T15:10:02Z",
location: [
47.61520116708219,
-122.35427961729266
],
orderId: "manufacturer-01",
originWarehouse: "manufacturer"
},
syncMode: ASYNC) {
transaction {
transactionId
}
}
}
Example Output
{
"data": {
"update_Shipment": {
"transaction": {
"transactionId": "017d7e4b-04e2-e742-5c1b-badeb90b6617"
}
}
}
}
Once the mutation is executed, a transactionId
value will be returned, which can be used to track the transaction through its full lifecycle.
Query the shipment again to verify its intended location was updated.
query manufacturing0102Shipment {
list_ShipmentItems(
filter: {
orderId: {eq: "manufacturer-01"}
}
) {
_ShipmentItems {
_id
orderId
delivered
originWarehouse
destinationWarehouse
location
created
lastUpdated
}
}
}
Hooray! The shipment was successfully delivered. Apply another mutation with new delivered
status and lastUpdated
data.
mutation UpdateShipment($shipmentId: ID!="017d7e12-5c29-165b-6051-f56a03bcb45e") {
update_Shipment (id: $shipmentId, input: {
delivered: true,
lastUpdated: "2020-12-02T16:10:02Z"
}, syncMode: ASYNC) {
transaction {
_id
}
}
}
List the shipment one final time.
query manufacturing0102Shipment {
list_ShipmentItems(
filter: {
orderId: {eq: "manufacturer-01"}
}
) {
_ShipmentItems {
_id
orderId
delivered
originWarehouse
destinationWarehouse
location
created
lastUpdated
}
}
}
The result shows the shipment made it to its final destination.
{
"data": {
"list_ShipmentItems": {
"_ShipmentItems": [
{
"_id": "017d7e12-5c29-165b-6051-f56a03bcb45e",
"orderId": "manufacturer-01",
"delivered": true,
"originWarehouse": "manufacturer",
"destinationWarehouse": "retailer01",
"location": [
47.6152,
-122.354
],
"created": "2020-12-02T14:10:02Z",
"lastUpdated": "2020-12-02T16:10:02Z"
}
]
}
}
}
Because they are backed by an immutable distributed ledger, Vendia Unis contain the history of records as they are updated. You can query the ledger history with GraphQL to review past mutations.
query ledger {
listVendia_BlockItems {
Vendia_BlockItems {
_id
commitTime
transactions {
mutations
_owner
}
}
}
}
Transaction ledger
{
"data": {
"listVendia_BlockItems": {
"Vendia_BlockItems": [
{
"_id": "000000000000001",
"commitTime": "2021-12-03T02:21:44.823553+00:00",
"transactions": [
{
"mutations": [
"addSelf_Inventory(id:\"017d7e12-4be5-3a78-d0bf-a4a31962d4d2\", input: {name: \"Widget 123 - 10 count\", sku: \"WMl237GHI\", warehouse: \"manufacturer\", availableInventory: 83}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Shipment(id:\"017d7e12-5c29-165b-6051-f56a03bcb45e\", input: {originWarehouse: \"manufacturer\", destinationWarehouse: \"retailer01\", orderId: \"manufacturer-01\", created: \"2020-12-02T14:10:02Z\", lastUpdated: \"2020-12-02T14:10:02Z\", location: [47.3744, -122.035], delivered: true}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Order(id:\"017d7e12-5964-fd6e-5fc6-de578a144367\", input: {orderId: \"manufacturer-02\", items: [{sku: \"WMl237JKL\", quantity: 6}], manufacturerWarehouseCode: \"manufacturer\", manufacturerWarehouseLocation: [37.0483, -78.4887], retailerWarehouseCode: \"retailer02\", retailerWarehouseLocation: [37.7244, -122.49], delivered: false, created: \"2020-12-02T14:10:02Z\", updated: \"2020-12-02T14:10:02Z\"}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Inventory(id:\"017d7e12-5000-b93f-6ec4-ddba5ee13109\", input: {name: \"Widget 456 - 5 count\", sku: \"WMl237QRS\", warehouse: \"manufacturer\", availableInventory: 350}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Shipment(id:\"017d7e12-5d68-52d9-60d1-f31a15762edb\", input: {originWarehouse: \"manufacturer\", destinationWarehouse: \"retailer02\", orderId: \"manufacturer-02\", created: \"2020-12-02T14:10:02Z\", lastUpdated: \"2020-12-02T14:10:02Z\", location: [40.2045, -74.5759], delivered: false}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Order(id:\"017d7e12-5aea-0375-f236-94025c3f1474\", input: {orderId: \"manufacturer-03\", items: [{sku: \"WMl237DEF\", quantity: 2}, {sku: \"WMl237MNP\", quantity: 4}], manufacturerWarehouseCode: \"manufacturer\", manufacturerWarehouseLocation: [37.0483, -78.4887], retailerWarehouseCode: \"retailer02\", retailerWarehouseLocation: [37.7244, -122.49], delivered: false, created: \"2020-12-02T14:10:02Z\", updated: \"2020-12-02T14:10:02Z\"}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Inventory(id:\"017d7e12-4e63-e57e-5ae8-32eea308d82e\", input: {name: \"Widget 456 - 1 count\", sku: \"WMl237MNP\", warehouse: \"manufacturer\", availableInventory: 10}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Order(id:\"017d7e12-5811-fc6d-c931-aad502d6f168\", input: {orderId: \"manufacturer-01\", items: [{sku: \"WMl237TUV\", quantity: 10}], manufacturerWarehouseCode: \"manufacturer\", manufacturerWarehouseLocation: [37.0483, -78.4887], retailerWarehouseCode: \"retailer01\", retailerWarehouseLocation: [47.3744, -122.035], delivered: true, created: \"2020-12-02T14:10:02Z\", updated: \"2020-12-02T14:10:02Z\"}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Warehouse(id:\"017d7e12-5696-1029-2170-433edcc9a488\", input: {companyName: \"Outlet Shops LLC\", code: \"retailer02\", street1: \"3449 Wolf Pen Rd\", city: \"San Francisco\", state: \"CA\", postalCode: \"94107\", country: \"US\", phone: \"6505559544\", fax: \"4155556254\", created: \"2020-12-01T14:10:02Z\", updated: \"2020-12-01T14:10:02Z\"}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Inventory(id:\"017d7e12-4a64-56c4-ff78-94ada52294d7\", input: {name: \"Widget 123 - 5 count\", sku: \"WMl237DEF\", warehouse: \"manufacturer\", availableInventory: 12}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Inventory(id:\"017d7e12-513f-0fcc-7539-e9e948c233a5\", input: {name: \"Widget 456 - 10 count\", sku: \"WMl237TUV\", warehouse: \"manufacturer\", availableInventory: 1250}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Shipment(id:\"017d7e12-5efd-8ca7-46af-6cee30f92989\", input: {originWarehouse: \"manufacturer\", destinationWarehouse: \"retailer01\", orderId: \"manufacturer-03\", created: \"2020-12-02T14:10:02Z\", lastUpdated: \"2020-12-02T14:10:02Z\", location: [40.1956, -74.566], delivered: false}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Inventory(id:\"017d7e12-4d25-2fd8-a835-4e50668c9bcb\", input: {name: \"Widget 123 - 50 count\", sku: \"WMl237JKL\", warehouse: \"manufacturer\", availableInventory: 20}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Warehouse(id:\"017d7e12-5551-7f88-7fe7-95f8fa9805a5\", input: {companyName: \"Retailer Inc\", code: \"retailer01\", street1: \"558 Wilkinson Ct\", street2: \"ste 1402\", city: \"Maple Valley\", state: \"WA\", postalCode: \"98038\", country: \"US\", phone: \"4255551314\", fax: \"3605553213\", created: \"2020-12-01T14:10:02Z\", updated: \"2020-12-01T14:10:02Z\"}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Inventory(id:\"017d7e12-4926-5618-f881-77b5d2e63dbc\", input: {name: \"Widget 123 - 1 count\", sku: \"WMl237ABC\", warehouse: \"manufacturer\", availableInventory: 100}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Inventory(id:\"017d7e12-527b-4787-3f91-f4e21faa42be\", input: {name: \"Widget 456 - 50 count\", sku: \"WMl237WXY\", warehouse: \"manufacturer\", availableInventory: 49}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addVendia_DeploymentInfo(id:\"2021-12-03T02:21:44.823553+00:00\", input: {deploymentTime: \"2021-12-03T02:21:44.823553+00:00\" , consensusDefinitionHash: \"9e0c4a782ed0e5ddefb0a32d4734d690008e7b809847dcc0794499affc7eb505\" , versionTag: \"prod-release.2021-12-02.de91c6d\" } ) {error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"addSelf_Warehouse(id:\"017d7e12-540f-f94b-a54b-99dd262331d0\", input: {companyName: \"Manufacturing Company\", code: \"manufacturer\", street1: \"3543 Queens Lane\", city: \"Keysville\", state: \"VA\", postalCode: \"23947\", country: \"US\", phone: \"4345553444\", fax: \"4345553445\", created: \"2020-12-01T14:10:02Z\", updated: \"2020-12-01T14:10:02Z\"}){error}"
],
"_owner": "manufacturer"
},
{
"mutations": [
"putVendia_UniInfo(input: {name: \"test-track-n-trace.unis.vendia.net\", sku: \"SHARE\", schema: \"{\\\"$schema\\\":\\\"http://json-schema.org/draft-07/schema#\\\",\\\"$id\\\":\\\"http://vendia.com/schemas/demos/track-and-trace.json\\\",\\\"title\\\":\\\"Track and Trace\\\",\\\"description\\\":\\\"Track and trace shipments among a manufacturer, shipper, and retailer\\\",\\\"type\\\":\\\"object\\\",\\\"properties\\\":{\\\"Inventory\\\":{\\\"description\\\":\\\"Inventory information\\\",\\\"type\\\":\\\"array\\\",\\\"items\\\":{\\\"type\\\":\\\"object\\\",\\\"properties\\\":{\\\"name\\\":{\\\"description\\\":\\\"Product name\\\",\\\"type\\\":\\\"string\\\"},\\\"sku\\\":{\\\"description\\\":\\\"Product SKU\\\",\\\"type\\\":\\\"string\\\"},\\\"warehouse\\\":{\\\"description\\\":\\\"Manufacturer warehouse code\\\",\\\"type\\\":\\\"string\\\"},\\\"availableInventory\\\":{\\\"description\\\":\\\"Available inventory\\\",\\\"type\\\":\\\"integer\\\"}}}},\\\"Shipment\\\":{\\\"description\\\":\\\"Shipment information\\\",\\\"type\\\":\\\"array\\\",\\\"items\\\":{\\\"type\\\":\\\"object\\\",\\\"properties\\\":{\\\"originWarehouse\\\":{\\\"description\\\":\\\"Shipment origin\\\",\\\"type\\\":\\\"string\\\"},\\\"destinationWarehouse\\\":{\\\"description\\\":\\\"Shipment destination\\\",\\\"type\\\":\\\"string\\\"},\\\"orderId\\\":{\\\"description\\\":\\\"Order ID\\\",\\\"type\\\":\\\"string\\\"},\\\"created\\\":{\\\"description\\\":\\\"When the order was placed\\\",\\\"type\\\":\\\"string\\\",\\\"format\\\":\\\"date-time\\\"},\\\"lastUpdated\\\":{\\\"description\\\":\\\"When the order was last updated\\\",\\\"type\\\":\\\"string\\\",\\\"format\\\":\\\"date-time\\\"},\\\"location\\\":{\\\"description\\\":\\\"Current Lat/long of the shipment\\\",\\\"type\\\":\\\"array\\\",\\\"items\\\":{\\\"type\\\":\\\"number\\\"},\\\"minItems\\\":2,\\\"uniqueItems\\\":true},\\\"delivered\\\":{\\\"description\\\":\\\"Delivery status\\\",\\\"type\\\":\\\"boolean\\\"}}}},\\\"Order\\\":{\\\"description\\\":\\\"Order information\\\",\\\"type\\\":\\\"array\\\",\\\"items\\\":{\\\"type\\\":\\\"object\\\",\\\"properties\\\":{\\\"orderId\\\":{\\\"description\\\":\\\"Order ID\\\",\\\"type\\\":\\\"string\\\"},\\\"items\\\":{\\\"type\\\":\\\"array\\\",\\\"items\\\":{\\\"type\\\":\\\"object\\\",\\\"properties\\\":{\\\"sku\\\":{\\\"description\\\":\\\"Product SKU in order\\\",\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"description\\\":\\\"Quantity of product in order\\\",\\\"type\\\":\\\"integer\\\"}}}},\\\"manufacturerWarehouseCode\\\":{\\\"description\\\":\\\"Manufacturer warehouse that holds the inventory\\\",\\\"type\\\":\\\"string\\\"},\\\"manufacturerWarehouseLocation\\\":{\\\"description\\\":\\\"Lat/long of manufacturer warehouse\\\",\\\"type\\\":\\\"array\\\",\\\"items\\\":{\\\"type\\\":\\\"number\\\"},\\\"minItems\\\":2,\\\"uniqueItems\\\":true},\\\"retailerWarehouseCode\\\":{\\\"description\\\":\\\"Retailer warehouse that placed the order\\\",\\\"type\\\":\\\"string\\\"},\\\"retailerWarehouseLocation\\\":{\\\"description\\\":\\\"Lat/long of retailer warehouse\\\",\\\"type\\\":\\\"array\\\",\\\"items\\\":{\\\"type\\\":\\\"number\\\"},\\\"minItems\\\":2,\\\"uniqueItems\\\":true},\\\"delivered\\\":{\\\"description\\\":\\\"Order status\\\",\\\"type\\\":\\\"boolean\\\"},\\\"created\\\":{\\\"description\\\":\\\"When order was placed\\\",\\\"type\\\":\\\"string\\\",\\\"format\\\":\\\"date-time\\\"},\\\"updated\\\":{\\\"description\\\":\\\"When order was last updated\\\",\\\"type\\\":\\\"string\\\",\\\"format\\\":\\\"date-time\\\"}}}},\\\"Warehouse\\\":{\\\"description\\\":\\\"Warehouse information\\\",\\\"type\\\":\\\"array\\\",\\\"items\\\":{\\\"type\\\":\\\"object\\\",\\\"properties\\\":{\\\"companyName\\\":{\\\"description\\\":\\\"Company name\\\",\\\"type\\\":\\\"string\\\"},\\\"code\\\":{\\\"description\\\":\\\"Warehouse code\\\",\\\"type\\\":\\\"string\\\"},\\\"street1\\\":{\\\"description\\\":\\\"Warehouse Street Address\\\",\\\"type\\\":\\\"string\\\"},\\\"street2\\\":{\\\"description\\\":\\\"Warehouse Warehouse Street Address Continued\\\",\\\"type\\\":\\\"string\\\"},\\\"city\\\":{\\\"description\\\":\\\"Warehouse City\\\",\\\"type\\\":\\\"string\\\"},\\\"state\\\":{\\\"description\\\":\\\"Warehouse State\\\",\\\"type\\\":\\\"string\\\"},\\\"postalCode\\\":{\\\"description\\\":\\\"Warehouse Postal Code\\\",\\\"type\\\":\\\"string\\\"},\\\"country\\\":{\\\"description\\\":\\\"Warehouse Country Code\\\",\\\"type\\\":\\\"string\\\"},\\\"phone\\\":{\\\"description\\\":\\\"Warehouse Phone Number\\\",\\\"type\\\":\\\"string\\\"},\\\"fax\\\":{\\\"description\\\":\\\"Warehouse Fax Number\\\",\\\"type\\\":\\\"string\\\"},\\\"created\\\":{\\\"description\\\":\\\"When the Warehouse record was created\\\",\\\"type\\\":\\\"string\\\",\\\"format\\\":\\\"date-time\\\"},\\\"updated\\\":{\\\"description\\\":\\\"When Warehouse record was last updated\\\",\\\"type\\\":\\\"string\\\",\\\"format\\\":\\\"date-time\\\"}}}}}}\", schemaNamespace: \"Self\", status: \"RUNNING\", createdTime: \"2021-12-03T02:14:26.936578+00:00\", updatedTime: \"2021-12-03T02:21:44.823553+00:00\", nodes: [{name: \"manufacturer\", userId: \"512f2d97-979d-4cb5-9b52-04b5f1f7aa3d\", userEmail: \"james+demo@vendia.net\", status: \"RUNNING\", region: \"us-east-2\", tier: {share: FREE}, vendiaAccount: {csp: \"AWS\", accountId: \"255562891666\", org: \"332134949057\"}}, {name: \"shipper\", userId: \"512f2d97-979d-4cb5-9b52-04b5f1f7aa3d\", userEmail: \"james+demo@vendia.net\", status: \"RUNNING\", region: \"us-east-2\", tier: {share: FREE}, vendiaAccount: {csp: \"AWS\", accountId: \"380683105211\", org: \"332134949057\"}}]}) {error}"
],
"_owner": "manufacturer"
}
]
},
{
"_id": "000000000000002",
"commitTime": "2021-12-03T03:16:32.536005+00:00",
"transactions": [
{
"mutations": [
"updateSelf_Shipment(id:\"017d7e12-5c29-165b-6051-f56a03bcb45e\",input: {created: \"2020-12-02T14:10:02Z\", delivered: false, destinationWarehouse: \"retailer01\", lastUpdated: \"2020-12-02T15:10:02Z\", location: [47.6152, -122.354], orderId: \"manufacturer-01\", originWarehouse: \"manufacturer\"}){error}"
],
"_owner": "manufacturer"
}
]
},
{
"_id": "000000000000003",
"commitTime": "2021-12-03T03:23:12.940545+00:00",
"transactions": [
{
"mutations": [
"updateSelf_Shipment(id:\"017d7e12-5c29-165b-6051-f56a03bcb45e\",input: {delivered: true, lastUpdated: \"2020-12-02T16:10:02Z\"}){error}"
],
"_owner": "manufacturer"
}
]
}
]
}
}
}
Note that each block in the ledger is recorded with the Mutation data and metadata regarding the node that submitted the mutation. This can be very useful when researching the lineage of specific data such as when working to identify when and where the Shipment record was updated.
Step 5 - Trace issues with package handling
Sharing scalar data such tracking updates for shipments is easy with Vendia Share but it is only part of the data-sharing story. Another feature that logistics customers value is the ability to share files with nodes inside a Uni.
Imagine that the shipment with which you have been working finally makes it to its intended destination. Upon inspection however, the retailer reports the package has been damaged. Using Vendia Share, we can begin to add physical evidence to the activities in the supply chain to identify where such damage occurs.
Vendia's Glenn Dierkes details a solution for gathering such evidence in a recent Blog Article. This solution takes advantage of Vendia Share's file-sharing feature to allow partners to upload photos of products as they traverse the supply-chain. These photos can then later be correlated to reports of damage to identify loss patterns.
Adding photos to the supply chain
Using the GraphQL Explorer, provide a photo of the damaged item.
mutation addShipmentPhoto {
addVendia_File(
input: {
sourceBucket: "source-s3-bucket",
sourceKey: "box-image.jpg",
sourceRegion: "us-east-1",
destinationKey: "shipment-017d1206-7881-4279-995a-e4176d8f223a-delivery.jpg"
},
syncMode: ASYNC
) {
transaction {
_id
transactionId
}
}
}
NOTE: The sourceBucket
and sourceKey
should be updated to reflect your data.
This mutation has posted an update to the shipment record and added a file to the Uni at shipment-017d1206-7881-4279-995a-e4176d8f223a-delivery.jpg
. This file can be shared with other nodes and presented directly via cloud-based storage services. As the nodes in this Uni are deployed to AWS, the file is accessible via Amazon S3.
Run the following query in GraphQL Explorer to retrieve a temporary URL for the added file.
query listFiles {
listVendia_FileItems {
Vendia_FileItems {
_id
temporaryUrl
destinationKey
}
}
}
The returned TemporaryUrl can be opened from a web browser to inspect the photo. In this example, it appears the box was left unattended and thus was damaged.
Step 6 - Clean up
It is important that the Uni created in this Quick start is destroyed to prevent any unexpected charges. You can destroy the Uni from the Share Website or with the CLI command below.
share uni delete --uni test-track-and-trace
Note: The
--uni
argument should be adjusted to reflect the name of your Uni as defined by thename
property in the registration.json file.
Summary and Next Steps
This Quick start demonstrated the ease and speed of which Vendia Share can be leveraged to support supply chain logistics. With zero-code, data was quickly accessible between multiple parties and updates could be recorded and validated in real-time across parties.Vendia Share integrations and smart-contracts could be leveraged to further automate data collection and review. For example, email notifications for deliveries could be modeled against Shipment data and links to view progress on a map could be dynamically generated. If you would like to hear more about how logistics and inventory management customers use Vendia Share, reach out today. We would enjoy discussing this exciting platform with you in more detail.