# Policy Workflow Wrap Up

We can then look at the entire process.

<figure><img src="https://3006114282-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXVOaWpJKxLZf1Tee9eCO%2Fuploads%2FRG6nNFM8RasXGpqLypL6%2Fimage.png?alt=media&#x26;token=dc3b31e3-16c6-4f6a-a7cd-c62ce002f4c3" alt=""><figcaption></figcaption></figure>

We can also look at the code that has been created programmatically from the defined workflow by clicking on the “<>” button in the three-button chevron on the right-hand side.

<figure><img src="https://3006114282-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXVOaWpJKxLZf1Tee9eCO%2Fuploads%2FC8RGvJU9pvsd1k3akfLN%2Fimage.png?alt=media&#x26;token=99330901-9621-490c-b1de-8e1875503616" alt=""><figcaption></figcaption></figure>

The full coded version of the policy we just demoed is below (Reminder the coded version of this policy is for Guardian version 1.0.2):

```
//Policy logic starts with block 1.
{
  //blockType - the type of the block:
  //  "InterfaceContainerBlock" - a block which contains and organizes other blocks.
  //  First block should always be of the "InterfaceContainerBlock" type.
  "blockType": "InterfaceContainerBlock",
  //defaultActive shows whether this block is active at this time and whether it needs to be shown.
  "defaultActive": true,
  //permissions - users with these roles are allowed to interact with the block. Can contain the following values:
  //  "OWNER" = creator of the Policy.
  //  "NO_ROLE" = users without a role.
  //  "ANY_ROLE" = users with any role.
  //  "INSTALLER" = only users with a particular role (in this case - INSTALLER).
  "permissions": [
    // As per above, this block is accessible to all users (with any role).
    "ANY_ROLE"
  ],
  //uiMetaData - additional options which don't affect the behavior of the block but are needed for rendering.
  "uiMetaData": {
    //type - block UI behavior, can contain the following values:
    //  "blank" - does not contain any frame, will render all child elements one after the other.
    //  "tabs" - a container which has a tab for each of the child element. It will render the first child element as type "blank".
    "type": "blank"
  },
  //children - list of child blocks in a container block.
  "children": [
    //First policy step - select a role.
    {
      //"PolicyRolesBlock" - block which determines a role for the user.
      "blockType": "PolicyRolesBlock",
      //"tag" - a unique (for the Policy) textual tag for the block which can be used in other blocks for linking.
      "tag": "choose_role",
      //Non ContainerBlock do not contain child elements. They can exist but they are ignored for rendering.
      "children": [],
      "uiMetaData": {
        //html component has title and descriptions, which can be specified in the corresponding elements.
        "title": "registration",
        "description": "choose a role"
      },
      "permissions": [
        //Only users with no roles assigned can access the block.
        "NO_ROLE"
      ],
      //This block is active
      "defaultActive": true,
      //"roles" - available roles from which the user can choose.
      "roles": [
        //In this case the user can only be the INSTALLER.
        "INSTALLER"
      ]
    },
    // After the role is selected the corresponding branch in the policy will become accessible for the user.
    {
      //"InterfaceStepBlock" - similar to the InterfaceContainerBlock, with the difference that it can only render a single child element.
      //Rendered component is determined by the current step.
      //An event on a component automatically passes control to the next component.
      "blockType": "InterfaceStepBlock",
      "defaultActive": true,
      "tag": "init_installer_steps",
      "permissions": [
        //This block is only accessible to users with the INSTALLER role.
        "INSTALLER"
      ],
      "uiMetaData": {
        //Currently there is only one type - "blank".
        //Only 1 active block is rendered.
        "type": "blank"
      },
      "children": [
        //First step after the selection of the INSTALLER roles is to fill out the VC form.
        {
          //"requestVcDocumenBlock" - a type of the block which creates a form from the schema, and sends the document to the server.
          "blockType": "requestVcDocumentBlock",
          "tag": "add_new_installer_request",
          "defaultActive": true,
          "permissions": [
            "INSTALLER"
          ],
          //"schema" - uuid of the schema, which will be used to build the form.
          "schema": "1a5347ba-5e5f-49a7-8734-3dcc953a03ed",
          //"idType" - when the documents is saved it would automatically get an ID.
          // In this example the document ID would be the DID of the current user.
          // Can be one of these values:
          //   "UUID" - new uuid.
          //   "DID" - new DID.
          //   "OWNER" - DID of the current user.
          "idType": "OWNER",
          "uiMetaData": {
            //"type" - style of the render of the form, one of these values:
            //  "page" - the form is rendered as a page.
            //  "dialog" - displays a button, which opens a dialogue with the form when clicked.
            "type": "page",
            // The page contains title and description, as well as the form.
            "title": "New Installer",
            "description": "Description"
          }
        },
        // Next step is to save it in the DB.
        {
          //"sendToGuardianBlock" - a type of the block which can save a new or updated document.
          //This block does not contain defaultActive and does not render, only relevant on the server side.
          "blockType": "sendToGuardianBlock",
          "tag": "save_new_approve_document",
          //"dataType" - where to save the document, possible values:
          //  "approve" - approve DB table.
          //  "vc-documents" - vc-documents DB table.
          //  "did-documents" - did-documents DB table.
          //  "hedera" - document would be sent to the corresponding Policy topic in Hedera.
          // In this example VC would be stored in a approve table, waiting for approval.
          "dataType": "approve",
          //"entityType" - mark the document in the DB. Needed for filtering.
          "entityType": "Installer",
          //"stopPropagation" - end processing here, don't pass control to the next block.
          "stopPropagation": false,
          "uiMetaData": {}
        },
        // Notify the user after submitting the request for approval.
        {
          //"InformationBlock" - block type which can display a notification or a progress bar.
          "blockType": "InformationBlock",
          "tag": "wait_fo_approve",
          "children": [],
          "uiMetaData": {
            //"type" - notification type, possible values:
            //  "text" - textual message.
            //  "loader" - progress bar.
            "type": "text",
            // Set title and description for the page, only if the "type" is "text".
            "title": "Waiting for approval",
            "description": "Waiting for approval"
          },
          "permissions": [
            "INSTALLER"
          ],
          // Do not pass control to the next block after displaying the message as need to wait for Standard Registry approval.
          "stopPropagation": true,
          "defaultActive": true
        },
        // After the approval continue creating the document.
        // Update document status in the DB.
        {
          "tag": "update_approve_document_status",
          "blockType": "sendToGuardianBlock",
          "dataType": "approve",
          "entityType": "Installer",
          "uiMetaData": {}
        },
        // Now send the document to Hedera Topic.
        {
          "tag": "send_installer_vc_to_hedera",
          "blockType": "sendToGuardianBlock",
          "dataType": "hedera",
          "entityType": "Installer",
          "uiMetaData": {}
        },
        // Finally save the VC document in the vc-documents DB table.
        {
          "tag": "Submission_of_CSD01_Documentation",
          "blockType": "sendToGuardianBlock",
          "dataType": "vc-documents",
          "entityType": "Installer",
          "uiMetaData": {}
        },
        // After the document has been created; the user can access the document with grids.
        // Create an InterfaceContainerBlock to group all pages accessible after registration is completed.
        {
          "blockType": "InterfaceContainerBlock",
          "tag": "installer_header",
          "defaultActive": true,
          "permissions": [
            "INSTALLER"
          ],
          "uiMetaData": {
            // In this example, INSTALLER would be able to access two tabs.
            "type": "tabs"
          },
          "children": [
            // Create an InterfaceContainerBlock to group all components on the sensor page.
            {
              "blockType": "InterfaceContainerBlock",
              "tag": "sensors_page",
              "defaultActive": true,
              "permissions": [
                "INSTALLER"
              ],
              "uiMetaData": {
                "type": "blank",
                // "title" - name of the tab. If the parent is interfaceContainerBlock the value from title is used for tab name.
                // If the "title" is empty the block name is used as the tab name.
                "title": "Sensors"
              },
              // Sensor page. Contains a grid and a "create new sensor" button.
              "children": [
                {
                  //"InterfaceDocumentsSourceBlock" - block type which outputs information from the DB as grid.
                  "blockType": "InterfaceDocumentsSourceBlock",
                  "tag": "sensors_grid",
                  "defaultActive": true,
                  "permissions": [
                    "INSTALLER"
                  ],
                  
                  // When true, this filter out the documents not created by the current user when rendering.
                  "onlyOwnDocuments": true,
                  //"dataType" - Specificy the table to request the data from. Possible values:
                  //  "vc-documents".
                  //  "did-documents".
                  //  "vp-documents".
                  //  "approve".
                  //  "standard-registries" - list of users with the Standard Registry role.
                  "dataType": "vc-documents",
                  // Custom filters, based on any existing fields.
                  "filters": {
                    // Filter on the basis of schema ID.
                    "schema": "9d31b4ee-2280-43ee-81e7-b225ee208802",
                    // Filter on the basis of the "entityType" field in the "sendToGuardianBlock" block.
                    "type": "Inverter"
                  },
                  "uiMetaData": {
                    //"fields" - list of grid columns
                    "fields": [
                      {
                        // Object fields to retrieve the values from. Internal fields are separated by ".", access to array elements is via index.
                        // For example "document.credentialSubject.0.id" - is document.credentialSubject[0].id
                        "name": "document.id",
                        // Title of the column.
                        "title": "ID",
                        // Type of the displayed value, possible options:
                        //  "text" - ordinary text.
                        //  "button" - a button.
                        //  "block" - a block embedded into the column.
                        "type": "test",
                        // Floating hint/tooltip for the column.
                        "tooltip": ""
                      },
                      {
                        "name": "document.credentialSubject.0.id",
                        "title": "DID",
                        "type": "text"
                      },
                      {
                        "name": "document",
                        "title": "Document",
                        "tooltip": "",
                        "type": "button",
                        // The "button" type can contain the following parameters:
                        //"action" - action type, e.g. open a dialog˚.
                        "action": "dialog",
                        //"content" - text inside the column.
                        "content": "View Document",
                        //"uiClass" - button style.
                        "uiClass": "link",
                        //"dialogContent" - dialog title.
                        "dialogContent": "VC",
                        //"dialogClass" - dialog style.
                        "dialogClass": "",
                        //"dialogType" - currently only json type is supported.
                        "dialogType": "json"
                        // additionally specifying a "bindBlock" field would result in the display of the linked block in side the dialog.
                      },
                      {
                        "name": "document.id",
                        "title": "Config",
                        "tooltip": "",
                        // "block" - render the block inside the grid column.
                        "type": "block",
                        "uiClass": "",
                        //"bindBlock" - block to embed into the grid.
                        "bindBlock": "download_config_btn"
                      }
                    ]
                  }
                },
                // Block to download the config file.
                {
                  //"InterfaceActionBlock" -  block to create custom actions.
                  "blockType": "InterfaceActionBlock",
                  // The block in embedded into the grid, not rendered independently
                  "defaultActive": false,
                  "tag": "download_config_btn",
                  "permissions": [
                    "INSTALLER"
                  ],
                  //"type" - block type, example values:
                  //  "download" - download files.
                  //  "selector" - select an action.
                  "type": "download",
                  //schema and the targetUrl - specific configuration parameters, Only needed in the reference implementation of the Guardian because of the IoT Simulator that is generating MRV data.
                  "schema": "c4623dbd-2453-4c12-941f-032792a00727",
                  "targetUrl": "http://message-broker:3003/mrv",
                  "uiMetaData": {
                    //"content" - text inside the column
                    "content": "download"
                  }
                },
                // Button to create new sensor, displayed after the grid.
                // Component is embedded into the InterfaceStepBlock to join all steps.
                {
                  "defaultActive": true,
                  "tag": "create_new_sensor_steps",
                  "permissions": [
                    "INSTALLER"
                  ],
                  "blockType": "InterfaceStepBlock",
                  "uiMetaData": {
                    "type": "blank"
                  },
                  "children": [
                    // Button to create new sensor.
                    {
                      "tag": "add_sensor_bnt",
                      "defaultActive": true,
                      "permissions": [
                        "INSTALLER"
                      ],
                      "blockType": "requestVCDocumentBlock",
                      "schema": "9d31b4ee-2280-43ee-81e7-b225ee208802",
                      // Generate new DID for the new sensor.
                      "idType": "DID",
                      "uiMetaData": {
                        // Open the a dialog containing the new sensor.
                        "type": "dialog",
                        // Text on the button.
                        "content": "New Sensors",
                        //Button style.
                        "uiClass": "btn",
                        //Dialog title.
                        "dialogContent": "New Sensors",
                        //Description.
                        "description": "Description",
                        //Dialog style.
                        "dialogClass": ""
                      }
                    },
                    // Save the created sensor VC in the corresponding Heder Topic.
                    {
                      "tag": "send_sensor_vc_to_hedera",
                      "blockType": "sendToGuardianBlock",
                      "dataType": "hedera",
                      "entityType": "Inverter",
                      "uiMetaData": {}
                    },
                    // Also save it in the DB.
                    {
                      "tag": "CSD02_device_registration",
                      "blockType": "sendToGuardianBlock",
                      "dataType": "vc-documents",
                      // Document in the DB is labeled as "Inverter" to enable later filtering in the grid.
                      "entityType": "Inverter",
                      "stopPropagation": false,
                      "uiMetaData": {}
                    }
                  ],
                  //"cyclic" - go back one step to enable the creation of another sensor.
                  "cyclic": true
                }
              ]
            },
            // Create InterfaceContainerBlock to group all components on the page with MRV data.
            {
              "blockType": "InterfaceContainerBlock",
              "tag": "mrv_page",
              "defaultActive": true,
              "permissions": [
                "INSTALLER"
              ],  
              "uiMetaData": {
                "type": "blank",
                "title": "MRV"
              },
              "children": [
                // MRV grid.
                {
                  "tag": "mrv_grid",
                  "defaultActive": true,
                  "permissions": [
                    "INSTALLER"
                  ],
                  "blockType": "InterfaceDocumentsSourceBlock",
                  "dependencies": [
                    "SendToGuardianBlock"
                  ],
                  "onlyOwnDocuments": true,
                  "dataType": "vc-documents",
                  "filters": {
                    "schema": "c4623dbd-2453-4c12-941f-032792a00727",
                    "type": "MRV"
                  },
                  "uiMetaData": {
                    "fields": [
                      {
                        "name": "document.id",
                        "title": "ID",
                        "type": "button"
                      },
                      {
                        "name": "document.issuer",
                        "title": "Sensor DID",
                        "type": "text"
                      },
                      {
                        "name": "document",
                        "title": "Document",
                        "tooltip": "",
                        "type": "button",
                        "action": "dialog",
                        "content": "View Document",
                        "uiClass": "link",
                        "dialogContent": "VC",
                        "dialogClass": "",
                        "dialogType": "json"
                      }
                    ]
                  }
                }
              ]
            }
          ]
        },
        // Block to display rejection info (i.e. the INSTALLER was not approved by Standard Registry).
        {
          "tag": "installer_rejected",
          "blockType": "InformationBlock",
          "children": [],
          "uiMetaData": {
            "type": "text",
            "description": "Your application was rejected",
            "title": "Rejected"
          },
          "stopPropagation": true,
          "permissions": [
            "INSTALLER"
          ],
          "defaultActive": true
        }
      ]
    },
    // This Policy branch is used by users with the Standard Registry roles.
    //Starting with the ContainerBlock.
    {
      "tag": "standard_registry_header",
      "defaultActive": true,
      "permissions": [
        "OWNER"
      ],
      "blockType": "InterfaceContainerBlock",
      "uiMetaData": {
        "type": "tabs"
      },
      "children": [
        // Page containing the list of installers which sent documents for approval.
        {
          "tag": "approve_page",
          "defaultActive": true,
          "permissions": [
            "OWNER"
          ],
          "blockType": "InterfaceContainerBlock",
          "uiMetaData": {
            "type": "blank",
            "title": "Approve Documents"
          },
          "children": [
            // Grid listing VCs of the Installers, which require approval from the Standard Registry.
            {
              "tag": "approve_documents_grid",
              "defaultActive": true,
              "permissions": [
                "OWNER"
              ],
              "blockType": "InterfaceDocumentsSourceBlock",
              // Displays all VC documents from all Installers.
              "onlyOwnDocuments": false,
              "dataType": "approve",
              "dependencies": [
                // Refreshed when a VC is stored in the DB
                "save_new_approve_document"
              ],
              "uiMetaData": {
                "fields": [
                  {
                    "name": "document.issuer",
                    "title": "Owner",
                    "type": "text",
                    "tooltip": "Installer did"
                  },
                  {
                    "name": "createDate",
                    "title": "Create Date",
                    "type": "text"
                  },
                  {
                    "name": "document",
                    "title": "Document",
                    "tooltip": "",
                    "type": "button",
                    "action": "dialog",
                    "content": "View Document",
                    "uiClass": "link",
                    "dialogContent": "VC",
                    "dialogClass": "",
                    "dialogType": "json"
                  },
                  {
                    "name": "status",
                    "title": "Status",
                    "type": "text"
                  },
                  // Column with the Approve/Reject buttons
                  {
                    "name": "status",
                    "title": "Operation",
                    "tooltip": "",
                    "type": "block",
                    "action": "block",
                    "content": "",
                    "uiClass": "",
                    "bindBlock": "approve_documents_btn"
                  }
                ]
              },
              "children": [],
              "filters": {}
            },
            // Block with the Approve/Reject buttons, embedded into the grid
            {
              "tag": "approve_documents_btn",
              "blockType": "InterfaceActionBlock",
              "permissions": [
                "OWNER"
              ],
              "type": "selector",
              // For the selector type:
              "uiMetaData": {
                //"field" - field which is linked to the selector.
                "field": "status",
                //"options" - list of the possible options.
                "options": [
                  //Button:
                  {
                    //Button text.
                    "name": "Approve",
                    //Value which will be stored in the "field".
                    //In this example document.status = "APPROVED"
                    "value": "APPROVED",
                    //Button style.
                    "uiClass": "btn-approve",
                    //Specify which block to pass control to.
                    //If the "Approve" button was clicked, the control would be passed to the update_approve_document_status block.
                    "bindBlock": "update_approve_document_status"
                  },
                  {
                    "name": "Reject",
                    "value": "REJECTED",
                    "uiClass": "btn-reject",
                    //If the "Reject" button was clicked pass control to the installer_rejected block.
                    "bindBlock": "installer_rejected"
                  }
                ]
              }
            }
          ]
        }
      ]
    },
    // Policy branch for minting tokens.
    {
      "tag": "mint_events",
      "permissions": [
        "OWNER",
        "INSTALLER"
      ],
      "blockType": "InterfaceContainerBlock",
      "uiMetaData": {
        "type": "blank"
      },
      "children": [
        // Receive the MRV.
        {
          //"externalDataBlock" - receives data from the external source and passes them over the the next block.
          // Each Policy has a policyTag. Data received onto the external API are filtered by the policyTag, and passed on to all externalDataBlock inside the Policy.
          "blockType": "externalDataBlock",
          "tag": "mrv_source",
          "entityType": "MRV",
          // Filter the documents by schema ID. If the document is not related to the given schema it does not get passed further.
          "schema": "c4623dbd-2453-4c12-941f-032792a00727",
          "uiMetaData": {}
        },
        // Store the new MRV.
        {
          "tag": "CSD04_requesting_i_Rec_issuance",
          "blockType": "sendToGuardianBlock",
          "dataType": "vc-documents",
          "entityType": "MRV",
          "uiMetaData": {}
        },
        //Minting
        {
          //"mintDocument" - receives the VC from the previous block and mints based on the rule[s].
          "blockType": "mintDocumentBlock",
          "tag": "mint_token",
          //"tokenId" - ID of the token
          // User should be previously linked with token.
          "tokenId": "0.0.26063342",
          // Rules under which the number of tokens is calculated. Math operations are supported, e.g. the following:
          //  data = { amount: 2 }
          //  rule = "amount * 10"
          // will result in 20 tokens.
          "rule": "1",
          "uiMetaData": {}
        }
      ]
    }
  ]
}
```
