Development


Agile

Agile

Definition of Done

We consider a User Story or Defect to be complete when it has met the following criteria:

Agile

Stand up

3 Standup Questions (per story)

Agile

Agile Trainings

Agile-GettingStarted.pptx
Agile Training to go over the basics of Agility, covering:

ProductOwnerTraining.pptx
Product Owner Training

ScrumMasterTraining.pptx
Scrum Master Training

Agile

User Story Template

User Story

Write user story text description.

Note

User stories should be written according to the following pattern:
As a <type of user>, I want <some goal> so that <some reason>.
Important: a user story should consider needs of particular type (most often role) of user.
User stories should follow INVEST principles:

  1. Writing a user story (anyone is allowed to write a user story, most often it'll be Product Owner);
  2. Discussion (all teams should take part in the final discussion):
    1. [Optional] Breaking an epic into smaller user stories;
    2. Splitting into sub-tasks (with tech specifics);
    3. Verification of acceptance criteria completeness;
    4. Update user story contents if needed;
  3. Mark as ready. Goes to the implementation pipeline when it's time.

Activity

Note

Activities (also known as themes) are common groups (usually features) that combine user stories together. As an example, "Account" activity may contain user stories describing registration, password recovery, profile updates, etc. Granularity of activities should be chosen in a way that doesn't lead to activities with too many user stories (in such cases these activities should be split into smaller ones).
When combined with user stories, activities present a good visualization of the backlog, called user story map.

Type

Epic or User story. Epics should only be used as a temporary stub for user story(ies). See definition of an epic above.

Status

Status of user story readiness in terms of the lifecycle. A user story should only be marked as ready when all sections were filled in and reviewed by team members.
An example:

Components

Provide a list of affected components (e.g. back-end, front-end, etc.).

Sketches/wireframes/mockups

All graphical data goes here (with some captions if necessary).
An example:
Sketch 1

Workflow

Describe the whole workflow from user's perspective, step by step, with all necessary details.
All stakeholders should be able to understand contents of this section, so no sophisticated technical details should be placed here.
An example:

  1. User opens web app link.
  2. User enters credentials.
  3. User logs in and sees the dashboard.

Acceptance Criteria

Describe details that are required to validate the software once it's implemented: UI elements behavior, validation logic, messages of all types (validation errors, hints, etc.).
An example:

Tech Notes

Describe all low level technical details here, like API specification, error handling conventions, timeout values, etc. May also contain some diagrams, (pseudo) code snippets, etc.

Agile

Agile Discussion Jan 25 2021

Named Roles:

Splitting of PO and Scrum Master

Do a full split of the teams, not a large kanban of items.

Ceremonies in Order:

Product Council:

Release Cycle:

Faster releases - Goal of constant releases during the day

Action Items:

Agile

ADO Work Item Standardization

User Stories

image.png


Bugs

The primary difference between a bug and a user story is that the bug should include the Repro Steps

image.png


Emails

Guide on how to trigger each email.

Emails

AccessLink

How to trigger:

image.png

image.png

Emails

Share

How to trigger:

image.png

image.png

Emails

EmailFiles

How to trigger:

image.png

image.png

image.png

image.png

image.png

Emails

EmailImportFailure

How to trigger:

Emails

EmailImportMaxFailure

How to trigger:

Emails

MfaAuthCode

How to trigger:

image.png

image.png



Emails

MfaQrCode

How to trigger:

image.png

image.png


Emails

NewDocumentRequest

How to trigger:

image.png

image.png

Emails

NewUser

How to trigger:

image.png

image.png

image.png

image.png

Emails

PasswordReset

How to trigger:

image.png

image.png

Emails

SmtpEmailSettingFailure

How to trigger:

The only way I've been able to trigger this consistently is to


Emails

SmtpEmailSettingMaxFailure

How to trigger:

Emails

Status

How to trigger:

Emails

TestEmail

How to trigger:

image.png

image.png

Form Fill

Form Fill

PrizmDoc Resources

Sample Projects:
prizm-samples-mvc.zip
prizm-samples-webforms.zip

Form Fill

File Request Recipient

FileRequestFormFill - Request1.png

FileRequestFormFill - Request2.png

FileRequestFormFill - Request3.png

FileRequestFormFill - Request4.png

Form Fill

File Request - Form Fill Create

FileRequestFormFillCreate1.png
FileRequestFormFillCreate2.png
FileRequestFormFillCreate3.png
FileRequestFormFillCreate3-1.png
FileRequestFormFillCreate4.png
FileRequestFormFillCreate5.png

Form Fill

UI Mockups

2 buttons added to previewer, Icon to indicated that a document has form fill. Form Template button in bottom right is still a pending discussion (4/9/2020)
FormFillPreviewer.png

Previewer
PreviewerUI.png

Adding a default Template Library to store Form Definitions
FormFillTemplates.png

Designer View - Allow linking of profile items to Form fields
PreviewerFormFillDesigner.png

Templates - Allow Multi Select and Partial Template application
Templates Additions DualScreen.png

Database Model
image.png

Form Fill

Form Fill User Experience

Phase 1:

Add manual push using Form Template in the Profile Dialog of Right pane menu
Expose Anonymous File Requests and Share in Workflow
Add step in workflow to push profile using form fill
Add file request container type that uses a file and form fill template
Cleanup Accusoft UI, change button locations.
Change Name of Checklist for things filler needs to do

Phase 2:

Zonal OCR form template fields

Misc..

Change annotation Tool Order

Research:

Guided Form Fill
Auto-save Form Fill - Both Design and Playthrough
Need to allow filling it out partially and then resuming

User Stories:

User pushes metadata into document using Form Fill Template
User Creates Form Fill Template and asks different user to fill it out
User Fills out document and info is pulled into profile

Notes:

More Notes:

Form Fill Profiles:

Previewer UI

Templates

DB Model:

File Requests:

Notes for FormFill Request Creation

Ideas for Recipient playthrough

To Ask Jessie:

Integromat

Integromat

Getting Started

Setup

  1. Head to integromat.com 
  2. Login
Integromat

eFileCabinet App

Click here  to see our app.

An integromat app is composed of several components. The important ones are:

Integromat

Remote Procedure Calls (RPCs)

What are they?

How do I use them?




List Files

Communication

Each number in the following ordered list is referring to a block in code

  1. This block grabs the parent workspace id and initializes a counter so that the RPC will know where it currently is when it iterates in block 2. It also determines the last string in the path so that block 2 knows when it is done iterating
  2. This block iterates through each string in the path to get the nodeId by it's name
    • It knows it is done when the lastNamePath is equal to its currentName
    • This "condition": "{{if(parameters.path !== '/', true, false)}}" will prevent it from running when there is no path entered so as to save an API call
  3. This will show the user the next layer in the path
Notice
"response": {
     "iterate": "{{body}}",
     "output": {
          "label": "{{item.name}}",
          "value": "{{item.id}}",
          "file": "{{if(item.systemType === 7, true, false)}}"
      }
}


List Folders

Communication

Each number in the following ordered list is referring to a block in code

  1. This block grabs the parent workspace id and initializes a counter so that the RPC will know where it currently is when it iterates in block 2. It also determines the last string in the path so that block 2 knows when it is done iterating
  2. This block iterates through each string in the path to get the nodeId by it's name
    • It knows it is done when the lastNamePath is equal to its currentName
    • This "condition": "{{if(parameters.path !== '/', true, false)}}" will prevent it from running when there is no path entered so as to save an API call
  3. This will show the user the next layer in the path
Notice
"response": {
     "iterate": "{{filterFolders(body)}}",
     "output": {
          "label": "{{item.name}}",
          "value": "{{item.id}}"
      }
}
Integromat

Modules

As of 10/06/2020, we have 4 modules built:

Download a file

Required Inputs Using Mappable Parameters

Interface

Note that this tab is only used when you need to specify to other modules what your output will be

Communication

Each number in the following ordered list is referring to a block in code

  1. This block grabs the parent workspace id and initializes a counter so that the module will know where it currently is when it iterates in block 2. It also determines the last string in the path so that block 2 knows when it is done iterating
  2. This block iterates through each string in the path to get the nodeId by it's name
    • It knows it is done when the lastNamePath is equal to its currentName
    • This "condition": "{{if(parameters.path !== '/', true, false)}}" will prevent it from running when there is no path entered so as to save an API call
  3. This block uses the pathId and the accessToken to makes a call to our API so that we can GET the file to download


Upload a file

Required Inputs Using Mappable Parameters

Communication

Each number in the following ordered list is referring to a block in code

  1. This block grabs the parent workspace id and initializes a counter so that the module will know where it currently is when it iterates in block 2. It also determines the last string in the path so that block 2 knows when it is done iterating
  2. This block iterates through each string in the path to get the nodeId by it's name
    • It knows it is done when the lastNamePath is equal to its currentName
    • This "condition": "{{if(parameters.path !== '/', true, false)}}" will prevent it from running when there is no path entered so as to save an API call
  3. This block processes the node that the user has input by selecting the last node. It then saves this id into a temp variable called "pathId"
  4. This block attempts to create the file in the requested parent node
    • If there is an error (as seen in the response body), then it will take the suggestedName in the Batch Object name for block 3
  5. Conditional block: This block will only run if the suggested name received in block 2 does not equal the file name parameter received
    • If this runs it will create the node with the suggested name
  6. Now that the node has been created it will begin the upload process. This block will FileUpload POST to retrieve the uploadIdentifier
  7. With the uploadIdentifier retrieved, this block will start the data upload
  8. Once the data has finished uploading, it will finalize by sending "complete": true


Create a node

Required Inputs Using Mappable Parameters

Communication

Each number in the following ordered list is referring to a block in code

  1. This block grabs the parent workspace id and initializes a counter so that the module will know where it currently is when it iterates in block 2. It also determines the last string in the path so that block 2 knows when it is done iterating
  2. This block iterates through each string in the path to get the nodeId by it's name
    • It knows it is done when the lastNamePath is equal to its currentName
    • This "condition": "{{if(parameters.path !== '/', true, false)}}" will prevent it from running when there is no path entered so as to save an API call
  3. This block uses the pathid found in block 2 to make a call to our API so that we can fetch the systemType. It then saves that in to temp variable "parentSystemType".
  4. This block starts by figuring the systemType of the new node, then it will POST the new node using the pathId, systemType, and name
    • If the parent is a workspace, it will create a cabinet
    • If the parent is a cabinet, it will create a drawer
    • If the parent is a drawer, it will create a folder
    • If the parent is a folder, it will create a folder


Rename a node

Required Inputs Using Mappable Parameters

Communication

Each number in the following ordered list is referring to a block in code

  1. This block grabs the parent workspace id and initializes a counter so that the module will know where it currently is when it iterates in block 2. It also determines the last string in the path so that block 2 knows when it is done iterating
  2. This block iterates through each string in the path to get the nodeId by it's name
    • It knows it is done when the lastNamePath is equal to its currentName
    • This "condition": "{{if(parameters.path !== '/', true, false)}}" will prevent it from running when there is no path entered so as to save an API call
  3. This block uses the pathId found in block 2 to update the node using PUT with the gathered name in the body

Mac Desktop Client

Mac Desktop Client

Mac Desktop Client

see README.md in source code

OCR

OCR

OCR Web Wrapper Image

To create the image of the web wrapper, you need to do 5 things:

  1. Spin up Windows Server base Image.
  2. Add IIS
  3. Ensure/Add .NET Framework extended/ ASP.NET  in Windows Features
  4. Install Visual C++ 2010, 2012, 2013, 2015/2022
  5. Copy publish folder of the OCR Web Wrapper project

PostgreSQL

PostgreSQL

PostgreSQL Information

**Note: If you don't have the Utopia solution cloned to your local machine, follow these instructions

Installation and Setup

Connecting to your Server

Creating your Database

Changing the postgres user's password

If you accidentally didn't set the postgres user's password to our standard pass@word1, then here are steps to help you fix it.

  1. Open Command Prompt and navigate to the PostgreSQL bin folder on your machine. Assuming you didn't change the default installation directory, the path should be C:\Program Files\PostgreSQL\13\bin
  2. Once there, you can use the psql command (another way to do this is to add that bin folder path to your environment PATH variable). Type the following command:
    psql -U postgres
  3. You will be asked for the current password of the pstgress user. Enter it to continue.
  4. Type alter user postgres with password 'pass@word1', and you can substitute pass@word1 with any password you happen to need.
  5. The command \q exits you back to the regular command line. Yay, your postgres user password will now be what you want!
PostgreSQL

Distribute Foreign Keys

When it's time to distribute the foreign keys in postgres:
select 'alter table '||quote_ident(ns.nspname)||'.'||quote_ident(tb.relname)||
' drop constraint '||quote_ident(conname)||';'||chr(10)||
'alter table '||quote_ident(ns.nspname)||'.'||quote_ident(tb.relname)||
' add constraint '||quote_ident(conname)||' '||
pg_get_constraintdef(c.oid, true)||';' as ddl
from pg_constraint c
join pg_class tb on tb.oid = c.conrelid
join pg_namespace ns on ns.oid = tb.relnamespace
where ns.nspname in ('public') --<<< adjust the schema name(s) here
and c.contype = 'f'; (edited)

Pulled from: https://dba.stackexchange.com/questions/125578/recreate-all-foreign-keys-in-all-tables-as-deferrable-batch 

PostgreSQL

Backup and Restore

See pgAdmin Backup and restore.pdf that Ty Toon created for RPC backups. Most of the steps should work for a local backup. See the differences below. The backup will be saved to the file path and name saved in the backup step.

The Key Difference:

Previewer

Previewer

Supported Previewer File Types

As of 5/31/2022 these are the supported Previewer file types. This list can be found in code in Utopia/wwwroot/Client/app/shared/sharedServices.js

"pdf",
"doc",
"dot",
"docx",
"docm",
"dotx",
"dotm",
"rtf",
"xls",
"xlt",
"xlsx",
"xlsm",
"xltx",
"xltm",
"ppt",
"pot",
"pps",
"pptx",
"pptm",
"potx",
"potm",
"ppsx",
"ppsm",
"odt",
"ott",
"fodt",
"ods",
"ots",
"fods",
"odp",
"otp",
"fodp",
"odf",
"odg",
"otg",
"fodg",
"dwg",
"dxf",
"dwf",
"dgn",
"html",
"htm",
"xhtml",
"xhtm",
"msg",
"eml",
"txt",
"csv",
"dcm",
"dicom",
"dcim",
"dicm",
"tif",
"tiff",
"jpg",
"jpeg",
"jp2",
"jpc",
"gif",
"png",
"psd",
"psb",
"bmp",
"dib",
"pct",
"pic",
"pict",
"wmf",
"emf",
"pcx",
"dcx",
"ras",
"pcd",
"tga",
"tpic",
"cal",
"cals",
"ico",
"cur",
"ncr",
"xwd",
"sgi",
"wbmp",
"sct",
"wpg",
"xbm",
"pbm",
"pgm",
"ppm",
"img",
"cut",
// Legacy support
"dbf",
"nef",
"svg",
"pdb",
"dif",
"pfb",
"xpm",
"fax",
"info",
"std",
"arw",
"sdc",
"sxw"

PreviewerX (Apryse)

All about PreviewerX

PreviewerX (Apryse)

PreviewerX Overview - Architecture, Building, Running, Deploying

Base Project Architecture

General Info

apryse-webviewer - Repos (azure.com)

Main branch - previewerX/8.12-Main - this is our main branch because we can't use the actual Main. This is because we originally forked off of the Apryse Gihub project and we need to preserve their branches so we can more easily pull updates in the future if needed.

After cloning, you'll need to make sure you've checked out the previewerX/8.12-Main branch, since the default master branch won't have the Revver-specific changes and you won't be able to get very far through this installation guide.

There's 3 main pieces to PreviewerX and depending on the work you're doing it may change which ones you'll be interacting with the most.

Demo Project - /Demo

This project is not deployed anywhere, it is simply an internal project to speed up testing so you don't have to constantly move files into Utopia/Atlantis in order to see your changes. One nice thing about this project is that you can make changes in the PreviewerX project and with a quick reload, you'll see those changes come through.

If you want to run the demo project pointed at your local files, please see Previewer Setup for Local Environment. However, if you're only making changes to the PreviewerX code and not any interactions specifically with Utopia, you can also point the URLs in the form to staging which are provided as the default values.

PreviewerX - /PreviewerX

This is the main project where we try to put the majority of our code. It provided a wrapper for the Apryse Previewer objects and it provides the interface that Utopia (and eventually Atlantis) will see when you integrate your changes into Utopia. 

ApryseUI - Root folder and /src

The other 2 projects are nested into this main project folder. This project is the UI code provided from Apryse and was originally forked from their repo in Github.

This is a dense project to initially dig into and we try to avoid making changes in this area, mostly because any changes we make in here will make it harder for us to stay up to date when Apryse releases new versions and will inevitably cause merge conflicts. The main reason you might find yourself making changes in here is because the internal state of the app is not visible or modifiable outside of their React app. Most of the time, that's okay, there's an interface to hook into the internal events, and that would be the preferable method. However, we've had to add a few modals directly into the previewer itself such as watermarks where we want to block interaction behind the scenes but need to provide a modal that's still within the bounds of the previewer itself.

Build and Run this bad boy

As mentioned there's 3 separate projects inside this repo, but we've added some convenience scripts to make building and launching as easy as possible.

We've all generally been using Node version 14+ and had no issues. If you have Node 11 (from the less cool and older previewer) it will cause issues during build time. You'll also need to have Python version 3.11 installed; if you have version 3.12 installed, you'll get lots of errors and you'll waste half your day troubleshooting and get super sad.

NOTE: All the following command and some more can be found in the root package.json file

  1. Open a terminal in the root folder
  2. npm run install-all
    • This will go into each project and run npm i for you
  3. npm run download-webviewer
    • This will install the correct version of the "Core" webviewer files, these are the super secret libraries that power the UI
    • You MUST do this before running the next command, the build command takes these files and puts them where the demo project needs them in order to properly run
  4. npm run build-all
  5. Congrats, everything should be built now! You have a couple options from here:
    1. To launch the demo project and test things out use npm run demo
    2. To build the standalone file that is transferred to Utopia use npm run build-standalone
      1. This will output a js file into the /PreviewerX/Standalone folder that can be copied over to the Utopia/wwwroot/scripts/previewer folder

PreviewerX (Apryse)

Running WebViewer Locally

Local Webviewer Server with Local Utopia

Preface

This guide is assuming you already have previewerX building and running. If you leave the Web Server Url and 'Connecting to local Utopia and Webviewer' checkbox unchecked, PreviewerX will run client side only and will only preview PDF files properly. This is fine for most use cases, but if you need to work with annotations, redactions, or any page manipulation functions you'll need the Webviewer Server running.

Instructions

  1. If you don't have it already, download and install Docker Desktop
  2. Download the docker-compose.yml file, preferably somewhere you can find it
  3. Open a command prompt in that folder and run: docker-compose up -d --force-recreate
    1.  This will take a few seconds to spin up the first time, you can test if it's up by going to http://localhost:8090/demo?s
  4. Navigate to the Utopia project (The main project, not the base repo) from the repo base
    1. Find the .vs/Utopia/config/applicationhost.config file and open in an editor like notepad++
    2. Find the <sites> section and the <site name="Utopia"> section inside of it
    3. Add the additional binding
      <binding protocol="https" bindingInformation="*:44334:host.docker.internal" />
      the full Utopia Site section should look similar to this:
            <site name="Utopia" id="2">
              <application path="/" applicationPool="Utopia AppPool">
                <virtualDirectory path="/" physicalPath="C:\src\Utopia\Utopia\Utopia" />
              </application>
              <bindings>
                <binding protocol="http" bindingInformation="*:57584:localhost" />
                <binding protocol="https" bindingInformation="*:44334:localhost" />
                <binding protocol="https" bindingInformation="*:44334:host.docker.internal" />
              </bindings>
            </site>


  5. You may need to restart Visual Studio if it was already running
  6. If you're testing in the PreviewerX Demo project, enter the following values into the form on the side:
    Base Url - https://localhost:44334
    Web Server Url - http://localhost:8090
    Check the box for 'Connecting to local Utopia and Webviewer' 
    (Make sure there isn't whitespace at the end of the URL, but that would never happen to you, right?)

Congrats! Everything should be working locally now!

Technical Details

To add technical details in case there's any issues later on.. under the hood we were having issues running locally be the webviewer running in docker couldn't make a call out to Localhost on the host machine, so it was impossible to load the file. Fortunately, docker desktop adds a host.docker.internal dns entry under the hood that allows docker containers to reach the host machine. I'll be honest, I'm not sure if it's mapped to the loopback on the host somehow, or if it's the local IP. I assume the local IP. To get everything running locally, we're simply overriding the base URL of the loadDocument call to use the host.docker.internal address. However, that means we also need to add that as a viable binding in IISExpress, so we modify the binding in the applicationhost.config file. I'm looking to see if there's a way to just add this by default to Utopia, but for now, hopefully this isn't too painful.

Problems and Solutions

Sometimes Docker gets confuse and you get a "Error: (HTTP code 500) server error - Ports are not available: exposing port TCP 0.0.0.0:60001 -> 0.0.0.0:0: listen tcp 0.0.0.0:60001: bind: An attempt was made to access a socket in a way forbidden by its access permissions." from the loadbalancer docker image. Usually you'll notice this because previewerX can't connect to localhost:8090 even though everything is running. When this happens try this:

  1. Stop the Apryse Docker images
  2. Open an admin/elevated command prompt and run:
    net stop winnat
  3. Restart the docker images or re-run docker-compose up -d --force-recreate from the folder with the docker-compose.yml file
  4. Once everything is green, go back to the command prompt and run:
    net start winnat

RPC

RPC

Control Center Design

URL to Powerpoint: https://1drv.ms/p/s!AgkwKyXrWS3Xhg0oRDG4giTo7jw3?e=8oA7mO 

Slide1.jpgSlide2.jpgSlide3.jpgSlide4.jpgSlide5.jpgSlide6.jpgSlide7.jpgSlide8.jpgSlide9.jpgSlide10.jpgSlide11.jpg

RPC

On Premise Design Plan - 2019

Server Application Update and Versioning - DSR
· There should be notifications when the update is available
· Online
o BatchWorker checks for the new version in the shared location and in the network
o BatchWorker downloads a package and stores it in the folder for the updates
§ File storage should be used for storing updates because it is shared between the components
o User should confirm the update
o Marks the DB that the Update is available  and confirmed (BatchWorker)
§ the user should confirm the update start
o Each component will shut itself down and reinstall itself (including the CM)
o Once the update process is done the health status should be updated
o Alternatively, the admin console should trigger the update.
· Offline
o The update is downloaded manually
o The user puts the installer into the downloads folder
o The Admin Console accepts the update package and stores it
o ... the same as the online version
· Rollback
o There should be a history of updates and ability to go to any of it
o For now - manual process
· Downloads and puts into the permanent storage
· Indicate that the update is available.
· Each component will update itself on its own (maybe)
· Health dashboard is required
· Shared Updates location (centralized)
o Each component will have its own access to the centralized storage
· Getting older versions in the new installation - is it possible?
o New users should get the latest version for the 1st installation
o After the 1st installation we should store the installation package in the storage.
o Will require the support managers training
· Currently the Admin Console worker is supposed to be the updater  but it conflicts with the admin console role. Can we move the Call Home and update functionality to Admin Console
o The Batch Worker downloads the files and mars the DB as ready for update
§ The BW will delete all intermediate updates so the user will not be able to install them. User will be able to install the newest version only.
o Admin Console will control the installation
· Will the updates be located in the central storage or on each machine separately (it will have to download them somehow)?
o All updates should be in the file storage which is accessible for all components
o We don't have to encrypt the updates files
o The key is stored in each component configuration string (please see above)
 
Database Update and Versioning
· Nice to have option: install the SQL express for the user and start it
· Change the Utopia to use migrations and code first at some point
o We will use code first and migrations.

------ Old Notes ------

Researches to be done:
· Research for feasibility: - done
o drag out event from the browser control (including Outlook)
o Important to have
· Research for options (BE):
o Install Shield installer and updater for Desktop when the pipe is small
· Research for solution of changing IP address (BE): 
o Self-hosted ClickOnce installer and updater that checks for updates manually and provides a link to download
· Research if Mac updates the applications of the same name and different versions, especially, for non-store apps
· Research: can we implement Drag and Drop for the Windows taskbar icons (it works in Mac) - lowest priority
· Research: running indexer ( ElasticSearch ) on a  laptop and its memory consumption
o Possibly it can be excluded for small accounts
· SQL Server Express: can we include it into the installation package?
· Multi-instance data migration for Desktop: migration and integration.
o Only for Casselle, possibly they will go to Cloud
· Research the encryption so that we can use the main key and recovery keys
· Proof of concept: self-updating service that starts the installer and then itself
· Research: if dotless can be used in the desktop version
 
 
Client UI
· Will be available for Mac (phase 2) and Windows (phase 1)
· Keep the existing functionality to support d&d, printing, scanning, watch folder, office addins, managing check-in/out
· Change the UI to Web completely (except settings and Addins UI)
o There is no big value in changing the Settings and Addins UI to Web
o The Store Window can be a value for attracting clients to the Utopia and change the name of scanned files
§ Should be enabled by a user setting
o Store dialog design is required
· Discussed Items:
o Switching modes: A button on the top of the form that hides everything and shows the browser window
o Implement dragging files on the SideKick taskbar icon so that we can avoid showing the Orb - (not many windows users use it) ?
o Remember the last selected mode: Maximized and Minimized
o Authentication:
§ Reuse the authentication screen from the SideKick
§ Do not use the Web Auth screen
§ Change the browser to refresh the authentication using the refresh tocken
§ Track the url or JS event for logging out - display the sign in screen from the SideKick
§ The SideKick sign in UI has a server name/IP address selector
§ There should be a mode selector for full-sized mode and limited mode. Prompt can be here as well.
o Disconnected mode for the web and limited view
o The front end side will be done by the EFC team
o For the future: Move the settings, addons etc. to the web part
o Configuration
§ Should include the OCR running schedule (currently it does not support the schedules) - admin console
§  
 
Server Side
· Servers discoverability of the desktop can be postponed for phase 2
· Integration implementation (store dialog and population) - phase 2
· Requirements
o The Desktop 2.0 should be able to handle up to 1000 users
§ The requirement is fulfilled
o We don't need to care about the Load Balancing (it will be done by customers)
o We need to make sure the system components will be configurable and will be able to handle load balancers configuration
o Installation must consider that different components can be installed on different machines
§ Current Desktop configuration is 2-3 different machines: OCR, Server Services + Indexing service
o Instructions documentation should be provided
§ Should include the list of load balancers that will work
· Scaled components:
o Database
o Application server
o Batch Worker can be included into the installer
o Index server (ElasticSearch)
o OCR server
o Image server
o Admin Console (native or web-hosted)
· Non-functional requirements:
o Indexer limitation for memory consumption (to be defined)
o OCR server limitation for threads number, CPU usage
o Must be able to work offline completely
· Discussion
o Switching to self-hosted Web API
o OCR should be the separate installer because many of the customers will not have it
o Must work offline (including the licensing)
o There should be a provider that works on the local file system
§ The files should be encrypted individually
§ It should not take long
§ There should be a way to avoid windows file system number of files limitation
§ There will be no ability to map different locations for file storage
o Backdoor: need a research encryption best practices to have several keys that can unlock. 
 
Licensing:
· Batch worker will need to call home periodically for the account updates (contains features and keys that will expire)
· Batch Worker will be a kind of the licensing server
· Batch Worker should be able to update itself
· The user should be able to update the application package by downloading it and applying.
· Application package can be downloaded independently from the update package
· The Account package will be provided annually
· Obfuscation is required
 
Installation and configuration
Requirements
· Installer should have a link to SQL Express.
· Updates should be optional. The update package should be downloaded for the account and should be downloadable separatelly.
· Will need an installation wizard
· We will need a configuration wizard that can be reused to set/edit configuration
· Dashboard (admin console) should be combined with the installation wizard
· Admin console should be a prerequisite for the installer in order to avoid multiple Admin Consoles installations.
· Will need to have several installation options
o Typical
§ Should be a single machine, should work on laptops and should be as simple as possible
§ Will still include the Admin console full functionality
o Custom
· We need an MSI for each individual component and all inclusive MSI that includes all individual components MSIs
· User is able to install the components without signing in and licensing
o Obfuscation is nice to have, can be phase 2
· Will need to provide ability to update the server when it is offline
o Using the installer
o Should prevent a component from running if it is not up to date
§ Can be done by a component
§ Will be done throug a heartbeat table for each component
§ The version should be tracked by the admin console
· Backup - ask JR and Jesse about it
o Should be done before each update
o Should have its own folder to store data
o Should not include the files
Admin Console
· Requirements
o Should include the admin email setup for notifications
o If the BatchWorker is not able to phone home then the user should be able to provide an account data package and the account data hash
o The user will be able to download the account data package from the EFC server
o Remote configuration
§ Provide the configuration string for a remote machine. Remote machine config wizard will be able to accept the string and configure the services by it.
§ Can be used in the installer as well
§ Updating configuration is a challenge: the user needs to know that each component configuration should be updated
§ If the component starts and there is no configuration it should start a configuration manager (if possible for a component)
o Includes the UI to check health and configure
o Each Utopia configuration item should be configurable except the SecureDrawer
§ Please see the UtopiaConfiguration class for details
o We can allow them to enter their own encryption string
§ In this case, there will be no way to restore if the key is lost
§ Generate a key for them
§ generate recovery keys for them (like 2FA in GitHub)
§ We need to have 2 options for encryptions keys: auto generated and provided manually
o It should be a separate component that can be installed on a different machine
o Should provide access to the older installers in case of the version downgrade
§ Sometimes customers downgrade but more often they just need an older version of a particular component
o If the service is not able to phone home it looks at the installation packages and sends an email to the admin about the account data packages expiration
o Should show all the components and their versions
o Running status of the components
§ Will work through the DB
o Will need to add some checks for cheating
 
Client application update
· We might switch the application to use the same installer (Install Shield or ClickOnce or anything else). It depends on the installers research.
· Current (ClickOnce)
o Locally hosted ClickOnce application (on the server which will get the updated ClickOnce installer once it is updated by itself)
o The challenge is to switch the client from Cloud to local server
 
 
Server Application Update and Versioning
· There should be notifications when the update is available
· Online
o BatchWorker checks for the new version in the shared location and in the network
o BatchWorker downloads a package and stores it in the folder for the updates
§ File storage should be used for storing updates because it is shared between the components
o User should confirm the update
o Marks the DB that the Update is available  and confirmed (BatchWorker)
§ the user should confirm the update start
o Each component will shut itself down and reinstall itself (including the CM)
o Once the update process is done the health status should be updated
o Alternatively, the admin console should trigger the update.
· Offline
o The update is downloaded manually
o The user puts the installer into the downloads folder
o The Admin Console accepts the update package and stores it
o ... the same as the online version
· Rollback
o There should be a history of updates and ability to go to any of it
o For now - manual process
· Downloads and puts into the permanent storage
· Indicate that the update is available.
· Each component will update itself on its own (maybe)
· Health dashboard is required
· Shared Updates location (centralized)
o Each component will have its own access to the centralized storage
· Getting older versions in the new installation - is it possible?
o New users should get the latest version for the 1st installation
o After the 1st installation we should store the installation package in the storage.
o Will require the support managers training
· Currently the Admin Console worker is supposed to be the updater  but it conflicts with the admin console role. Can we move the Call Home and update functionality to Admin Console
o The Batch Worker downloads the files and mars the DB as ready for update
§ The BW will delete all intermediate updates so the user will not be able to install them. User will be able to install the newest version only.
o Admin Console will control the installation
· Will the updates be located in the central storage or on each machine separately (it will have to download them somehow)?
o All updates should be in the file storage which is accessible for all components
o We don't have to encrypt the updates files
o The key is stored in each component configuration string
 
 
Database Update and Versioning
· Nice to have option: install the SQL express for the user and start it
· Change the Utopia to use migrations and code first at some point?
o We will use code first and migrations. DSR will work on WBS and estimate
o The available team can start working on it (possibly, DSR, after the Pandora and Pangea)
o We will need a training after it is done (if DSR does it)

RPC

Global Relay

PXL_20210928_194928751 (1).jpg20210812_163746.jpg

RPC

Common RPC Errors

Error: Maximum number of retries (2) exceeded while executing database operations with 'UtopiaExecutionStrategy'. See inner exception for the most recent failure. The underlying provider failed on Open. 53300: sorry, too many clients already

Solution: By default the number of connections that a postgresql db can have is 100 and they are hitting that thresh hold. Increasing the max number of connections allowed should resolve this. this article details how to do this.

Other Details: We've seen this happen when using Pangea to export from RPC to windows.

-----------------------------------------------------------------------------------------------------------------------------------------------

Rubex Reports

Rubex Reports

Rubex Reports slick, resources, and videos

CSM Training: https://drive.google.com/file/d/1FyJ0ghFSmBlU3gU_OIj-MBow3lixIBco/view?usp=sharing 
Quick Tutorial: https://drive.google.com/file/d/1bmNXgrMi8fxXPO6MSfvA0g51XsIflqc6/view?usp=sharing
Customer Facing Guide: https://vimeo.com/686033213/2dae251ffa 
User Guide: https://efilecabinethelp.zendesk.com/hc/en-us/articles/7736949209876-Rubex-Reports-Getting-Started-User-Guide-
Blog Post: https://www.efilecabinet.com/rubex-reports/ 

Scripts

Scripts

Purged Account Migration From Backup Script

-- to install extension
CREATE EXTENSION postgres_fdw;

-- you need to create a reference to the backup server
CREATE SERVER backup_prod_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'hostAddressHere', port '5432', dbname 'postgres');

-- you need to define the user credentials to access the backup db
CREATE USER MAPPING FOR currentDbUserNameHere
SERVER staging
OPTIONS (user 'usernameHere', password 'passwordHere');

-- and you need to define a reference to the external db schema(s) (you actually need to create a schema named backup_prod_db_public)
IMPORT FOREIGN SCHEMA public
FROM SERVER backup_prod_server
INTO backup_prod_db_public;

-- and you need to define a reference to the external db schema(s) (you actually need to create a schema named backup_prod_db_workflow)
IMPORT FOREIGN SCHEMA workflow
FROM SERVER backup_prod_server
INTO backup_prod_db_workflow;

INSERT INTO public."DbBrandings"
SELECT * FROM backup_prod_db_public."DbBrandings" where "Id" IN (SELECT "BrandingID" FROM backup_prod_db_public."DbAccounts" WHERE "Id" = {ACCOUNT_ID});

INSERT INTO public."DbAccounts"
SELECT * FROM backup_prod_db_public."DbAccounts" where "Id" = {ACCOUNT_ID};

INSERT INTO public."DbSamlConfigurations"
SELECT * FROM backup_prod_db_public."DbSamlConfigurations" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSamlRoleAuthentications"
SELECT * FROM backup_prod_db_public."DbSamlRoleAuthentications" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSamlResponses"
SELECT * FROM backup_prod_db_public."DbSamlResponses" where "AccountID" = {ACCOUNT_ID};

CREATE TEMP TABLE Temp_Email_Settings_Ids(Id integer);
INSERT INTO Temp_Email_Settings_Ids
SELECT "EmailSettingsID" from backup_prod_db_public."DbEmailSettingToAccounts" where "AccountID" = {ACCOUNT_ID};
INSERT INTO public."DbEmailSettings"
SELECT * FROM backup_prod_db_public."DbEmailSettings" where "Id" IN (SELECT "Id" FROM Temp_Email_Settings_Ids);

INSERT INTO public."DbEmailSettingToAccounts"
SELECT * FROM backup_prod_db_public."DbEmailSettingToAccounts" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbProfileItemHiddenCharacterConfigurations"
SELECT * FROM backup_prod_db_public."DbProfileItemHiddenCharacterConfigurations" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbProfileItemHiddenCharacterRanges"
SELECT * FROM backup_prod_db_public."DbProfileItemHiddenCharacterRanges" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbProfileItems"
SELECT * FROM backup_prod_db_public."DbProfileItems" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbProfiles"
SELECT * FROM backup_prod_db_public."DbProfiles" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbPresetValues"
SELECT * FROM backup_prod_db_public."DbPresetValues" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbProfileToProfileItems"
SELECT * FROM backup_prod_db_public."DbProfileToProfileItems" where "ProfileID" in (select "Id" from backup_prod_db_public."DbProfiles" where "AccountID" = {ACCOUNT_ID});

INSERT INTO public."DbFormFillDefinitions"
SELECT * FROM backup_prod_db_public."DbFormFillDefinitions" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbFormFillToProfileItems"
SELECT * FROM backup_prod_db_public."DbFormFillToProfileItems" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbFormFillPendings"
SELECT * FROM backup_prod_db_public."DbFormFillPendings" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSecurityPolicies"
SELECT * FROM backup_prod_db_public."DbSecurityPolicies" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSecurityPolicyIpAddresses"
SELECT * FROM backup_prod_db_public."DbSecurityPolicyIpAddresses" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSecurityPolicyLoginTimes"
SELECT * FROM backup_prod_db_public."DbSecurityPolicyLoginTimes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSystemPermissions"
SELECT * FROM backup_prod_db_public."DbSystemPermissions" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbRoles"
SELECT * FROM backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbRoleToAccountFeatures"
SELECT * FROM backup_prod_db_public."DbRoleToAccountFeatures" where "RoleID" in (select "Id" from backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID});

INSERT INTO public."DbUserRolePreferences"
SELECT * FROM backup_prod_db_public."DbUserRolePreferences" where "RoleID" in (select "Id" from backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID});

INSERT INTO public."DbUserSessions"
SELECT * FROM backup_prod_db_public."DbUserSessions" where "RoleID" in (select "Id" from backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID});

INSERT INTO public."DbUserSessionToDbRoles"
SELECT * FROM backup_prod_db_public."DbUserSessionToDbRoles" where "UserSessionID" in (select "Id" from "DbUserSessions" where backup_prod_db_public."RoleID" in (select "Id" from "DbRoles" where "AccountID" = {ACCOUNT_ID}));

INSERT INTO public."DbUserSessionToDbRoles"
SELECT * FROM backup_prod_db_public."DbUserSessionToDbRoles" where "RoleID" in (select "Id" from backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID});

INSERT INTO public."DbProfileValueRoles"
SELECT * FROM backup_prod_db_public."DbProfileValueRoles" where "RoleID" in (select "Id" from backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID});

INSERT INTO public."DbRoleRelationships"
SELECT * FROM backup_prod_db_public."DbRoleRelationships" where "ParentRoleID" in (select "Id" from backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID});

DELETE FROM public."DbRoleClosures" where "ParentID" in (select "Id" from backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID});
INSERT INTO public."DbRoleClosures"
SELECT * FROM backup_prod_db_public."DbRoleClosures" where "ParentID" in (select "Id" from backup_prod_db_public."DbRoles" where "AccountID" = {ACCOUNT_ID});

INSERT INTO public."DbNotifications"
SELECT * FROM backup_prod_db_public."DbNotifications" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbWorkflowStageInstanceToNotifications"
SELECT * FROM backup_prod_db_public."DbWorkflowStageInstanceToNotifications" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAccountSettings"
SELECT * FROM backup_prod_db_public."DbAccountSettings" where "AccountID" = {ACCOUNT_ID};

CREATE TEMP TABLE Temp_Active_File_Infoes(NodeID bigint, FileInfoID bigint);
INSERT INTO Temp_Active_File_Infoes (nodeid, fileinfoid)
SELECT "Id", "FileInfoID" from backup_prod_db_public."DbNodes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbNodes" ("Id", "AccountID", "CreatedByUserID", "ParentID", "Name", "SystemType", "FileInfoID", "ProfileID", "CreatedOn", "ModifiedOn", "DeletedOn", "PurgedOn")
SELECT backup_prod_db_public."DbNodes"."Id", backup_prod_db_public."DbNodes"."AccountID", backup_prod_db_public."DbNodes"."CreatedByUserID", backup_prod_db_public."DbNodes"."ParentID", backup_prod_db_public."DbNodes"."Name", backup_prod_db_public."DbNodes"."SystemType", NULL, backup_prod_db_public."DbNodes"."ProfileID", backup_prod_db_public."DbNodes"."CreatedOn", backup_prod_db_public."DbNodes"."ModifiedOn", backup_prod_db_public."DbNodes"."DeletedOn", backup_prod_db_public."DbNodes"."PurgedOn"
FROM backup_prod_db_public."DbNodes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbNodeComments"
SELECT * FROM backup_prod_db_public."DbNodeComments" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbFileInfoes"
SELECT * FROM backup_prod_db_public."DbFileInfoes" where "AccountID" = {ACCOUNT_ID};

UPDATE public."DbNodes"
SET "FileInfoID" = Temp_Active_File_Infoes.fileinfoid
FROM Temp_Active_File_Infoes
WHERE public."DbNodes"."Id" = Temp_Active_File_Infoes.nodeid;

INSERT INTO public."DbNodeToFileInfoes"
SELECT * FROM backup_prod_db_public."DbNodeToFileInfoes" where "AccountID" = {ACCOUNT_ID};

DELETE FROM public."DbNodeClosures" WHERE "AccountID" = {ACCOUNT_ID};
INSERT INTO public."DbNodeClosures" ("ParentID", "ChildID", "Depth", "AccountID")
SELECT backup_prod_db_public."DbNodeClosures"."ParentID", backup_prod_db_public."DbNodeClosures"."ChildID", backup_prod_db_public."DbNodeClosures"."Depth", backup_prod_db_public."DbNodeClosures"."AccountID"
FROM backup_prod_db_public."DbNodeClosures" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbEmailQueueAttachmentNodes"
SELECT * FROM backup_prod_db_public."DbEmailQueueAttachmentNodes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbPortfolioToNodes"
SELECT * FROM backup_prod_db_public."DbPortfolioToNodes"
where "AddedByUserID" IN (select "UserID" from backup_prod_db_public."DbRoles" where backup_prod_db_public."DbRoles"."AccountID" = {ACCOUNT_ID} and backup_prod_db_public."DbRoles"."UserID" is not null)
and isnumeric(backup_prod_db_public."DbPortfolioToNodes"."NodeID")
and EXISTS (SELECT * FROM backup_prod_db_public."DbNodes" WHERE "Id" = CAST(backup_prod_db_public."DbPortfolioToNodes"."NodeID" as bigint) AND "AccountID" = {ACCOUNT_ID});

INSERT INTO public."DbTemplateNodeChangeLogs"
SELECT * FROM backup_prod_db_public."DbTemplateNodeChangeLogs" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbESignatureTransactions"
SELECT * FROM backup_prod_db_public."DbESignatureTransactions" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbESignatureNodeAssociations"
SELECT * FROM backup_prod_db_public."DbESignatureNodeAssociations" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbESignatureSigners"
SELECT * FROM backup_prod_db_public."DbESignatureSigners" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbRetentionChangeReason"
SELECT * FROM backup_prod_db_public."DbRetentionChangeReason" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbRightSignatureDocuments"
SELECT * FROM backup_prod_db_public."DbRightSignatureDocuments" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbNodeAnnotations"
SELECT * FROM backup_prod_db_public."DbNodeAnnotations" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbUserImageStamps"
SELECT * FROM backup_prod_db_public."DbUserImageStamps" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbDocumentRequests"
SELECT * FROM backup_prod_db_public."DbDocumentRequests" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbDocumentRequestToNotifications"
SELECT * FROM backup_prod_db_public."DbDocumentRequestToNotifications" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbDocumentRequestRoles"
SELECT * FROM backup_prod_db_public."DbDocumentRequestRoles" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbDocumentRequestContainers"
SELECT * FROM backup_prod_db_public."DbDocumentRequestContainers" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbDocumentRequestAttachments"
SELECT * FROM backup_prod_db_public."DbDocumentRequestAttachments" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbDocumentRequestContainerNodes"
SELECT * FROM backup_prod_db_public."DbDocumentRequestContainerNodes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbFileQueue"
SELECT * FROM backup_prod_db_public."DbFileQueue" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbNodeShares"
SELECT * FROM backup_prod_db_public."DbNodeShares" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbProfileValueNodes"
SELECT * FROM backup_prod_db_public."DbProfileValueNodes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbPermissions"
SELECT * FROM backup_prod_db_public."DbPermissions" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbLegacyNodeMappings"
SELECT * FROM backup_prod_db_public."DbLegacyNodeMappings" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTriggerMessageContent"
SELECT * FROM backup_prod_db_public."DbTriggerMessageContent" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTriggers"
SELECT * FROM backup_prod_db_public."DbTriggers" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTriggerToSearchCriteria"
SELECT * FROM backup_prod_db_public."DbTriggerToSearchCriteria" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTriggerToApiCallouts"
SELECT * FROM backup_prod_db_public."DbTriggerToApiCallouts" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTriggerInfoNodes"
SELECT * FROM backup_prod_db_public."DbTriggerInfoNodes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTriggerToNode"
SELECT * FROM backup_prod_db_public."DbTriggerToNode" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTriggerToRoles"
SELECT * FROM backup_prod_db_public."DbTriggerToRoles" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTriggerToWorkflow"
SELECT * FROM backup_prod_db_public."DbTriggerToWorkflow" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbTimeTriggers"
SELECT * FROM backup_prod_db_public."DbTimeTriggers" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbEventTriggers"
SELECT * FROM backup_prod_db_public."DbEventTriggers" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbEmailImportMappings"
SELECT * FROM backup_prod_db_public."DbEmailImportMappings" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbEmailQueue"
SELECT * FROM backup_prod_db_public."DbEmailQueue" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbEmailRecipients"
SELECT * FROM backup_prod_db_public."DbEmailRecipients" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbEmailQueueAttachmentNodes"
SELECT * FROM backup_prod_db_public."DbEmailQueueAttachmentNodes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAuditLogs"
SELECT * FROM backup_prod_db_public."DbAuditLogs" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAuditLogsToRoles"
SELECT * FROM backup_prod_db_public."DbAuditLogsToRoles" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAuditLogsToRoleDetails"
SELECT * FROM backup_prod_db_public."DbAuditLogsToRoleDetails" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAuditLogsToNodes"
SELECT * FROM backup_prod_db_public."DbAuditLogsToNodes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAuditLogsToNodeDetails"
SELECT * FROM backup_prod_db_public."DbAuditLogsToNodeDetails" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAccessLinks"
SELECT * FROM backup_prod_db_public."DbAccessLinks" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAccessLinksToDocumentRequests"
SELECT * FROM backup_prod_db_public."DbAccessLinksToDocumentRequests" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAccessLinksToNodeAndTriggers"
SELECT * FROM backup_prod_db_public."DbAccessLinksToNodeAndTriggers" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAccountFeatureUsages"
SELECT * FROM backup_prod_db_public."DbAccountFeatureUsages" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbAccountFeatures"
SELECT * FROM backup_prod_db_public."DbAccountFeatures" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbCheckoutInfoes"
SELECT * FROM backup_prod_db_public."DbCheckoutInfoes" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSfMappingDestinations"
SELECT * FROM backup_prod_db_public."DbSfMappingDestinations" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSfMappings"
SELECT * FROM backup_prod_db_public."DbSfMappings" where "AccountID" = {ACCOUNT_ID};

INSERT INTO public."DbSfLinks"
SELECT * FROM backup_prod_db_public."DbSfLinks" where "AccountID" = {ACCOUNT_ID};

-- WORKFLOW TABLES

INSERT INTO workflow."DbWorkflows"
SELECT * FROM backup_prod_db_workflow."DbWorkflows" where "AccountId" = {ACCOUNT_ID};

INSERT INTO workflow."DbWorkflowAssets"
SELECT * FROM backup_prod_db_workflow."DbWorkflowAssets" where "WorkflowID" IN (SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowStages"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStages" where "WorkflowID" IN (SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowsAvailableStates"
SELECT * FROM backup_prod_db_workflow."DbWorkflowsAvailableStates" where "WorkflowID" IN (SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

CREATE TEMP TABLE Temp_Current_Workflow_Stages(WorkflowInstanceID bigint, WorkflowStageInstanceID bigint);
INSERT INTO Temp_Current_Workflow_Stages (workflowinstanceid, workflowstageinstanceid)
SELECT "Id", "CurrentStageID" from backup_prod_db_workflow."DbWorkflowInstances" where "WorkflowID" IN (SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowInstances" ("Id", "Name", "Description", "IsActive", "StateID", "WorkflowID", "OwnerID", "CreatedDate", "LastModifiedDate", "CurrentStageID")
SELECT "Id", "Name", "Description", "IsActive", "StateID", "WorkflowID", "OwnerID", "CreatedDate", "LastModifiedDate", NULL
FROM backup_prod_db_workflow."DbWorkflowInstances" where "WorkflowID" IN (SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowStageInstances"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStageInstances" where "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

UPDATE workflow."DbWorkflowInstances"
SET "CurrentStageID" = Temp_Current_Workflow_Stages.workflowstageinstanceid
FROM Temp_Current_Workflow_Stages
WHERE workflow."DbWorkflowInstances"."Id" = Temp_Current_Workflow_Stages.workflowinstanceid;

INSERT INTO workflow."DbAssetNodeReference"
SELECT * FROM backup_prod_db_workflow."DbAssetNodeReference" where "AssetID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowAssets" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbWorkflowAssetsStages"
SELECT * FROM backup_prod_db_workflow."DbWorkflowAssetsStages" where "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbWorkflowAssetInstances"
SELECT * FROM backup_prod_db_workflow."DbWorkflowAssetInstances" where "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbAssetInstanceNodeReferences"
SELECT * FROM backup_prod_db_workflow."DbAssetInstanceNodeReferences" where "AssetInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowAssetInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbProfileRoutingRules"
SELECT * FROM backup_prod_db_workflow."DbProfileRoutingRules" where "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbWorkflowSteps"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSteps" where "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbStageApproveResults"
SELECT * FROM backup_prod_db_workflow."DbStageApproveResults" where "StageInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowAssetsStagesInstances"
SELECT * FROM backup_prod_db_workflow."DbWorkflowAssetsStagesInstances" where "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowStepInstances"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepInstances" where "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowSetProfileInstanceItems"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSetProfileInstanceItems" where "StepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowSetProfileInstanceItemPresetValues"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSetProfileInstanceItemPresetValues" where "StepProfileItemID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSetProfileInstanceItems" WHERE "StepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})))));

INSERT INTO workflow."DbWorkflowSendMessageInstanceRecipients"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSendMessageInstanceRecipients" where "StepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowStepInstanceEmailUserGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepInstanceEmailUserGroups" where "WorkflowAddTriggerStepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowStepInstanceEmailUsers"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepInstanceEmailUsers" where "WorkflowAddTriggerStepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowRequestFileExternalStepInstanceNewUserReferences"
SELECT * FROM backup_prod_db_workflow."DbWorkflowRequestFileExternalStepInstanceNewUserReferences" where "StepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowRequestFileExternalStepInstanceRecipientGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowRequestFileExternalStepInstanceRecipientGroups" where "WorkflowStepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowRequestFileExternalStepInstanceRecipients"
SELECT * FROM backup_prod_db_workflow."DbWorkflowRequestFileExternalStepInstanceRecipients" where "WorkflowStepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowStepInstanceDocumentRequestContainers"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepInstanceDocumentRequestContainers" where "StepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowStepInstanceUserReferences"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepInstanceUserReferences" where "StepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowStepInstanceGroupReferences"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepInstanceGroupReferences" where "StepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowShareStepInstanceNewUserReferences"
SELECT * FROM backup_prod_db_workflow."DbWorkflowShareStepInstanceNewUserReferences" where "StepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowStepInstanceUsers"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepInstanceUsers" where "WorkflowSetPermissionsStepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowStepInstanceUserGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepInstanceUserGroups" where "WorkflowSetPermissionsStepInstanceID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStepInstances" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStageInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowInstances" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowInstanceHistoryRecords"
SELECT * FROM backup_prod_db_workflow."DbWorkflowInstanceHistoryRecords" where "WorkflowID" IN (SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowSetProfileItems"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSetProfileItems" where "StepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowSetProfileItemPresetValues"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSetProfileItemPresetValues" where "StepProfileItemID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSetProfileItems" WHERE "StepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}))));

INSERT INTO workflow."DbWorkflowSendMessageRecipients"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSendMessageRecipients" where "StepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowAddTriggerStepEmailUserGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowAddTriggerStepEmailUserGroups" where "WorkflowStepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowAddTriggerStepEmailUsers"
SELECT * FROM backup_prod_db_workflow."DbWorkflowAddTriggerStepEmailUsers" where "WorkflowStepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowRequestFileExternalStepNewUserReferences"
SELECT * FROM backup_prod_db_workflow."DbWorkflowRequestFileExternalStepNewUserReferences" where "StepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowRequestFileExternalStepRecipientGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowRequestFileExternalStepRecipientGroups" where "WorkflowStepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowRequestFileExternalStepRecipients"
SELECT * FROM backup_prod_db_workflow."DbWorkflowRequestFileExternalStepRecipients" where "WorkflowStepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowStepDocumentRequestContainers"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepDocumentRequestContainers" where "StepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowShareStepNewUserReferences"
SELECT * FROM backup_prod_db_workflow."DbWorkflowShareStepNewUserReferences" where "StepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowStepUserReferences"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepUserReferences" where "StepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowStepGroupReferences"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStepGroupReferences" where "StepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowSetPermissionsStepUsers"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSetPermissionsStepUsers" where "WorkflowStepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowSetPermissionsStepUserGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowSetPermissionsStepUserGroups" where "WorkflowStepID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowSteps" WHERE "StageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID})));

INSERT INTO workflow."DbWorkflowStageAssigneeGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStageAssigneeGroups" where "WorkflowStageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbWorkflowStageAssignees"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStageAssignees" where "WorkflowStageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbWorkflowStageApproverGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStageApproverGroups" where "WorkflowStageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbWorkflowStageApprovers"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStageApprovers" where "WorkflowStageID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflowStages" WHERE "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID}));

INSERT INTO workflow."DbWorkflowStarterGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStarterGroups" where "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowStarters"
SELECT * FROM backup_prod_db_workflow."DbWorkflowStarters" where "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowOwnerGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowOwnerGroups" where "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowOwners"
SELECT * FROM backup_prod_db_workflow."DbWorkflowOwners" where "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowWatcherGroups"
SELECT * FROM backup_prod_db_workflow."DbWorkflowWatcherGroups" where "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowWatchers"
SELECT * FROM backup_prod_db_workflow."DbWorkflowWatchers" where "WorkflowID" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowScheduleConfigurations"
SELECT * FROM backup_prod_db_workflow."DbWorkflowScheduleConfigurations" where "Id" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowNotificationConfigurations"
SELECT * FROM backup_prod_db_workflow."DbWorkflowNotificationConfigurations" where "Id" IN
(SELECT "Id" FROM backup_prod_db_workflow."DbWorkflows" WHERE "AccountId" = {ACCOUNT_ID});

INSERT INTO workflow."DbWorkflowJobsQueue"
SELECT * FROM backup_prod_db_workflow."DbWorkflowJobsQueue" where "AccountId" = {ACCOUNT_ID};

INSERT INTO workflow."DbWorkflowAccountEmailConfig"
SELECT * FROM backup_prod_db_workflow."DbWorkflowAccountEmailConfig" where "AccountId" = {ACCOUNT_ID};

Setup and Configurations

Setup and Configurations

Connecting to UtopiaNuget

First connect to feed by pressing the Connect to Feed button at the top. Click on the Visual Studio option. Follow steps.

(Once you've created the Nuget Package Source, try to build the project and see if it succeeds before moving trying the below stuff)

Once connected to feed then go ahead an find the nuget that is needed and click on it. Then copy the nuget command and go into visual studio and go to Tools-Nuget Package Manager-Package Manager Console. Then paste the nuget command into the console and run.

If issue of 401 comes up use link to resolve: https://blog.rsuter.com/how-to-use-a-private-vsts-nuget-package-feed-with-the-net-core-cli/#:~:text=If you have a.NET Core project which references,status code does not indicate success%3A 401 (Unauthorized) .


UtopiaNuget on Mac

If you're doing this on mac (sorry), then the process is slightly different.  See this other wiki page.

Setup and Configurations

Steps to setup pg_partman

Steps to setup partman

** Make sure you don't have the postgres service running on windows **

Use WSL Ubuntu :

Install postgresql on ubuntu:

Login and setup postgres and postgres user:

  1. Run the psql command from the postgres user account
    • sudo -u postgres psql postgres
  2. Set the password
    • \password postgres
  3. Enter a new password (pass@word1)
  4. Close psql
    • \q

Run the following commands:

`sudo apt install make`
`sudo apt install gcc`
`sudo apt install postgresql-server-dev-13` (if the version ever changes, change that number at the end)

Setting up partman:

Commands that may come in handy:

`sudo service postgresql start` (starts postgres service)
`sudo service postgresql restart` (restarts postgres service)
`sudo service postgresql stop` (stops postgres service)
`explorer.exe .` ( Use this if you fancy an explorer view instead of a terminal one.  Also allows you to edit the files without using vim)

To get PgAdmin working:

Inside of the pg_hba.conf file, change the local connection to
	`host    all             all             0.0.0.0/0            md5`
Inside of postgres.conf change listen_addresses under CONNECTIONS AND AUTHENTICATION to 
	`listen_addresses = '*'`

Example docs to get partman setup:


Additional Info

https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md 

Partition types that pg_partman supports


Peformance with 1 billion entries

Saved in the SPIKE:

Setup and Configurations

How to run and Release Mobile

Debugging the iOS app:

  1. Set efcMobileApp.iOS as the startup project
  2. Pair the Mac by clicking this icon:
    image.png
  3. Make sure you are in Debug mode, not Release mode
  4. Click the down arrow on the start options, and pick the device you want to simulate - Remote Device will not work
  5. Happy testing!

Releasing the iOS app:

  1. In the efcMobileApp.iOS/Info.plist file, scroll down to Bundle version and bundle versions string (short) then add 1 to each value.
  2. Set efcMobileApp.iOS as the startup project
  3. Pair the Mac (see step 2 of Debugging the iOS app)
  4. Make sure you are in Release mode, not Debug mode
  5. Right click on efcMobileApp.iOS and click Archive...
  6. Wait for the Archive to finish - if there's a signing error:
    a. Right click on efcMobileApp.iOS and click Properties.
    b. Once there, click the iOS Bundle Signing tab and make sure the Signing Identity is: iPhone Distribution: eFileCabinet, Inc. and the Provisioning Profile is: eFileCabinet Online AppStore and try the Archive again.
    c. If there's still an issue, the signing certificate may be out of date. Please get with dev management to get a new signing certificate.
  7. Once the Archive has finished, use VNC Viewer to connect to the Mac Mini (if you need credentials, ask dev management)
  8. Open XCode
  9. On the top toolbar, click Windows and then click Organizers
  10. You should see Archives as a tab on the left, and in there you should see the archive you just created in Visual Studio
  11. Select the archive and click distribute app
  12. Follow the wizard, leaving all the defaults except the one asking about sending reports to Apple and XCode - uncheck that box
  13. Please step through next steps with a member of the Dev management.
  14. Login into https://developer.apple.com/ using login from Last pass: Mobile Dev Apple Account. (may need to be logged into the dev mac to get the authentication code on login)
  15. Go to the App Store Connect section and choose Apps: 

    image.png

  16. Then go to the TestFlight tab at the top. You will now see the most recent version displayed. It will take a while to process.
  17. Once done processing it will ask to complete some compliance information. Click on manage and then answer the questions as shown below (I had two different sets of questions I had to ask so both are listed below):image.pngimage.png

    image.png

image.png

image.png

18. Once you hit start internal testing make sure your apple ID is added to the internal testings users list and download the testflight app on your apple device. Once app is up and running log in and accept the invite to the app.

19. You are not good to test the app.


Debugging the Android app:

  1. Set efcMobileApp.Droid as the startup project
  2. Make sure you are in Debug mode, not Release mode
  3. Run the emulator you have (you may need to install a new device)
  4. Make sure you have enabled Hyper-V and Windows Hypervisor Platform in windows features, and that you have enabled Virtulization (or SVM on AMD) in your bios (If you don't android emulation probably won't actually work). You will want to restart your computer when you do this. Also see this doc for further guidance.

    image.png


  5. Wait for a long time - the Android emulator is very slow on startup
  6. Alternative: If you have an Android phone, plug it in and on step 3 select your phone on the run dropdown. That way debugging should be a lot faster.

Releasing the Android app:

  1. Release can not be done in Visual Studio 2022, Please use Visual Studio 2019
  2. Make sure you've followed the steps found here to make sure JDK 11 is installed and will work with VS 2019.
  3. Set efcMobileApp.Droid as the startup project
  4. Make sure you are in Release mode, not Debug mode
  5. Right click on efcMobileApp.Droid and click Archive...
  6. Once the Archive has completed, click Open Distribution (you can also click the 'Distribute' button, and wak through through the steps, at the end just make sure you upload to the lowest level track)
  7. If at any point you are asked for signing credentials, they are found in the Android Signature Key Info file in the root of the source code.
  8. If at any point you are asked for a keystore file, import the keystore file found in the root of the source code.
  9. Give the resulting apk file to dev management to upload to the play store.
Setup and Configurations

SonarCloud and SonarLint Setup Steps

  1. Go to the SonarCloud link and click "Log In" then "With Azure Devops" button
  2. Let one of the senior devs know so they can add you to the SonarCloud project
  3. Login again and make sure you can access the Utopia project in SonarCloud

Download and setup the SonarLint IDE tool

  1. Go to https://marketplace.visualstudio.com/items?itemName=SonarSource.SonarLintforVisualStudio2019  and download the extension.
  2. Restart VS if it was running. (Yes, you have to)
  3. Inside VS go to Team Explorer > SonarQube > connect
  4. You'll be prompted for a url and login for SonarCloud.
  1. In the Team Explorer > SonarQube tab, right click on Utopia and select Bind (Or update if it's already been bound)
  2. It will take a minute, but all of the linter rules will be pulled down from the cloud and you should start seeing additional Warnings for security issues in the Error List tab on the bottom of the IDE (Error Code will start with an 'S')
Setup and Configurations

How to Run WOPI Validator Tests on O365

The WOPI Validator Tool allows us to make sure our endpoints conform to the WOPI protocol so we can offer an Office 365 integration. This tool is run through Windows PowerShell, but in order to make it work, we need 4 things first:

  1. The WOPI source code on our machine
  2. A valid Rubex Authentication token
  3. The port that we can use to run the WOPI tool with
  4. The node id of the file we're running the WOPI too

Please note, number 4 is only needed if you're using a file endpoint from FilesController.cs in Utopia (wopi/files/{id}). There are other endpoints you can use, just be sure to update the powershell command accordingly. This is just an example using the file endpoint.


Source Code Setup (Utopia and WOPI)

  1. Clone the WOPI source code  onto your machine in a place easily accessible to you. A good option is just your source folder where your other repositories are.
  2. Once the WOPI code is cloned, open the solution at the path: wopi-validator-core\WopiValidator.sln
  3. Build the project in Release mode. This will add the necessary files and directories to enable you to run the tool in PowerShell later.
  4. In Utopia, navigate to Utopia/Controllers/Wopi/WopiBaseController.cs - modify the ValidateRequestAsync method to always return true. We cannot run the proofkey portion of the test locally.

Rubex Authentication Token

  1. Run Utopia
  2. Go to the UtopiaDB and view the data in the DbUserSessions table.
  3. Copy the token under the AccessToken column header on your current session row (i.e. 07680FAC-90D8-419B-AF81-5C14BFA23F4F). This token is the valid Rubex Auth Token you need to run the WOPI tool. Copy it and paste it somewhere that will be easily accessible later.
    1. Alternatively, open up devtools networking tab in the Utopia window. Find an API call and copy the access token from the Authorization header
  4. Important: Keep your local Rubex session alive during the entire rest of this process or you will need to grab a new auth token!

Port to Use

  1. With the Utopia project still running, go to your taskbar and right click IIS Express.
  2. Under the header "View Sites", you should see Utopia. Hover over it to see the ports Rubex is using.
    image.png
  3. There should be two ports, one that matches the port in the URL (i.e. localhost:54298) and one that's different (i.e. localhost:44313).
  4. The port you want to copy and save for later is the one that doesn't match the URL port when you look at the browser running your Utopia project. The port you want is probably 44313 or 44311 or the like.
  5. Keep track of it in the same place you saved your authentication token.

Node ID to Use

  1. Download one of the wopi test files found here . It doesn't matter which one you use, there are just a few in here to try out.
  2. Upload the file you chose to your localhost environment.
  3. Once the upload completes, go to the UtopiaDB again and view the data in the DbNodes table.
  4. Find the wopi test file you created and grab its Node ID from the Id column of the table (i.e. 294 or 11020). Keep track of it in the same place you saved your port and authentication token.

Putting it All Together

  1. Open PowerShell in the wopi-validator-core\src\WopiValidator\bin\Release\net6.0\ directory
  2. The first time you try to run a test with a new user, you must run the following test:
    dotnet Microsoft.Office.WopiValidator.dll -t TOKEN -l 0 -w https://localhost:PORT/wopi/files/NODE_ID -g PutUserInfo This will populate a string value on the user so that all subsequent tests will pass. If this is missing, you'll get error messages about missing the "UserInfo" property.
    Substitute the TOKEN, PORT, and NODE_ID for your retrieved values.
  3. If you want to run all of the WOPI Validations tests, run:
    dotnet Microsoft.Office.WopiValidator.dll -t TOKEN -l 0 -w https://localhost:PORT/wopi/files/NODE_ID --ignore-skipped
    Substitute the TOKEN, PORT, and NODE_ID for your retrieved values.
  4. If you want to run a specific Test Case of the WOPI Validation tests, run:
    dotnet Microsoft.Office.WopiValidator.dll -n NAME -w https://localhost:PORT/<YOUR ROUTE HERE> -t TOKEN -l 0
    Substitute the TOKEN and PORT with your retrieved values and the YOUR ROUTE HERE needs to match up to the endpoint you are testing. The NAME is where you place the name of the test case you want to run.
    • For example: If you are testing name containers.EnumerateAncestorsOnRoot then you should match it to the endpoint /wopi/containers/NODE_ID/ancestry where node is NODE_ID is your retrieved value from above.
    • Test case and test group names are all found inside of TestCases.xml found in the same folder as that .dll
  5. See the Additional Info section for more commands

Troubleshooting

  • If at any time, all your test cases are getting skipped and you want to see why, be sure to remove the --ignore-skipped flag from your command and run it again. If you see that the reason for skipping the test cases is a 306 Unused error, that means your port is wrong. Make sure you're using one of the ports listed under Utopia in IIS Express, and make sure it's not the port your browser is using to connect to Rubex.
  • If you are getting lots of Authorization exceptions while you're running your test cases, it simply means your Rubex Authentication token is no longer valid. Log out (if you're not already) and login again. Then follow the steps in the Rubex Authentication Token section of this document to get the new auth token. Replace the token in your command with this new one and run the test cases again.
  • If you are seeing a message about missing the UserInfo property, see step 2 of "Putting it All Together"

Additional Info

Wopi Documentation 

Microsoft.Office.WopiValidator 1.0.0
Copyright (C) 2018 Microsoft

  -w, --wopisrc           Required. WopiSrc URL for a wopitest file

  -t, --token             Required. WOPI access token

  -l, --token_ttl         Required. WOPI access token ttl

  -c, --config            (Default: runConfig.xml) Path to XML file with test definitions

  -g, --testgroup         Run only the tests in the specified group (cannot be used with testname)

  -n, --testname          Run only the test specified (cannot be used with testgroup)

  -e, --testcategory      (Default: All) Run only the tests in the specified category

  -s, --ignore-skipped    Don't output any info about skipped tests.

  --help                  Display this help screen.

  --version               Display version information.

Setup and Configurations

AWS DMS Setup

How to setup AWS DMS:

This is assuming the PostgreSQL DB is already created

SETUP SCHEMA:

A. Get the sqlserver2pgsql.pl script from https://github.com/dalibo/sqlserver2pgsql/blob/master/INSTALL.md 

B. Install perl

C. In MSSQ Studio, right click on the database required to migrate and select Task -> Generate Scripts

D. In the terminal, go to where the sqlserver2pgsql.pl script is kept and run the following:
~/sqlserver2pgsql.pl -f <THE NAME OF THE FILE DUMP THAT CAME FROM PART C> -b before.sql -a after.sql -u unsure.sql -keep_identifier_case -stringtype_unspecified

E. Connect to the PostgreSQL DB and run the before script (this will build the tables, types, and columns)

F. Migrate your data over as listed in the 'SETUP AND RUN AWS DMS' section

G. Make sure that everything is migrated over

H. Connect to the PostgreSQL DB and run the after and unsure scripts
- Do so after you've reviewed them to make sure they're accurate and the constraint names are 63 characters or less

I. Go play some Starcraft, you've earned it

SETUP AND RUN AWS DMS:

  1. Create your Replication Instance on AWS DMS
    • Not needed anymore, can just use the one that's already built
    • Make sure that the Replication Instance's IP address is allowed to enter the VPC security group of both the Source enpoint's DB and the Target endpoint's DB, if not, add it to both
  2. Create your endpoints (source and target)
    • Test the connection with the Replication Instance before creating the endpoint (it will create even if the Replication instance can't connect to it)
  3. Do everything here on the MSSQ DB
    • https://aws.amazon.com/premiumsupport/knowledge-center/dms-migrate-rds-sqlserver/ 
    • I know that it sucks to need to enable CDC for each table sooo just run the AutoWriter program if the tables are different then what's there, make sure you replace the strings in the file
    • I've noticed better results (in that the task would run without errors) by just keeping 'exec sys.sp_cdc_stop_job;' and not turning it back on, though keep in mind that you probably won't be able to get your logs, so turn it back on if you need those
    • You may get a table that fails, that's fine as it's probably a table that MSSQ made and isn't in the DB
      • Run these to get the tables if needed
        For the dbo SCHEMA:
		SELECT TABLE_NAME
		FROM INFORMATION_SCHEMA.TABLES
		WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA='dbo'
			
	For the workflow SCHEMA:
		SELECT TABLE_NAME
		FROM INFORMATION_SCHEMA.TABLES
		WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA='workflow'
  1. Create a DB migration task
    • Task Identifier: Something unique
    • Descriptive Amazon Resource Name (ARN): Skip this
    • Replication instance: Choose the Replication Instance from step 1
    • Select your Endpoints
    • Migration Type - I recommend 'Migrate existing data and replicate ongoing changes'
    • Editing mode: Wizard
    • Target table preparation mode: Do Nothing
    • Include LOB columns in replication: Full LOB mode
    • Maximum LOB size (KB): I set it to 10,000 but you can set it to whatever is needed
    • Enable validation: true
    • Enable CloudWatch logs: true
    • Advanced task settings
      • Create control table in target using schema: dms
      • Enable control table - enable all
    • Table mappings
      • Create two new selection rules and include SCHEMAs 'dbo' and 'workflow'
      • Create one new transformation rule with Target -> Schema, Schema name -> 'dbo', Action -> 'Rename to', Value -> 'public'
    • Migration task startup configuration: Automatically start
    • Save n start it
Setup and Configurations

Previewer Setup for Local Environment

Use Docker To get the Previewer Up and Running: For local use

Taken from Accusoft’s Try It link:
Accusoft: Try It! 

  1. Make sure you have stopped Prizm and Prizm Application Services so the ports won’t conflict
  2. Download Docker Desktop (Windows): Docker Desktop 
  3. Open up PowerShell and run this command: 
    docker pull accusoft/prizmdoc-viewer-eval:13.26
  4. Find our Solution Name and License Key in LastPass under Prizm License and replace YOUR_SOLUTION_NAME and YOUR_LICENSE_KEY in the command below of your choice
  1. It takes a few minutes for everything to start up, even though it says it's running in Docker. Confirm that everything is running with these checks:
  1. Once the application loads or all the checks come back with OK you are ready to start using the PrizmDoc Previewer with the AccusoftPreviewer solution.

Note: To get updates, just click the delete icon in Docker Desktop and repeat the steps above.

For debugging the front end of the Previewer:

On your machine, make sure you have node.js, npm, and gulp installed.

Now you've got what you need. To run the previewer and debug it:

  1. Run Utopia and Utopia\UtopiaPreviewers\AccusoftPreviewer at the same time.
  2. In the source code, open the source code and go to the following directory: Utopia\UtopiaPreviewers\AccusoftPreviewer\AccusoftPreviewer\wwwroot\ViewerSources
  3. Open a powershell window in that directory and run the command ./builddev.bat
  4. In the Utopia window, open the dev tools and make sure the cache is disabled
  5. In the Utopia dev tools, you'll see a "Previewer" item in the tree view - if you expand it, you should see webpack://, which you can expand and find ./modules
  6. If you don't see ./modules then you'll need to right click the Previewer in the browser and select Reload Frame. Then repeat steps 4 and 5.
  7. In the ./modules directory, you'll see the client code for debugging.
  8. Go eat a donut. You deserve it. You're ready to debug with the Previewer!

Troubleshooting

  1. Make sure you have Azure Storage Emulator running.
  2. If running the ./builddev.bat script doesn't work, try running it again in PowerShell as an administrator 
  3. If that still doesn't work, try running the AccusoftPreviewer project as an administrator in Visual Studio.

The Way of Pain - To get the Previewer up and running:

  1. Download and install the PrizmDoc Server and Client
  1. Restart your computer, yes... you have to.

  2. Make sure the PrizmDoc server and client are running, (Demo isn't required to be running). These are services that need to be running called 'PrizmDoc' and 'PrizmApplicationServices'

  3. Start the Utopia Project found Utopia\UtopiaPreviewers\AccusoftPreviewer - While this is running you can preview files in your local Utopia instance and the previewer project webpage will be a HTTP Error 403.14 - Forbidden type page.

Note: Azure storage needs to be running or the previewer will timeout while loading

Note: Make sure your port number is correct in the AccusoftPreviewer.csproj file. The line <IISExpressSSLPort>44318</IISExpressSSLPort> got changed to <IISExpressSSLPort>44300</IISExpressSSLPort>. VS automatically sets this in some fashion, so make sure your hitting the correct port, I also made the mistake of trying to line it up to port 50560 (not the 44300 or the correct one 44318) which didn't help finding the problem. To not have problems in the future you need to update the ssl port in 3 different files.

Setup and Configurations

OCR Worker Local Setup

Keep in mind that these are the instructions that were used during testing of the OnPremise/Master merge that happened

  1. Download Accusoft ImageGear  (it is NOT a service)
  2. Install it with the evaluators license
  3. Inside of appsettings.json set "RunAsService" to false
  4. Inside of App.config set
    <add key="AccusoftSolutionName" value="EFileCabinet" />
    <add key="AccusoftSolutionKey" value="0x50DBF8B0,0x898D16D1,0x6BBB80AD,0xD99D98D8" />
    to
    <add key="AccusoftSolutionName" value="" />
    <add key="AccusoftSolutionKey" value="" />
  5. Inside of Program.cs inside of LoadWorkerConfiguration() comment out these two lines
    AccusoftSolutionName = InstanceSettingsManager.Get<string>(InstanceSettingEnum.FileOCRWorkerAccusoftSolutionName),
    AccusoftSolutionKey = InstanceSettingsManager.Get<string>(InstanceSettingEnum.FileOCRWorkerAccusoftSolutionKey),
  6. Test that all is well by performing an OCR
    • You will probably get a GdPicture error, that is expected, just continue
Setup and Configurations

Windows Services

Server Service:

First, we need to publish the Utopia Project.

image.png

After that we need to create the service by running the command (use Admin Command Prompt):
SC CREATE "ServerService" binpath="C:\Projects\Efilecabinet\Utopia\Utopia\Utopia\bin\Release\netcoreapp3.1\publish\Utopia.exe"

The bin path it's the path of the publish project + "Utopia.exe".

Now the service it's created. We can open the Services app of windows and check it.

image.png

The logs go to this path or similar:

image.png

Useful commands:

Delete the service:

sc.exe delete "ServerService"

Stop the service:

sc stop "FileOCRService"

List of the service names and projects:

FileOCRService - File OCR worker
Index Service - File Indexing worker
Rubex Service - Utopia Batch Worker
Server - Utopia

All the projects use .net core worker sdk, except File OCR Worker that continues on .net framework. For this project, we need to use the exact same name on the creation of the service. And if an error like this one ("Login failed for user 'NT AUTHORITY\SYSTEM'. Reason: Failed to open the explicitly specified database 'UtopiaDB2'. [CLIENT: <local machine>]") occurs, we need to create the user 'NT AUTHORITY\SYSTEM' on the db with all permissions.

Checking Event Viewer windows app it's useful for debugging services that fail to start for example.

image.png

Setup and Configurations

Setup/Configurations for Mac Mini

Connecting

*You will need to be at our office or on the VPN to do this

  1. Download VNC Viewer
  2. Make sure the Mac you're wanting to connect to is actually plugged in (check the ethernet cable) and turned on
    • The two QA ones are by all the other QA testing machines (as of 10/25/2022)
    • The Dev one is by McKay's space - in the Ops corner (as of 10/25/2022)
  3. Once it's open, add a new connection see credentials
    • The dev mac currently is the only machine that has all the signing certificates for the Mac Desktop Client
      • The dev mac is often turned off
    • The QA mac 1 is much faster than any of the others, but doesn't have the signing certificates for the Desktop Client
      • When setting up the QA mac within VNC, turn Encryption > Prefer Off
      • Make sure no one from QA is using it

Credentials

DEV MAC

IP Address: 10.10.0.60
Login Info In Last Pass: Development Mac Mini

QA MAC 1

IP Address: 10.10.0.68
Login Info In Last Pass: QA Mac Mini 1

QA MAC 2 (not recommended)

IP Address: 10.10.0.67
Login Info In Last Pass: QA Mac Mini 2

Before you get started

 You will need the following installed on your machine (Dev mac and QA mac 1 have these already):

Version Control

IMPORTANT - the master branch for the Mac Desktop Client is different from windows.  You're looking for origin/mac-master. Branch off of that unless instructed otherwise

Sometimes git through Visual Studio for mac is really dumb, especially with changing branches.  The good news is that you can use git through terminal where needed.

Useful Git Commands

NuGet

You will probably need to add our UtopiaNuget at some point to a project on mac.  The process is slightly different than what is described in our other wiki page.

  1. Go to the NuGet packages in the solution and select Configure Sources
    • image.png

  2. Go in to ADO and select Personal Access Tokens 
    • image.png

      1. Select + New Token
      2. Give it a name
      3. Change the expiration to be far in the future
      4. Give full access scope
      5. Click Create
      6. Save the token you are given and don't lose it
        • You will not be given it again and will need to regenerate another one if you lose it, potentially breaking other connections
  3. Add a new package source
    1. Name it UtopiaNuget
    2. The location is https://pkgs.dev.azure.com/eFileCabinet/Utopia/_packaging/UtopiaNuget/nuget/v3/index.json 
    3. The username is your ADO username
    4. The password is the token you generated in step 2
    5. Click Add Source
  4. Click OK
  5. At this point, if you select UtopiaNuget as the package source and are on the browse page, you should be able to see all of our packages we offer.
Troubleshooting

Mac Desktop Client

IMPORTANT - the master branch for mac is different from windows.  You're looking for origin/mac-master. Branch off of that unless instructed otherwise

If you're feeling courageous and want to mess with getting the signing certificates working on a machine other than the dev mac machine, then the credentials are found in last pass and is named Mobile Dev Apple Account.

Helpful Tips

It may be beneficial to run a local instance of Utopia to connect to for the Desktop Client. 

Building in Debug Mode

*If you're building on a machine that doesn't have the signing certificates (any other than Dev Mac Machine), you will need to set signing to false in the project file.

To be able to build, you need to first have built two other projects on the machine:

It is very likely that you will need to update their references to UtopiaSharedClasses in NuGet.  I recommend going into the UtopiaWindowsDesktopClient to update the packages and build them.

Building in Release Mode

*As of right now the signing certificates are only on the Dev Mac machine.  I've tried putting it on the other mac, and they are there, but they require a password per use, which we don't have.

To build in release mode, it's as simple as putting it in release mode in visual studio, updating the version number in the Product.plist file, and running build.  Once done, then go into the bin folder to get the dmg file

../UtopiaMacDesktopClient/RubexClient/bin/Release/RubexInstaller.dmg

Send this to QA to test your changes.  If they sign off on it then you're good to have it replace the dmg file in Utopia.  Make sure you update the version number in the json file in the Utopia project after updating the dmg file!

Note

There is a chance that building it won't sign it properly or build the dmg.  I never had this problem, but if you do then you will need to follow these steps:

Monterey 12.0.1 has build issues when trying to build an installer from Visual Studios when running the release mode for Rubex Desktop Mac Application. Had to manually build the files. There is a Product.plist file in the obj/release folder that has a property called “os”, delete this entry and run the below commands (with the proper version).

productbuild --product /Users/dev/UtopiaClientApplications/UtopiaMacDesktopClient/RubexClient/obj/Release/Product.plist --component /Users/dev/UtopiaClientApplications/UtopiaMacDesktopClient/RubexClient/bin/Release/Rubex.app /Applications --sign "Developer ID Installer: eFileCabinet, Inc. (J82X76G6Y8)" /Users/dev/UtopiaClientApplications/UtopiaMacDesktopClient/RubexClient/bin/Release/Rubex-1.0.4.pkg

appdmg /Users/dev/UtopiaClientApplications/UtopiaMacDesktopClient/RubexClient/InstallerItems/spec.json /Users/dev/UtopiaClientApplications/UtopiaMacDesktopClient/RubexClient/bin/Release/RubexInstaller.dmg


iOS Mobile

*I haven't touched this much but we do have a helpful page already built.  I don't know how up to date it may be.

Setup and Configurations

Office Addins Terminal Services Environment

With Terminal Services, the Office Add-ins don't always show up, despite being installed for all users.
The batch script below imports the registry settings needed into HKEY_CURRENT_USER and can be run for each user to make the Office Add-ins show up. It is dependent on them installing it to the default path.
OfficeAddinRegistry.zip

Setup and Configurations

Utopia Local DB Refresher

The Utopia local database refresher solution is located in the Utopia repo in the UtopiaLocalDatabaseRefresher folder.

  1. Check that all the requirements are met before running:
    1. Make sure you've stopped the Microsoft Azure Storage Emulator
    2. PG Admin already set up with the local Postgres instance for Utopia
    3. Docker needs to be installed. (Docker Desktop is available on the Company Portal)
    4. Get ElasticSearch Running in Docker (see ElasticSearch Doc)
    5. DbMigratorEF has been rebuilt in debug (Open the Utopia solution, switch to DbMigratorEF and rebuild in debug)
    6. Rebuild UtopiaBatchWorker in debug as well
  2. Open the UtopiaLocalDatabaseRefresher solution
  3. (Optional) Update the "TestUserName" and the "TestUserPassword" to the desired values in appSettings.json 
  4. Ensure you have met the requirements
  5. Run the solution in debug

Azurite Docker Doc

If things are broken and you need to do it manually:

Setup and Configurations

Generating a DB Connection String

Create a new connection string 

Pull information from a connection string

Encrypt a connection string from a JSON object

Populate configuration values from a connection string

Setup and Configurations

How to Sign and Notarize a New Build for the Mac

I recently learned how to sign and notarize our build for the Mac Mini and will be documenting both the one-time setup that I had to do, as well as the steps that must be taken with each new build. Many of these steps began as outlined in this blog, though with extensive changes along the way. If all you're looking for is how to make the next build for the Mac, please skip down to the "Notarize and Staple a Build" section.

Initial Setup

All of this setup has already occurred, and you probably won't ever need to do any of it again. These instructions are here just so that we can reproduce these actions if that is ever made necessary.

Update the Keychain certificates

In order to sign and notarize our build file, we're going to need to use two Keychain Certificates.

  1. Open the Keychain Access app, open the "All Items" tab
  2. Search for "J82X76G6Y8" (our "team identifier")
  3. Among the results you are looking for these two certificates 
    • Developer ID Application: eFilecabinet, Inc. (J82X76G6Y8)
    • Developer ID Installer: eFilecabinet, Inc. (J82X76G6Y8)
  4. You need to verify that both of these are still current (not expired). You also need to make sure that there aren't any expired duplicates of these certificates. If there are, then right-click on the expired duplicates and delete them.

Configure Visual Studio to use the Hardened Runtime

For our application to be notarized, it is also necessary for it to be compiled using the Hardened Runtime. 

  1. Right-click on the RubexClient project in the Solution side-panel of Visual Studio and select Properties. Then open the Build->Mac Signing view
    • Check "Enable Hardened Runtime
    • In the "Custom entitlements" field enter: Entitlements.plist
    • Open the Entitlements.plist and add a necessary permission.
      • If you are doing this in Visual Studio, click "Add new entry" and then enter the following in each column
        • Property: com.apple.security.cs.allow-jit
        • Type: Boolean
        • Value: Yes
      • If you are doing this in a text editor, inside of the <dict></dict> section add the following:

        <key>com.apple.security.cs.allow-jit</key>
        <true/>

Configure Visual Studio to sign the .dmg build

Now Visual Studio needs to be configured to sign the package as part of the build process. For this you will need the name of the Installer certificate from the last step, as well as the identifier for our application (currently "com.efilecabinet.rubex").

  1. In the Visual Studio project find and open the spec.json file
  2. On the same level as the title, background, icon-size, contents, and window, add a new section as follows (with the current signing-identity and identifier as defined above):

    "code-sign": {
         "signing-identity": "Developer ID Application: eFilecabinet, Inc. (J82X76G6Y8)",
         "identifier": "com.efilecabinet.rubex"
    }

  3. Next, right-click on the RubexClient project in the Solution side-panel of Visual Studio and select Properties. Then open the Build->Mac Signing view
    • Check "Sign the application bundle" at the top
    • For the "Identity" directly beneath that checkbox select "Developer ID: eFilecabinet, Inc. (J82X76G6Y8)"
    • Check "Sign the installer package" at the bottom
    • For the "Identity" directly beneath that checkbox select "Developer ID Installer: eFilecabinet, Inc. (J82X76G6Y8)"
  4. Now when you build the project, towards the end of the process you should see a line that says: 
    • [20/21] Signing image...             [ OK ]

Generate Application-Specific Password for notarytool

Now that we have a signed build using the hardened runtime, we can configure our notarization tools. For this, we use the command-line utility "notarytool." First, though, we must authenticate the tool with an application-specific password. The current application-password is stored in LastPass, under the Notes section of the Mobile Dev Apple Account item. If you ever need to create a new password, then:

  1. Go to the Apple ID website
  2. Enter the sign-in credentials under the Mobile Dev Apple Account item in LastPass
  3. You will probably need to enter a second-factor code. For this you'll want to be signed into the Development Mac Mini so you can see the sign-in attempt alert, approve it, and get the 6-digit code to complete your sign in
  4. Under the Sign-in and Security section select App-Specific Passwords
  5. Press the + button, enter a memorable name, and press the Create button
  6. You will ONLY be able to see the password one time on the next screen, so be sure to save that somewhere for reference

Authorize notarytool

Now we can use this password to authorize the notarytool.

  1. In a terminal on the mac run:

    xcrun notarytool store-credentials --apple-id "mobiledev@efilecabinet.net" --team-id "J82X76G6Y8"

    Note the 10-digit team id at the end that we got from our certificates. Also, the Apple ID is the same one that we used to sign into the mobile dev account.
  2. You will then be asked for a "Profile name." Choose something meaningful and write it down for future use. Our current profile name is "notary-credentials"
  3. You will then be asked for the password that goes with your account (mobiledev@efilecabinet.net). This does not mean the password that you used to sign into the Apple Id account. It means the Application-Specific Password that you generated at the end of the last section.
  4. It should process for a minute and then tell you that it has validated your credentials and saved them to Keychain. You will now be able to reference that Keychain item using the "Profile name" that you provided on step 2.

In the following section it refers to the keychain profile as "notary-credentials." Obviously, you would change that to whatever profile name you set in this section.

Notarize and Staple a Build

  1. Increment the "Bundle versions string" in the Info.plist of the Visual Studio project
  2. Ensure that your Visual Studio project is set to build for Release
  3. Select Build->Rebuild Solution
  4. Open a terminal and navigate to the build location: dev/UtopiaClientApplications/UtopiaMacDesktopClient/RubexClient/bin/Release/
  5. Notarize the built .dmg file with the following command:

    xcrun notarytool submit RubexInstaller.dmg --keychain-profile "notary-credentials" --wait

    It will run for a while, just wait for it to complete with a success message.
  6. Now you need to "staple" that notarization to the .dmg file. You do that with this command:

    xcrun stapler staple RubexInstaller.dmg

  7. Finally, check that everything is correct by running this command

    spctl --assess -vv --type install RubexInstaller.dmg

    This should give a response message the .dmg file is "accepted," that the source is a "Notarized Developer ID," and the origin should be our developer id.

You may now give the signed and notarized RubexInstaller.dmg to QA for testing and then SecDevOps for release.

Setup and Configurations

How to Renew a Certificate for Mac

To build and sign our Apple-product applications it is required for us to point the build towards valid certificates, which expire after a number of years. We will periodically need to renew these certificates. You can view the status of any certificates by opening Keychain Access. Any items that are already expired will have a red X by them, and every certificate's expiration date can be seen in a column to the right. To renew any expired/soon-to-be-expired certificates:

  1. Open Xcode.
  2. Don't open or create a project, just select Xcode->Settings from the top menu.
  3. Select Accounts from the top ribbon menu.
  4. Select the mobiledev@efilecabinet.net account (not mobiledev@efilecabinet.com). You may need to sign in again, using the credentials in LastPass.
  5. Select the "eFileCabinet, Inc." team.
  6. Click Manage Certificates.
  7. Click the + dropdown button in the bottom-left.
  8. Select the needed certificate type.
  9. You should now see the new certificate in the main list, and it should have the same name as the previous certificate in that category.

**Note: The next time that you try to build a project that relies on the new certificate you might get a popup requesting the "login" keychain password. This password should be the same one that you used to sign into the Dev account on the Mac machine (e.g. the password for the Development Mac Mini item in LastPass). Make sure to select "Allow Always" after entering the password so you won't have to do this again.

Go ahead and delete the old certificate once you verify that the new one is working for you. Having duplicates can make certain signing operations confused.

Setup and Configurations

Local Testing

Test Utopia local changes in Atlantis local

  1. Check that Utopia appsettings.json has: 

      "Environ": "Staging",
      "Region": "LocalToStage"
  2. In Utopia file SystemResourceController.cs search for AtlantisFrontendUrl = UtopiaSettings?.AtlantisFrontendUrl and change it to AtlantisFrontendUrl = "https://localhost:44437"
  3. Make sure you're opted into Atlantis or in Utopia go to the file UserService.cs, search for the method GetAtlantisOptInStatusAsync, and have it return true
  4. Check that Atlantis appsettings.json has: 
    "Environ": "Local"

Note: You will be using your local database. Don't change DbConnectionConfigurationData in Utopia appsettings.json.

Test Utopia local changes against local DB

  1. Leave Utopia appsettings.json as: 

      "Environ": "Staging",
      "Region": "LocalToStage"
  2. Make sure you're opted out of Atlantis or in Utopia go to the file UserService.cs, search for the method GetAtlantisOptInStatusAsync, and have it return false

Test Utopia local changes against staging DB

  1. Leave Utopia appsettings.json as: 

      "Environ": "Staging",
      "Region": "LocalToStage"
  2. Update DbConnectionConfigurationData to the staging connection string found in LastPass under "Utopia Staging DB AWS"
  3. Make sure you're opted out of Atlantis or in Utopia go to the file UserService.cs, search for the method GetAtlantisOptInStatusAsync, and have it return false
  4. If working remotely make sure you're on the VPN

Standards

Standards

Coding Standards

Coding Rules

  1. Thou shalt not commit to the master branch, pull requests only.
  2. Thou shalt not use magic values.
  3. Thou shalt not use static classes save for utilities.
  4. Thou shalt not write recursive methods without an exit case.
  5. Thou shalt spell things correctly.
  6. Thou shalt modularize all thine code.
  7. Thou shalt keep thine methods short.
  8. Thou shalt name thine variables with a descriptive name.
  9. Thou shalt name thine methods with a name that describes what the method does.
  10. Thou shalt think of the future while coding the present.
  11. Thou shalt make thy code self-documenting.

Please read: https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md 

And: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/ 

Javascript Styling Guidelines

  1. With dependency injections, (think AngularJS controllers) the expected pattern is to have the item name declared at the top and then use new lines after each dependency declaration.

Clean Code Article

Clean Code.pdf

Standards

Pull Request Checklist

General Items

  1. Code compiles
  2. Code has been developer-tested
  3. Code is tidy (indentation, line length, no commented-out code, no spelling mistakes, etc)
  4. Code adheres to the Coding Styles and Standards Guidelines (Found in the documentation folder)
  5. Exceptions have been used properly
  6. New functionality is appropriately logged as needed
  7. Unused using's have been removed
  8. Eliminated warnings
  9. Ensured NullReference Exceptions caught or handled appropriately
  10. Leftover stubs and test routines have been removed
  11. Hard-coded or development only things have been removed
  12. Considered performance and scalability
  13. Considered security, and potential exploits
  14. All resources (HTTP connections, DB connection, files, etc) properly released in all code exits (i.e. normal and exception)
  15. Corner cases and workarounds for known limitations of dependencies are well documented
  16. No new code is a repeat of existing functionality that can be safely reused
  17. Thread safety and possible deadlocks are considered and handled accordingly
  18. Method bodies are kept as close to 4 lines or less if possible
  19. Method names must be descriptive (reveal their intention aka what they do)
  20. Methods do one thing only
  21. Asynchronous Methods have the post-fix of "Async" appended to the end of their names.

Utopia Specific Checklist Items

  1. All code added to UtopiaSharedClasses is safe to expose to customers (No sensitive information)
  2. Libraries or projects that could become Libraries should be stored at the top level of the Utopia Repository
  3. Public API endpoints have documentation comments if needed

General

  1. .NET standard Coding Guidelines: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/ 
  2. Clean Code Book with corresponding guidelines are found in the Utopia Repository under Documentation.

Code Reviewer's Checklist

  1. Types have been generalized where possible
  2. Parameterized types have been used appropriately
  3. Exceptions have been used appropriately
  4. Repetitive code has been factored out
  5. Frameworks have been used appropriately – methods have all been defined appropriately
  6. Classes have been designed to only have one purpose
  7. Views do not contain business logic
  8. Common errors have been checked for
  9. Potential threading issues have been eliminated where possible
  10. Any security concerns have been addressed
  11. Performance and Scalability was considered
  12. The functionality fits the current design/architecture
  13. The code does not use unjustifiable static methods/blocks
  14. The code complies to coding standards
  15. Logging used appropriately (proper logging level and details)
  16. Exception use is in compliance with proper methodology
  17. Code quality is excellent

Utopia Specific Checklist Items

  1. All code added to UtopiaSharedClasses is safe to expose to customers (No sensitive information)
  2. Libraries or projects that could become Libraries should be stored at the top level of the Utopia Repository
  3. Public API endpoints have documentation comments if needed
  4. Functionality should be exposed at the highest layer of the architecture as possible and only moved down when reuse becomes necessary. (i.e. CSV generation at the presentation layer, but could be moved into business logic if reuse becomes necessary)
Standards

ADA Compliance Checklist

This is not meant to be a comprehensive list but is hopefully a good starting place. Feel free to add.

To see the WCAG standards established by W3C go here


For a more comprehensive checklist from WebAIM go here


SIGNiX

SIGNiX

SIGNiX Documentation and API Links

Support Contacts at SIGNiX:

Heide Abbajay  - Support person
Hannah Detherow - role?
Joshua Curry - VP of something, don’t want to bother unless no one responds.

API Docs:

SIGNiX FlexAPI


Resend emails:

XML - Email Resend.docx

API Email Resend Ajax Call.docx

 

For In-Person signing, all you do is use a stripped-down GAL call and the TransactionRole changes based on the Signer’s position in the XML.  Signer 1 = ‘1’, Signer 2 = ‘2’, etc.

<?xml version="1.0" encoding="utf-16"?><GetAccessLinkRq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:com:signix:schema:sdddc-1-1">

<CustInfo>

<Sponsor>efilecabinet</Sponsor>

<Client>efilecabinet</Client>

<UserId>efilecabinet</UserId>

<Pswd>********</Pswd>

</CustInfo>

<Data>

<TransactionID>3e3750f5-a66e-4ee9-a8a1-def6364bf432</TransactionID>

<TransactionRole>1</TransactionRole>

<SkinID>Signix.Base</SkinID>

<Embedded>iframe</Embedded>

<ContainerOrigin>https://account.efilecabinet.net/</ContainerOrigin>

</Data>

</GetAccessLinkRq>

Technologies

Technologies

Http Client

you should use either long-lived clients and set PooledConnectionLifetime (.NET Core and .NET 5+) or short-lived clients created by IHttpClientFactory.

*see HttpClient guidelines for .NET - .NET | Microsoft Learn

How?

In the Startup file (or Program.cs file in cases, wherever you are doing dependency injection is where you want to do this), do

 builer.Services.AddHttpClient();

This will allow you to dependency inject IHttpClientFactory in other classes, which you can use to create short lived HttpClient objects whose connections will be cleaned up immediately after disposal with the following code.

using HttpClient httpClient = HttpClientFactory.CreateClient();

For example in Atlantis Front-End of how we did this, reference the following files:

Another way to do this is by dependency injecting a singeton HttpClient. I (Quinn) had trouble getting the IHttpClientFactory to dependency inject in functions apps. I kept running into dependency issues with different nuget packages, but this approach worked great.

In your startup.cs add the following 

builder.Services.AddSingleton(() => new HttpClient(
    new SocketsHttpHandler { PooledConnectionLifetime = TimeSpan.FromMinutes(2) }
));

Once you do this, you can add a HttpClient as a parameter to any constructor of a class that is dependency injected.

The approach this way is different than the one above because you aren't creating short lived HttpClients, but instead, you have a singleton HttpClient. This is fine because most functions are thread safe, but you won't want to dispose of the HttpClient anywhere.

Why?

In the Atlantis Front-End we learned this the hard way. We were spinning up a new HttpClient object every time a request was sent to Utopia or the Atlantis Back End (which happens for basically every request to the Atlantis Front End server). When we opted in all users to the new experience, we got a lot more traffic and starting seeing thousands of failed requests with the following error message:

An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. (utopia.revverdocs.com:443) An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

After researching a bit, we learned that each HttpClient object has it's own connection pool, and even when you dispose of the HttpClient object, it's connection pool stays alive and keeps all connections in the pool alive for 2 minutes (this time is configurable though). While the connection is still alive, it blocks another connection from being created on the same port, and your server does have a limited number of ports, so if you have a bunch of connections blocking all your ports from being used, you start to get the error above because there are no ports available to send you web request out on.

Utopia

Utopia

Windows File Encryption

Decryption

Utopia

Open Source Software List

Correct as of 8/23/2021
Server-Side: ElasticSearch, Postgresql, iTextSharp - LGPL, MailKit, BouncyCastle, AutoMapper, DeviceId, dotLess.Core, FluentValidation, .Net 5, MimeTypes, NUglify, Chutzpah, Ninject, Serilog, Swashbuckle, SkiaSharp, OpenIddict, StackExchange.Redis, LigerShark.WebOptimizer
Client-Side: AngularJS, Angular-UI (various sub-libraries), Font-Awesome, Bootstrap, ngDialog, daterangepicker, Cytoscape, jasmine, jquery, less, lodash, moment.js, signalr, split.js

Utopia

First Time Setup - Utopia (Work in Progress)

Step 1: Postgresql

After install is complete - Run the DbMigratorEF and update to latest migration

Apply the "DB InstanceSettings Local Config.sql" file to the local db - this is found in the top level folder inside the Utopia repo

Step 2: Install Elastic Search

ElasticSearch Installer In Rubex 
ElasticSearch Direct Download 

Step 3: Install Azure Storage Emulator

Azure Storage Emulator 

Step 4: Run the UtopiaBatchWorker to pull down local accounts

Utopia

Utopia Articles of Permissions (2020)

Utopia Articles of Permissions

This file is to explain the over-arching permissions strategy

Node Permissions

  1. Every node inherits it's permission set from it's parent by default.

  2. a. A node's permission set consists of accumulating all permissions on and above the given node.

    b. The permission set requires that the roles be unique. (One permission per role in the permission set collection)

    c. In the case that more than one permission per role is found, (e.g. group has a permission on the cabinet and a different permission on the drawer) the closest permission is taken for evaluation.

  3. Only member/personal roles can have the override/enforce permission.

  4. The Override/Enforce permission, when checked on a member/personal role, results in all other permissions being ignored for evaluation.

    a. If multiple permissions are found with override checked, the nearest permission is choosen for evaluation.

  5. Pushdown is an action offered when a permission is added, updated, or removed.

    a. When taken, it removes all permissions on descendants that have a matching role.

System Permissions

  1. These are permissions for a specific role to access certain system features. (e.g. workflow, manage users, recycle bin, etc.)
  2. A particular users' total system permission set consists of any system permissions assigned to their personal role, or any roles they are a member of.

Non-Inheritable (Only this item) Behavior

Expected behavior for various parent folder with inheritable permission and a sub folder w/ non-inheritance(Only this item) relationships.

Vocabulary:
Parent = Parent with inheritable permissions
Child = Child with NotInerhitable(Only this item) permission
RWD = Permissions (Read/Write/Delete)

Behaviors:
E = Edit/Rename Child
D = Delete Child

V = View Children of Child
C = Create folder or Upload File into Child
L = Delete children of Child


No Parent Permissions Parent-R Parent-RW Parent-RWD
Child-R
V VC VCL
Child-RW E EV EVC EVCL
Child-RWD ED EDV EDVC EDVCL
Utopia

Utopia Architecture Notes (2020) Has Changed

utopia_diagram.png

Download link: Utopia Architecture Notes.docx

DataAccess Notes

BusinessLogic Notes

EventSystem Notes

UtopiaSharedClass Notes

Security

Utopia

File OCR Worker debugging (2021)

This is the instruction how to debug OCR worker.
a. If you no need to use FREngine

  1. In Program.cs comment row `FREngineOCRWorker.Initialize(Configuration);
  2. Put breakpoints
  3. Run File OCR Worker in Debug mode

b. If you need to use FREngine

  1. FREngine can't initialize correctly if you trying to run File OCR Worker in debug mode, so DO NOT PUT BREAKPOINTS AND DO NOT RUN IT IN DEBUG MODE. For debugging purposes you can print debug information in logs and analyze it.
Utopia

Utopia Bundle Installer build instruction

  1. Build all components which should be included into installer
    1a. If PrizmDoc should be included, PrizmInstaller project should be built as well. Do not forget to specify PrizmServer license key into the Strings resource of PrizmInstaller.
    1b. If ElasticSearch should be included, UtopiaSearchServiceWrapper project should be built as well

NOTE: For build installer locally you need to make sure that each project that is going to be installed as a component, that in the appsettings.json both the "RunAsService" needs to be true and the ConnectionString needs to be updated/accurate to their DB (or Utopia)

  1. Open Utopia installer project and navigate to appsettings.json file
  2. Specify all components which should be included into installer in this configuration file. By default it contains configuration for including all Utopia componets, but it can be easily changed. If some component should be excluded from installer, it just should be removed from Components section in appsettings.json. This is the appsettings.json structure:
  "BundleTargetDirectory": "[ProgramFilesFolder]eFileCabinet",- Default installation directory for bundle
  "ProjectTargetDirectory": "%ProgramFiles%\\eFileCabinet",   - Default installation directory for msi
  "BundleName": "Utopia Bundle",                              - Bundle name
  "BundleVersion": "1.0.0",                                   - Bundle version
  "ProjectName": "Utopia Solution",                           - Installer name (will be included into bundle)
  "Components": [                                             - List of components
    {
      "Identifier": "ce279e3c-8c3e-469c-9454-6f4b9035eae8",   - Unique component identifier (GUID), it is used by windows to detect if this component already installed.
      "SourceDirectory": "..\\..\\pgsql",                     - Root directory with component's files
      "ApplicationFolder": "eFileCabinetDatabaseService",     - Target component directory in installation path
      "ServiceName": "eFileCabinet Database Service",         - Feature / Service name
      "Required": true,                                       - Required for installation
      "IncludeIntoBundle" : true,                             - If true then msi will be included into the bundle
      "AfterInstall": {                                       - After install block
        "DirectoryForCheck": "data",                          - If this directory DOESN'T exist, after install actions will be executed
        "Actions": [                                          - After install actions    
          {
            "File": "bin\\initdb.exe",                        - File to execute
            "Arguments": "-D ../data -U postgres -A trust",   - Execution arguments
            "WaitForExit": true                               - Sync or async execution (in current example - sync),
            "Local": true                                     - if true then full installation path will be added to the file
          }
        ]
      },
      "BeforeUninstall": {                                    - Before Uninstall block
        "Actions": [
          {
            "Local": false,                                   
            "File": "cmd.exe",
            "Arguments": "/C \"net.exe stop ^\"eFileCabinet Database Service^\"\"",
            "WaitForExit": true
          },
          {
            "Local": false,
            "File": "cmd.exe",
            "Arguments": "/C \"sc.exe delete ^\"eFileCabinet Database Service^\"\"",
            "WaitForExit": true
          }
        ]
      }
      "DependsOn": [                                           - List of required for installation components. It WILL NOT be displayed in Feature select list
        {
          "SourceDirectory": "..\\..\\Prizm",                  - Root directory with component's files
          "ApplicationFolder": "PrizmDoc",                     - Target component directory in installation
          "AfterInstall": {                                    - After install block
            "DirectoryForCheck": "PrizmServer",                - If this directory DOESN'T exist, after install actions will be executed
            "Actions": [
              {
                "File": "PrizmInstaller.exe",                  - File to execute
                "WaitForExit": false                           - Sync or async execution (in current example - async)
              }
            ]
          }
        }
      ]
    }
]

3a. If AccusoftPreviewer (PrizmDoc) should be included, do the following steps:
3a1. Put PrizmDoc Server Installer, PrizmDoc Client installer and PrizmInstaller.exe (result of 1a) into the one directory.
3a2. Rename PrizmDoc Server Installer from PrizmDocServer-<version>.exe to PrizmDocServer.exe and PrizmDoc Client installer from PrizmDocClient-<version>.exe to PrizmDocClient.exe
image.png
3b. If ElasticSearch should be included, do the following steps:
3b1. Download OpenJDK8 (https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jdk_x64_windows_hotspot_8u292b10.zip ) and elasticsearch 6.* (https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.11.zip )
3b2. Unzip elasticsearch into the new folder
3b3. Unzip java into the folder from 3b2
3b4. Rename jdk8u292-b10 folder to java.
Result of 3b1 - 3b4 should be like on the screenshot below
image.png
4. Build project (It can takes more than 10 minutes). During the build installer with name <BundleName>.exe will be created. (This project can't be run, only build action is required)

Local build Issues

Missing assembly: System.Drawing

  1. The folder that this assembly sits in is mega hidden. The only way to access it is by entering the run tool (Windows + R) and then type C:\Windows\assembly\GAC_MSIL
  2. Check this repository. You're looking for System, System.Core, System.Drawing, and System.Windows.Forms
  3. Add any missing folders from here 
Utopia

Azure Active Directory SAML Configuration (2020)

  1. In Azure search for "Enterprise applications"
  2. On "Enterprise applications" click "New application". Then click "Non-gallery application"
  3. Put whatever you want to the name field (I named it "TestSaml") and press "Add"
  4. On your app page select "Single sign-on" and then select "SAML"

image.png

  1. You should see SAML settings and configurations. You will need "Certificate" (base64), "Login URL (Azure)" and "Azure AD Identifier"

image.png

  1. Go to Rubex -> Hamburger menu -> Admin -> Settings -> Single Sign-On Settings -> Create Saml Configuration.
    Name: Whatever you like
    Issuer: Copy contents of "Azure AD Identifier"
    Entity ID: Whatever valid URL you like
    Saml Endpoint: "Login URL (Azure)"
    Certificate: Load "Certificate" file

image.png

  1. Click Create/Update. You will need "Login URL (Rubex)"
    THIS URL SHOULD BE HTTPS!!! Otherwise, it will not work with Azure

image.png

  1. Go back to Azure app settings.
    Identifier (Entity ID): Put the same Entity ID as in Rubex
    Reply URL: Copy "Login URL (Rubex)"
    Save everything. You can also press the Test button to test auth from Identity Provider

image.png

  1. To add users to Active Directory search for "Users" in top search bar.
  2. To add groups to Active Directory search for "Groups" in top search bar. Set type as "Security" and add some users during creation.
  3. To add users to SAML application go back to the Enterprise application, select users and groups and add existing AD users

image.png

  1. To import groups select "Single Sign-on" -> "User attributes & claims"

image.png

  1. Then click "add a group claim", check "Customize the name...", Name: "groups" or something else. The namespace should be empty. Source attribute needs to be checked for different values, because ID returns... ID! Save everything

image.png

  1. Put the same name ("groups") to Rubex saml settings

image.png

Utopia

OneLogin SAML SSO Configuration

  1. Create developers OneLogin Account.
  2. After the registration go to Applications page and push Add App button.
    Screenshot_2020-07-24 https chevron-dev onelogin com.png
  3. In the search field print "SAML" and select SAML Test Connector (Advanced).
    OneLogin_APP.PNG
  4. Save application.
  5. Navigate to SSO tab. There are three URLs and certificate on this page. We need two of these URLs (Issuer URL and SAML 2.0 Endpoint (HTTP)) and certificate.
    Screenshot_2020-07-24 OneLogin_4.png

Screenshot_2020-07-24 OneLogin_1.png

  1. Open Rubex on another tab (or browser) and navigate to SAML configuration (Admin -> Settings -> Single Sign-On Settings).

  2. Create new SAML configuration.

  3. Fill Issuer field with value from OneLogin Issuer URLSaml Endpoint with value from SAML 2.0 Endpoint (HTTP)Entity ID with any url. Aslo specify SAML Attribute Name for Groups (attribute where all user groups will be listed, usually Group) and upload OneLogin certificate downloaded on step 5
    Image Pasted at 2020-7-24 15-18.png

  4. Save configuration and open it again. Save Login URL from the bottom of this page.

  5. Back to OneLogin. Navigate to Configuration tab.

  6. Fill Audience (EntityID) with the same URL like in Entity ID Rubex SAML Configuration, RecipientACS (Consumer) URL and Login URL with Login URL from Rubex SAML Configuration. Save configuration.
    Screenshot_2020-07-24 OneLogin_2.png

  7. Navigate to Parameters tab and add Group attribute (Do not forget to select Include in SAML Assertion)
    Screenshot_2020-07-24 OneLogin_3.png.
    Push Save button. On the next window select default value for this attribute (It can be any user attribute (default or custom)) and save it again.

  8. Save all configuration again.

Utopia

Okta SAML SSO Configuration

Setting up Okta

  1. Go to the Admin Dashboard and create an app integration.
    • Select SAML 2.0
  2. Have the fields match as to what is shown in the below screenshots for the Configure SAML section
    • Keep in mind that the Single-sign on URL will be dependent on the environment you're setting this up for, and the ID at the end will be dependent on your Revver SAML Config (once the config is created in Revver, edit it and the URL will contain the ID)
    • The SAML Issuer Id needs to begin with http://www.okta.com/ but anything after that is up to you.  It does need something and it needs to be unique, but it is something that you can make up if you'd like image.png

      image.png

       

  3. Once it's been configured and the app is up and running, you'll need to get the SAML signing certificate
    • Inside the app, go to the Sign On tab 

      image.png

    • Find and download the SHA-1 Certificate (note you may need to activate it first.  In which case ignore the warning and continue)

      image.png

    • You will receive a .cert file.  Change the extension type to .cer

Configuring SAML in Revver 

  1. Configure the name
  2. The Issuer is the Issuer Id configured above
    • You can find this in Okta by going to going to the Sign On tab => Scroll to the Settings section => Click More Details => Issuer
  3. The Entity ID will match the Audience Restriction area in Okta's app by going to General => SAML Settings => Audience Restriction
  4. Be careful when using the SAML Endpoint as Okta has some misleading areas to find this
    • This can be found in Sign On => Settings => More Details => Sign on URL
  5. Leave the rest blank (or configure as needed)
  6. For the Signature, Choose File => Select the .cer file (formerly a .cert file) that was downloaded (see the above Setting Up Okta section)
  7. Click save

Here's an example Config:

image.png

Utopia

Entity Framework Code First

Difference between code first and DB first

In code first approach we have

  • entity to tables mapping in the C# code instead of .edmx XML file
  • use a general connection string. We don't need to specify configuration files in the connection string
  • We create all entities and mapping manually instead of code generation in DB first
  • EF can update DB with using our mapping

Entities and mapping

We create entities as general C# objects. Most of them are the same as
Mapping will bind entities to the DB tables. We can apply mapping in two ways:

  • Use code annotations attributes
  • Use fluent API with DbModelBuilder
  • We can combine these two approaches in the same context. (we apply this approach in the Utopia)
  • Use separately classes with mapping for each entity. (This approach we used in workflows.)

mapping example:

Mapping by attributes

public partial class DbNode
    {
        [Key]
        public long Id { get; set; }

        [Required]
        [StringLength(255)]
        public string Name { get; set; }

Mapping by modelBuilder

 public partial class UtopiaDB : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // map foreign key.One to many
            modelBuilder.Entity<DbNode>()
                            .HasMany(e => e.DbEmailQueueAttachmentNodes)
                            .WithRequired(e => e.DbNode)
                            .HasForeignKey(e => e.NodeID)
                            .WillCascadeOnDelete(false);

            // map foreign key. many to many
            modelBuilder.Entity<DbSearchCriteria>()
                .HasMany(e => e.DbTriggers)
                .WithMany(e => e.DbSearchCriterias)
                .Map(m => m.ToTable("DbTriggerToSearchCriteria")
                                    .MapLeftKey("SearchCriteriaId")
                                    .MapRightKey("TriggerId"));

            // map complex primary key
            modelBuilder.Entity<DbTriggerInfoNodes>()
                .HasKey(e => new {e.TriggerID, e.NodeInfoType});
        }
    }

Mapping by mapping class (used in WF)

public class DbWorkflowMap : EntityTypeConfiguration<Workflow>
    {
        public DbWorkflowMap(string tablePrefix)
        {
            ToTable(tablePrefix + "DbWorkflows");

            HasKey(t => t.Id);
            Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            HasMany(t => t.Owners).WithMany().Map(a => a.MapLeftKey("WorkflowID")
                                                        .MapRightKey("UserID")
                                                        .ToTable(tablePrefix + "DbWorkflowOwners"));
                                    

Migration

To update the DB structure we use migration.

  • Migration is a C# class that contains updating instruction.
  • EF can generate migrations automatically

How to change structure

  1. Add changes to entities and mapping if it needed
  2. Create a migration for this changes. To make it automatically create a migration, run this command in the Package Manager Console:
Add-Migration "MigrationNameHere" -ProjectName DataAccess -ConnectionString "data source=(localdb)\MSSQLLocalDB;initial catalog=UtopiaDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" -ConnectionProviderName System.Data.SqlClient -ConfigurationTypeName UtopiaDBMigrationConfiguration
  1. After this command EF will generate C# class for this migration. Please check it
        public partial class InitialMigration : DbMigration
            {
                public override void Up()
                {
                   //Some instructions
                }

                public override void Down()
                {
                }
            }
  1. To apply migration to the DB you can run next command:

Update DB to the last state

update-database -verbose -ProjectName DataAccess -ConnectionString "data source=(localdb)\MSSQLLocalDB;initial catalog=UtopiaDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" -ConfigurationTypeName UtopiaDbMigrationConfiguration -ConnectionProviderName System.Data.SqlClient

Update/Downgrade db to a specific migration.

update-database -TargetMigration:<Insert migration name> -verbose -ProjectName DataAccess -ConnectionString "data source=(localdb)\MSSQLLocalDB;initial catalog=UtopiaDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" -ConfigurationTypeName UtopiaDbMigrationConfiguration -ConnectionProviderName System.Data.SqlClient

Update for updating remote DB's/connections that require authentication:

update-database -verbose -ProjectName DataAccess -ConnectionString "data source={databaseserveraddress};User={databaseUsername};password={password};initial catalog={schemaName};integrated security=False;MultipleActiveResultSets=True;App=EntityFramework" -ConfigurationTypeName UtopiaDbMigrationConfiguration -ConnectionProviderName System.Data.SqlClient
  1. Applied migrations are stored in __MigrationHistory table

PostgreSQL process

There are several things that are different during PostgreSQL Code-First Migration process:

  1. Update DB to the last state
update-database -verbose -ProjectName DataAccess -ConnectionString "Host=localhost;Database=UtopiaDB;Integrated Security=False;Username=postgres;Password=pass@word1;Port=5432" -ConfigurationTypeName UtopiaDbMigrationConfiguration -ConnectionProviderName Npgsql
  1. If Package Manager Console cannot update database, DbMigratorEF project can be used. Pay attention to constants and main method before running it, main methods are UpdateDatabase(config) and ScaffoldNewMigration(config)

  2. During master merging into feature/OnPremiseMaster new migrations should be deleted and rescafolded. If "dbo" scheme appears after migration, that means one or more migrations are not deleted.



1 visit in last 30 days
Quinn Godfrey
Quinn Godfreycommented Jul 6, 2020 (edited)

Generate SQL for migration:
Update-Database -Script -SourceMigration: [CurrentAppliedMigrationName] -TargetMigration: [MigrationToUpdateToName]

Trevor Chadwick
Trevor Chadwickcommented Jul 21, 2020 (edited)

Update for updating remote DB's/connections that require authentication:
update-database -verbose -ProjectName DataAccess -ConnectionString "data source={databaseserveraddress};User={databaseUsername};password={password};initial catalog={schemaName};integrated security=False;MultipleActiveResultSets=True;App=EntityFramework" -ConfigurationTypeName UtopiaDbMigrationConfiguration -ConnectionProviderName System.Data.SqlClient

Chayston Wood

Update DB to the last state - NO VERBOSE
update-database -ProjectName DataAccess -ConnectionString "data source=(localdb)\MSSQLLocalDB;initial catalog=UtopiaDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" -ConfigurationTypeName UtopiaDbMigrationConfiguration -ConnectionProviderName System.Data.SqlClient

Bryan Christensen
Bryan Christensencommented Nov 23, 2020

This message comes through when I went and changed DbNodeClosures ID, needing to drop the restraint and change the Primary Key name. We were forcing users to Manual to change these, but we can use this script (or a variant of it) to do the rename automatically.

From Roman Alekhin
@BryanC this script searching constraint name in sys.key_constraints which contains constrains names for all tables. We just specify table name and constraint type (PK or UK) and receive for example primary key name for specific DB. As result we will receive correct name for any person's DB.
This will find PK or UK by table name in sys.key_constraints and generate SQL script for dropping it

private const string BasicScript = @"DECLARE @TableName NVARCHAR(128)
            SELECT @TableName = '<tableName>'
            DECLARE @SQL NVARCHAR(MAX)
            SELECT 
                @SQL = 'ALTER TABLE ' + @TableName + ' DROP CONSTRAINT [' + kc.name + ']'
            FROM
            sys.key_constraints kc
            WHERE
            kc.[type] = '<constraintType>'
                AND kc.parent_object_id = OBJECT_ID(@TableName)
            EXEC SP_EXECUTESQL @SQL";

This just replaces <constraitType> macro to PK

private const string ConstraintTypePlaceholder = "<constraintType>";
private const string PrimaryKeyConstraintType = "PK";
private readonly string _dropPrimaryKeyScript =
            BasicScript.Replace(ConstraintTypePlaceholder, PrimaryKeyConstraintType);

And this drops PK for all tables in list:

private const string TableNamePlaceholder = "<tableName>";
private void DropPrimaryKeyConstraint(string[] tableNames)
        {
            foreach (var tableName in tableNames)
            {
                Sql(_dropPrimaryKeyScript.Replace(TableNamePlaceholder, tableName));
            }
        }
Utopia

Code First Training Video

https://youtu.be/goRtW-1c_BY

Utopia

Entity Framework Optimizations

Entity framework does not have great performance when dealing with large batches of data. We've compiled this list as a reference so that our batch operations can be efficient as possible.

Please Read these Articles

https://weblog.west-wind.com/posts/2014/dec/21/gotcha-entity-framework-gets-slow-in-long-iteration-loops 
https://weblog.west-wind.com/posts/2013/Dec/22/Entity-Framework-and-slow-bulk-INSERTs 

Disable Auto Detecting Changes

see https://docs.microsoft.com/en-us/ef/ef6/saving/change-tracking/auto-detect-changes 

using (var context = new BloggingContext())
{
    try
    {
        context.Configuration.AutoDetectChangesEnabled = false;

        // Make many calls in a loop
        foreach (var blog in aLotOfBlogs)
        {
            context.Blogs.Add(blog);
        }
    }
    finally
    {
        // make sure you re enable AutoDetectChangesEnabled before calling SaveChanges
        context.Configuration.AutoDetectChangesEnabled = true;
        await context.SaveChangesAsync();
    }
}

Bloated DbContext

With Entity Framework, you have a dbContext object that tracks all the entities you've read from the database and changes that have been made to them. If it starts to track too many entities you can start getting pretty slow performance.

There a several thanks that can be done to address this issue.

.AsNoTracking()

List<DbNodes> childNodes = UtopiaDB.DbNodes.Where(i => i.ParentID = 1).AsNoTracking().ToListAsync();

When you use .AsNoTracking() the entities that get returned will not be tracked by the dbContext. You should use this when you are querying data from the db that is read only.

Re-Create DbContext Object

The easiest way to get past a bloated dbContext is to create a new dbContext object.

This is difficult in our Utopia solution because create one dbContext object per session, so unless a new session is created, a new dbContext object cannot be created.

To address this we have added code to to detach all entities from the dbContext

UtopiaDB.DetachEntitiesFromUtopiaDB();

The intent behind this code was to have the same effect as creating a new DbContext object.

Smaller Batches

Typically we've seen better performance when we process things in smaller batches (500 items or less), call 'SaveChangesAsync()', then detach all entities from the DbContext object, and process another small batch.

Utopia

Adding a new Email Type

Steps required to add a new email type

  1. Add the new email type to the EmailEnum in UtopiaSharedClasses
  2. Add the new email template inside of UtopiaSharedResources
    You must add both an efilecabinet and a SecureDrawer version of name format:
    xx_eFileCabinet.html
    xx_SecureDrawer.html
  3. Change VS property "Copy to Output Directory" to "Copy Always" on those html files
  4. The Hub must be published and any partners must have their own templates added
Utopia

Utopia External Login Instructions and Options

Utopia External Login Instructions and Options
This file is to explain how to create an external login page and the options available
External Login Instructions

  1. Create an iframe with the src set to "~/#/extLogin/" (replace ~ with host site)
  2. Examples:

<iframe src='https://app.securedrawer.com/#/extLogin/'/> <iframe src='https://express.efilecabinet.net/#/extLogin/'/>

External Login Options and Notes

  1. Open a New Tab on Successful Login - this is done by setting the src to "~/#/extLoginNewTab/". a. This will authorize the user in a new tab and clear out their login details after success b. This will allow websites to embed a small login snippet and not a full page iframe. c. Minimum height and width of the iframe is: height="305px" width="250px"
  2. Redirect to Specific Logcation After Login - This is accomplished by appending the desired location to the src. a. Redirect Instructions: 1. Navigate to the desired redirect location inside the system. 2. Copy the segment of the URL that appears after the hash '#' 3. Append that segment to the end of the src URL "/#/home/state/data/node/490025/1375574/details/1375574" - a location in my account b. I now copy "/home/state/data/node/490025/1375574/details/1375574" c. and append it the src URL "https://~/#/home/state/data/node/490025/1375574/details/1375574 " d. Now anyone logging in through that iframe will be redirected to the navigated location automatically if they have access to it.
Utopia

Test Against Production Read Replica

To follow our security policy YOU MUST HAVE TWO OTHER DEVELOPERS OBSERVING when you access production information

Be sure to step over the listed breakpoints to ensure we don't send notifications to users in production

Note: The snapshot of production is likely from a previous date. Ensure that your branches state will work with where production was at.

  1. If remote, connect to the VPN
  2. Delete the conf.json file from C:\ProgramData\EFC\Configuration
  3. Use the DbConnectionConfigurationData string from Prod DB Read Replica found in the Shared-Development section in LastPass to update the DbConnectionConfigurationData string in Utopia's appsettings.json.
  4. Add a breakpoint to step over  await ValidatePasswordAsync(password, dbUser); in the method ValidateUsernameAndPasswordAsync in BusinessLogic/Services/AuthenticationService.cs
  5. Add loginRequirementsStatus.UserSettingMFARequirementMet = true; below where the loginRequirementsStatus gets set in the method GetUserLoginRequirementsStatusAsync in BusinessLogic/Services/AuthenticationService.cs
  6. And add a breakpoint to step over: PopulateUserSettingLoginRequirements, PopulateSecurityPolicyStatuses, await PopulateRolesFailingOtherRequirementsAsync, InvalidateGroupRolesWhereUserRoleIsFailing in the method GetUserLoginRequirementsStatusAsync in BusinessLogic/Services/AuthenticationService.cs 



Utopia

How to run local Utopia over LAN/connect from outside network

Why

At times it may be helpful to connect to your local instance of Utopia from other devices to be able to debug/test:

To name a few.  Also, it just feels cool.

How to setup Utopia over LAN

The key here is to set up IIS properly and then open whatever ports are needed on your firewall.

  1. Lets first get your local IP
    1. Run command prompt
    2. Type ipconfig
    3. Copy and save your IPv4 Address
      • image.png

  2. Inside of Visual Studios, click on the IIS Express dropdown arrow and select Utopia Debug Properties
    • image.png
  3. Scroll down until you see App URL.  Replace localhost with the saved IPv4 Address
    • image.png

  4. Close the window
  5. Find the .vs hidden folder of the Utopia solution and then go into Utopia\Config and open applicationhost.config
    1. For me it's C:\src\Utopia\Utopia\.vs\Utopia\config\applicationhost.config
  6. Inside of applicationhost.config, find where it sets up it's bindings
    1. Usually around line 162
    2. Searching for binding and it should go straight to it
  7. Duplicate the two lines that bind the two ports to localhost.  Replace localhost with your saved IPv4 Address on those duplicated lines.
    • image.png

  8. Next, open up the ports inside of your windows firewall
    1. You will need to open up port 44334 for both UDP and TCP
      • Actually not sure if you need both but I did just in case
      • In some instances you may need to open 57584 as well
        • I had to to be able to connect from the company mac via the desktop client (it was yelling at the not trusted certificate)
      • Allow the connection
      • Have Domain, Private, and Public all checked
      • Give it a meaningful name
      • image.png

  9. Close out Visual Studio completely
  10. Open Visual Studio as administrator
    • image.png

  11. Finally, open Utopia and run it with IIS Express


Note: 

How to connect from outside network

This one is actually really simple.  All you need to do is do some port forwarding.  I'm not going to get into how to do this since each router is unique (basics is to log into the router and go to advanced).


Note:
Utopia

How to create a new user license type

C#

UtopiaSharedClasses\Enums\UserLicenseEnums.cs
UtopiaSharedResources\Utilities\UserLicenseUtilities.cs
UtopiaSharedClasses\Enums\AccountFeatureEnum.cs
UtopiaSharedResources\Language\EnumDisplayNames.resx
UtopiaSharedClasses\Classes\AccountClasses.cs
  • Add an int property to the AccountUsage class
BusinessLogic\Services\AccountService.cs
BusinessLogic\Services\AccountUsageService.cs
DataAccess\Methods\RoleMethods.cs

JavaScript

wwwroot\Client\app\accountFeature\accountFeatureServices.js
wwwroot\Client\app\auth\authFactories.js
wwwroot\Client\app\permission\permissionServices.js
wwwroot\Client\app\roles\roleServices.js
Utopia

Concurrent Licenses

This feature is primarily used by Caselle

Utopia Architecture

Utopia Architecture

eFC Enterprise Architecture

Introduction

eFileCabinet has 3 Legacy platforms and 1 flagship platform that all legacy platforms are migrating to.

Reference: Utopia Architecture.pptx

Flagship

Legacy Platforms

Supporting Systems

The following are systems utilized to support selling, supporting, and provisioning these platforms.

Legacy Supporting Systems

The following are system previously used for selling, supporting, and provisioning

Utopia Architecture

Enterprise Architecture Diagram

image.png

Windows Desktop Client

Windows Desktop Client

Utopia Windows Desktop Client Update Creation Process

To Create an update to the Utopia Windows Desktop Client, you will do the following steps:

  1. Right-click the UtopiaWindowsDesktopClient project in Visual Studio and select Properties.
  2. Under the Application tab on the left side, click the "Assembly Information" button.
  3. Change both the Assembly version and the File version. (Yes, you must do both!)
  4. Click Ok, Save All.
  5. Select the UtopiaWindowsDesktopClientSetup and go to the properties window.
  6. Change the "Version" property to match the version set in Assembly Information.
  7. Save All, this will prompt you to automatically change the Product Code, Accept this. (We want it to change the Product Code. NEVER Change the Upgrade Code)
  8. To create a new exe:
    1. Clean and rebuild the solution in Debug
    2. Switch to Release mode
    3. Right click UtopiaWindowsDesktopClientSetup and Rebuild or Build
  9. Take the resulting "RubexInstaller.exe", found in UtopiaClientApplications\UtopiaWindowsDesktopClient\UtopiaWindowsDesktopClientSetup\Release within your local repo, and copy it to the Utopia Web Project's ClientApplicationInstallers/Windows folder. (Replacing the existing installer)
  10. Edit the WindowsClientVersion.json file in the given folder, change the Version property to the correct value.

Congratulations, You've updated the Windows Desktop Client!

Windows Desktop Client

Update CefSharp to 64 bit (when we want to do it)

When updating the build of this application, you must change the version number in the Assembly Information of the UtopiaDesktopClientApplication AND the UtopiaWindowsDesktopClientSetup version.

Most of this should build and run out of the box. However, there are some CefSharp caveats,
first and foremost, CefSharp cares about x86 vs x64. Everything is currently targeting x86, but if and when the day comes that we do a x64 version, here are some of the changes needed (May want to consider making x86 and x64 versions with a shared project, same with installer):

  1. Change the targeting to x64 in the configuration manager.
  2. You may have to change the references in the UtopiaWindowsDesktopClient project to target the x64 versions of the cefsharp dlls (CefSharp, CefSharp.Core, CefSharp.Wpf)
  3. The following files directly referenced in the setup project will need to be pointed at the x64 versions:
    a. CefSharp.BrowserSubprocess.Core.dll
    b. CefSharp.BrowserSubprocess.exe
    c. cef.pak
    d. cef_100_percent.pak
    e. cef_200_percent.pak
    f. cef_extensions.pak
    g. chrome_elf.dll
    h. d3dcompiler_47.dll
    i. icudtl.dat
    j. libcef.dll
    k. libEGL.dll
    l. libGLESv2.dll
    m. natives_blob.bin
    n. snapshot_blob.bin
    o. v8_context_snapshot.bin
Windows Desktop Client

Client Application Update Process

Untitled Diagram.png

Windows Desktop Client

Code Scanning

Resources

Background

We wanted to do a code scan of the Revver Desktop App, but after some research and some trial and error, we found that this was going to be more difficult than anticipated.

In order to be able to used ADO advanced security to code scan, we needed to build the app in and ADO pipeline. There are two issues with this. 1) you can't build a .vsproj project (Visual Studio Installer Project) in ADO pipelines (well, we probably could if we we had our own build machines), and 2) our projects store nuget packages in a packages.config file and the ADO pipelines have issues restoring nuget packages when they are configured this way.

We attempted migrating from the packages.config to package references, and this was successful, however, it broke the installer project. We did spend several hours trying to see if we could reconfigure things in the installer project so that when you built the installer, things would work, but did not want to spend more effort trying to get this to work, so eventually gave up on this.

In the end, a pipeline was created (referenced at the top of this page), but it cannot currently be used with the master branch. In order to do a code scan you need to branch off of master, migrate the packages.config to package references, and run the pipeline on that branch. Keep in mind this will not scan the installers, just the build projects.

Doing a code scan

  1. Create a branch of master (or the branch you want to create a new update installer off of)
  2. Migrate from packages.config to package references
    • you can use the reference at the top of this page for instructions on how to do this (but long story short, you right click the packages.config file and select Migrate packages.config to PackageReference...)
  3. Commit the changes to your branch and push it to ADO
  4. Run the 'Revver Windows Desktop App Code Scan' build pipeline on your branch

How can we automate this in the future?

I think the best way to do this would be to build the installer using wixsharp, rather than a visual studio installer project.

 

Windows Desktop Client

How To Update CefSharp Version

This update process may not work for future updates to CefSharp. The next version of CefSharp starts using some different libraries (chromiumembeddedframework instead of cef.redist.x86). Knowing these steps will likely still be important though because we will still likely need to update the setup / installer project

  1.  Update the version of CefSharp.Wpf to the desired version
    • This will also update CefSharp.Common and cef.redist.x86 and cef.redist.x64image.png
  2. Attempt to rebuild the UtopiaWindowsDesktopClient (Release | x86), you should get build errors in the output console indicating that it couldn't find files specific to the previous version of CefSharp.
    • example error
      • ERROR: Unable to find source file 'C:\src\UtopiaClientApplications\UtopiaWindowsDesktopClient\packages\cef.redist.x86.109.1.11\CEF\locales\ru.pak' for file 'ru.pak', located in '[TARGETDIR]\locales', the file may be absent or locked. 
    • You may also get build errors you need to resolve because CefSharp updates are not always backwards compatible.
  3. In the UtopiaWindowsDesktopClient project, double click the first file (af.pak currently) to open up a view that looks like the following screen shot
    • image.png

  4. Delete all the files that are currently in the 'locales' folder.

    • image.png

  5. Right click the 'locales' folder on the left, and in the dropdown select 'Add' -> 'File', and add all the files from 'C:\src\UtopiaClientApplications\UtopiaWindowsDesktopClient\packages\cef.redist.x86.{UPDATED_TO_VERSION}\CEF\locales'
  6. Now select the 'Application Folder' folder on the left.
  7. Delete any files that start with the following paths (be vary careful when you do this so you don't accidentally delete a file you weren't supposed to)
    • C:\src\UtopiaClientApplications\UtopiaWindowsDesktopClient\packages\CefSharp.Common.109.1.110\CefSharp\x86\
    • 'C:\src\UtopiaClientApplications\UtopiaWindowsDesktopClient\packages\cef.redist.x86.109.1.11\CEF\
    • image.png

    • you can reference the errors in the output console when building to see exactly what files it can't find and need to be deleted
    • they may also be underlined in blue
  8. Right click 'Application Folder' on the left, and in the dropdown select 'Add' => 'File', and all the files from 'C:\src\UtopiaClientApplications\UtopiaWindowsDesktopClient\packages\cef.redist.x86.{UPDATED_TO_VERSION}\CEF' except for the following
    • locales folder
    • README.txt
    • LICENSE.txt
    • maybe keeps eyes out for other .txt files that might be added the future (you basically want the .dlls. .pak, .dat, .bin, and .json files)
    • image.png

  9. Right click 'Application Folder' on the left, and in the dropdown select 'Add' => 'File', and all the files from 'C:\src\UtopiaClientApplications\UtopiaWindowsDesktopClient\packages\CefSharp.Common.{UPDATED_TO_VERSION}\CefSharp\x86' 
    • image.png

  10. You may want to make sure that you now don't have any duplicate files in 'Application Folder' or any files that you missed deleting that referenced the old CefSharp version.
  11. You should now be able to build the installers per ususal.

Archived

Archived

Azure Arc Citus Deployment

How to deploy Azure Arc

Basicly, this guide  provides almost all things required for deployment arc in EKS. There are some tips about this cluster creation

  1. Variables
    image.png
    TF_VAR_client_id: everywhere in description it is named as "Principal name" and if you will see the response of principal creation, it contains "name" field image.png
    But in fact in this variable you need to specify appId

  2. terraform apply
    image.png
    When I did that, this step was failed on deploying windows server VM with issue "file is locked". To avoid this you need to add an additional flag to the command. Result is:
    terraform apply --auto-approve --lock=false

How to create citus cluster and connect to it

  1. Connect via RDP to the machine with arc and open shell.
  2. Login to azdata: azdata login --namespace $env:ARC_DC_NAME
    2.1 It'll output a url with port number defined, this is what you'll use in step 4 for the Controller URL.
  3. Create postgreSQL cluster: azdata arc postgres server create -n postgres01 --workers 2.
  4. Open Azure Data Studio and expand the Connections pane and expand the Azure Arc Controllers are and Connect Controller.
    4.1. If you receive an error: Could not connect to controller https://x.x.x.x:30080 . Microsoft Privacy statement and Azure Data CLI license terms have not been accepted. Execute the command: Azure Data CLI: Accept EULA to accept EULA to enable the features that requires Azure Data CLI. execute azdata login --namespace $env:ARC_DC_NAME --accept-eula ACCEPT_EULA and restart Azure Data Studio
  5. Expand Azure Arc Controllers -> [Your Arc Controller] and select [Your PostgreSQL cluster].
  6. Click on Reset Password button and specify new password for your cluster.
  7. You can connect to your cluster via PgAdmin or any other app

How to create distributed database

  1. Create new database

  2. Add citus extension

  3. Add worker nodes SELECT * from master_add_node('[worker_address]', 5432);

  4. Execute InitialMigration.sql to create db schema on master node

    • InitialMigration.sql can be found here
  5. Execute SELECT * FROM run_command_on_workers($cmd$ [content of InitialMigration.sql] $cmd$); to create db schema on worker nodes. (Citus doesn't propagate CREATE command)

  6. Run the following command on the master node

SELECT * FROM run_command_on_workers($cmd$ 
									 
CREATE SCHEMA IF NOT EXISTS "workflow";
CREATE SCHEMA IF NOT EXISTS "public";
CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA public
									 
$cmd$);
  1. Run the following command on the master node
alter table public."DbAccessLinks" drop constraint "FK_DbAccounts";
alter table public."DbAccountFeatures" drop constraint "FK_DbAccounts";
alter table public."DbAccountSettings" drop constraint "FK_DbAccounts";
alter table public."DbAccountSettings" drop constraint "FK_DbEmailSettings";
alter table public."DbAccounts" drop constraint "FK_BrandingID";
alter table public."DbAuditLogs" drop constraint "FK_DbAccounts";
alter table public."DbAuditLogsToNodeDetails" drop constraint "FK_DbAccounts";
alter table public."DbAuditLogsToNodes" drop constraint "FK_DbAccounts";
alter table public."DbAuditLogsToRoleDetails" drop constraint "FK_DbAccounts";
alter table public."DbAuditLogsToRoles" drop constraint "FK_DbAccounts";
alter table public."DbDocumentRequests" drop constraint "FK_DbAccounts";
alter table public."DbESignatureTransactions" drop constraint "FK_DbAccount";
alter table public."DbEmailImportMappings" drop constraint "FK_AccountID";
alter table public."DbEmailImportMappings" drop constraint "FK_EmailSettingID";
alter table public."DbEmailQueue" drop constraint fk_accounts;
alter table public."DbEmailQueue" drop constraint fk_emailsettings;
alter table public."DbEmailSettingToAccounts" drop constraint fk_account;
alter table public."DbEmailSettingToAccounts" drop constraint fk_emailsetting;
alter table public."DbEmailSettingToUsers" drop constraint fk_emailsetting;
alter table public."DbEmailTemplateToPartner" drop constraint "FK_DbEmailTemplate";
alter table public."DbFileInfoes" drop constraint "FK_AccountID";
alter table public."DbFileQueue" drop constraint "FK_Account";
alter table public."DbNodeAnnotations" drop constraint fk_account;
alter table public."DbNodeClosures" drop constraint "fk_accountID";
alter table public."DbAccessLinksToDocumentRequests" drop constraint "FK_public.DbAccessLinksToDocumentRequests_public.DbAccessLinks_";
alter table public."DbAccessLinksToNodeAndTriggers" drop constraint "FK_public.DbAccessLinksToNodeAndTriggers_public.DbAccessLinks_A";
alter table public."DbAccessLinks" drop constraint "FK_public.DbAccessLinks_public.DbRoles_RoleID_AccountID";
alter table public."DbAccessLinksToDocumentRequests" drop constraint "FK_public.DbAccessLinksToDocumentRequests_public.DbDocumentRequ";
alter table public."DbAccountSettings" drop constraint "FK_public.DbAccountSettings_public.DbSecurityPolicies_DefaultGu";
alter table public."DbAccountSettings" drop constraint "FK_public.DbAccountSettings_public.DbSecurityPolicies_DefaultUs";
alter table public."DbEmailImportMappings" drop constraint "FK_public.DbEmailImportMappings_public.DbNodes_NodeID_AccountID";
alter table public."DbAccessLinksToNodeAndTriggers" drop constraint "FK_public.DbAccessLinksToNodeAndTriggers_public.DbNodes_NodeID_";
alter table public."DbAuditLogsToNodes" drop constraint "FK_public.DbAuditLogsToNodes_public.DbNodes_NodeID_AccountID";
alter table public."DbNodeShares" drop constraint fk_account;
alter table public."DbNodeToFileInfoes" drop constraint "FK_DbAccounts";
alter table public."DbNodes" drop constraint fk_account;
alter table public."DbNotifications" drop constraint "FK_DbAccounts";
alter table public."DbPartners" drop constraint "FK_BrandingID";
alter table public."DbPermissions" drop constraint fk_account;
alter table public."DbPortfolioToNodes" drop constraint "FK_DbPortfolios";
alter table public."DbPortfolioToUsers" drop constraint "FK_DbPortfolios";
alter table public."DbPresetValues" drop constraint "FK_Account";
alter table public."DbProfileItems" drop constraint fk_account;
alter table public."DbProfiles" drop constraint fk_account;
alter table public."DbRetentionChangeReason" drop constraint "FK_DbAccount";
alter table public."DbRoles" drop constraint "FK_DbAccounts";
alter table public."DbSamlConfigurations" drop constraint "FK_DbAccounts";
alter table public."DbSamlResponses" drop constraint "FK_DbAccounts";
alter table public."DbSearchCriteria" drop constraint "fk_parentUserSearchCriteria";
alter table public."DbSecurityPolicies" drop constraint "FK_DbAccounts";
alter table public."DbSfLinks" drop constraint "FK_DbAccounts";
alter table public."DbSfMappings" drop constraint "FK_DbAccounts";
alter table public."DbTriggerToSearchCriteria" drop constraint "FK_DbSearchCriteria";
alter table public."DbUserImageStamps" drop constraint "FK_DbAccounts";
alter table public."DbUserSearchToSearchCriteria" drop constraint "FK_DbSearchCriteria";
alter table public."DbUserSearchToSearchCriteria" drop constraint "FK_DbUserSearches";
alter table public."DbUserSettings" drop constraint "FK_DbEmailSettings";
alter table public."DbUserSettings" drop constraint "FK_DbPortfolios";
alter table public."DbUsers" drop constraint "FK_DbUserSettings";
alter table workflow."DbWorkflowInstanceHistoryRecords" drop constraint "FK_DbWorkflowInstanceHistoryRecordTypes_RecordTypeID";
alter table workflow."DbWorkflowSteps" drop constraint "FK_DbWorkflowStepTypes_TypeID";
alter table public."DbDocumentRequestContainers" drop constraint "DbFileRequestContainers_check";
alter table public."DbDocumentRequests" drop constraint "DbFileRequests_check";
alter table public."DbTimeTriggers" drop constraint "check_timeTrigger_preActionNotificationTimeSpanInDays";
alter table public."DbTimeTriggers" drop constraint "check_timeTrigger_timeSpanInSeconds";
alter table public."DbComponentStatusHistories" drop constraint "FK_public.DbComponentStatusHistories_public.DbComponentStatus_C";
alter table public."DbDocumentRequestAttachments" drop constraint "FK_public.DbDocumentRequestAttachments_public.DbNodes_Attachmen";
alter table public."DbDocumentRequestContainerNodes" drop constraint "FK_public.DbDocumentRequestContainerNodes_public.DbNodes_NodeID";
alter table public."DbDocumentRequests" drop constraint "FK_public.DbDocumentRequests_public.DbNodes_DestinationNodeID_A";
alter table public."DbEmailQueueAttachmentNodes" drop constraint "FK_public.DbEmailQueueAttachmentNodes_public.DbNodes_NodeID_Acc";
alter table public."DbESignatureNodeAssociations" drop constraint "FK_public.DbESignatureNodeAssociations_public.DbNodes_OriginalN";
alter table public."DbESignatureNodeAssociations" drop constraint "FK_public.DbESignatureNodeAssociations_public.DbNodes_SignedNod";
alter table public."DbESignatureTransactions" drop constraint "FK_public.DbESignatureTransactions_public.DbNodes_AuditTrailNod";
alter table public."DbESignatureTransactions" drop constraint "FK_public.DbESignatureTransactions_public.DbNodes_AuditTrailPar";
alter table public."DbESignatureTransactions" drop constraint "FK_public.DbESignatureTransactions_public.DbNodes_SignedDocumen";
alter table public."DbNodes" drop constraint "FK_public.DbNodes_public.DbFileInfoes_FileInfoID_AccountID";
alter table public."DbFileQueue" drop constraint "FK_public.DbFileQueue_public.DbNodes_NodeID_AccountID";
alter table public."DbLegacyNodeMappings" drop constraint "FK_public.DbLegacyNodeMappings_public.DbNodes_NodeId_AccountID";
alter table public."DbNodes" drop constraint "FK_public.DbNodes_public.DbNodes_ParentID_AccountID";
alter table public."DbNodeAnnotations" drop constraint "FK_public.DbNodeAnnotations_public.DbNodes_NodeID_AccountID";
alter table public."DbNodeClosures" drop constraint "FK_public.DbNodeClosures_public.DbNodes_ChildID_AccountID";
alter table public."DbRoleRelationships" drop constraint "Parent_Is_Group";
alter table public."DbAccessLinks" drop constraint "FK_public.DbAccessLinks_public.DbUsers_CreatedByUserID";
alter table public."DbAuditLogs" drop constraint "FK_public.DbAuditLogs_public.DbUsers_UserID";
alter table public."DbAuditLogs" drop constraint "FK_public.DbAuditLogs_public.DbUsers_GeneratedByUserID";
alter table public."DbDocumentRequests" drop constraint "FK_public.DbDocumentRequests_public.DbUsers_CreatedByUserID";
alter table public."DbEmailImportMappings" drop constraint "FK_public.DbEmailImportMappings_public.DbUsers_CreatedByUserID";
alter table public."DbESignatureTransactions" drop constraint "FK_public.DbESignatureTransactions_public.DbUsers_UserID";
alter table public."DbFileInfoes" drop constraint "FK_public.DbFileInfoes_public.DbUsers_CreatedByUserID";
alter table public."DbNodeComments" drop constraint "FK_public.DbNodeComments_public.DbUsers_LastModifiedByUserID";
alter table public."DbNodeComments" drop constraint "FK_public.DbNodeComments_public.DbUsers_CreatedByUserID";
alter table public."DbNodes" drop constraint "FK_public.DbNodes_public.DbUsers_CreatedByUserID";
alter table public."DbPortfolios" drop constraint "FK_public.DbPortfolios_public.DbUsers_OwnerUserID";
alter table public."DbPortfolioToNodes" drop constraint "FK_public.DbPortfolioToNodes_public.DbUsers_AddedByUserID";
alter table public."DbPortfolioToUsers" drop constraint "FK_public.DbPortfolioToUsers_public.DbUsers_UserID";
alter table public."DbResetPasswordRequests" drop constraint "FK_public.DbResetPasswordRequests_public.DbUsers_UserID";
alter table public."DbRightSignatureUsers" drop constraint "FK_public.DbRightSignatureUsers_public.DbUsers_UserID";
alter table public."DbRoles" drop constraint "FK_public.DbRoles_public.DbUsers_UserID";
alter table public."DbSamlConfigurations" drop constraint "FK_public.DbSamlConfigurations_public.DbUsers_CreatedByUserID";
alter table public."DbTriggers" drop constraint "FK_public.DbTriggers_public.DbUsers_CreatedByUserID";
alter table public."DbUserApplicationsMfa" drop constraint "FK_public.DbUserApplicationsMfa_public.DbUsers_UserID";
alter table public."DbUserExternalAuthentications" drop constraint "FK_public.DbUserExternalAuthentications_public.DbUsers_UserID";
alter table public."DbUserImageStamps" drop constraint "FK_public.DbUserImageStamps_public.DbUsers_UserID";
alter table public."DbUserPasswordHistories" drop constraint "FK_public.DbUserPasswordHistories_public.DbUsers_UserID";
alter table public."DbUserSearches" drop constraint "FK_public.DbUserSearches_public.DbUsers_UserID";
alter table public."DbUserSessions" drop constraint "FK_public.DbUserSessions_public.DbUsers_UserID";
alter table public."DbUserSessions" drop constraint "FK_public.DbUserSessions_public.DbUsers_GeneratedByUserID";
alter table public."DbEmailSettingToUsers" drop constraint "FK_public.DbEmailSettingToUsers_public.DbUsers_UserID";
alter table public."DbRightSignatureDocuments" drop constraint "FK_public.DbRightSignatureDocuments_public.DbRightSignatureUser";
alter table public."DbFormFillPendings" drop constraint "FK_public.DbFormFillPendings_public.DbUsers_UserID";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowSteps_Db";
alter table workflow."DbWorkflowInstances" drop constraint "FK_workflow.DbWorkflowInstances_workflow.DbWorkflowInstanceStat";
alter table workflow."DbStageApproveResults" drop constraint "FK_workflow.DbStageApproveResults_workflow.DbWorkflowStageInsta";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI1";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI2";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI3";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI4";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI5";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI6";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI7";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI8";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI9";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset10";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset11";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset12";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset14";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset15";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset16";
alter table workflow."DbWorkflowESignatureStepInstanceUserReferences" drop constraint "FK_workflow.DbWorkflowESignatureStepInstanceUserReferences_wor1";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset17";
alter table workflow."DbWorkflowESignatureStepInstanceTemplateDocuments" drop constraint "FK_workflow.DbWorkflowESignatureStepInstanceTemplateDocuments_1";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset18";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset19";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset20";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset21";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset22";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset23";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset24";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset25";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset26";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset27";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset28";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset29";
alter table workflow."DbWorkflowStepInstanceDocumentRequestContainers" drop constraint "FK_workflow.DbWorkflowStepInstanceDocumentRequestContainers_wo1";
alter table workflow."DbAssetInstanceNodeReferences" drop constraint "FK_workflow.DbAssetInstanceNodeReferences_workflow.DbWorkflowAs";
alter table workflow."DbWorkflowAssetsStagesInstances" drop constraint "FK_workflow.DbWorkflowAssetsStagesInstances_workflow.DbWorkflo1";
alter table workflow."DbWorkflowStepInstanceEmailUserGroups" drop constraint "FK_workflow.DbWorkflowStepInstanceEmailUserGroups_workflow.DbWo";
alter table workflow."DbWorkflowStepInstanceEmailUsers" drop constraint "FK_workflow.DbWorkflowStepInstanceEmailUsers_workflow.DbWorkflo";
alter table workflow."DbWorkflowESignatureStepInstanceUserReferences" drop constraint "FK_workflow.DbWorkflowESignatureStepInstanceUserReferences_wor2";
alter table workflow."DbWorkflowESignatureStepInstanceTemplateDocuments" drop constraint "FK_workflow.DbWorkflowESignatureStepInstanceTemplateDocuments_2";
alter table workflow."DbWorkflowSendMessageInstanceRecipients" drop constraint "FK_workflow.DbWorkflowSendMessageInstanceRecipients_workflow.Db";
alter table workflow."DbWorkflowStepInstanceUserGroups" drop constraint "FK_workflow.DbWorkflowStepInstanceUserGroups_workflow.DbWorkflo";
alter table workflow."DbWorkflowStepInstanceUsers" drop constraint "FK_workflow.DbWorkflowStepInstanceUsers_workflow.DbWorkflowStep";
alter table workflow."DbWorkflowSetProfileInstanceItems" drop constraint "FK_workflow.DbWorkflowSetProfileInstanceItems_workflow.DbWorkfl";
alter table workflow."DbWorkflowShareStepInstanceNewUserReferences" drop constraint "FK_workflow.DbWorkflowShareStepInstanceNewUserReferences_workfl";
alter table workflow."DbWorkflowStepInstanceGroupReferences" drop constraint "FK_workflow.DbWorkflowStepInstanceGroupReferences_workflow.DbWo";
alter table workflow."DbWorkflowStepInstanceUserReferences" drop constraint "FK_workflow.DbWorkflowStepInstanceUserReferences_workflow.DbWor";
alter table workflow."DbWorkflowInstanceHistoryRecords" drop constraint "FK_workflow.DbWorkflowInstanceHistoryRecords_workflow.DbWorkfl1";
alter table workflow."DbWorkflowStepInstanceDocumentRequestContainers" drop constraint "FK_workflow.DbWorkflowStepInstanceDocumentRequestContainers_wo2";
alter table workflow."DbWorkflowRequestFileExternalStepInstanceRecipientGroups" drop constraint "FK_workflow.DbWorkflowRequestFileExternalStepInstanceRecipientG";
alter table workflow."DbWorkflowRequestFileExternalStepInstanceNewUserReferences" drop constraint "FK_workflow.DbWorkflowRequestFileExternalStepInstanceNewUserRef";
alter table workflow."DbWorkflowRequestFileExternalStepInstanceRecipients" drop constraint "FK_workflow.DbWorkflowRequestFileExternalStepInstanceRecipients";
alter table workflow."DbWorkflowStepDocumentRequestContainers" drop constraint "FK_workflow.DbWorkflowStepDocumentRequestContainers_workflow.D1";
alter table workflow."DbWorkflowRequestFileExternalStepRecipientGroups" drop constraint "FK_workflow.DbWorkflowRequestFileExternalStepRecipientGroups_wo";
alter table workflow."DbWorkflowRequestFileExternalStepNewUserReferences" drop constraint "FK_workflow.DbWorkflowRequestFileExternalStepNewUserReferences_";
alter table workflow."DbWorkflowRequestFileExternalStepRecipients" drop constraint "FK_workflow.DbWorkflowRequestFileExternalStepRecipients_workflo";
alter table workflow."DbWorkflowAddTriggerStepEmailUserGroups" drop constraint "FK_workflow.DbWorkflowAddTriggerStepEmailUserGroups_workflow.Db";
alter table workflow."DbWorkflowAddTriggerStepEmailUsers" drop constraint "FK_workflow.DbWorkflowAddTriggerStepEmailUsers_workflow.DbWorkf";
alter table workflow."DbWorkflowESignatureStepUserReferences" drop constraint "FK_workflow.DbWorkflowESignatureStepUserReferences_workflow.DbW";
alter table workflow."DbWorkflowESignatureStepTemplateDocuments" drop constraint "FK_workflow.DbWorkflowESignatureStepTemplateDocuments_workflow1";
alter table workflow."DbWorkflowSendMessageRecipients" drop constraint "FK_workflow.DbWorkflowSendMessageRecipients_workflow.DbWorkflow";
alter table workflow."DbWorkflowSetPermissionsStepUserGroups" drop constraint "FK_workflow.DbWorkflowSetPermissionsStepUserGroups_workflow.DbW";
alter table workflow."DbWorkflowSetPermissionsStepUsers" drop constraint "FK_workflow.DbWorkflowSetPermissionsStepUsers_workflow.DbWorkfl";
alter table public."DbNodeClosures" drop constraint "FK_public.DbNodeClosures_public.DbNodes_ParentID_AccountID";
alter table public."DbTriggers" drop constraint "FK_public.DbTriggers_public.DbAccounts_AccountID";
alter table public."DbEmailContent" drop constraint "FK_public.DbEmailContent_public.DbAccounts_AccountID";
alter table public."DbEventTriggers" drop constraint "FK_public.DbEventTriggers_public.DbAccounts_AccountID";
alter table public."DbTimeTriggers" drop constraint "FK_public.DbTimeTriggers_public.DbAccounts_AccountID";
alter table public."DbTriggerInfoNodes" drop constraint "FK_public.DbTriggerInfoNodes_public.DbAccounts_AccountID";
alter table public."DbTriggerToNode" drop constraint "FK_public.DbTriggerToNode_public.DbAccounts_AccountID";
alter table public."DbTriggerToWorkflow" drop constraint "FK_public.DbTriggerToWorkflow_public.DbAccounts_AccountID";
alter table public."DbTriggerToRoles" drop constraint "FK_public.DbTriggerToRoles_public.DbAccounts_AccountID";
alter table public."DbTriggerToSearchCriteria" drop constraint "FK_public.DbTriggerToSearchCriteria_public.DbAccounts_AccountID";
alter table public."DbProfileValueNodes" drop constraint "FK_public.DbProfileValueNodes_public.DbAccounts_AccountID";
alter table public."DbProfileToProfileItems" drop constraint "FK_public.DbProfileToProfileItems_public.DbAccounts_AccountID";
alter table public."DbProfileValueRoles" drop constraint "FK_public.DbProfileValueRoles_public.DbAccounts_AccountID";
alter table public."DbRoleRelationships" drop constraint "FK_public.DbRoleRelationships_public.DbAccounts_AccountID";
alter table public."DbRoleToAccountFeatures" drop constraint "FK_public.DbRoleToAccountFeatures_public.DbAccounts_AccountID";
alter table public."DbSystemPermissions" drop constraint "FK_public.DbSystemPermissions_public.DbAccounts_AccountID";
alter table public."DbEmailQueueAttachmentNodes" drop constraint "FK_public.DbEmailQueueAttachmentNodes_public.DbAccounts_Account";
alter table public."DbTemplateNodeChangeLogs" drop constraint "FK_public.DbTemplateNodeChangeLogs_public.DbAccounts_AccountID";
alter table public."DbTemplateNodeLinks" drop constraint "FK_public.DbTemplateNodeLinks_public.DbAccounts_AccountID";
alter table public."DbWorkflowStageInstanceToNotifications" drop constraint "FK_public.DbWorkflowStageInstanceToNotifications_public.DbAccou";
alter table public."DbRoleClosures" drop constraint "FK_public.DbRoleClosures_public.DbAccounts_AccountID";
alter table public."DbAccessLinksToNodeAndTriggers" drop constraint "FK_public.DbAccessLinksToNodeAndTriggers_public.DbAccounts_Acco";
alter table public."DbDocumentRequestRoles" drop constraint "FK_public.DbDocumentRequestRoles_public.DbAccounts_AccountID";
alter table public."DbNodeComments" drop constraint "FK_public.DbNodeComments_public.DbNodes_NodeID_AccountID";
alter table public."DbNodeShares" drop constraint "FK_public.DbNodeShares_public.DbNodes_AccountWorkspaceNodeID_Ac";
alter table public."DbNodeShares" drop constraint "FK_public.DbNodeShares_public.DbNodes_SharedWorkspaceNodeID_Acc";
alter table public."DbNodeToFileInfoes" drop constraint "FK_public.DbNodeToFileInfoes_public.DbNodes_NodeID_AccountID";
alter table public."DbPermissions" drop constraint "FK_public.DbPermissions_public.DbNodes_NodeID_AccountID";
alter table public."DbNodes" drop constraint "FK_public.DbNodes_public.DbProfiles_ProfileID_AccountID";
alter table public."DbProfileValueNodes" drop constraint "FK_public.DbProfileValueNodes_public.DbNodes_NodeID_AccountID";
alter table public."DbRightSignatureDocuments" drop constraint "FK_public.DbRightSignatureDocuments_public.DbNodes_NodeID_Accou";
alter table public."DbSfLinks" drop constraint "FK_public.DbSfLinks_public.DbNodes_NodeID_AccountID";
alter table public."DbSfMappings" drop constraint "FK_public.DbSfMappings_public.DbNodes_ParentNodeID_AccountID";
alter table public."DbTemplateNodeChangeLogs" drop constraint "FK_public.DbTemplateNodeChangeLogs_public.DbNodes_TemplateNodeI";
alter table public."DbTemplateNodeLinks" drop constraint "FK_public.DbTemplateNodeLinks_public.DbNodes_AppliedNodeID_Acco";
alter table public."DbTemplateNodeLinks" drop constraint "FK_public.DbTemplateNodeLinks_public.DbNodes_TemplateNodeID_Acc";
alter table public."DbTriggerInfoNodes" drop constraint "FK_public.DbTriggerInfoNodes_public.DbNodes_NodeID_AccountID";
alter table public."DbTriggerToNode" drop constraint "FK_public.DbTriggerToNode_public.DbNodes_NodeID_AccountID";
alter table public."DbUserImageStamps" drop constraint "FK_public.DbUserImageStamps_public.DbNodes_NodeID_AccountID";
alter table public."DbAccessLinksToNodeAndTriggers" drop constraint "FK_public.DbAccessLinksToNodeAndTriggers_public.DbTriggers_Trig";
alter table public."DbTriggers" drop constraint "FK_public.DbTriggers_public.DbEmailContent_EmailContentID_Accou";
alter table public."DbEventTriggers" drop constraint "FK_public.DbEventTriggers_public.DbTriggers_TriggerID_AccountID";
alter table public."DbTimeTriggers" drop constraint "FK_public.DbTimeTriggers_public.DbTriggers_TriggerID_AccountID";
alter table public."DbTriggerInfoNodes" drop constraint "FK_public.DbTriggerInfoNodes_public.DbTriggers_TriggerID_Accoun";
alter table public."DbTriggerToApiCallouts" drop constraint "FK_public.DbTriggerToApiCallouts_public.DbTriggers_TriggerID_Ac";
alter table public."DbTriggerToNode" drop constraint "FK_public.DbTriggerToNode_public.DbTriggers_TriggerID_AccountID";
alter table public."DbTriggerToRoles" drop constraint "FK_public.DbTriggerToRoles_public.DbTriggers_TriggerID_AccountI";
alter table public."DbTriggerToSearchCriteria" drop constraint "FK_public.DbTriggerToSearchCriteria_public.DbTriggers_TriggerID";
alter table public."DbTriggerToWorkflow" drop constraint "FK_public.DbTriggerToWorkflow_public.DbTriggers_TriggerID_Accou";
alter table public."DbWatermarkTriggerInfo" drop constraint "FK_public.DbWatermarkTriggerInfo_public.DbTriggers_TriggerID_Ac";
alter table public."DbTriggerToRoles" drop constraint "FK_public.DbTriggerToRoles_public.DbRoles_RoleID_AccountID";
alter table public."DbAuditLogsToRoles" drop constraint "FK_public.DbAuditLogsToRoles_public.DbRoles_RoleID_AccountID";
alter table public."DbDocumentRequestRoles" drop constraint "FK_public.DbDocumentRequestRoles_public.DbRoles_RecipientRoleID";
alter table public."DbESignatureSigners" drop constraint "FK_public.DbESignatureSigners_public.DbRoles_RoleID_AccountID";
alter table public."DbFileInfoes" drop constraint "FK_public.DbFileInfoes_public.DbRoles_CheckedOutByRoleID_Accoun";
alter table public."DbNodeShares" drop constraint "FK_public.DbNodeShares_public.DbRoles_RoleID_AccountID";
alter table public."DbNotifications" drop constraint "FK_public.DbNotifications_public.DbRoles_RecipientRoleID_Accoun";
alter table public."DbPermissions" drop constraint "FK_public.DbPermissions_public.DbRoles_RoleID_AccountID";
alter table public."DbRoles" drop constraint "FK_public.DbRoles_public.DbProfiles_ProfileID_AccountID";
alter table public."DbProfileValueRoles" drop constraint "FK_public.DbProfileValueRoles_public.DbRoles_RoleID_AccountID";
alter table public."DbRoleClosures" drop constraint "FK_public.DbRoleClosures_public.DbRoles_ChildID_AccountID";
alter table public."DbRoleClosures" drop constraint "FK_public.DbRoleClosures_public.DbRoles_ParentID_AccountID";
alter table public."DbRoles" drop constraint "FK_public.DbRoles_public.DbRoles_RoleManagerID_AccountID";
alter table public."DbRoleRelationships" drop constraint "FK_public.DbRoleRelationships_public.DbRoles_ParentRoleID_Accou";
alter table public."DbRoleRelationships" drop constraint "FK_public.DbRoleRelationships_public.DbRoles_ChildRoleID_Accoun";
alter table public."DbRoleToAccountFeatures" drop constraint "FK_public.DbRoleToAccountFeatures_public.DbRoles_RoleID_Account";
alter table public."DbSamlConfigurations" drop constraint "FK_public.DbSamlConfigurations_public.DbRoles_DefaultGroupID_Ac";
alter table public."DbRoles" drop constraint "FK_public.DbRoles_public.DbSecurityPolicies_SecurityPolicyID_Ac";
alter table public."DbRoles" drop constraint "FK_public.DbRoles_public.DbSystemPermissions_SystemPermissionID";
alter table public."DbUserRolePreferences" drop constraint "FK_public.DbUserRolePreferences_public.DbRoles_RoleID_AccountID";
alter table public."DbUserSessions" drop constraint "FK_public.DbUserSessions_public.DbRoles_RoleID_AccountID";
alter table public."DbUserSessionToDbRoles" drop constraint "FK_public.DbUserSessionToDbRoles_public.DbRoles_RoleID_AccountI";
alter table public."DbAuditLogsToRoles" drop constraint "FK_public.DbAuditLogsToRoles_public.DbAuditLogs_AuditLogID_Acco";
alter table public."DbAuditLogsToRoleDetails" drop constraint "FK_public.DbAuditLogsToRoleDetails_public.DbAuditLogsToRoles_Au";
alter table public."DbAuditLogsToNodes" drop constraint "FK_public.DbAuditLogsToNodes_public.DbAuditLogs_AuditLogID_Acco";
alter table public."DbAuditLogsToNodeDetails" drop constraint "FK_public.DbAuditLogsToNodeDetails_public.DbAuditLogsToNodes_Au";
alter table public."DbDocumentRequestAttachments" drop constraint "FK_public.DbDocumentRequestAttachments_public.DbDocumentRequest";
alter table public."DbDocumentRequestContainers" drop constraint "FK_public.DbDocumentRequestContainers_public.DbDocumentRequests";
alter table public."DbDocumentRequestRoles" drop constraint "FK_public.DbDocumentRequestRoles_public.DbDocumentRequests_Docu";
alter table public."DbDocumentRequestToNotifications" drop constraint "FK_public.DbDocumentRequestToNotifications_public.DbDocumentReq";
alter table public."DbDocumentRequestContainerNodes" drop constraint "FK_public.DbDocumentRequestContainerNodes_public.DbDocumentRequ";
alter table public."DbDocumentRequestContainers" drop constraint "FK_public.DbDocumentRequestContainers_public.DbFileInfoes_FileI";
alter table public."DbDocumentRequestContainers" drop constraint "FK_public.DbDocumentRequestContainers_public.DbFormFillDefiniti";
alter table public."DbFileQueue" drop constraint "FK_public.DbFileQueue_public.DbFileInfoes_FileInfoID_AccountID";
alter table public."DbFileInfoes" drop constraint "FK_public.DbFileInfoes_public.DbFormFillDefinitions_FormFillDef";
alter table public."DbFileInfoes" drop constraint "FK_public.DbFileInfoes_public.DbNodeComments_NodeCommentID_Acco";
alter table public."DbNodeToFileInfoes" drop constraint "FK_public.DbNodeToFileInfoes_public.DbFileInfoes_FileInfoID_Acc";
alter table public."DbFileInfoes" drop constraint "FK_public.DbFileInfoes_public.DbFileInfoes_GeneratedFromFileInf";
alter table public."DbFormFillPendings" drop constraint "FK_public.DbFormFillPendings_public.DbFormFillDefinitions_FormF";
alter table public."DbFormFillToProfileItems" drop constraint "FK_public.DbFormFillToProfileItems_public.DbFormFillDefinitions";
alter table public."DbFormFillDefinitions" drop constraint "FK_public.DbFormFillDefinitions_public.DbProfiles_ProfileID_Acc";
alter table public."DbFormFillPendings" drop constraint "FK_public.DbFormFillPendings_public.DbFileInfoes_AppliedNodeFil";
alter table public."DbFormFillToProfileItems" drop constraint "FK_public.DbFormFillToProfileItems_public.DbProfileItems_Profil";
alter table public."DbPresetValues" drop constraint "FK_public.DbPresetValues_public.DbProfileItems_ProfileItemID_Ac";
alter table public."DbProfileToProfileItems" drop constraint "FK_public.DbProfileToProfileItems_public.DbProfileItems_Profile";
alter table public."DbProfileValueNodes" drop constraint "FK_public.DbProfileValueNodes_public.DbProfileItems_ProfileItem";
alter table public."DbProfileValueRoles" drop constraint "FK_public.DbProfileValueRoles_public.DbProfileItems_ProfileItem";
alter table public."DbProfileValueNodes" drop constraint "FK_public.DbProfileValueNodes_public.DbPresetValues_PresetValue";
alter table public."DbProfileValueRoles" drop constraint "FK_public.DbProfileValueRoles_public.DbPresetValues_PresetValue";
alter table public."DbProfileValueNodes" drop constraint "FK_public.DbProfileValueNodes_public.DbProfiles_ProfileID_Accou";
alter table public."DbProfileToProfileItems" drop constraint "FK_public.DbProfileToProfileItems_public.DbProfiles_ProfileID_A";
alter table public."DbProfileValueRoles" drop constraint "FK_public.DbProfileValueRoles_public.DbProfiles_ProfileID_Accou";
alter table public."DbDocumentRequestToNotifications" drop constraint "FK_public.DbDocumentRequestToNotifications_public.DbNotificatio";
alter table public."DbWorkflowStageInstanceToNotifications" drop constraint "FK_public.DbWorkflowStageInstanceToNotifications_public.DbNotif";
alter table public."DbESignatureNodeAssociations" drop constraint "FK_public.DbESignatureNodeAssociations_public.DbESignatureTrans";
alter table public."DbESignatureSigners" drop constraint "FK_public.DbESignatureSigners_public.DbESignatureTransactions_T";
alter table public."DbESignatureTransactions" drop constraint "FK_public.DbESignatureTransactions_public.DbESignatureTransacti";
alter table public."DbSamlResponses" drop constraint "FK_public.DbSamlResponses_public.DbSamlConfigurations_Configura";
alter table public."DbPermissions" drop constraint "FK_public.DbPermissions_public.DbPermissions_ChildPermissionId_";
alter table public."DbSecurityPolicyIpAddresses" drop constraint "FK_public.DbSecurityPolicyIpAddresses_public.DbSecurityPolicies";
alter table public."DbSecurityPolicyLoginTimes" drop constraint "FK_public.DbSecurityPolicyLoginTimes_public.DbSecurityPolicies_";
alter table public."DbEmailQueueAttachmentNodes" drop constraint "FK_public.DbEmailQueueAttachmentNodes_public.DbEmailQueue_Email";
alter table public."DbEmailRecipients" drop constraint "FK_public.DbEmailRecipients_public.DbEmailQueue_EmailQueueID_Ac";
alter table public."DbSfLinks" drop constraint "FK_public.DbSfLinks_public.DbSfMappings_SfMappingID_AccountID";
alter table public."DbSfMappings" drop constraint "FK_public.DbSfMappings_public.DbPermissions_GroupPermissionID_A";
alter table public."DbSfMappings" drop constraint "FK_public.DbSfMappings_public.DbPermissions_UserPermissionID_Ac";
alter table public."DbEmailTemplateToPartner" drop constraint "FK_public.DbEmailTemplateToPartner_public.DbPartners_PartnerID";
alter table public."DbUserSessionToDbRoles" drop constraint "FK_public.DbUserSessionToDbRoles_public.DbUserSessions_UserSess";
alter table workflow."DbWorkflowSetProfileItems" drop constraint "FK_workflow.DbWorkflowSetProfileItems_workflow.DbWorkflowSteps_";
alter table workflow."DbWorkflowShareStepNewUserReferences" drop constraint "FK_workflow.DbWorkflowShareStepNewUserReferences_workflow.DbWor";
alter table workflow."DbWorkflowStepGroupReferences" drop constraint "FK_workflow.DbWorkflowStepGroupReferences_workflow.DbWorkflowSt";
alter table workflow."DbWorkflowStepUserReferences" drop constraint "FK_workflow.DbWorkflowStepUserReferences_workflow.DbWorkflowSte";
alter table workflow."DbWorkflowAssetsStages" drop constraint "FK_workflow.DbWorkflowAssetsStages_workflow.DbWorkflowStages_St";
alter table workflow."DbWorkflowStageInstances" drop constraint "FK_workflow.DbWorkflowStageInstances_workflow.DbWorkflowStages_";
alter table workflow."DbWorkflowStageApproverGroups" drop constraint "FK_workflow.DbWorkflowStageApproverGroups_workflow.DbWorkflowSt";
alter table workflow."DbWorkflowStageApprovers" drop constraint "FK_workflow.DbWorkflowStageApprovers_workflow.DbWorkflowStages_";
alter table workflow."DbWorkflowStageAssigneeGroups" drop constraint "FK_workflow.DbWorkflowStageAssigneeGroups_workflow.DbWorkflowSt";
alter table workflow."DbWorkflowStageAssignees" drop constraint "FK_workflow.DbWorkflowStageAssignees_workflow.DbWorkflowStages_";
alter table workflow."DbProfileRoutingRules" drop constraint "FK_workflow.DbProfileRoutingRules_workflow.DbWorkflowStages_Sta";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowStages_StageID";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_requestF1";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_requestF2";
alter table workflow."DbWorkflowStepDocumentRequestContainers" drop constraint "FK_workflow.DbWorkflowStepDocumentRequestContainers_workflow.D2";
alter table workflow."DbAssetNodeReference" drop constraint "FK_workflow.DbAssetNodeReference_workflow.DbWorkflowAssets_Asse";
alter table workflow."DbWorkflowAssetsStages" drop constraint "FK_workflow.DbWorkflowAssetsStages_workflow.DbWorkflowAssets_As";
alter table workflow."DbWorkflowStages" drop constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowAssets_Approval";
alter table workflow."DbProfileRoutingRules" drop constraint "FK_workflow.DbProfileRoutingRules_workflow.DbWorkflowAssets_Ass";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_addTrigg1";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_addTrigg2";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_applyTemp";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_comment_T";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_copy_Dest";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_copy_Resu";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_copy_Sour";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_createLo1";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_createLo2";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_delete_Ta";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu1";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu2";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu3";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu4";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu5";
alter table workflow."DbWorkflowESignatureStepTemplateDocuments" drop constraint "FK_workflow.DbWorkflowESignatureStepTemplateDocuments_workflow2";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_move_Dest";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_move_Sour";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_rename_Ta";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_sendMessa";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_setPermis";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_setProfil";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_setReten1";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_setReten2";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_share_Sou";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_upload_Re";
alter table workflow."DbWorkflowSteps" drop constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_upload_So";
alter table workflow."DbWorkflowAssetInstances" drop constraint "FK_workflow.DbWorkflowAssetInstances_workflow.DbWorkflowAssets_";
alter table workflow."DbWorkflowAssets" drop constraint "FK_workflow.DbWorkflowAssets_workflow.DbWorkflows_WorkflowID";
alter table workflow."DbWorkflowInstanceHistoryRecords" drop constraint "FK_workflow.DbWorkflowInstanceHistoryRecords_workflow.DbWorkfl2";
alter table workflow."DbWorkflowInstances" drop constraint "FK_workflow.DbWorkflowInstances_workflow.DbWorkflows_WorkflowID";
alter table workflow."DbWorkflowsAvailableStates" drop constraint "FK_workflow.DbWorkflowsAvailableStates_workflow.DbWorkflows_Wor";
alter table workflow."DbWorkflowNotificationConfigurations" drop constraint "FK_workflow.DbWorkflowNotificationConfigurations_workflow.DbWor";
alter table workflow."DbWorkflowOwnerGroups" drop constraint "FK_workflow.DbWorkflowOwnerGroups_workflow.DbWorkflows_Workflow";
alter table workflow."DbWorkflowOwners" drop constraint "FK_workflow.DbWorkflowOwners_workflow.DbWorkflows_WorkflowID";
alter table workflow."DbWorkflowScheduleConfigurations" drop constraint "FK_workflow.DbWorkflowScheduleConfigurations_workflow.DbWorkflo";
alter table workflow."DbWorkflowStages" drop constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflows_WorkflowID";
alter table workflow."DbWorkflowStarterGroups" drop constraint "FK_workflow.DbWorkflowStarterGroups_workflow.DbWorkflows_Workfl";
alter table workflow."DbWorkflowStarters" drop constraint "FK_workflow.DbWorkflowStarters_workflow.DbWorkflows_WorkflowID";
alter table workflow."DbWorkflowWatcherGroups" drop constraint "FK_workflow.DbWorkflowWatcherGroups_workflow.DbWorkflows_Workfl";
alter table workflow."DbWorkflowWatchers" drop constraint "FK_workflow.DbWorkflowWatchers_workflow.DbWorkflows_WorkflowID";
alter table workflow."DbWorkflowsAvailableStates" drop constraint "FK_workflow.DbWorkflowsAvailableStates_workflow.DbWorkflowInsta";
alter table workflow."DbWorkflowStages" drop constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowInstanceStates1";
alter table workflow."DbWorkflowStages" drop constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowInstanceStates2";
alter table workflow."DbWorkflowStages" drop constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowInstanceStates3";
alter table workflow."DbProfileRoutingRules" drop constraint "FK_workflow.DbProfileRoutingRules_workflow.DbWorkflowInstanceSt";
alter table workflow."DbWorkflowStages" drop constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowInstanceStates4";
alter table workflow."DbWorkflowAssetInstances" drop constraint "FK_workflow.DbWorkflowAssetInstances_workflow.DbWorkflowInstanc";
alter table workflow."DbWorkflowInstanceHistoryRecords" drop constraint "FK_workflow.DbWorkflowInstanceHistoryRecords_workflow.DbWorkfl3";
alter table workflow."DbWorkflowStageInstances" drop constraint "FK_workflow.DbWorkflowStageInstances_workflow.DbWorkflowInstanc";
alter table workflow."DbWorkflowInstanceHistoryRecords" drop constraint "FK_workflow.DbWorkflowInstanceHistoryRecords_workflow.DbWorkfl4";
alter table workflow."DbWorkflowStepInstances" drop constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowStageIns";
alter table workflow."DbWorkflowInstances" drop constraint "FK_workflow.DbWorkflowInstances_workflow.DbWorkflowStageInstanc";
alter table workflow."DbWorkflowAssetsStagesInstances" drop constraint "FK_workflow.DbWorkflowAssetsStagesInstances_workflow.DbWorkflo2";
alter table workflow."DbWorkflowSetProfileInstanceItemPresetValues" drop constraint "FK_workflow.DbWorkflowSetProfileInstanceItemPresetValues_workfl";
alter table workflow."DbWorkflowSetProfileItemPresetValues" drop constraint "FK_workflow.DbWorkflowSetProfileItemPresetValues_workflow.DbWor";
alter table public."DbWorkflowStageInstanceToNotifications" drop constraint "FK_DbWorkflowStageInstanceToNotifications_DbWorkflowStageInstan";
alter table public."DbRoles" drop constraint "CK_RoleManagerID";
alter table public."DbDocumentRequestAttachments" drop constraint "FK_public.DbDocumentRequestAttachments_public.DbAccounts_Accoun";
alter table public."DbFormFillDefinitions" drop constraint "FK_public.DbFormFillDefinitions_public.DbAccounts_AccountID";
alter table public."DbDocumentRequestContainers" drop constraint "FK_public.DbDocumentRequestContainers_public.DbAccounts_Account";
alter table public."DbDocumentRequestContainerNodes" drop constraint "FK_public.DbDocumentRequestContainerNodes_public.DbAccounts_Acc";
alter table public."DbFormFillPendings" drop constraint "FK_public.DbFormFillPendings_public.DbAccounts_AccountID";
alter table public."DbFormFillToProfileItems" drop constraint "FK_public.DbFormFillToProfileItems_public.DbAccounts_AccountID";
alter table public."DbNodeComments" drop constraint "FK_public.DbNodeComments_public.DbAccounts_AccountID";
alter table public."DbESignatureSigners" drop constraint "FK_public.DbESignatureSigners_public.DbAccounts_AccountID";
alter table public."DbESignatureNodeAssociations" drop constraint "FK_public.DbESignatureNodeAssociations_public.DbAccounts_Accoun";
alter table public."DbSecurityPolicyIpAddresses" drop constraint "FK_public.DbSecurityPolicyIpAddresses_public.DbAccounts_Account";
alter table public."DbSecurityPolicyLoginTimes" drop constraint "FK_public.DbSecurityPolicyLoginTimes_public.DbAccounts_AccountI";
alter table public."DbUserRolePreferences" drop constraint "FK_public.DbUserRolePreferences_public.DbAccounts_AccountID";
alter table public."DbTriggerToApiCallouts" drop constraint "FK_public.DbTriggerToApiCallouts_public.DbAccounts_AccountID";
alter table public."DbWatermarkTriggerInfo" drop constraint "FK_public.DbWatermarkTriggerInfo_public.DbAccounts_AccountID";
alter table public."DbLegacyNodeMappings" drop constraint "FK_public.DbLegacyNodeMappings_public.DbAccounts_AccountID";
alter table public."DbAccessLinksToDocumentRequests" drop constraint "FK_public.DbAccessLinksToDocumentRequests_public.DbAccounts_Acc";
alter table public."DbDocumentRequestToNotifications" drop constraint "FK_public.DbDocumentRequestToNotifications_public.DbAccounts_Ac";
alter table public."DbPermissions" drop constraint ck_permission;
DROP TRIGGER tr_dbnode_insert ON "public"."DbNodes";
DROP TRIGGER tr_dbnode_update ON "public"."DbNodes";
DROP TRIGGER tr_dbroleclosures_insert ON "public"."DbRoleClosures";
DROP TRIGGER tr_dbrole_insert ON "public"."DbRoles";
DROP TRIGGER tr_dbrole_delete ON "public"."DbRoles";
DROP TRIGGER tr_dbrolerelationships_insert ON "public"."DbRoleRelationships";
DROP TRIGGER tr_dbrolerelationships_delete ON "public"."DbRoleRelationships";
DROP TRIGGER tr_dbrolerelationships_update ON "public"."DbRoleRelationships";
SELECT create_reference_table('"workflow"."DbAssetInstanceNodeReferences"');
SELECT create_reference_table('"workflow"."DbAssetNodeReference"');
SELECT create_reference_table('"workflow"."DbEventServiceInstancesInfo"');
SELECT create_reference_table('"workflow"."DbProfileRoutingRules"');
SELECT create_reference_table('"workflow"."DbStageApproveResults"');
SELECT create_reference_table('"workflow"."DbWorkflowAccountEmailConfig"');
SELECT create_reference_table('"workflow"."DbWorkflowAddTriggerStepEmailUserGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowAddTriggerStepEmailUsers"');
SELECT create_reference_table('"workflow"."DbWorkflowAssetInstances"');
SELECT create_reference_table('"workflow"."DbWorkflowAssets"');
SELECT create_reference_table('"workflow"."DbWorkflowAssetsStages"');
SELECT create_reference_table('"workflow"."DbWorkflowAssetsStagesInstances"');
SELECT create_reference_table('"workflow"."DbWorkflowESignatureStepInstanceTemplateDocuments"');
SELECT create_reference_table('"workflow"."DbWorkflowESignatureStepInstanceUserReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowESignatureStepTemplateDocuments"');
SELECT create_reference_table('"workflow"."DbWorkflowESignatureStepUserReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowInstanceHistoryRecordTypes"');
SELECT create_reference_table('"workflow"."DbWorkflowInstanceHistoryRecords"');
SELECT create_reference_table('"workflow"."DbWorkflowInstanceStates"');
SELECT create_reference_table('"workflow"."DbWorkflowInstances"');
SELECT create_reference_table('"workflow"."DbWorkflowJobsQueue"');
SELECT create_reference_table('"workflow"."DbWorkflowNotificationConfigurations"');
SELECT create_reference_table('"workflow"."DbWorkflowOwnerGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowOwners"');
SELECT create_reference_table('"workflow"."DbWorkflowRequestFileExternalStepInstanceNewUserReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowRequestFileExternalStepInstanceRecipientGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowRequestFileExternalStepInstanceRecipients"');
SELECT create_reference_table('"workflow"."DbWorkflowRequestFileExternalStepNewUserReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowRequestFileExternalStepRecipientGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowRequestFileExternalStepRecipients"');
SELECT create_reference_table('"workflow"."DbWorkflowScheduleConfigurations"');
SELECT create_reference_table('"workflow"."DbWorkflowSendMessageInstanceRecipients"');
SELECT create_reference_table('"workflow"."DbWorkflowSendMessageRecipients"');
SELECT create_reference_table('"workflow"."DbWorkflowSetPermissionsStepUserGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowSetPermissionsStepUsers"');
SELECT create_reference_table('"workflow"."DbWorkflowSetProfileInstanceItemPresetValues"');
SELECT create_reference_table('"workflow"."DbWorkflowSetProfileInstanceItems"');
SELECT create_reference_table('"workflow"."DbWorkflowSetProfileItemPresetValues"');
SELECT create_reference_table('"workflow"."DbWorkflowSetProfileItems"');
SELECT create_reference_table('"workflow"."DbWorkflowShareStepInstanceNewUserReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowShareStepNewUserReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowStageApproverGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowStageApprovers"');
SELECT create_reference_table('"workflow"."DbWorkflowStageAssigneeGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowStageAssignees"');
SELECT create_reference_table('"workflow"."DbWorkflowStageInstances"');
SELECT create_reference_table('"workflow"."DbWorkflowStages"');
SELECT create_reference_table('"workflow"."DbWorkflowStarterGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowStarters"');
SELECT create_reference_table('"workflow"."DbWorkflowStepDocumentRequestContainers"');
SELECT create_reference_table('"workflow"."DbWorkflowStepGroupReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowStepInstanceDocumentRequestContainers"');
SELECT create_reference_table('"workflow"."DbWorkflowStepInstanceEmailUserGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowStepInstanceEmailUsers"');
SELECT create_reference_table('"workflow"."DbWorkflowStepInstanceGroupReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowStepInstanceUserGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowStepInstanceUserReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowStepInstanceUsers"');
SELECT create_reference_table('"workflow"."DbWorkflowStepInstances"');
SELECT create_reference_table('"workflow"."DbWorkflowStepTypes"');
SELECT create_reference_table('"workflow"."DbWorkflowStepUserReferences"');
SELECT create_reference_table('"workflow"."DbWorkflowSteps"');
SELECT create_reference_table('"workflow"."DbWorkflowWatcherGroups"');
SELECT create_reference_table('"workflow"."DbWorkflowWatchers"');
SELECT create_reference_table('"workflow"."DbWorkflows"');
SELECT create_reference_table('"workflow"."DbWorkflowsAvailableStates"');
SELECT create_reference_table('"public"."DbBrandings"');
SELECT create_reference_table('"public"."DbClientApplications"');
SELECT create_reference_table('"public"."DbComponentStatus"');
SELECT create_reference_table('"public"."DbComponentStatusHistories"');
SELECT create_reference_table('"public"."DbEmailSettingToUsers"');
SELECT create_reference_table('"public"."DbEmailSettings"');
SELECT create_reference_table('"public"."DbEmailTemplateToPartner"');
SELECT create_reference_table('"public"."DbEmailTemplates"');
SELECT create_reference_table('"public"."DbInstanceSettings"');
SELECT create_reference_table('"public"."DbPartners"');
SELECT create_reference_table('"public"."DbPortfolioToNodes"');
SELECT create_reference_table('"public"."DbPortfolioToUsers"');
SELECT create_reference_table('"public"."DbPortfolios"');
SELECT create_reference_table('"public"."DbResetPasswordRequests"');
SELECT create_reference_table('"public"."DbRightSignatureUsers"');
SELECT create_reference_table('"public"."DbSearchCriteria"');
SELECT create_reference_table('"public"."DbUserApplicationsMfa"');
SELECT create_reference_table('"public"."DbUserExternalAuthentications"');
SELECT create_reference_table('"public"."DbUserPasswordHistories"');
SELECT create_reference_table('"public"."DbUserSearchToSearchCriteria"');
SELECT create_reference_table('"public"."DbUserSearches"');
SELECT create_reference_table('"public"."DbUserSettings"');
SELECT create_reference_table('"public"."DbUsers"');
SELECT create_reference_table('"public"."DbUserSessions"');
SELECT create_distributed_table('"public"."DbNodeClosures"', 'AccountID');
SELECT create_distributed_table('"public"."DbAccountFeatures"', 'AccountID');
SELECT create_distributed_table('"public"."DbSecurityPolicies"', 'AccountID');
SELECT create_distributed_table('"public"."DbAuditLogsToNodeDetails"', 'AccountID');
SELECT create_distributed_table('"public"."DbAuditLogsToNodes"', 'AccountID');
SELECT create_distributed_table('"public"."DbAuditLogsToRoleDetails"', 'AccountID');
SELECT create_distributed_table('"public"."DbDocumentRequestAttachments"', 'AccountID');
SELECT create_distributed_table('"public"."DbEmailQueue"', 'AccountID');
SELECT create_distributed_table('"public"."DbEmailSettingToAccounts"', 'AccountID');
SELECT create_distributed_table('"public"."DbFileQueue"', 'AccountID');
SELECT create_distributed_table('"public"."DbNodeAnnotations"', 'AccountID');
SELECT create_distributed_table('"public"."DbNodeToFileInfoes"', 'AccountID');
SELECT create_distributed_table('"public"."DbProfiles"', 'AccountID');
SELECT create_distributed_table('"public"."DbPresetValues"', 'AccountID');
SELECT create_distributed_table('"public"."DbProfileItems"', 'AccountID');
SELECT create_distributed_table('"public"."DbProfileToProfileItems"', 'AccountID');
SELECT create_distributed_table('"public"."DbRetentionChangeReason"', 'AccountID');
SELECT create_distributed_table('"public"."DbSamlResponses"', 'AccountID');
SELECT create_distributed_table('"public"."DbSfLinks"', 'AccountID');
SELECT create_distributed_table('"public"."DbTriggerToNode"', 'AccountID');
SELECT create_distributed_table('"public"."DbAccountSettings"', 'AccountID');
SELECT create_distributed_table('"public"."DbProfileValueNodes"', 'AccountID');
SELECT create_distributed_table('"public"."DbAccessLinks"', 'AccountID');
SELECT create_distributed_table('"public"."DbDocumentRequests"', 'AccountID');
SELECT create_distributed_table('"public"."DbEmailImportMappings"', 'AccountID');
SELECT create_distributed_table('"public"."DbNodes"', 'AccountID');
SELECT create_distributed_table('"public"."DbAuditLogs"', 'AccountID');
SELECT create_distributed_table('"public"."DbAuditLogsToRoles"', 'AccountID');
SELECT create_distributed_table('"public"."DbDocumentRequestRoles"', 'AccountID');
SELECT create_distributed_table('"public"."DbESignatureTransactions"', 'AccountID');
SELECT create_distributed_table('"public"."DbNodeShares"', 'AccountID');
SELECT create_distributed_table('"public"."DbNotifications"', 'AccountID');
SELECT create_distributed_table('"public"."DbProfileValueRoles"', 'AccountID');
SELECT create_distributed_table('"public"."DbRoleToAccountFeatures"', 'AccountID');
SELECT create_distributed_table('"public"."DbSamlConfigurations"', 'AccountID');
SELECT create_distributed_table('"public"."DbTriggerToRoles"', 'AccountID');
SELECT create_distributed_table('"public"."DbUserRolePreferences"', 'AccountID');
SELECT create_distributed_table('"public"."DbUserImageStamps"', 'AccountID');
SELECT create_distributed_table('"public"."DbTemplateNodeLinks"', 'AccountID');
SELECT create_distributed_table('"public"."DbFileInfoes"', 'AccountID');
SELECT create_distributed_table('"public"."DbRoles"', 'AccountID');
SELECT create_distributed_table('"public"."DbSystemPermissions"', 'AccountID');
SELECT create_distributed_table('"public"."DbTriggers"', 'AccountID');
SELECT create_distributed_table('"public"."DbEmailContent"', 'AccountID');
SELECT create_distributed_table('"public"."DbEventTriggers"', 'AccountID');
SELECT create_distributed_table('"public"."DbWorkflowStageInstanceToNotifications"', 'AccountID');
SELECT create_distributed_table('"public"."DbRoleClosures"', 'AccountID');
SELECT create_distributed_table('"public"."DbRoleRelationships"', 'AccountID');
SELECT create_distributed_table('"public"."DbTimeTriggers"', 'AccountID');
SELECT create_distributed_table('"public"."DbTriggerInfoNodes"', 'AccountID');
SELECT create_distributed_table('"public"."DbTriggerToWorkflow"', 'AccountID');
SELECT create_distributed_table('"public"."DbEmailQueueAttachmentNodes"', 'AccountID');
SELECT create_distributed_table('"public"."DbTemplateNodeChangeLogs"', 'AccountID');
SELECT create_distributed_table('"public"."DbTriggerToSearchCriteria"', 'AccountID');
SELECT create_distributed_table('"public"."DbFormFillDefinitions"', 'AccountID');
SELECT create_distributed_table('"public"."DbAccessLinksToDocumentRequests"', 'AccountID');
SELECT create_distributed_table('"public"."DbAccessLinksToNodeAndTriggers"', 'AccountID');
SELECT create_distributed_table('"public"."DbESignatureSigners"', 'AccountID');
SELECT create_distributed_table('"public"."DbESignatureNodeAssociations"', 'AccountID');
SELECT create_distributed_table('"public"."DbFormFillPendings"', 'AccountID');
SELECT create_distributed_table('"public"."DbFormFillToProfileItems"', 'AccountID');
SELECT create_distributed_table('"public"."DbNodeComments"', 'AccountID');
SELECT create_distributed_table('"public"."DbSecurityPolicyIpAddresses"', 'AccountID');
SELECT create_distributed_table('"public"."DbSecurityPolicyLoginTimes"', 'AccountID');
SELECT create_distributed_table('"public"."DbTriggerToApiCallouts"', 'AccountID');
SELECT create_distributed_table('"public"."DbWatermarkTriggerInfo"', 'AccountID');
SELECT create_distributed_table('"public"."DbDocumentRequestContainerNodes"', 'AccountID');
SELECT create_distributed_table('"public"."DbDocumentRequestContainers"', 'AccountID');
SELECT create_distributed_table('"public"."DbLegacyNodeMappings"', 'AccountID');
SELECT create_distributed_table('"public"."DbDocumentRequestToNotifications"', 'AccountID');
SELECT create_distributed_table('"public"."DbSfMappings"', 'AccountID');
SELECT create_distributed_table('"public"."DbPermissions"', 'AccountID');
SELECT create_distributed_table('"public"."DbRightSignatureDocuments"', 'AccountID');
SELECT create_distributed_table('"public"."DbUserSessionToDbRoles"', 'AccountID');
SELECT create_distributed_table('"public"."DbEmailRecipients"', 'AccountID');
SELECT create_distributed_table('"DbAccounts"', 'Id');
alter table public."DbAccessLinks" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAccountFeatures" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAccountSettings" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAccountSettings" add constraint "FK_DbEmailSettings" FOREIGN KEY ("EmailSettingID") REFERENCES "DbEmailSettings"("Id");
alter table public."DbAccounts" add constraint "FK_BrandingID" FOREIGN KEY ("BrandingID") REFERENCES "DbBrandings"("Id");
alter table public."DbAuditLogs" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAuditLogsToNodeDetails" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAuditLogsToNodes" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAuditLogsToRoleDetails" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAuditLogsToRoles" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbDocumentRequests" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbESignatureTransactions" add constraint "FK_DbAccount" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbEmailImportMappings" add constraint "FK_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbEmailImportMappings" add constraint "FK_EmailSettingID" FOREIGN KEY ("EmailSettingID") REFERENCES "DbEmailSettings"("Id");
alter table public."DbEmailQueue" add constraint fk_accounts FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbEmailQueue" add constraint fk_emailsettings FOREIGN KEY ("EmailSettingID") REFERENCES "DbEmailSettings"("Id");
alter table public."DbEmailSettingToAccounts" add constraint fk_account FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbEmailSettingToAccounts" add constraint fk_emailsetting FOREIGN KEY ("EmailSettingsID") REFERENCES "DbEmailSettings"("Id");
alter table public."DbEmailSettingToUsers" add constraint fk_emailsetting FOREIGN KEY ("EmailSettingsID") REFERENCES "DbEmailSettings"("Id");
alter table public."DbEmailTemplateToPartner" add constraint "FK_DbEmailTemplate" FOREIGN KEY ("EmailTemplateID") REFERENCES "DbEmailTemplates"("Id");
alter table public."DbFileInfoes" add constraint "FK_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbFileQueue" add constraint "FK_Account" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbNodeAnnotations" add constraint fk_account FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbNodeClosures" add constraint "fk_accountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAccessLinksToDocumentRequests" add constraint "FK_public.DbAccessLinksToDocumentRequests_public.DbAccessLinks_" FOREIGN KEY ("AccessLinkID", "AccountID") REFERENCES "DbAccessLinks"("Id", "AccountID");
alter table public."DbAccessLinksToNodeAndTriggers" add constraint "FK_public.DbAccessLinksToNodeAndTriggers_public.DbAccessLinks_A" FOREIGN KEY ("AccessLinkID", "AccountID") REFERENCES "DbAccessLinks"("Id", "AccountID");
alter table public."DbAccessLinks" add constraint "FK_public.DbAccessLinks_public.DbRoles_RoleID_AccountID" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbAccessLinksToDocumentRequests" add constraint "FK_public.DbAccessLinksToDocumentRequests_public.DbDocumentRequ" FOREIGN KEY ("DocumentRequestID", "AccountID") REFERENCES "DbDocumentRequests"("Id", "AccountID") ON DELETE CASCADE;
alter table public."DbAccountSettings" add constraint "FK_public.DbAccountSettings_public.DbSecurityPolicies_DefaultGu" FOREIGN KEY ("DefaultGuestSecurityPolicyID", "AccountID") REFERENCES "DbSecurityPolicies"("Id", "AccountID");
alter table public."DbAccountSettings" add constraint "FK_public.DbAccountSettings_public.DbSecurityPolicies_DefaultUs" FOREIGN KEY ("DefaultUserSecurityPolicyID", "AccountID") REFERENCES "DbSecurityPolicies"("Id", "AccountID");
alter table public."DbEmailImportMappings" add constraint "FK_public.DbEmailImportMappings_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbAccessLinksToNodeAndTriggers" add constraint "FK_public.DbAccessLinksToNodeAndTriggers_public.DbNodes_NodeID_" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbAuditLogsToNodes" add constraint "FK_public.DbAuditLogsToNodes_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodeShares" add constraint fk_account FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbNodeToFileInfoes" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbNodes" add constraint fk_account FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbNotifications" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbPartners" add constraint "FK_BrandingID" FOREIGN KEY ("BrandingID") REFERENCES "DbBrandings"("Id");
alter table public."DbPermissions" add constraint fk_account FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbPortfolioToNodes" add constraint "FK_DbPortfolios" FOREIGN KEY ("PortfolioID") REFERENCES "DbPortfolios"("Id");
alter table public."DbPortfolioToUsers" add constraint "FK_DbPortfolios" FOREIGN KEY ("PortfolioID") REFERENCES "DbPortfolios"("Id");
alter table public."DbPresetValues" add constraint "FK_Account" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbProfileItems" add constraint fk_account FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbProfiles" add constraint fk_account FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbRetentionChangeReason" add constraint "FK_DbAccount" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbRoles" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbSamlConfigurations" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbSamlResponses" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbSearchCriteria" add constraint "fk_parentUserSearchCriteria" FOREIGN KEY ("ParentUserSearchCriteriaId") REFERENCES "DbSearchCriteria"("Id");
alter table public."DbSecurityPolicies" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbSfLinks" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbSfMappings" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTriggerToSearchCriteria" add constraint "FK_DbSearchCriteria" FOREIGN KEY ("SearchCriteriaID") REFERENCES "DbSearchCriteria"("Id");
alter table public."DbUserImageStamps" add constraint "FK_DbAccounts" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbUserSearchToSearchCriteria" add constraint "FK_DbSearchCriteria" FOREIGN KEY ("SearchCriteriaId") REFERENCES "DbSearchCriteria"("Id");
alter table public."DbUserSearchToSearchCriteria" add constraint "FK_DbUserSearches" FOREIGN KEY ("UserSearchId") REFERENCES "DbUserSearches"("Id");
alter table public."DbUserSettings" add constraint "FK_DbEmailSettings" FOREIGN KEY ("EmailSettingID") REFERENCES "DbEmailSettings"("Id");
alter table public."DbUserSettings" add constraint "FK_DbPortfolios" FOREIGN KEY ("DefaultPortfolioID") REFERENCES "DbPortfolios"("Id");
alter table public."DbUsers" add constraint "FK_DbUserSettings" FOREIGN KEY ("UserSettingsID") REFERENCES "DbUserSettings"("Id");
alter table workflow."DbWorkflowInstanceHistoryRecords" add constraint "FK_DbWorkflowInstanceHistoryRecordTypes_RecordTypeID" FOREIGN KEY ("RecordTypeID") REFERENCES workflow."DbWorkflowInstanceHistoryRecordTypes"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_DbWorkflowStepTypes_TypeID" FOREIGN KEY ("TypeID") REFERENCES workflow."DbWorkflowStepTypes"("Id");
alter table public."DbDocumentRequestContainers" add constraint "DbFileRequestContainers_check" CHECK ("Rename" = false OR "Rename" = true AND "IsMultiple" = false);
alter table public."DbDocumentRequests" add constraint "DbFileRequests_check" CHECK ("IsTemplate" = true OR "IsTemplate" = false AND "DestinationNodeID" IS NOT NULL);
alter table public."DbTimeTriggers" add constraint "check_timeTrigger_preActionNotificationTimeSpanInDays" CHECK ("PreActionNotificationTimeSpanInDays" <= 365);
alter table public."DbTimeTriggers" add constraint "check_timeTrigger_timeSpanInSeconds" CHECK ("TimeSpanInSeconds"::numeric <= '220898664000'::numeric);
alter table public."DbComponentStatusHistories" add constraint "FK_public.DbComponentStatusHistories_public.DbComponentStatus_C" FOREIGN KEY ("ComponentStatusId") REFERENCES "DbComponentStatus"("Id") ON DELETE CASCADE;
alter table public."DbDocumentRequestAttachments" add constraint "FK_public.DbDocumentRequestAttachments_public.DbNodes_Attachmen" FOREIGN KEY ("AttachmentNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbDocumentRequestContainerNodes" add constraint "FK_public.DbDocumentRequestContainerNodes_public.DbNodes_NodeID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbDocumentRequests" add constraint "FK_public.DbDocumentRequests_public.DbNodes_DestinationNodeID_A" FOREIGN KEY ("DestinationNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbEmailQueueAttachmentNodes" add constraint "FK_public.DbEmailQueueAttachmentNodes_public.DbNodes_NodeID_Acc" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbESignatureNodeAssociations" add constraint "FK_public.DbESignatureNodeAssociations_public.DbNodes_OriginalN" FOREIGN KEY ("OriginalNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbESignatureNodeAssociations" add constraint "FK_public.DbESignatureNodeAssociations_public.DbNodes_SignedNod" FOREIGN KEY ("SignedNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbESignatureTransactions" add constraint "FK_public.DbESignatureTransactions_public.DbNodes_AuditTrailNod" FOREIGN KEY ("AuditTrailNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbESignatureTransactions" add constraint "FK_public.DbESignatureTransactions_public.DbNodes_AuditTrailPar" FOREIGN KEY ("AuditTrailParentNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbESignatureTransactions" add constraint "FK_public.DbESignatureTransactions_public.DbNodes_SignedDocumen" FOREIGN KEY ("SignedDocumentParentNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodes" add constraint "FK_public.DbNodes_public.DbFileInfoes_FileInfoID_AccountID" FOREIGN KEY ("FileInfoID", "AccountID") REFERENCES "DbFileInfoes"("Id", "AccountID");
alter table public."DbFileQueue" add constraint "FK_public.DbFileQueue_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbLegacyNodeMappings" add constraint "FK_public.DbLegacyNodeMappings_public.DbNodes_NodeId_AccountID" FOREIGN KEY ("NodeId", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodes" add constraint "FK_public.DbNodes_public.DbNodes_ParentID_AccountID" FOREIGN KEY ("ParentID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodeAnnotations" add constraint "FK_public.DbNodeAnnotations_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodeClosures" add constraint "FK_public.DbNodeClosures_public.DbNodes_ChildID_AccountID" FOREIGN KEY ("ChildID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbRoleRelationships" add constraint "Parent_Is_Group" CHECK ("func_RoleIsGroup"("ParentRoleID") = true);
alter table public."DbAccessLinks" add constraint "FK_public.DbAccessLinks_public.DbUsers_CreatedByUserID" FOREIGN KEY ("CreatedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbAuditLogs" add constraint "FK_public.DbAuditLogs_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbAuditLogs" add constraint "FK_public.DbAuditLogs_public.DbUsers_GeneratedByUserID" FOREIGN KEY ("GeneratedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbDocumentRequests" add constraint "FK_public.DbDocumentRequests_public.DbUsers_CreatedByUserID" FOREIGN KEY ("CreatedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbEmailImportMappings" add constraint "FK_public.DbEmailImportMappings_public.DbUsers_CreatedByUserID" FOREIGN KEY ("CreatedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbESignatureTransactions" add constraint "FK_public.DbESignatureTransactions_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbFileInfoes" add constraint "FK_public.DbFileInfoes_public.DbUsers_CreatedByUserID" FOREIGN KEY ("CreatedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbNodeComments" add constraint "FK_public.DbNodeComments_public.DbUsers_LastModifiedByUserID" FOREIGN KEY ("LastModifiedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbNodeComments" add constraint "FK_public.DbNodeComments_public.DbUsers_CreatedByUserID" FOREIGN KEY ("CreatedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbNodes" add constraint "FK_public.DbNodes_public.DbUsers_CreatedByUserID" FOREIGN KEY ("CreatedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbPortfolios" add constraint "FK_public.DbPortfolios_public.DbUsers_OwnerUserID" FOREIGN KEY ("OwnerUserID") REFERENCES "DbUsers"("Id");
alter table public."DbPortfolioToNodes" add constraint "FK_public.DbPortfolioToNodes_public.DbUsers_AddedByUserID" FOREIGN KEY ("AddedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbPortfolioToUsers" add constraint "FK_public.DbPortfolioToUsers_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbResetPasswordRequests" add constraint "FK_public.DbResetPasswordRequests_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbRightSignatureUsers" add constraint "FK_public.DbRightSignatureUsers_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbRoles" add constraint "FK_public.DbRoles_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbSamlConfigurations" add constraint "FK_public.DbSamlConfigurations_public.DbUsers_CreatedByUserID" FOREIGN KEY ("CreatedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbTriggers" add constraint "FK_public.DbTriggers_public.DbUsers_CreatedByUserID" FOREIGN KEY ("CreatedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbUserApplicationsMfa" add constraint "FK_public.DbUserApplicationsMfa_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbUserExternalAuthentications" add constraint "FK_public.DbUserExternalAuthentications_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbUserImageStamps" add constraint "FK_public.DbUserImageStamps_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbUserPasswordHistories" add constraint "FK_public.DbUserPasswordHistories_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbUserSearches" add constraint "FK_public.DbUserSearches_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbUserSessions" add constraint "FK_public.DbUserSessions_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table public."DbUserSessions" add constraint "FK_public.DbUserSessions_public.DbUsers_GeneratedByUserID" FOREIGN KEY ("GeneratedByUserID") REFERENCES "DbUsers"("Id");
alter table public."DbEmailSettingToUsers" add constraint "FK_public.DbEmailSettingToUsers_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id") ON DELETE CASCADE;
alter table public."DbRightSignatureDocuments" add constraint "FK_public.DbRightSignatureDocuments_public.DbRightSignatureUser" FOREIGN KEY ("SenderUserID") REFERENCES "DbRightSignatureUsers"("UserID");
alter table public."DbFormFillPendings" add constraint "FK_public.DbFormFillPendings_public.DbUsers_UserID" FOREIGN KEY ("UserID") REFERENCES "DbUsers"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowSteps_Db" FOREIGN KEY ("DbWorkflowStepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowInstances" add constraint "FK_workflow.DbWorkflowInstances_workflow.DbWorkflowInstanceStat" FOREIGN KEY ("StateID") REFERENCES workflow."DbWorkflowInstanceStates"("Id");
alter table workflow."DbStageApproveResults" add constraint "FK_workflow.DbStageApproveResults_workflow.DbWorkflowStageInsta" FOREIGN KEY ("StageInstanceID") REFERENCES workflow."DbWorkflowStageInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI1" FOREIGN KEY ("requestFileExternal_AttachmentAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI2" FOREIGN KEY ("addTrigger_DestinationAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI3" FOREIGN KEY ("addTrigger_TargetAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI4" FOREIGN KEY ("applyTemplate_TargetPathAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI5" FOREIGN KEY ("comment_TargetAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI6" FOREIGN KEY ("copy_DestinationAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI7" FOREIGN KEY ("copy_ResultAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI8" FOREIGN KEY ("copy_SourceAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAssetI9" FOREIGN KEY ("createLocation_ResultAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset10" FOREIGN KEY ("createLocation_SourceAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset11" FOREIGN KEY ("delete_TargetAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset12" FOREIGN KEY ("esignature_AuditTrailAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset14" FOREIGN KEY ("esignature_AuditTrailDestinationAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset15" FOREIGN KEY ("esignature_SignedResultAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset16" FOREIGN KEY ("esignature_SignedResultDestinationAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowESignatureStepInstanceUserReferences" add constraint "FK_workflow.DbWorkflowESignatureStepInstanceUserReferences_wor1" FOREIGN KEY ("AssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset17" FOREIGN KEY ("esignature_SourceAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowESignatureStepInstanceTemplateDocuments" add constraint "FK_workflow.DbWorkflowESignatureStepInstanceTemplateDocuments_1" FOREIGN KEY ("SourceAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset18" FOREIGN KEY ("move_DestinationAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset19" FOREIGN KEY ("move_SourceAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset20" FOREIGN KEY ("rename_TargetAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset21" FOREIGN KEY ("sendMessage_AttachmentAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset22" FOREIGN KEY ("setPermissions_SourceAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset23" FOREIGN KEY ("setProfile_TargetAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset24" FOREIGN KEY ("setRetention_DestinationAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset25" FOREIGN KEY ("setRetention_TargetAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset26" FOREIGN KEY ("share_SourceAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset27" FOREIGN KEY ("upload_ResultAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset28" FOREIGN KEY ("upload_SourceAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowAsset29" FOREIGN KEY ("requestFileExternal_DestinationAssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstanceDocumentRequestContainers" add constraint "FK_workflow.DbWorkflowStepInstanceDocumentRequestContainers_wo1" FOREIGN KEY ("AssetInstanceID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbAssetInstanceNodeReferences" add constraint "FK_workflow.DbAssetInstanceNodeReferences_workflow.DbWorkflowAs" FOREIGN KEY ("AssetInstanceID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowAssetsStagesInstances" add constraint "FK_workflow.DbWorkflowAssetsStagesInstances_workflow.DbWorkflo1" FOREIGN KEY ("AssetID") REFERENCES workflow."DbWorkflowAssetInstances"("Id");
alter table workflow."DbWorkflowStepInstanceEmailUserGroups" add constraint "FK_workflow.DbWorkflowStepInstanceEmailUserGroups_workflow.DbWo" FOREIGN KEY ("WorkflowAddTriggerStepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowStepInstanceEmailUsers" add constraint "FK_workflow.DbWorkflowStepInstanceEmailUsers_workflow.DbWorkflo" FOREIGN KEY ("WorkflowAddTriggerStepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowESignatureStepInstanceUserReferences" add constraint "FK_workflow.DbWorkflowESignatureStepInstanceUserReferences_wor2" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowESignatureStepInstanceTemplateDocuments" add constraint "FK_workflow.DbWorkflowESignatureStepInstanceTemplateDocuments_2" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowSendMessageInstanceRecipients" add constraint "FK_workflow.DbWorkflowSendMessageInstanceRecipients_workflow.Db" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowStepInstanceUserGroups" add constraint "FK_workflow.DbWorkflowStepInstanceUserGroups_workflow.DbWorkflo" FOREIGN KEY ("WorkflowSetPermissionsStepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowStepInstanceUsers" add constraint "FK_workflow.DbWorkflowStepInstanceUsers_workflow.DbWorkflowStep" FOREIGN KEY ("WorkflowSetPermissionsStepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowSetProfileInstanceItems" add constraint "FK_workflow.DbWorkflowSetProfileInstanceItems_workflow.DbWorkfl" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowShareStepInstanceNewUserReferences" add constraint "FK_workflow.DbWorkflowShareStepInstanceNewUserReferences_workfl" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowStepInstanceGroupReferences" add constraint "FK_workflow.DbWorkflowStepInstanceGroupReferences_workflow.DbWo" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowStepInstanceUserReferences" add constraint "FK_workflow.DbWorkflowStepInstanceUserReferences_workflow.DbWor" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowInstanceHistoryRecords" add constraint "FK_workflow.DbWorkflowInstanceHistoryRecords_workflow.DbWorkfl1" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowStepInstanceDocumentRequestContainers" add constraint "FK_workflow.DbWorkflowStepInstanceDocumentRequestContainers_wo2" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowRequestFileExternalStepInstanceRecipientGroups" add constraint "FK_workflow.DbWorkflowRequestFileExternalStepInstanceRecipientG" FOREIGN KEY ("WorkflowStepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowRequestFileExternalStepInstanceNewUserReferences" add constraint "FK_workflow.DbWorkflowRequestFileExternalStepInstanceNewUserRef" FOREIGN KEY ("StepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowRequestFileExternalStepInstanceRecipients" add constraint "FK_workflow.DbWorkflowRequestFileExternalStepInstanceRecipients" FOREIGN KEY ("WorkflowStepInstanceID") REFERENCES workflow."DbWorkflowStepInstances"("Id");
alter table workflow."DbWorkflowStepDocumentRequestContainers" add constraint "FK_workflow.DbWorkflowStepDocumentRequestContainers_workflow.D1" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowRequestFileExternalStepRecipientGroups" add constraint "FK_workflow.DbWorkflowRequestFileExternalStepRecipientGroups_wo" FOREIGN KEY ("WorkflowStepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowRequestFileExternalStepNewUserReferences" add constraint "FK_workflow.DbWorkflowRequestFileExternalStepNewUserReferences_" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowRequestFileExternalStepRecipients" add constraint "FK_workflow.DbWorkflowRequestFileExternalStepRecipients_workflo" FOREIGN KEY ("WorkflowStepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowAddTriggerStepEmailUserGroups" add constraint "FK_workflow.DbWorkflowAddTriggerStepEmailUserGroups_workflow.Db" FOREIGN KEY ("WorkflowStepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowAddTriggerStepEmailUsers" add constraint "FK_workflow.DbWorkflowAddTriggerStepEmailUsers_workflow.DbWorkf" FOREIGN KEY ("WorkflowStepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowESignatureStepUserReferences" add constraint "FK_workflow.DbWorkflowESignatureStepUserReferences_workflow.DbW" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowESignatureStepTemplateDocuments" add constraint "FK_workflow.DbWorkflowESignatureStepTemplateDocuments_workflow1" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowSendMessageRecipients" add constraint "FK_workflow.DbWorkflowSendMessageRecipients_workflow.DbWorkflow" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowSetPermissionsStepUserGroups" add constraint "FK_workflow.DbWorkflowSetPermissionsStepUserGroups_workflow.DbW" FOREIGN KEY ("WorkflowStepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowSetPermissionsStepUsers" add constraint "FK_workflow.DbWorkflowSetPermissionsStepUsers_workflow.DbWorkfl" FOREIGN KEY ("WorkflowStepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table public."DbNodeClosures" add constraint "FK_public.DbNodeClosures_public.DbNodes_ParentID_AccountID" FOREIGN KEY ("ParentID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbTriggers" add constraint "FK_public.DbTriggers_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbEmailContent" add constraint "FK_public.DbEmailContent_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbEventTriggers" add constraint "FK_public.DbEventTriggers_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTimeTriggers" add constraint "FK_public.DbTimeTriggers_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTriggerInfoNodes" add constraint "FK_public.DbTriggerInfoNodes_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTriggerToNode" add constraint "FK_public.DbTriggerToNode_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTriggerToWorkflow" add constraint "FK_public.DbTriggerToWorkflow_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTriggerToRoles" add constraint "FK_public.DbTriggerToRoles_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTriggerToSearchCriteria" add constraint "FK_public.DbTriggerToSearchCriteria_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbProfileValueNodes" add constraint "FK_public.DbProfileValueNodes_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbProfileToProfileItems" add constraint "FK_public.DbProfileToProfileItems_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbProfileValueRoles" add constraint "FK_public.DbProfileValueRoles_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbRoleRelationships" add constraint "FK_public.DbRoleRelationships_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbRoleToAccountFeatures" add constraint "FK_public.DbRoleToAccountFeatures_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbSystemPermissions" add constraint "FK_public.DbSystemPermissions_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbEmailQueueAttachmentNodes" add constraint "FK_public.DbEmailQueueAttachmentNodes_public.DbAccounts_Account" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTemplateNodeChangeLogs" add constraint "FK_public.DbTemplateNodeChangeLogs_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTemplateNodeLinks" add constraint "FK_public.DbTemplateNodeLinks_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbWorkflowStageInstanceToNotifications" add constraint "FK_public.DbWorkflowStageInstanceToNotifications_public.DbAccou" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbRoleClosures" add constraint "FK_public.DbRoleClosures_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAccessLinksToNodeAndTriggers" add constraint "FK_public.DbAccessLinksToNodeAndTriggers_public.DbAccounts_Acco" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbDocumentRequestRoles" add constraint "FK_public.DbDocumentRequestRoles_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbNodeComments" add constraint "FK_public.DbNodeComments_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodeShares" add constraint "FK_public.DbNodeShares_public.DbNodes_AccountWorkspaceNodeID_Ac" FOREIGN KEY ("AccountWorkspaceNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodeShares" add constraint "FK_public.DbNodeShares_public.DbNodes_SharedWorkspaceNodeID_Acc" FOREIGN KEY ("SharedWorkspaceNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodeToFileInfoes" add constraint "FK_public.DbNodeToFileInfoes_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbPermissions" add constraint "FK_public.DbPermissions_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbNodes" add constraint "FK_public.DbNodes_public.DbProfiles_ProfileID_AccountID" FOREIGN KEY ("ProfileID", "AccountID") REFERENCES "DbProfiles"("Id", "AccountID");
alter table public."DbProfileValueNodes" add constraint "FK_public.DbProfileValueNodes_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbRightSignatureDocuments" add constraint "FK_public.DbRightSignatureDocuments_public.DbNodes_NodeID_Accou" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbSfLinks" add constraint "FK_public.DbSfLinks_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbSfMappings" add constraint "FK_public.DbSfMappings_public.DbNodes_ParentNodeID_AccountID" FOREIGN KEY ("ParentNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbTemplateNodeChangeLogs" add constraint "FK_public.DbTemplateNodeChangeLogs_public.DbNodes_TemplateNodeI" FOREIGN KEY ("TemplateNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbTemplateNodeLinks" add constraint "FK_public.DbTemplateNodeLinks_public.DbNodes_AppliedNodeID_Acco" FOREIGN KEY ("AppliedNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbTemplateNodeLinks" add constraint "FK_public.DbTemplateNodeLinks_public.DbNodes_TemplateNodeID_Acc" FOREIGN KEY ("TemplateNodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbTriggerInfoNodes" add constraint "FK_public.DbTriggerInfoNodes_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbTriggerToNode" add constraint "FK_public.DbTriggerToNode_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbUserImageStamps" add constraint "FK_public.DbUserImageStamps_public.DbNodes_NodeID_AccountID" FOREIGN KEY ("NodeID", "AccountID") REFERENCES "DbNodes"("Id", "AccountID");
alter table public."DbAccessLinksToNodeAndTriggers" add constraint "FK_public.DbAccessLinksToNodeAndTriggers_public.DbTriggers_Trig" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbTriggers" add constraint "FK_public.DbTriggers_public.DbEmailContent_EmailContentID_Accou" FOREIGN KEY ("EmailContentID", "AccountID") REFERENCES "DbEmailContent"("Id", "AccountID");
alter table public."DbEventTriggers" add constraint "FK_public.DbEventTriggers_public.DbTriggers_TriggerID_AccountID" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbTimeTriggers" add constraint "FK_public.DbTimeTriggers_public.DbTriggers_TriggerID_AccountID" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbTriggerInfoNodes" add constraint "FK_public.DbTriggerInfoNodes_public.DbTriggers_TriggerID_Accoun" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbTriggerToApiCallouts" add constraint "FK_public.DbTriggerToApiCallouts_public.DbTriggers_TriggerID_Ac" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbTriggerToNode" add constraint "FK_public.DbTriggerToNode_public.DbTriggers_TriggerID_AccountID" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbTriggerToRoles" add constraint "FK_public.DbTriggerToRoles_public.DbTriggers_TriggerID_AccountI" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbTriggerToSearchCriteria" add constraint "FK_public.DbTriggerToSearchCriteria_public.DbTriggers_TriggerID" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID") ON DELETE CASCADE;
alter table public."DbTriggerToWorkflow" add constraint "FK_public.DbTriggerToWorkflow_public.DbTriggers_TriggerID_Accou" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbWatermarkTriggerInfo" add constraint "FK_public.DbWatermarkTriggerInfo_public.DbTriggers_TriggerID_Ac" FOREIGN KEY ("TriggerID", "AccountID") REFERENCES "DbTriggers"("Id", "AccountID");
alter table public."DbTriggerToRoles" add constraint "FK_public.DbTriggerToRoles_public.DbRoles_RoleID_AccountID" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbAuditLogsToRoles" add constraint "FK_public.DbAuditLogsToRoles_public.DbRoles_RoleID_AccountID" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbDocumentRequestRoles" add constraint "FK_public.DbDocumentRequestRoles_public.DbRoles_RecipientRoleID" FOREIGN KEY ("RecipientRoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbESignatureSigners" add constraint "FK_public.DbESignatureSigners_public.DbRoles_RoleID_AccountID" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbFileInfoes" add constraint "FK_public.DbFileInfoes_public.DbRoles_CheckedOutByRoleID_Accoun" FOREIGN KEY ("CheckedOutByRoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbNodeShares" add constraint "FK_public.DbNodeShares_public.DbRoles_RoleID_AccountID" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbNotifications" add constraint "FK_public.DbNotifications_public.DbRoles_RecipientRoleID_Accoun" FOREIGN KEY ("RecipientRoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbPermissions" add constraint "FK_public.DbPermissions_public.DbRoles_RoleID_AccountID" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbRoles" add constraint "FK_public.DbRoles_public.DbProfiles_ProfileID_AccountID" FOREIGN KEY ("ProfileID", "AccountID") REFERENCES "DbProfiles"("Id", "AccountID");
alter table public."DbProfileValueRoles" add constraint "FK_public.DbProfileValueRoles_public.DbRoles_RoleID_AccountID" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbRoleClosures" add constraint "FK_public.DbRoleClosures_public.DbRoles_ChildID_AccountID" FOREIGN KEY ("ChildID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbRoleClosures" add constraint "FK_public.DbRoleClosures_public.DbRoles_ParentID_AccountID" FOREIGN KEY ("ParentID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbRoles" add constraint "FK_public.DbRoles_public.DbRoles_RoleManagerID_AccountID" FOREIGN KEY ("RoleManagerID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbRoleRelationships" add constraint "FK_public.DbRoleRelationships_public.DbRoles_ParentRoleID_Accou" FOREIGN KEY ("ParentRoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbRoleRelationships" add constraint "FK_public.DbRoleRelationships_public.DbRoles_ChildRoleID_Accoun" FOREIGN KEY ("ChildRoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbRoleToAccountFeatures" add constraint "FK_public.DbRoleToAccountFeatures_public.DbRoles_RoleID_Account" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbSamlConfigurations" add constraint "FK_public.DbSamlConfigurations_public.DbRoles_DefaultGroupID_Ac" FOREIGN KEY ("DefaultGroupID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbRoles" add constraint "FK_public.DbRoles_public.DbSecurityPolicies_SecurityPolicyID_Ac" FOREIGN KEY ("SecurityPolicyID", "AccountID") REFERENCES "DbSecurityPolicies"("Id", "AccountID");
alter table public."DbRoles" add constraint "FK_public.DbRoles_public.DbSystemPermissions_SystemPermissionID" FOREIGN KEY ("SystemPermissionID", "AccountID") REFERENCES "DbSystemPermissions"("Id", "AccountID");
alter table public."DbUserRolePreferences" add constraint "FK_public.DbUserRolePreferences_public.DbRoles_RoleID_AccountID" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbUserSessionToDbRoles" add constraint "FK_public.DbUserSessionToDbRoles_public.DbRoles_RoleID_AccountI" FOREIGN KEY ("RoleID", "AccountID") REFERENCES "DbRoles"("Id", "AccountID");
alter table public."DbAuditLogsToRoles" add constraint "FK_public.DbAuditLogsToRoles_public.DbAuditLogs_AuditLogID_Acco" FOREIGN KEY ("AuditLogID", "AccountID") REFERENCES "DbAuditLogs"("Id", "AccountID");
alter table public."DbAuditLogsToRoleDetails" add constraint "FK_public.DbAuditLogsToRoleDetails_public.DbAuditLogsToRoles_Au" FOREIGN KEY ("AuditLogToRoleID", "AccountID") REFERENCES "DbAuditLogsToRoles"("Id", "AccountID");
alter table public."DbAuditLogsToNodes" add constraint "FK_public.DbAuditLogsToNodes_public.DbAuditLogs_AuditLogID_Acco" FOREIGN KEY ("AuditLogID", "AccountID") REFERENCES "DbAuditLogs"("Id", "AccountID");
alter table public."DbAuditLogsToNodeDetails" add constraint "FK_public.DbAuditLogsToNodeDetails_public.DbAuditLogsToNodes_Au" FOREIGN KEY ("AuditLogToNodeID", "AccountID") REFERENCES "DbAuditLogsToNodes"("Id", "AccountID");
alter table public."DbDocumentRequestAttachments" add constraint "FK_public.DbDocumentRequestAttachments_public.DbDocumentRequest" FOREIGN KEY ("DocumentRequestID", "AccountID") REFERENCES "DbDocumentRequests"("Id", "AccountID");
alter table public."DbDocumentRequestContainers" add constraint "FK_public.DbDocumentRequestContainers_public.DbDocumentRequests" FOREIGN KEY ("DocumentRequestID", "AccountID") REFERENCES "DbDocumentRequests"("Id", "AccountID");
alter table public."DbDocumentRequestRoles" add constraint "FK_public.DbDocumentRequestRoles_public.DbDocumentRequests_Docu" FOREIGN KEY ("DocumentRequestID", "AccountID") REFERENCES "DbDocumentRequests"("Id", "AccountID");
alter table public."DbDocumentRequestToNotifications" add constraint "FK_public.DbDocumentRequestToNotifications_public.DbDocumentReq" FOREIGN KEY ("DocumentRequestID", "AccountID") REFERENCES "DbDocumentRequests"("Id", "AccountID") ON DELETE CASCADE;
alter table public."DbDocumentRequestContainerNodes" add constraint "FK_public.DbDocumentRequestContainerNodes_public.DbDocumentRequ" FOREIGN KEY ("DocumentRequestContainerID", "AccountID") REFERENCES "DbDocumentRequestContainers"("Id", "AccountID");
alter table public."DbDocumentRequestContainers" add constraint "FK_public.DbDocumentRequestContainers_public.DbFileInfoes_FileI" FOREIGN KEY ("FileInfoID", "AccountID") REFERENCES "DbFileInfoes"("Id", "AccountID");
alter table public."DbDocumentRequestContainers" add constraint "FK_public.DbDocumentRequestContainers_public.DbFormFillDefiniti" FOREIGN KEY ("FormFillDefinitionID", "AccountID") REFERENCES "DbFormFillDefinitions"("Id", "AccountID");
alter table public."DbFileQueue" add constraint "FK_public.DbFileQueue_public.DbFileInfoes_FileInfoID_AccountID" FOREIGN KEY ("FileInfoID", "AccountID") REFERENCES "DbFileInfoes"("Id", "AccountID");
alter table public."DbFileInfoes" add constraint "FK_public.DbFileInfoes_public.DbFormFillDefinitions_FormFillDef" FOREIGN KEY ("FormFillDefinitionID", "AccountID") REFERENCES "DbFormFillDefinitions"("Id", "AccountID");
alter table public."DbFileInfoes" add constraint "FK_public.DbFileInfoes_public.DbNodeComments_NodeCommentID_Acco" FOREIGN KEY ("NodeCommentID", "AccountID") REFERENCES "DbNodeComments"("Id", "AccountID");
alter table public."DbNodeToFileInfoes" add constraint "FK_public.DbNodeToFileInfoes_public.DbFileInfoes_FileInfoID_Acc" FOREIGN KEY ("FileInfoID", "AccountID") REFERENCES "DbFileInfoes"("Id", "AccountID");
alter table public."DbFileInfoes" add constraint "FK_public.DbFileInfoes_public.DbFileInfoes_GeneratedFromFileInf" FOREIGN KEY ("GeneratedFromFileInfoID", "AccountID") REFERENCES "DbFileInfoes"("Id", "AccountID");
alter table public."DbFormFillPendings" add constraint "FK_public.DbFormFillPendings_public.DbFormFillDefinitions_FormF" FOREIGN KEY ("FormFillDefinitionID", "AccountID") REFERENCES "DbFormFillDefinitions"("Id", "AccountID") ON DELETE CASCADE;
alter table public."DbFormFillToProfileItems" add constraint "FK_public.DbFormFillToProfileItems_public.DbFormFillDefinitions" FOREIGN KEY ("FormFillDefinitionID", "AccountID") REFERENCES "DbFormFillDefinitions"("Id", "AccountID") ON DELETE CASCADE;
alter table public."DbFormFillDefinitions" add constraint "FK_public.DbFormFillDefinitions_public.DbProfiles_ProfileID_Acc" FOREIGN KEY ("ProfileID", "AccountID") REFERENCES "DbProfiles"("Id", "AccountID");
alter table public."DbFormFillPendings" add constraint "FK_public.DbFormFillPendings_public.DbFileInfoes_AppliedNodeFil" FOREIGN KEY ("AppliedNodeFileInfoID", "AccountID") REFERENCES "DbFileInfoes"("Id", "AccountID") ON DELETE CASCADE;
alter table public."DbFormFillToProfileItems" add constraint "FK_public.DbFormFillToProfileItems_public.DbProfileItems_Profil" FOREIGN KEY ("ProfileItemID", "AccountID") REFERENCES "DbProfileItems"("Id", "AccountID");
alter table public."DbPresetValues" add constraint "FK_public.DbPresetValues_public.DbProfileItems_ProfileItemID_Ac" FOREIGN KEY ("ProfileItemID", "AccountID") REFERENCES "DbProfileItems"("Id", "AccountID");
alter table public."DbProfileToProfileItems" add constraint "FK_public.DbProfileToProfileItems_public.DbProfileItems_Profile" FOREIGN KEY ("ProfileItemID", "AccountID") REFERENCES "DbProfileItems"("Id", "AccountID");
alter table public."DbProfileValueNodes" add constraint "FK_public.DbProfileValueNodes_public.DbProfileItems_ProfileItem" FOREIGN KEY ("ProfileItemID", "AccountID") REFERENCES "DbProfileItems"("Id", "AccountID");
alter table public."DbProfileValueRoles" add constraint "FK_public.DbProfileValueRoles_public.DbProfileItems_ProfileItem" FOREIGN KEY ("ProfileItemID", "AccountID") REFERENCES "DbProfileItems"("Id", "AccountID");
alter table public."DbProfileValueNodes" add constraint "FK_public.DbProfileValueNodes_public.DbPresetValues_PresetValue" FOREIGN KEY ("PresetValueID", "AccountID") REFERENCES "DbPresetValues"("Id", "AccountID");
alter table public."DbProfileValueRoles" add constraint "FK_public.DbProfileValueRoles_public.DbPresetValues_PresetValue" FOREIGN KEY ("PresetValueID", "AccountID") REFERENCES "DbPresetValues"("Id", "AccountID");
alter table public."DbProfileValueNodes" add constraint "FK_public.DbProfileValueNodes_public.DbProfiles_ProfileID_Accou" FOREIGN KEY ("ProfileID", "AccountID") REFERENCES "DbProfiles"("Id", "AccountID");
alter table public."DbProfileToProfileItems" add constraint "FK_public.DbProfileToProfileItems_public.DbProfiles_ProfileID_A" FOREIGN KEY ("ProfileID", "AccountID") REFERENCES "DbProfiles"("Id", "AccountID");
alter table public."DbProfileValueRoles" add constraint "FK_public.DbProfileValueRoles_public.DbProfiles_ProfileID_Accou" FOREIGN KEY ("ProfileID", "AccountID") REFERENCES "DbProfiles"("Id", "AccountID");
alter table public."DbDocumentRequestToNotifications" add constraint "FK_public.DbDocumentRequestToNotifications_public.DbNotificatio" FOREIGN KEY ("NotificationID", "AccountID") REFERENCES "DbNotifications"("Id", "AccountID") ON DELETE CASCADE;
alter table public."DbWorkflowStageInstanceToNotifications" add constraint "FK_public.DbWorkflowStageInstanceToNotifications_public.DbNotif" FOREIGN KEY ("NotificationID", "AccountID") REFERENCES "DbNotifications"("Id", "AccountID") ON DELETE CASCADE;
alter table public."DbESignatureNodeAssociations" add constraint "FK_public.DbESignatureNodeAssociations_public.DbESignatureTrans" FOREIGN KEY ("TransactionID", "AccountID") REFERENCES "DbESignatureTransactions"("Id", "AccountID");
alter table public."DbESignatureSigners" add constraint "FK_public.DbESignatureSigners_public.DbESignatureTransactions_T" FOREIGN KEY ("TransactionID", "AccountID") REFERENCES "DbESignatureTransactions"("Id", "AccountID");
alter table public."DbESignatureTransactions" add constraint "FK_public.DbESignatureTransactions_public.DbESignatureTransacti" FOREIGN KEY ("TemplateID", "AccountID") REFERENCES "DbESignatureTransactions"("Id", "AccountID");
alter table public."DbSamlResponses" add constraint "FK_public.DbSamlResponses_public.DbSamlConfigurations_Configura" FOREIGN KEY ("ConfigurationID", "AccountID") REFERENCES "DbSamlConfigurations"("Id", "AccountID");
alter table public."DbPermissions" add constraint "FK_public.DbPermissions_public.DbPermissions_ChildPermissionId_" FOREIGN KEY ("ChildPermissionId", "AccountID") REFERENCES "DbPermissions"("Id", "AccountID");
alter table public."DbSecurityPolicyIpAddresses" add constraint "FK_public.DbSecurityPolicyIpAddresses_public.DbSecurityPolicies" FOREIGN KEY ("SecurityPolicyID", "AccountID") REFERENCES "DbSecurityPolicies"("Id", "AccountID");
alter table public."DbSecurityPolicyLoginTimes" add constraint "FK_public.DbSecurityPolicyLoginTimes_public.DbSecurityPolicies_" FOREIGN KEY ("SecurityPolicyID", "AccountID") REFERENCES "DbSecurityPolicies"("Id", "AccountID");
alter table public."DbEmailQueueAttachmentNodes" add constraint "FK_public.DbEmailQueueAttachmentNodes_public.DbEmailQueue_Email" FOREIGN KEY ("EmailQueueID", "AccountID") REFERENCES "DbEmailQueue"("Id", "AccountID");
alter table public."DbEmailRecipients" add constraint "FK_public.DbEmailRecipients_public.DbEmailQueue_EmailQueueID_Ac" FOREIGN KEY ("EmailQueueID", "AccountID") REFERENCES "DbEmailQueue"("Id", "AccountID");
alter table public."DbSfLinks" add constraint "FK_public.DbSfLinks_public.DbSfMappings_SfMappingID_AccountID" FOREIGN KEY ("SfMappingID", "AccountID") REFERENCES "DbSfMappings"("Id", "AccountID");
alter table public."DbSfMappings" add constraint "FK_public.DbSfMappings_public.DbPermissions_GroupPermissionID_A" FOREIGN KEY ("GroupPermissionID", "AccountID") REFERENCES "DbPermissions"("Id", "AccountID");
alter table public."DbSfMappings" add constraint "FK_public.DbSfMappings_public.DbPermissions_UserPermissionID_Ac" FOREIGN KEY ("UserPermissionID", "AccountID") REFERENCES "DbPermissions"("Id", "AccountID");
alter table public."DbEmailTemplateToPartner" add constraint "FK_public.DbEmailTemplateToPartner_public.DbPartners_PartnerID" FOREIGN KEY ("PartnerID") REFERENCES "DbPartners"("Id");
alter table public."DbUserSessionToDbRoles" add constraint "FK_public.DbUserSessionToDbRoles_public.DbUserSessions_UserSess" FOREIGN KEY ("UserSessionID") REFERENCES "DbUserSessions"("Id");
alter table workflow."DbWorkflowSetProfileItems" add constraint "FK_workflow.DbWorkflowSetProfileItems_workflow.DbWorkflowSteps_" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowShareStepNewUserReferences" add constraint "FK_workflow.DbWorkflowShareStepNewUserReferences_workflow.DbWor" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowStepGroupReferences" add constraint "FK_workflow.DbWorkflowStepGroupReferences_workflow.DbWorkflowSt" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowStepUserReferences" add constraint "FK_workflow.DbWorkflowStepUserReferences_workflow.DbWorkflowSte" FOREIGN KEY ("StepID") REFERENCES workflow."DbWorkflowSteps"("Id");
alter table workflow."DbWorkflowAssetsStages" add constraint "FK_workflow.DbWorkflowAssetsStages_workflow.DbWorkflowStages_St" FOREIGN KEY ("StageID") REFERENCES workflow."DbWorkflowStages"("Id");
alter table workflow."DbWorkflowStageInstances" add constraint "FK_workflow.DbWorkflowStageInstances_workflow.DbWorkflowStages_" FOREIGN KEY ("StageTypeID") REFERENCES workflow."DbWorkflowStages"("Id");
alter table workflow."DbWorkflowStageApproverGroups" add constraint "FK_workflow.DbWorkflowStageApproverGroups_workflow.DbWorkflowSt" FOREIGN KEY ("WorkflowStageID") REFERENCES workflow."DbWorkflowStages"("Id");
alter table workflow."DbWorkflowStageApprovers" add constraint "FK_workflow.DbWorkflowStageApprovers_workflow.DbWorkflowStages_" FOREIGN KEY ("WorkflowStageID") REFERENCES workflow."DbWorkflowStages"("Id");
alter table workflow."DbWorkflowStageAssigneeGroups" add constraint "FK_workflow.DbWorkflowStageAssigneeGroups_workflow.DbWorkflowSt" FOREIGN KEY ("WorkflowStageID") REFERENCES workflow."DbWorkflowStages"("Id");
alter table workflow."DbWorkflowStageAssignees" add constraint "FK_workflow.DbWorkflowStageAssignees_workflow.DbWorkflowStages_" FOREIGN KEY ("WorkflowStageID") REFERENCES workflow."DbWorkflowStages"("Id");
alter table workflow."DbProfileRoutingRules" add constraint "FK_workflow.DbProfileRoutingRules_workflow.DbWorkflowStages_Sta" FOREIGN KEY ("StageID") REFERENCES workflow."DbWorkflowStages"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowStages_StageID" FOREIGN KEY ("StageID") REFERENCES workflow."DbWorkflowStages"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_requestF1" FOREIGN KEY ("requestFileExternal_AttachmentAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_requestF2" FOREIGN KEY ("requestFileExternal_DestinationAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowStepDocumentRequestContainers" add constraint "FK_workflow.DbWorkflowStepDocumentRequestContainers_workflow.D2" FOREIGN KEY ("AssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbAssetNodeReference" add constraint "FK_workflow.DbAssetNodeReference_workflow.DbWorkflowAssets_Asse" FOREIGN KEY ("AssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowAssetsStages" add constraint "FK_workflow.DbWorkflowAssetsStages_workflow.DbWorkflowAssets_As" FOREIGN KEY ("AssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowStages" add constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowAssets_Approval" FOREIGN KEY ("ApprovalAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbProfileRoutingRules" add constraint "FK_workflow.DbProfileRoutingRules_workflow.DbWorkflowAssets_Ass" FOREIGN KEY ("AssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_addTrigg1" FOREIGN KEY ("addTrigger_DestinationAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_addTrigg2" FOREIGN KEY ("addTrigger_TargetAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_applyTemp" FOREIGN KEY ("applyTemplate_TargetPathAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_comment_T" FOREIGN KEY ("comment_TargetAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_copy_Dest" FOREIGN KEY ("copy_DestinationAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_copy_Resu" FOREIGN KEY ("copy_ResultAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_copy_Sour" FOREIGN KEY ("copy_SourceAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_createLo1" FOREIGN KEY ("createLocation_ParentPathAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_createLo2" FOREIGN KEY ("createLocation_ResultAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_delete_Ta" FOREIGN KEY ("delete_TargetAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu1" FOREIGN KEY ("esignature_AuditTrailAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu2" FOREIGN KEY ("esignature_AuditTrailDestinationAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu3" FOREIGN KEY ("esignature_SignedResultAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu4" FOREIGN KEY ("esignature_SignedResultDestinationAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_esignatu5" FOREIGN KEY ("esignature_SourceAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowESignatureStepTemplateDocuments" add constraint "FK_workflow.DbWorkflowESignatureStepTemplateDocuments_workflow2" FOREIGN KEY ("SourceAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_move_Dest" FOREIGN KEY ("move_DestinationAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_move_Sour" FOREIGN KEY ("move_SourceAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_rename_Ta" FOREIGN KEY ("rename_TargetAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_sendMessa" FOREIGN KEY ("sendMessage_AttachmentAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_setPermis" FOREIGN KEY ("setPermissions_TargetAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_setProfil" FOREIGN KEY ("setProfile_TargetAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_setReten1" FOREIGN KEY ("setRetention_DestinationAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_setReten2" FOREIGN KEY ("setRetention_TargetAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_share_Sou" FOREIGN KEY ("share_SourceAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_upload_Re" FOREIGN KEY ("upload_ResultAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowSteps" add constraint "FK_workflow.DbWorkflowSteps_workflow.DbWorkflowAssets_upload_So" FOREIGN KEY ("upload_SourceAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowAssetInstances" add constraint "FK_workflow.DbWorkflowAssetInstances_workflow.DbWorkflowAssets_" FOREIGN KEY ("WorkflowAssetID") REFERENCES workflow."DbWorkflowAssets"("Id");
alter table workflow."DbWorkflowAssets" add constraint "FK_workflow.DbWorkflowAssets_workflow.DbWorkflows_WorkflowID" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowInstanceHistoryRecords" add constraint "FK_workflow.DbWorkflowInstanceHistoryRecords_workflow.DbWorkfl2" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowInstances" add constraint "FK_workflow.DbWorkflowInstances_workflow.DbWorkflows_WorkflowID" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowsAvailableStates" add constraint "FK_workflow.DbWorkflowsAvailableStates_workflow.DbWorkflows_Wor" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowNotificationConfigurations" add constraint "FK_workflow.DbWorkflowNotificationConfigurations_workflow.DbWor" FOREIGN KEY ("Id") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowOwnerGroups" add constraint "FK_workflow.DbWorkflowOwnerGroups_workflow.DbWorkflows_Workflow" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowOwners" add constraint "FK_workflow.DbWorkflowOwners_workflow.DbWorkflows_WorkflowID" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowScheduleConfigurations" add constraint "FK_workflow.DbWorkflowScheduleConfigurations_workflow.DbWorkflo" FOREIGN KEY ("Id") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowStages" add constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflows_WorkflowID" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowStarterGroups" add constraint "FK_workflow.DbWorkflowStarterGroups_workflow.DbWorkflows_Workfl" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowStarters" add constraint "FK_workflow.DbWorkflowStarters_workflow.DbWorkflows_WorkflowID" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowWatcherGroups" add constraint "FK_workflow.DbWorkflowWatcherGroups_workflow.DbWorkflows_Workfl" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowWatchers" add constraint "FK_workflow.DbWorkflowWatchers_workflow.DbWorkflows_WorkflowID" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflows"("Id");
alter table workflow."DbWorkflowsAvailableStates" add constraint "FK_workflow.DbWorkflowsAvailableStates_workflow.DbWorkflowInsta" FOREIGN KEY ("StateID") REFERENCES workflow."DbWorkflowInstanceStates"("Id");
alter table workflow."DbWorkflowStages" add constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowInstanceStates1" FOREIGN KEY ("ApprovedRoutingWorkflowInstanceStateID") REFERENCES workflow."DbWorkflowInstanceStates"("Id");
alter table workflow."DbWorkflowStages" add constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowInstanceStates2" FOREIGN KEY ("DefaultProfileRoutingWorkflowInstanceStateID") REFERENCES workflow."DbWorkflowInstanceStates"("Id");
alter table workflow."DbWorkflowStages" add constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowInstanceStates3" FOREIGN KEY ("PastRoutingWorkflowInstanceStateID") REFERENCES workflow."DbWorkflowInstanceStates"("Id");
alter table workflow."DbProfileRoutingRules" add constraint "FK_workflow.DbProfileRoutingRules_workflow.DbWorkflowInstanceSt" FOREIGN KEY ("RoutingWorkflowInstanceStateID") REFERENCES workflow."DbWorkflowInstanceStates"("Id");
alter table workflow."DbWorkflowStages" add constraint "FK_workflow.DbWorkflowStages_workflow.DbWorkflowInstanceStates4" FOREIGN KEY ("RejectedRoutingWorkflowInstanceStateID") REFERENCES workflow."DbWorkflowInstanceStates"("Id");
alter table workflow."DbWorkflowAssetInstances" add constraint "FK_workflow.DbWorkflowAssetInstances_workflow.DbWorkflowInstanc" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflowInstances"("Id");
alter table workflow."DbWorkflowInstanceHistoryRecords" add constraint "FK_workflow.DbWorkflowInstanceHistoryRecords_workflow.DbWorkfl3" FOREIGN KEY ("WorkflowInstanceID") REFERENCES workflow."DbWorkflowInstances"("Id");
alter table workflow."DbWorkflowStageInstances" add constraint "FK_workflow.DbWorkflowStageInstances_workflow.DbWorkflowInstanc" FOREIGN KEY ("WorkflowID") REFERENCES workflow."DbWorkflowInstances"("Id");
alter table workflow."DbWorkflowInstanceHistoryRecords" add constraint "FK_workflow.DbWorkflowInstanceHistoryRecords_workflow.DbWorkfl4" FOREIGN KEY ("StageInstanceID") REFERENCES workflow."DbWorkflowStageInstances"("Id");
alter table workflow."DbWorkflowStepInstances" add constraint "FK_workflow.DbWorkflowStepInstances_workflow.DbWorkflowStageIns" FOREIGN KEY ("StageID") REFERENCES workflow."DbWorkflowStageInstances"("Id");
alter table workflow."DbWorkflowInstances" add constraint "FK_workflow.DbWorkflowInstances_workflow.DbWorkflowStageInstanc" FOREIGN KEY ("CurrentStageID") REFERENCES workflow."DbWorkflowStageInstances"("Id");
alter table workflow."DbWorkflowAssetsStagesInstances" add constraint "FK_workflow.DbWorkflowAssetsStagesInstances_workflow.DbWorkflo2" FOREIGN KEY ("StageID") REFERENCES workflow."DbWorkflowStageInstances"("Id");
alter table workflow."DbWorkflowSetProfileInstanceItemPresetValues" add constraint "FK_workflow.DbWorkflowSetProfileInstanceItemPresetValues_workfl" FOREIGN KEY ("StepProfileItemID") REFERENCES workflow."DbWorkflowSetProfileInstanceItems"("Id");
alter table workflow."DbWorkflowSetProfileItemPresetValues" add constraint "FK_workflow.DbWorkflowSetProfileItemPresetValues_workflow.DbWor" FOREIGN KEY ("StepProfileItemID") REFERENCES workflow."DbWorkflowSetProfileItems"("Id");
alter table public."DbWorkflowStageInstanceToNotifications" add constraint "FK_DbWorkflowStageInstanceToNotifications_DbWorkflowStageInstan" FOREIGN KEY ("WorkflowStageInstanceID") REFERENCES workflow."DbWorkflowStageInstances"("Id");
alter table public."DbRoles" add constraint "CK_RoleManagerID" CHECK ("RoleType" = 3 AND "RoleManagerID" IS NOT NULL OR "RoleType" <> '-1'::integer AND "RoleManagerID" IS NULL);
alter table public."DbDocumentRequestAttachments" add constraint "FK_public.DbDocumentRequestAttachments_public.DbAccounts_Accoun" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbFormFillDefinitions" add constraint "FK_public.DbFormFillDefinitions_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbDocumentRequestContainers" add constraint "FK_public.DbDocumentRequestContainers_public.DbAccounts_Account" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbDocumentRequestContainerNodes" add constraint "FK_public.DbDocumentRequestContainerNodes_public.DbAccounts_Acc" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbFormFillPendings" add constraint "FK_public.DbFormFillPendings_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbFormFillToProfileItems" add constraint "FK_public.DbFormFillToProfileItems_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbNodeComments" add constraint "FK_public.DbNodeComments_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbESignatureSigners" add constraint "FK_public.DbESignatureSigners_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbESignatureNodeAssociations" add constraint "FK_public.DbESignatureNodeAssociations_public.DbAccounts_Accoun" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbSecurityPolicyIpAddresses" add constraint "FK_public.DbSecurityPolicyIpAddresses_public.DbAccounts_Account" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbSecurityPolicyLoginTimes" add constraint "FK_public.DbSecurityPolicyLoginTimes_public.DbAccounts_AccountI" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbUserRolePreferences" add constraint "FK_public.DbUserRolePreferences_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbTriggerToApiCallouts" add constraint "FK_public.DbTriggerToApiCallouts_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbWatermarkTriggerInfo" add constraint "FK_public.DbWatermarkTriggerInfo_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbLegacyNodeMappings" add constraint "FK_public.DbLegacyNodeMappings_public.DbAccounts_AccountID" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbAccessLinksToDocumentRequests" add constraint "FK_public.DbAccessLinksToDocumentRequests_public.DbAccounts_Acc" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbDocumentRequestToNotifications" add constraint "FK_public.DbDocumentRequestToNotifications_public.DbAccounts_Ac" FOREIGN KEY ("AccountID") REFERENCES "DbAccounts"("Id");
alter table public."DbPermissions" add constraint ck_permission CHECK ("Restrict" = false OR "Restrict" = true AND "Preview" = false AND "Read" = false AND "Write" = false AND "Delete" = false AND "Admin" = false AND "UploadFiles" = false AND "CreateDirectories" = false AND "ChildPermissionId" IS NULL AND ("Enforce" = false OR "Enforce" = true));

select create_distributed_function('"patindex"(character varying,character varying)');
select create_distributed_function('"isnumeric"(text)');
select create_distributed_function('"func_getnaturalsortablevalue"(character varying)');
select create_distributed_function('"datediff"(character varying,timestamp without time zone,timestamp without time zone)');
select create_distributed_function('"func_insertintodbtemptablesearchresults"(dbtemptablesearchresulttype[])');

CREATE OR REPLACE FUNCTION createrelationships() RETURNS TRIGGER AS $$
BEGIN 
  EXECUTE format(
	  'insert into %1$s ("ParentID", "ChildID", "Depth", "AccountID") values (($1)."Id", ($1)."Id", 0, ($1)."AccountID");
	  insert into %1$s ("ParentID", "ChildID", "Depth", "AccountID")
	  select closures."ParentID", ($1)."Id", closures."Depth" + 1, ($1)."AccountID"
	  from %1$s as closures WHERE ($1)."ParentID" = closures."ChildID";',
	  TG_ARGV[0]
   ) USING NEW;	
   RETURN NEW;
END;
$$ LANGUAGE plpgsql;

select create_distributed_function('createrelationships()');

SELECT run_command_on_colocated_placements(
  'public."DbNodes"',
  'public."DbNodeClosures"',
  $cmd$
    CREATE TRIGGER tr_dbnode_insert AFTER INSERT ON %s
      FOR EACH ROW EXECUTE PROCEDURE createRelationships(%L)
  $cmd$	
);

CREATE OR REPLACE FUNCTION updateRelationships() RETURNS TRIGGER AS $$
BEGIN 
  EXECUTE format(
	  'delete from %1$s
	   where "ChildID" in (select "ChildID" from %1$s where "ParentID" = ($1)."Id" and "AccountID" = ($1)."AccountID")
       and "ParentID" in (select "ParentID" from %1$s where "ChildID" = ($1)."Id" and "ParentID" != "ChildID" and "AccountID" = ($1)."AccountID");
	   
	   insert into %1$s ("ParentID", "ChildID", "Depth", "AccountID")
       select supertree."ParentID", subtree."ChildID", supertree."Depth" + subtree."Depth" + 1, supertree."AccountID"
       from %1$s supertree, %1$s subtree
       where supertree."ChildID" = ($1)."ParentID" and subtree."ParentID" = ($1)."Id" and supertree."AccountID" = subtree."AccountID";',
	  TG_ARGV[0]
   ) USING NEW;	
   RETURN NEW;
END;
$$ LANGUAGE plpgsql;

select create_distributed_function('updateRelationships()');

SELECT run_command_on_colocated_placements(
  'public."DbNodes"',
  'public."DbNodeClosures"',
  $cmd$
    CREATE TRIGGER tr_dbnode_update AFTER UPDATE ON %s
      FOR EACH ROW WHEN ((old."ParentID" IS DISTINCT FROM new."ParentID")) EXECUTE PROCEDURE updaterelationships(%L)
  $cmd$	
);

CREATE OR REPLACE FUNCTION createdroleclosurerelationship() RETURNS TRIGGER AS $$
DECLARE
closure bigint := NULL;
BEGIN	
	EXECUTE format(
	'SELECT * FROM "%s" WHERE "ChildID" = ($1)."ParentID" AND "ParentID" = ($1)."ChildID" AND ($1)."AccountID" = "AccountID";', 
	 TG_ARGV[0]) USING NEW INTO closure;
    IF closure IS NOT NULL
 	THEN
    	RETURN NULL;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

select create_distributed_function('createdroleclosurerelationship()');

SELECT run_command_on_placements(
  'public."DbRoleClosures"',
  $cmd$
    CREATE TRIGGER tr_dbroleclosures_insert BEFORE INSERT ON %1$s
	  FOR EACH ROW EXECUTE FUNCTION createdroleclosurerelationship(%1$s)
  $cmd$	
);

CREATE OR REPLACE FUNCTION createrolerelationship() RETURNS TRIGGER AS $$
BEGIN	
    EXECUTE format(
    'INSERT INTO %s ("ParentID", "ChildID", "AccountID") values (($1)."Id", ($1)."Id", ($1)."AccountID");',
	 TG_ARGV[0]
   ) USING NEW;
   RETURN NEW;
END;
$$ LANGUAGE plpgsql;

select create_distributed_function('createrolerelationship()');

SELECT run_command_on_colocated_placements(
  'public."DbRoles"',
  'public."DbRoleClosures"',
  $cmd$
    CREATE TRIGGER tr_dbrole_insert AFTER INSERT ON %s 
	  FOR EACH ROW EXECUTE FUNCTION createrolerelationship(%L);
  $cmd$	
);

CREATE OR REPLACE FUNCTION deleterolerelationship() RETURNS TRIGGER AS $$
BEGIN	
    EXECUTE format(
    'DELETE FROM %s
     where "ParentID" = "ChildID" and "ChildID" = ($1)."Id" and "AccountID" = ($1)."AccountID";',
	 TG_ARGV[0]
   ) USING OLD;
   RETURN OLD;
END;
$$ LANGUAGE plpgsql;

select create_distributed_function('deleterolerelationship()');

SELECT run_command_on_colocated_placements(
  'public."DbRoles"',
  'public."DbRoleClosures"',
  $cmd$
    CREATE TRIGGER tr_dbrole_delete BEFORE DELETE ON %s 
	  FOR EACH ROW EXECUTE FUNCTION deleterolerelationship(%L);
  $cmd$	
);

CREATE OR REPLACE PROCEDURE sp_insertRoleRelationshipClosures(tableName text, parentid bigint, childid bigint, accountID int)
AS $$
BEGIN
	EXECUTE format(
    'INSERT INTO %1$s ("ParentID", "ChildID", "AccountID")
     SELECT cl."ParentID", child."ChildID", child."AccountID"
     FROM %1$s AS cl
	 JOIN %1$s AS child on child."ParentID" = $2 AND child."AccountID" = cl."AccountID"
     WHERE cl."ChildID" = $1 AND cl."AccountID" = $3;',
	 tableName
   ) USING parentid, childid, accountID;
END;
$$ LANGUAGE 'plpgsql';	

select create_distributed_function('"sp_insertrolerelationshipclosures"(text,bigint,bigint,integer)');

CREATE OR REPLACE FUNCTION insertrolerelationshipclosures() RETURNS TRIGGER AS $$
BEGIN	
    EXECUTE format(
    'CALL sp_insertRoleRelationshipClosures(''%1$s'', ($1)."ParentRoleID", ($1)."ChildRoleID", ($1)."AccountID");',
	 TG_ARGV[0]
   ) USING NEW;
   RETURN NEW;
END;
$$ LANGUAGE plpgsql;

select create_distributed_function('insertrolerelationshipclosures()');

SELECT run_command_on_colocated_placements(
  'public."DbRoleRelationships"',
  'public."DbRoleClosures"',
  $cmd$
	CREATE TRIGGER tr_dbrolerelationships_insert AFTER INSERT ON %s 
	  FOR EACH ROW EXECUTE FUNCTION insertrolerelationshipclosures(%L);
  $cmd$	
);

CREATE OR REPLACE PROCEDURE sp_deleteRoleRelationshipClosures(tablename text, parentid bigint, childid bigint, accountid int)
AS $$
DECLARE
    db_row RECORD;
    db_cursor refcursor;
BEGIN
    OPEN db_cursor FOR EXECUTE format(
	'SELECT parent."ParentID", child."ChildID" 
	 FROM %1$s AS parent 
	 JOIN %1$s AS child ON child."ParentID" = $2 AND child."AccountID" = parent."AccountID"
	 WHERE parent."ChildID" = $1 AND parent."AccountID" = $3 
	 GROUP BY parent."ParentID", child."ChildID"', tablename) USING parentid, childid, accountid;
    LOOP
        FETCH db_cursor INTO db_row;
        EXIT WHEN NOT FOUND;
        EXECUTE format('DELETE FROM %s cl WHERE cl."ParentID" = $1 AND cl."ChildID" = $2 AND cl."AccountID" = $3;', tablename) USING db_row."ParentID", db_row."ChildID", accountid;
    END LOOP;
    CLOSE db_cursor;
END;
$$ LANGUAGE 'plpgsql';
								   
select create_distributed_function('"sp_deleterolerelationshipclosures"(text,bigint,bigint,int)');

CREATE OR REPLACE FUNCTION deleteRoleRelationshipClosures() RETURNS TRIGGER AS $$
BEGIN	
    EXECUTE format(
	'CALL sp_deleterolerelationshipclosures(''%1$s'', ($1)."ParentRoleID", ($1)."ChildRoleID", ($1)."AccountID")',
	 TG_ARGV[0]
   ) USING OLD;
   RETURN OLD;
END;
$$ LANGUAGE plpgsql;

select create_distributed_function('deleteRoleRelationshipClosures()');

SELECT run_command_on_colocated_placements(
  'public."DbRoleRelationships"',
  'public."DbRoleClosures"',
  $cmd$
	CREATE TRIGGER tr_DbRoleRelationships_delete BEFORE DELETE ON %s 
	  FOR EACH ROW EXECUTE PROCEDURE deleteRoleRelationshipClosures(%L);
  $cmd$	
);

CREATE OR REPLACE FUNCTION updateRoleRelationshipClosures()
    RETURNS trigger AS $$
BEGIN
	EXECUTE format('CALL sp_deleterolerelationshipclosures(''%1$s'', ($1)."ParentRoleID", ($1)."ChildRoleID", ($1)."AccountID");', TG_ARGV[0]) USING OLD;
	EXECUTE format('CALL sp_insertrolerelationshipclosures(''%1$s'', ($1)."ParentRoleID", ($1)."ChildRoleID", ($1)."AccountID");', TG_ARGV[0]) USING NEW;
    RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';

select create_distributed_function('updateRoleRelationshipClosures()');

SELECT run_command_on_colocated_placements(
  'public."DbRoleRelationships"',
  'public."DbRoleClosures"',
  $cmd$
	CREATE TRIGGER tr_dbrolerelationships_update AFTER UPDATE ON %s 
	  FOR EACH ROW EXECUTE FUNCTION updaterolerelationshipclosures(%L);
  $cmd$	
);

IMPORTANT!

  1. When you mark table as "distributed" all referenced table must be a distributed table or a reference table.
  2. When you mark table as "distributed" PK and Unique constraints must include distribution key (AccountID)
  3. You can't use GENERATED BY ... AS IDENTITY

 

The Following SQL Queries were super helpful in generating the script to distribute the database.

namespace CitusTableDistributionTool.SQL
{
    internal static class SqlQueries
    {
        public static string CreateDbAccountsDistributedTableCommand => @"SELECT create_distributed_table('""DbAccounts""', 'Id');";

        public static string CreateDbUsersSessionsReferenceTableCommand => @"SELECT create_reference_table('""public"".""DbUserSessions""');";

        public static string QueryAddConstraintCommands => @"
select 'alter table '||quote_ident(ns.nspname)||'.'||quote_ident(tb.relname)||
       ' add constraint '||quote_ident(conname)||' '||
       pg_get_constraintdef(c.oid, true)||';' as ddl
from pg_constraint c
  join pg_class tb on tb.oid = c.conrelid
  left outer join pg_inherits on pg_inherits.inhrelid = tb.oid
  join pg_namespace ns on ns.oid = tb.relnamespace
where ns.nspname in ('public', 'workflow')
 and c.contype in ('f', 'c')
 and pg_inherits.inhrelid is null;";       

        public static string QueryCreateDistributedTablesCommands => @"
select 'SELECT create_distributed_table(''""' || t.table_schema || '"".""' || t.table_name || '""'', ''AccountID'');'   
from information_schema.tables t
inner join information_schema.columns c on c.table_name = t.table_name
                                and c.table_schema = t.table_schema
join pg_class on pg_class.relname = c.table_name
left outer join pg_inherits on pg_inherits.inhrelid = pg_class.oid
where c.column_name = 'AccountID'
      and t.table_name != 'DbUserSessions'
      and t.table_schema in ('public')
      and t.table_type = 'BASE TABLE'
	  and pg_inherits.inhrelid is null
      and (pg_class.relkind = 'r' or pg_class.relkind = 'p')
order by t.table_schema;";

        public static string QueryCreatePublicReferenceTablesCommands => @"
select 'SELECT create_reference_table(''""' || t.table_schema || '"".""' || t.table_name || '""'');' 
from information_schema.tables t
left join (select table_schema, table_name
           from information_schema.columns
           where column_name = 'AccountID') c
                    on c.table_name = t.table_name
                    and c.table_schema = t.table_schema
join pg_class on pg_class.relname = t.table_name
left outer join pg_inherits on pg_inherits.inhrelid = pg_class.oid
where c.table_name is null 
      and t.table_name != 'DbAccounts'
      and t.table_schema in ('public')
      and t.table_type = 'BASE TABLE'
      and pg_inherits.inhrelid is null
      and (pg_class.relkind = 'r' or pg_class.relkind = 'p')
order by t.table_schema,
         t.table_name;";

        public static string QueryCreateTriggerCommands => @"
SELECT pg_get_triggerdef(oid) || ';'
FROM information_schema.triggers
JOIN pg_trigger ON pg_trigger.tgname = information_schema.triggers.trigger_name
WHERE trigger_schema in ('public', 'workflow');";

        public static string QueryCreateWorkflowReferenceTablesCommands => @"
select 'SELECT create_reference_table(''""' || t.table_schema || '"".""' || t.table_name || '""'');' 
from information_schema.tables t
join pg_class on pg_class.relname = t.table_name
left outer join pg_inherits on pg_inherits.inhrelid = pg_class.oid
where t.table_schema in ('workflow')
      and t.table_type = 'BASE TABLE'
      and pg_inherits.inhrelid is null
      and (pg_class.relkind = 'r' or pg_class.relkind = 'p')
order by t.table_schema,
         t.table_name;";

        public static string QueryDistributeFunctionsAndStoredProceduresInfo => @"
        select 'select create_distributed_function(''""' || p.proname || '""(' || '{0}' || ')'');' as CommandTemplate,
       pg_get_function_arguments(p.oid) as Arguments
from pg_proc p
left join pg_namespace n on p.pronamespace = n.oid
left join pg_language l on p.prolang = l.oid
left join pg_type t on t.oid = p.prorettype 
where n.nspname not in ('pg_catalog', 'information_schema')
	and n.nspname in ('public', 'workflow')
    and p.proname not like '%uuid_%';
";

        public static string QueryDropConstraintCommands => @"
select 'alter table '||quote_ident(ns.nspname)||'.'||quote_ident(tb.relname)||
       ' drop constraint '||quote_ident(conname)||';' as ddl
from pg_constraint c
  join pg_class tb on tb.oid = c.conrelid
  left outer join pg_inherits on pg_inherits.inhrelid = tb.oid
  join pg_namespace ns on ns.oid = tb.relnamespace
where ns.nspname in ('public', 'workflow')
 and c.contype in ('f', 'c')
 and pg_inherits.inhrelid is null;";

        public static string QueryDropTriggerCommands => @"
SELECT 'DROP TRIGGER ' || tgname || ' ON ""' || event_object_schema || '"".""' || event_object_table || '"";'
FROM information_schema.triggers
JOIN pg_trigger ON pg_trigger.tgname = information_schema.triggers.trigger_name
WHERE trigger_schema in ('public', 'workflow');";

        public static string IfStatementForFutureUseInMigrations => @"
DO
    $do$
    BEGIN
        IF EXISTS (SELECT * FROM pg_extension WHERE extname = 'citus') THEN
            {COMMAND GOES HERE}
        END IF;
    END
$do$";
    }

    public class DistributeFunctionsAndStoredProceduresInfo
    {
        public string CommandTemplate { get; set; }
        public string Arguments { get; set; }
    }

    // views? types?


    //    distrubute functions https://docs.microsoft.com/en-us/azure/postgresql/reference-hyperscale-functions
    //    SELECT create_distributed_function('createrolerelationship()'); - seems to only work with trigger functions - jk SELECT create_distributed_function('"func_RoleIsGroup"(bigint)');

    //     also need to figure out how to do complex joins

    // need to apply extension uuis-ossp, triggers, to all worker nodes
}

A Few Things We Learned

 

This will colocate a set of tables with another table (there is also a parameter called 'colocate' to specify this when running the create_distributed_table command)

SELECT mark_tables_colocated('stores', ARRAY['products', 'line_items']);

 

A few changes that still need to accounted for on the quinng/citusStuffs branch.

Unit Testing

Unit Testing

Interfaces

For interfaces that we've created exclusively for unit testing, put the interface in the same file as the implementing class.

Azure

Azure

Azure App Config

If a value was not in the azure app config before the function app started up, changes to that value will not be propogated to the app until it is restarted.

 

Postman

Postman

Account Management

Managing Access to Add-Ons

You may need the Admin and / or Billing role assigned to your user in order to manage access to add-ons.

You can manage user access to add-ons (like Collection Runner) by taking the following steps.

  1. Click the Team dropdown button in the top right (outlined in PURPLE).
  2. Click the Manage Team button in the dropdown (outlined in BLUE).
  3. In the left side navigation menu, select Product Access (outlined in orange).
  4. There are three tabs along to top, one for each add-on. Select the tab for the add-on you grant access to a user (outlined in YELLOW).
  5. Click the Add Members button (outlined in RED). 

You will be shown a modal in which you can select which users have access to the add-on.

image.png




Azure Dev Ops

Azure Dev Ops

Build Pipelines

Allowing a build pipeline to read from a NuGet Feed in a different ADO Project

  1. Make sure the Build Authorization Scope is set to Project Collectionimage.png
  2. Make sure that the right services have permission to the NuGet feed. See this Microsoft article for details. Basically, the feed needs to have contributor permission for all project and organization build services.

     

    image.png

    image.png

Offloaded Operations

Documentation of all Offloaded Operations from a development perspective