From 40cb22a7d5c303cd0320ce9b1d846009b1ee8d72 Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Tue, 12 Mar 2024 13:45:09 +0100
Subject: [PATCH 01/12] Adds OnboardingProcessCorrelationKey

---
 packages/account-portal                     |  2 +-
 packages/frontend-core/src/constants.js     |  2 ++
 packages/shared-core/src/constants/index.ts | 19 +++++++++++++++++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/packages/account-portal b/packages/account-portal
index 0c050591c2..3ce7c629b5 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 0c050591c21d3b67dc0c9225d60cc9e2324c8dac
+Subproject commit 3ce7c629b523f2481a4d6c9ad906fb345cc9039d
diff --git a/packages/frontend-core/src/constants.js b/packages/frontend-core/src/constants.js
index edfdb1c5ef..68da439195 100644
--- a/packages/frontend-core/src/constants.js
+++ b/packages/frontend-core/src/constants.js
@@ -3,6 +3,7 @@
  */
 export { OperatorOptions, SqlNumberTypeRangeMap } from "@budibase/shared-core"
 export { Feature as Features } from "@budibase/types"
+import { BpmCorrelationKey } from "@budibase/shared-core"
 
 // Cookie names
 export const Cookies = {
@@ -10,6 +11,7 @@ export const Cookies = {
   CurrentApp: "budibase:currentapp",
   ReturnUrl: "budibase:returnurl",
   AccountReturnUrl: "budibase:account:returnurl",
+  OnboardingProcessCorrelationKey: BpmCorrelationKey.ONBOARDING,
 }
 
 // Table names
diff --git a/packages/shared-core/src/constants/index.ts b/packages/shared-core/src/constants/index.ts
index 99fb5c2a73..963ea9742a 100644
--- a/packages/shared-core/src/constants/index.ts
+++ b/packages/shared-core/src/constants/index.ts
@@ -158,3 +158,22 @@ export const InvalidFileExtensions = [
   "wsh",
   "zip",
 ]
+
+export enum BpmCorrelationKey {
+  ONBOARDING = "budibase:onboarding:correlationkey"
+}
+
+export enum BpmInstanceKey {
+  ONBOARDING = "budibase:onboarding:instancekey"
+}
+
+export enum BpmStatusKey {
+  ONBOARDING = "budibase:onboarding:status"
+}
+
+export enum BpmStatusValue {
+  STARTED = "started",
+  COMPLETING_ACCOUNT_INFO = "completing_account_info",
+  VALIDATING_EMAIL = "validating_email",
+  COMPLETED = "completed",
+}

From b1be076ed01e46b758446f5d4119108dd2521461 Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Tue, 12 Mar 2024 13:48:11 +0100
Subject: [PATCH 02/12] Update account portal submodule

---
 packages/account-portal | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/account-portal b/packages/account-portal
index 3ce7c629b5..4ccb03f951 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 3ce7c629b523f2481a4d6c9ad906fb345cc9039d
+Subproject commit 4ccb03f95110735332ce42b1817efbbd2e54864b

From 8ae579b1d79899f0fc74cf9e2d1479ea24606875 Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Thu, 14 Mar 2024 13:15:35 +0100
Subject: [PATCH 03/12] Lint

---
 packages/shared-core/src/constants/index.ts | 6 +++---
 packages/worker/src/utilities/email.ts      | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/packages/shared-core/src/constants/index.ts b/packages/shared-core/src/constants/index.ts
index 963ea9742a..924618efb8 100644
--- a/packages/shared-core/src/constants/index.ts
+++ b/packages/shared-core/src/constants/index.ts
@@ -160,15 +160,15 @@ export const InvalidFileExtensions = [
 ]
 
 export enum BpmCorrelationKey {
-  ONBOARDING = "budibase:onboarding:correlationkey"
+  ONBOARDING = "budibase:onboarding:correlationkey",
 }
 
 export enum BpmInstanceKey {
-  ONBOARDING = "budibase:onboarding:instancekey"
+  ONBOARDING = "budibase:onboarding:instancekey",
 }
 
 export enum BpmStatusKey {
-  ONBOARDING = "budibase:onboarding:status"
+  ONBOARDING = "budibase:onboarding:status",
 }
 
 export enum BpmStatusValue {
diff --git a/packages/worker/src/utilities/email.ts b/packages/worker/src/utilities/email.ts
index 27f2876eda..e963234791 100644
--- a/packages/worker/src/utilities/email.ts
+++ b/packages/worker/src/utilities/email.ts
@@ -45,8 +45,8 @@ function createSMTPTransport(config?: SMTPInnerConfig) {
       host: "smtp.ethereal.email",
       secure: false,
       auth: {
-        user: "seamus99@ethereal.email",
-        pass: "5ghVteZAqj6jkKJF9R",
+        user: "jeremy22@ethereal.email",
+        pass: "EkeTST7Zr2TEsWtkRh",
       },
     }
   }

From 6728fdad1dd0adfa3ac206370f915df8dbb505d6 Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Thu, 14 Mar 2024 15:35:45 +0100
Subject: [PATCH 04/12] VERIFYING_EMAIL

---
 packages/shared-core/src/constants/index.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/shared-core/src/constants/index.ts b/packages/shared-core/src/constants/index.ts
index 924618efb8..7acaa2cba1 100644
--- a/packages/shared-core/src/constants/index.ts
+++ b/packages/shared-core/src/constants/index.ts
@@ -174,6 +174,6 @@ export enum BpmStatusKey {
 export enum BpmStatusValue {
   STARTED = "started",
   COMPLETING_ACCOUNT_INFO = "completing_account_info",
-  VALIDATING_EMAIL = "validating_email",
+  VERIFYING_EMAIL = "verifying_email",
   COMPLETED = "completed",
 }

From ff231b0095ccefda0f15c6bac48b74fd2b47343a Mon Sep 17 00:00:00 2001
From: Mel O'Hagan <mel@budibase.com>
Date: Tue, 19 Mar 2024 13:30:42 +0000
Subject: [PATCH 05/12] Make password optional

---
 packages/backend-core/src/users/db.ts          | 4 ++--
 packages/types/src/api/web/user.ts             | 2 +-
 packages/worker/src/api/routes/global/users.ts | 3 ++-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/packages/backend-core/src/users/db.ts b/packages/backend-core/src/users/db.ts
index 136cb4b8ad..04d3264e6f 100644
--- a/packages/backend-core/src/users/db.ts
+++ b/packages/backend-core/src/users/db.ts
@@ -500,13 +500,13 @@ export class UserDB {
 
   static async createAdminUser(
     email: string,
-    password: string,
     tenantId: string,
+    password?: string,
     opts?: CreateAdminUserOpts
   ) {
     const user: User = {
       email: email,
-      password: password,
+      password,
       createdAt: Date.now(),
       roles: {},
       builder: {
diff --git a/packages/types/src/api/web/user.ts b/packages/types/src/api/web/user.ts
index 0de42622e6..d68d687dcb 100644
--- a/packages/types/src/api/web/user.ts
+++ b/packages/types/src/api/web/user.ts
@@ -63,7 +63,7 @@ export interface SearchUsersRequest {
 
 export interface CreateAdminUserRequest {
   email: string
-  password: string
+  password?: string
   tenantId: string
   ssoId?: string
 }
diff --git a/packages/worker/src/api/routes/global/users.ts b/packages/worker/src/api/routes/global/users.ts
index 3c9cfd2f41..6b9291b88b 100644
--- a/packages/worker/src/api/routes/global/users.ts
+++ b/packages/worker/src/api/routes/global/users.ts
@@ -7,12 +7,13 @@ import { users } from "../validation"
 import * as selfController from "../../controllers/global/self"
 
 const router: Router = new Router()
+const OPTIONAL_STRING = Joi.string().optional().allow(null).allow("")
 
 function buildAdminInitValidation() {
   return auth.joiValidator.body(
     Joi.object({
       email: Joi.string().required(),
-      password: Joi.string(),
+      password: OPTIONAL_STRING,
       tenantId: Joi.string().required(),
       ssoId: Joi.string(),
     })

From 7fe4fe9b15183f29f8bf966163d3e917f79f5ccf Mon Sep 17 00:00:00 2001
From: Mel O'Hagan <mel@budibase.com>
Date: Tue, 19 Mar 2024 17:29:52 +0000
Subject: [PATCH 06/12] Exclude .nx folder

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 3eb705dbbf..21a6c4dfaa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,3 +107,5 @@ budibase-component
 budibase-datasource
 
 *.iml
+
+.nx
\ No newline at end of file

From 7df5e7a8a78d4d8b88eaaafccf6a963b780d6ced Mon Sep 17 00:00:00 2001
From: Martin McKeaveney <martinmckeaveney@gmail.com>
Date: Thu, 21 Mar 2024 15:19:50 +0000
Subject: [PATCH 07/12] fix order of createAdminUser args

---
 packages/account-portal                             | 2 +-
 packages/worker/src/api/controllers/global/users.ts | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/account-portal b/packages/account-portal
index 4ccb03f951..80173fdf42 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 4ccb03f95110735332ce42b1817efbbd2e54864b
+Subproject commit 80173fdf426e124221adaff15b37418814ea2ad2
diff --git a/packages/worker/src/api/controllers/global/users.ts b/packages/worker/src/api/controllers/global/users.ts
index 28ba97b4e2..6b9e533f78 100644
--- a/packages/worker/src/api/controllers/global/users.ts
+++ b/packages/worker/src/api/controllers/global/users.ts
@@ -127,8 +127,8 @@ export const adminUser = async (
     try {
       const finalUser = await userSdk.db.createAdminUser(
         email,
-        password,
         tenantId,
+        password,
         {
           ssoId,
           hashPassword,

From 50c0fb1f973c14f283327db9f3272db270edcf44 Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Fri, 22 Mar 2024 10:41:04 +0100
Subject: [PATCH 08/12] Override identity for events sent from dispatcher

---
 packages/backend-core/src/events/events.ts        | 15 +++++++++++----
 .../backend-core/src/events/publishers/account.ts | 10 ++++++++--
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/packages/backend-core/src/events/events.ts b/packages/backend-core/src/events/events.ts
index f02b9fdf32..92b81553b0 100644
--- a/packages/backend-core/src/events/events.ts
+++ b/packages/backend-core/src/events/events.ts
@@ -1,4 +1,4 @@
-import { Event } from "@budibase/types"
+import { Event, Identity } from "@budibase/types"
 import { processors } from "./processors"
 import identification from "./identification"
 import * as backfill from "./backfill"
@@ -7,12 +7,19 @@ import { publishAsyncEvent } from "./asyncEvents"
 export const publishEvent = async (
   event: Event,
   properties: any,
-  timestamp?: string | number
+  timestamp?: string | number,
+  identityOverride?: Identity
 ) => {
   // in future this should use async events via a distributed queue.
-  const identity = await identification.getCurrentIdentity()
+  const identity =
+    identityOverride || (await identification.getCurrentIdentity())
+
+  // Backfilling is get from the user cache, but when we override the identity cache is not available. Overrides are
+  // normally performed in automatic actions or operations in async flows (BPM) where the user session is not available.
+  const backfilling = identityOverride
+    ? false
+    : await backfill.isBackfillingEvent(event)
 
-  const backfilling = await backfill.isBackfillingEvent(event)
   // no backfill - send the event and exit
   if (!backfilling) {
     // send off async events if required
diff --git a/packages/backend-core/src/events/publishers/account.ts b/packages/backend-core/src/events/publishers/account.ts
index d337e404ef..99767962dd 100644
--- a/packages/backend-core/src/events/publishers/account.ts
+++ b/packages/backend-core/src/events/publishers/account.ts
@@ -5,13 +5,19 @@ import {
   AccountCreatedEvent,
   AccountDeletedEvent,
   AccountVerifiedEvent,
+  Identity,
 } from "@budibase/types"
 
-async function created(account: Account) {
+async function created(account: Account, identityOverride?: Identity) {
   const properties: AccountCreatedEvent = {
     tenantId: account.tenantId,
   }
-  await publishEvent(Event.ACCOUNT_CREATED, properties)
+  await publishEvent(
+    Event.ACCOUNT_CREATED,
+    properties,
+    undefined,
+    identityOverride
+  )
 }
 
 async function deleted(account: Account) {

From 4314489e26f2898fd715bf496338098004f0b67d Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Mon, 25 Mar 2024 12:31:48 +0100
Subject: [PATCH 09/12] Restore ethereal user

---
 packages/worker/src/utilities/email.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/worker/src/utilities/email.ts b/packages/worker/src/utilities/email.ts
index e963234791..27f2876eda 100644
--- a/packages/worker/src/utilities/email.ts
+++ b/packages/worker/src/utilities/email.ts
@@ -45,8 +45,8 @@ function createSMTPTransport(config?: SMTPInnerConfig) {
       host: "smtp.ethereal.email",
       secure: false,
       auth: {
-        user: "jeremy22@ethereal.email",
-        pass: "EkeTST7Zr2TEsWtkRh",
+        user: "seamus99@ethereal.email",
+        pass: "5ghVteZAqj6jkKJF9R",
       },
     }
   }

From 62fa6d9fa46b1304030c7a744b878d578c6fe852 Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Tue, 26 Mar 2024 09:14:12 +0100
Subject: [PATCH 10/12] Account portal submodule update

---
 packages/account-portal | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/account-portal b/packages/account-portal
index 80173fdf42..f5b467b6b1 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 80173fdf426e124221adaff15b37418814ea2ad2
+Subproject commit f5b467b6b1c55c48847545db41be7b1c035e167a

From 7214cb43df0f70b9bff6d12e0657a443493e9522 Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Tue, 26 Mar 2024 09:32:55 +0100
Subject: [PATCH 11/12] Remove qa-core test. Suite is going to be removed. See
 https://linear.app/budibase/issue/BUDI-8106/remove-qa-core

---
 .../tests/users/appSpecificRoles.spec.ts      | 104 ------------------
 1 file changed, 104 deletions(-)
 delete mode 100644 qa-core/src/internal-api/tests/users/appSpecificRoles.spec.ts

diff --git a/qa-core/src/internal-api/tests/users/appSpecificRoles.spec.ts b/qa-core/src/internal-api/tests/users/appSpecificRoles.spec.ts
deleted file mode 100644
index 325735b3fc..0000000000
--- a/qa-core/src/internal-api/tests/users/appSpecificRoles.spec.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-import { User } from "@budibase/types"
-import { db } from "@budibase/backend-core"
-import * as fixtures from "../../fixtures"
-
-describe("Internal API - App Specific Roles & Permissions", () => {
-  const config = new TestConfiguration()
-
-  // Before each test, login as admin. Some tests will require login as a different user
-  beforeAll(async () => {
-    await config.beforeAll()
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("Add BASIC user to app", async () => {
-    const appUser = fixtures.users.generateUser()
-    expect(appUser[0].builder?.global).toEqual(false)
-    expect(appUser[0].admin?.global).toEqual(false)
-    const [createUserResponse, createUserJson] =
-      await config.api.users.addMultiple(appUser)
-
-    const app = await config.createApp(fixtures.apps.appFromTemplate())
-
-    const [userInfoResponse, userInfoJson] = await config.api.users.getInfo(
-      createUserJson.created.successful[0]._id
-    )
-    const body: User = {
-      ...userInfoJson,
-      roles: {
-        [app.appId!]: "BASIC",
-      },
-    }
-    await config.api.users.updateInfo(body)
-
-    const [changedUserInfoResponse, changedUserInfoJson] =
-      await config.api.users.getInfo(createUserJson.created.successful[0]._id)
-    expect(changedUserInfoJson.roles[app.appId!]).toBeDefined()
-    expect(changedUserInfoJson.roles[app.appId!]).toEqual("BASIC")
-  })
-
-  it("Add ADMIN user to app", async () => {
-    // Create a user with ADMIN role and check if it was created successfully
-    const adminUser = fixtures.users.generateUser(1, "admin")
-    expect(adminUser[0].builder?.global).toEqual(true)
-    expect(adminUser[0].admin?.global).toEqual(true)
-    const [createUserResponse, createUserJson] =
-      await config.api.users.addMultiple(adminUser)
-
-    // const app = await config.createApp(fixtures.apps.appFromTemplate())
-    const app = await config.createApp(fixtures.apps.appFromTemplate())
-
-    const [userInfoResponse, userInfoJson] = await config.api.users.getInfo(
-      createUserJson.created.successful[0]._id
-    )
-    const body: User = {
-      ...userInfoJson,
-      roles: {
-        [app.appId!]: "ADMIN",
-      },
-    }
-    await config.api.users.updateInfo(body)
-
-    const [changedUserInfoResponse, changedUserInfoJson] =
-      await config.api.users.getInfo(createUserJson.created.successful[0]._id)
-    expect(changedUserInfoJson.roles[app.appId!]).toBeDefined()
-    expect(changedUserInfoJson.roles[app.appId!]).toEqual("ADMIN")
-
-    // publish app
-    await config.api.apps.publish(app.appId)
-    // check published app renders
-    config.state.appId = db.getProdAppID(app.appId!)
-    await config.api.apps.canRender()
-  })
-
-  it("Add POWER user to app", async () => {
-    const powerUser = fixtures.users.generateUser(1, "developer")
-    expect(powerUser[0].builder?.global).toEqual(true)
-
-    const [createUserResponse, createUserJson] =
-      await config.api.users.addMultiple(powerUser)
-
-    const app = await config.createApp()
-
-    const [userInfoResponse, userInfoJson] = await config.api.users.getInfo(
-      createUserJson.created.successful[0]._id
-    )
-    const body: User = {
-      ...userInfoJson,
-      roles: {
-        [app.appId!]: "POWER",
-      },
-    }
-    await config.api.users.updateInfo(body)
-
-    // Get the user information again and check if the role was added
-    const [changedUserInfoResponse, changedUserInfoJson] =
-      await config.api.users.getInfo(createUserJson.created.successful[0]._id)
-    expect(changedUserInfoJson.roles[app.appId!]).toBeDefined()
-    expect(changedUserInfoJson.roles[app.appId!]).toEqual("POWER")
-  })
-})

From c5f5d9454ce1e98a81d3aa8786007a3a43ee80e5 Mon Sep 17 00:00:00 2001
From: jvcalderon <jose@budibase.com>
Date: Tue, 26 Mar 2024 09:41:57 +0100
Subject: [PATCH 12/12] Remove more qa-core tests. Suite is going to be
 removed. See https://linear.app/budibase/issue/BUDI-8106/remove-qa-core

---
 .../tests/applications/create.spec.ts         |  42 ------
 .../tests/applications/delete.spec.ts         |  19 ---
 .../tests/applications/publish.spec.ts        |  54 -------
 .../tests/applications/update.spec.ts         |  45 ------
 .../tests/screens/screens.spec.ts             |  51 -------
 .../internal-api/tests/tables/tables.spec.ts  | 133 ------------------
 .../tests/users/userManagement.spec.ts        |  90 ------------
 .../tests/applications/applications.spec.ts   |  97 -------------
 .../src/public-api/tests/tables/rows.spec.ts  |  62 --------
 .../public-api/tests/tables/tables.spec.ts    |  51 -------
 .../src/public-api/tests/users/users.spec.ts  |  49 -------
 11 files changed, 693 deletions(-)
 delete mode 100644 qa-core/src/internal-api/tests/applications/create.spec.ts
 delete mode 100644 qa-core/src/internal-api/tests/applications/delete.spec.ts
 delete mode 100644 qa-core/src/internal-api/tests/applications/publish.spec.ts
 delete mode 100644 qa-core/src/internal-api/tests/applications/update.spec.ts
 delete mode 100644 qa-core/src/internal-api/tests/screens/screens.spec.ts
 delete mode 100644 qa-core/src/internal-api/tests/tables/tables.spec.ts
 delete mode 100644 qa-core/src/internal-api/tests/users/userManagement.spec.ts
 delete mode 100644 qa-core/src/public-api/tests/applications/applications.spec.ts
 delete mode 100644 qa-core/src/public-api/tests/tables/rows.spec.ts
 delete mode 100644 qa-core/src/public-api/tests/tables/tables.spec.ts
 delete mode 100644 qa-core/src/public-api/tests/users/users.spec.ts

diff --git a/qa-core/src/internal-api/tests/applications/create.spec.ts b/qa-core/src/internal-api/tests/applications/create.spec.ts
deleted file mode 100644
index 2bb209719c..0000000000
--- a/qa-core/src/internal-api/tests/applications/create.spec.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-import * as fixtures from "../../fixtures"
-
-describe("Internal API - Application creation", () => {
-  const config = new TestConfiguration()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("Get applications without applications", async () => {
-    await config.api.apps.fetchEmptyAppList()
-  })
-
-  it("Get all Applications after creating an application", async () => {
-    await config.api.apps.create({
-      ...fixtures.apps.generateApp(),
-      useTemplate: "false",
-    })
-
-    await config.api.apps.fetchAllApplications()
-  })
-
-  it("Get application details", async () => {
-    const app = await config.createApp({
-      ...fixtures.apps.generateApp(),
-      useTemplate: "false",
-    })
-
-    const [appPackageResponse, appPackageJson] =
-      await config.api.apps.getAppPackage(app.appId!)
-    expect(appPackageJson.application.name).toEqual(app.name)
-    expect(appPackageJson.application.version).toEqual(app.version)
-    expect(appPackageJson.application.url).toEqual(app.url)
-    expect(appPackageJson.application.tenantId).toEqual(app.tenantId)
-    expect(appPackageJson.application.status).toEqual(app.status)
-  })
-})
diff --git a/qa-core/src/internal-api/tests/applications/delete.spec.ts b/qa-core/src/internal-api/tests/applications/delete.spec.ts
deleted file mode 100644
index 1841d7c42d..0000000000
--- a/qa-core/src/internal-api/tests/applications/delete.spec.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-
-describe("Internal API - Application creation, update, publish and delete", () => {
-  const config = new TestConfiguration()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("DELETE - Delete an application", async () => {
-    const app = await config.createApp()
-
-    await config.api.apps.delete(app.appId!)
-  })
-})
diff --git a/qa-core/src/internal-api/tests/applications/publish.spec.ts b/qa-core/src/internal-api/tests/applications/publish.spec.ts
deleted file mode 100644
index e614a0f2a4..0000000000
--- a/qa-core/src/internal-api/tests/applications/publish.spec.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-import { db } from "@budibase/backend-core"
-import * as fixtures from "../../fixtures"
-
-describe("Internal API - Application creation, update, publish and delete", () => {
-  const config = new TestConfiguration()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("Publish app", async () => {
-    // create the app
-    const app = await config.createApp(fixtures.apps.appFromTemplate())
-
-    // check preview renders
-    await config.api.apps.canRender()
-
-    // publish app
-    await config.api.apps.publish(app.appId)
-
-    // check published app renders
-    config.state.appId = db.getProdAppID(app.appId!)
-    await config.api.apps.canRender()
-
-    // unpublish app
-    await config.api.apps.unpublish(app.appId!)
-  })
-
-  it("Sync application before deployment", async () => {
-    const app = await config.createApp()
-
-    const [syncResponse, sync] = await config.api.apps.sync(app.appId!)
-    expect(sync).toEqual({
-      message: "App sync completed successfully.",
-    })
-  })
-
-  it("Sync application after deployment", async () => {
-    const app = await config.createApp()
-
-    // publish app
-    await config.api.apps.publish(app._id)
-
-    const [syncResponse, sync] = await config.api.apps.sync(app.appId!)
-    expect(sync).toEqual({
-      message: "App sync completed successfully.",
-    })
-  })
-})
diff --git a/qa-core/src/internal-api/tests/applications/update.spec.ts b/qa-core/src/internal-api/tests/applications/update.spec.ts
deleted file mode 100644
index 93b57dcb61..0000000000
--- a/qa-core/src/internal-api/tests/applications/update.spec.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-import { generator } from "../../../shared"
-import * as fixtures from "../../fixtures"
-
-describe("Internal API - Application creation, update, publish and delete", () => {
-  const config = new TestConfiguration()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("Update an application", async () => {
-    const app = await config.createApp()
-
-    await config.api.apps.rename(app.appId!, app.name!, {
-      name: generator.word(),
-    })
-  })
-
-  it("Revert Changes without changes", async () => {
-    const app = await config.createApp()
-
-    await config.api.apps.revertUnpublished(app.appId!)
-  })
-
-  it("Revert Changes", async () => {
-    const app = await config.createApp()
-
-    // publish app
-    await config.api.apps.publish(app._id)
-
-    // Change/add component to the app
-    await config.api.screens.create(fixtures.screens.generateScreen("BASIC"))
-
-    // // Revert the app to published state
-    await config.api.apps.revertPublished(app.appId!)
-
-    // Check screen is removed
-    await config.api.apps.getRoutes()
-  })
-})
diff --git a/qa-core/src/internal-api/tests/screens/screens.spec.ts b/qa-core/src/internal-api/tests/screens/screens.spec.ts
deleted file mode 100644
index 9c5fa42847..0000000000
--- a/qa-core/src/internal-api/tests/screens/screens.spec.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-import * as fixtures from "../../fixtures"
-
-describe("Internal API - /screens endpoints", () => {
-  const config = new TestConfiguration()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("Create a screen with each role type", async () => {
-    // Create app
-    await config.createApp()
-
-    // Create Screen
-    const roleArray = ["BASIC", "POWER", "ADMIN", "PUBLIC"]
-    for (let role in roleArray) {
-      const [response, screen] = await config.api.screens.create(
-        fixtures.screens.generateScreen(roleArray[role])
-      )
-    }
-  })
-
-  it("Get screens", async () => {
-    // Create app
-    await config.createApp()
-
-    // Create Screen
-    await config.api.screens.create(fixtures.screens.generateScreen("BASIC"))
-
-    // Check screen exists
-    await config.api.apps.getRoutes(true)
-  })
-
-  it("Delete a screen", async () => {
-    // Create app
-    await config.createApp()
-
-    // Create Screen
-    const [screenResponse, screen] = await config.api.screens.create(
-      fixtures.screens.generateScreen("BASIC")
-    )
-
-    // Delete Screen
-    await config.api.screens.delete(screen._id!, screen._rev!)
-  })
-})
diff --git a/qa-core/src/internal-api/tests/tables/tables.spec.ts b/qa-core/src/internal-api/tests/tables/tables.spec.ts
deleted file mode 100644
index a38b8e6059..0000000000
--- a/qa-core/src/internal-api/tests/tables/tables.spec.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-import { generator } from "../../../shared"
-import * as fixtures from "../../fixtures"
-
-describe("Internal API - Table Operations", () => {
-  const config = new TestConfiguration()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("Create and delete table, columns and rows", async () => {
-    // create the app
-    await config.createApp(fixtures.apps.appFromTemplate())
-
-    // Get current tables: expect 2 in this template
-    await config.api.tables.getAll(2)
-
-    // Add new table
-    const [createdTableResponse, createdTableData] =
-      await config.api.tables.save(fixtures.tables.generateTable())
-
-    //Table was added
-    await config.api.tables.getAll(3)
-
-    //Get information about the table
-    await config.api.tables.getTableById(createdTableData._id!)
-
-    //Add Column to table
-    const newColumn =
-      fixtures.tables.generateNewColumnForTable(createdTableData)
-    const [addColumnResponse, addColumnData] = await config.api.tables.save(
-      newColumn,
-      true
-    )
-
-    //Add Row to table
-    const newRow = fixtures.rows.generateNewRowForTable(addColumnData._id!)
-    await config.api.rows.add(addColumnData._id!, newRow)
-
-    //Get Row from table
-    const [getRowResponse, getRowData] = await config.api.rows.getAll(
-      addColumnData._id!
-    )
-
-    //Delete Row from table
-    const rowToDelete = {
-      rows: [getRowData[0]],
-    }
-    const [deleteRowResponse, deleteRowData] = await config.api.rows.delete(
-      addColumnData._id!,
-      rowToDelete
-    )
-    expect(deleteRowData[0]._id).toEqual(getRowData[0]._id)
-
-    //Delete the table
-    const [deleteTableResponse, deleteTable] = await config.api.tables.delete(
-      addColumnData._id!,
-      addColumnData._rev!
-    )
-
-    //Table was deleted
-    await config.api.tables.getAll(2)
-  })
-
-  it("Search and pagination", async () => {
-    // create the app
-    await config.createApp(fixtures.apps.appFromTemplate())
-
-    // Get current tables: expect 2 in this template
-    await config.api.tables.getAll(2)
-
-    // Add new table
-    const [createdTableResponse, createdTableData] =
-      await config.api.tables.save(fixtures.tables.generateTable())
-
-    //Table was added
-    await config.api.tables.getAll(3)
-
-    //Get information about the table
-    await config.api.tables.getTableById(createdTableData._id!)
-
-    //Add Column to table
-    const newColumn =
-      fixtures.tables.generateNewColumnForTable(createdTableData)
-    const [addColumnResponse, addColumnData] = await config.api.tables.save(
-      newColumn,
-      true
-    )
-
-    //Add Row to table
-    let newRow = fixtures.rows.generateNewRowForTable(addColumnData._id!)
-    await config.api.rows.add(addColumnData._id!, newRow)
-
-    //Search single row
-    await config.api.rows.searchNoPagination(
-      createdTableData._id!,
-      fixtures.rows.searchBody(createdTableData.primaryDisplay!)
-    )
-
-    //Add 10 more rows
-    for (let i = 0; i < 10; i++) {
-      let newRow = fixtures.rows.generateNewRowForTable(addColumnData._id!)
-      await config.api.rows.add(addColumnData._id!, newRow)
-    }
-
-    //Search rows with pagination
-    const [allRowsResponse, allRowsJson] =
-      await config.api.rows.searchWithPagination(
-        createdTableData._id!,
-        fixtures.rows.searchBody(createdTableData.primaryDisplay!)
-      )
-
-    //Delete Rows from table
-    const rowToDelete = {
-      rows: [allRowsJson],
-    }
-    const [deleteRowResponse, deleteRowData] = await config.api.rows.delete(
-      createdTableData._id!,
-      rowToDelete
-    )
-
-    //Search single row
-    await config.api.rows.searchWithPagination(
-      createdTableData._id!,
-      fixtures.rows.searchBody(createdTableData.primaryDisplay!)
-    )
-  })
-})
diff --git a/qa-core/src/internal-api/tests/users/userManagement.spec.ts b/qa-core/src/internal-api/tests/users/userManagement.spec.ts
deleted file mode 100644
index 28096c08c9..0000000000
--- a/qa-core/src/internal-api/tests/users/userManagement.spec.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-import { User } from "@budibase/types"
-import * as fixtures from "./../../fixtures"
-
-describe("Internal API - User Management & Permissions", () => {
-  const config = new TestConfiguration()
-
-  // Before each test, login as admin. Some tests will require login as a different user
-  beforeAll(async () => {
-    await config.beforeAll()
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("Add Users with different roles", async () => {
-    // Get all users
-    await config.api.users.search()
-
-    // Get all roles
-    await config.api.users.getRoles()
-
-    // Add users with each role
-    const admin = fixtures.users.generateUser(1, "admin")
-    expect(admin[0].builder?.global).toEqual(true)
-    expect(admin[0].admin?.global).toEqual(true)
-    const developer = fixtures.users.generateUser(1, "developer")
-    expect(developer[0].builder?.global).toEqual(true)
-    const appUser = fixtures.users.generateUser(1, "appUser")
-    expect(appUser[0].builder?.global).toEqual(false)
-    expect(appUser[0].admin?.global).toEqual(false)
-
-    const userList = [...admin, ...developer, ...appUser]
-
-    await config.api.users.addMultiple(userList)
-
-    // Check users are added
-    const [allUsersResponse, allUsersJson] = await config.api.users.getAll()
-    expect(allUsersJson.length).toBeGreaterThan(0)
-  })
-
-  it("Delete User", async () => {
-    const appUser = fixtures.users.generateUser()
-    expect(appUser[0].builder?.global).toEqual(false)
-    expect(appUser[0].admin?.global).toEqual(false)
-    const [userResponse, userJson] = await config.api.users.addMultiple(appUser)
-    const userId = userJson.created.successful[0]._id
-    await config.api.users.delete(userId)
-  })
-
-  it("Reset Password", async () => {
-    const appUser = fixtures.users.generateUser()
-    expect(appUser[0].builder?.global).toEqual(false)
-    expect(appUser[0].admin?.global).toEqual(false)
-    const [userResponse, userJson] = await config.api.users.addMultiple(appUser)
-    const [userInfoResponse, userInfoJson] = await config.api.users.getInfo(
-      userJson.created.successful[0]._id
-    )
-    const body: User = {
-      ...userInfoJson,
-      password: "newPassword",
-    }
-    await config.api.users.forcePasswordReset(body)
-  })
-
-  it("Change User information", async () => {
-    const appUser = fixtures.users.generateUser()
-    expect(appUser[0].builder?.global).toEqual(false)
-    expect(appUser[0].admin?.global).toEqual(false)
-    const [userResponse, userJson] = await config.api.users.addMultiple(appUser)
-    const [userInfoResponse, userInfoJson] = await config.api.users.getInfo(
-      userJson.created.successful[0]._id
-    )
-    const body: User = {
-      ...userInfoJson,
-      firstName: "newFirstName",
-      lastName: "newLastName",
-      builder: {
-        global: true,
-      },
-    }
-    await config.api.users.updateInfo(body)
-
-    const [changedUserInfoResponse, changedUserInfoJson] =
-      await config.api.users.getInfo(userJson.created.successful[0]._id)
-    expect(changedUserInfoJson.builder?.global).toBeDefined()
-    expect(changedUserInfoJson.builder?.global).toEqual(true)
-  })
-})
diff --git a/qa-core/src/public-api/tests/applications/applications.spec.ts b/qa-core/src/public-api/tests/applications/applications.spec.ts
deleted file mode 100644
index 0c8636452a..0000000000
--- a/qa-core/src/public-api/tests/applications/applications.spec.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import { db as dbCore } from "@budibase/backend-core"
-import { TestConfiguration } from "../../config"
-import { Application } from "../../../types"
-import * as fixtures from "../../fixtures"
-
-describe("Public API - /applications endpoints", () => {
-  const config = new TestConfiguration<Application>()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-    await config.createApp()
-    config.context = (await config.api.apps.read(config.state.appId!))[1]
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("POST - Create an application", async () => {
-    const [response, app] = await config.api.apps.create(
-      fixtures.apps.generateApp()
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(app._id).toBeDefined()
-  })
-
-  it("POST - Search applications", async () => {
-    const [response, apps] = await config.api.apps.search({
-      name: config.context.name,
-    })
-    expect(response).toHaveStatusCode(200)
-    expect(apps[0]).toEqual(config.context)
-  })
-
-  it("GET - Retrieve an application", async () => {
-    const [response, app] = await config.api.apps.read(config.context._id)
-    expect(response).toHaveStatusCode(200)
-    expect(app).toEqual(config.context)
-  })
-
-  it("PUT - update an application", async () => {
-    config.context.name = "UpdatedName"
-    const [response, app] = await config.api.apps.update(
-      config.context._id,
-      config.context
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(app.updatedAt).not.toEqual(config.context.updatedAt)
-    expect(app.name).toEqual(config.context.name)
-  })
-
-  it("POST - publish an application", async () => {
-    config.context.name = "UpdatedName"
-    const [response, deployment] = await config.api.apps.publish(
-      config.context._id
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(deployment).toEqual({
-      status: "SUCCESS",
-    })
-
-    // Verify publish
-    const prodAppId = dbCore.getProdAppID(config.context._id)
-    const [_, publishedApp] = await config.api.apps.read(prodAppId)
-    expect(response).toHaveStatusCode(200)
-    expect(publishedApp._id).toEqual(prodAppId)
-  })
-
-  it("POST - unpublish a published application", async () => {
-    await config.api.apps.publish(config.context._id)
-    const [response] = await config.api.apps.unpublish(config.context._id)
-    expect(response).toHaveStatusCode(204)
-  })
-
-  it("POST - unpublish an unpublished application", async () => {
-    const [response] = await config.api.apps.unpublish(config.context._id)
-    expect(response).toHaveStatusCode(400)
-  })
-
-  it("DELETE - delete a published application and the dev application", async () => {
-    await config.api.apps.publish(config.context._id)
-    const [response, deletion] = await config.api.apps.delete(
-      config.context._id
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(deletion._id).toEqual(config.context._id)
-
-    // verify dev app deleted
-    const [devAppResponse] = await config.api.apps.read(config.context._id)
-    expect(devAppResponse).toHaveStatusCode(404)
-
-    // verify prod app deleted
-    const prodAppId = dbCore.getProdAppID(config.context._id)
-    const [publishedAppResponse] = await config.api.apps.read(prodAppId)
-    expect(publishedAppResponse).toHaveStatusCode(404)
-  })
-})
diff --git a/qa-core/src/public-api/tests/tables/rows.spec.ts b/qa-core/src/public-api/tests/tables/rows.spec.ts
deleted file mode 100644
index e35f071a4e..0000000000
--- a/qa-core/src/public-api/tests/tables/rows.spec.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { TestConfiguration } from "../../config"
-import * as fixtures from "../../fixtures"
-import { Row } from "../../../types"
-
-describe("Public API - /rows endpoints", () => {
-  const config = new TestConfiguration<Row>()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-    await config.createApp()
-
-    const [tResp, table] = await config.api.tables.seed()
-    config.state.tableId = table._id
-
-    const [rResp, row] = await config.api.rows.seed(table._id)
-    config.context = row
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("POST - Create a row", async () => {
-    const [response, row] = await config.api.rows.create(
-      fixtures.rows.generateRow()
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(row._id).toBeDefined()
-  })
-
-  it("POST - Search rows", async () => {
-    const [response, rows] = await config.api.rows.search({
-      query: {
-        string: {
-          testColumn: config.context.testColumn as string,
-        },
-      },
-    })
-    expect(response).toHaveStatusCode(200)
-    expect(rows.length).toEqual(1)
-    expect(rows[0]._id).toEqual(config.context._id)
-    expect(rows[0].tableId).toEqual(config.context.tableId)
-    expect(rows[0].testColumn).toEqual(config.context.testColumn)
-  })
-
-  it("GET - Retrieve a row", async () => {
-    const [response, row] = await config.api.rows.read(config.context._id)
-    expect(response).toHaveStatusCode(200)
-    expect(row._id).toEqual(config.context._id)
-    expect(row.tableId).toEqual(config.context.tableId)
-  })
-
-  it("PUT - update a row", async () => {
-    config.context.testColumn = "UpdatedName"
-    const [response, row] = await config.api.rows.update(
-      config.context._id,
-      config.context
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(row.testColumn).toEqual(config.context.testColumn)
-  })
-})
diff --git a/qa-core/src/public-api/tests/tables/tables.spec.ts b/qa-core/src/public-api/tests/tables/tables.spec.ts
deleted file mode 100644
index 010444b7c8..0000000000
--- a/qa-core/src/public-api/tests/tables/tables.spec.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { TestConfiguration } from "../../config"
-import * as fixtures from "../../fixtures"
-import { Table } from "../../../types"
-
-describe("Public API - /tables endpoints", () => {
-  const config = new TestConfiguration<Table>()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-    await config.createApp()
-
-    const [tableResp, table] = await config.api.tables.seed()
-    config.context = table
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("POST - Create a table", async () => {
-    const [response, table] = await config.api.tables.create(
-      fixtures.tables.generateTable()
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(table._id).toBeDefined()
-  })
-
-  it("POST - Search tables", async () => {
-    const [response, tables] = await config.api.tables.search({
-      name: config.context.name,
-    })
-    expect(response).toHaveStatusCode(200)
-    expect(tables[0]).toEqual(config.context)
-  })
-
-  it("GET - Retrieve a table", async () => {
-    const [response, table] = await config.api.tables.read(config.context._id)
-    expect(response).toHaveStatusCode(200)
-    expect(table).toEqual(config.context)
-  })
-
-  it("PUT - update a table", async () => {
-    config.context.name = "updatedName"
-    const [response, table] = await config.api.tables.update(
-      config.context._id,
-      config.context
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(table).toEqual(config.context)
-  })
-})
diff --git a/qa-core/src/public-api/tests/users/users.spec.ts b/qa-core/src/public-api/tests/users/users.spec.ts
deleted file mode 100644
index 98f390b9bd..0000000000
--- a/qa-core/src/public-api/tests/users/users.spec.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import TestConfiguration from "../../config/TestConfiguration"
-import * as fixtures from "../../fixtures"
-import { User } from "../../../types"
-
-describe("Public API - /users endpoints", () => {
-  const config = new TestConfiguration<User>()
-
-  beforeAll(async () => {
-    await config.beforeAll()
-    const [_, user] = await config.api.users.seed()
-    config.context = user
-  })
-
-  afterAll(async () => {
-    await config.afterAll()
-  })
-
-  it("POST - Create a user", async () => {
-    const [response, user] = await config.api.users.create(
-      fixtures.users.generateUser()
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(user._id).toBeDefined()
-  })
-
-  it("POST - Search users", async () => {
-    const [response, users] = await config.api.users.search({
-      name: config.context.email,
-    })
-    expect(response).toHaveStatusCode(200)
-    expect(users[0]).toEqual(config.context)
-  })
-
-  it("GET - Retrieve a user", async () => {
-    const [response, user] = await config.api.users.read(config.context._id)
-    expect(response).toHaveStatusCode(200)
-    expect(user).toEqual(config.context)
-  })
-
-  it("PUT - update a user", async () => {
-    config.context.firstName = "Updated First Name"
-    const [response, user] = await config.api.users.update(
-      config.context._id,
-      config.context
-    )
-    expect(response).toHaveStatusCode(200)
-    expect(user).toEqual(config.context)
-  })
-})