chore(server): automate IoC 3 - validateAndUpdateAutomationFactory

This commit is contained in:
Kristaps Fabians Geikins
2024-09-20 13:12:38 +03:00
parent 5ed334b554
commit 7c365bf56e
9 changed files with 97 additions and 65 deletions
@@ -7,6 +7,8 @@ import { InsertableAutomationRevision } from '@/modules/automate/repositories/au
import { AuthCodePayload } from '@/modules/automate/services/authCode'
import { ProjectAutomationCreateInput } from '@/modules/core/graph/generated/graphql'
import { ContextResourceAccessRules } from '@/modules/core/helpers/token'
import { Nullable } from '@speckle/shared'
import { SetRequired } from 'type-fest'
export type StoreAutomation = (
automation: AutomationRecord
@@ -20,6 +22,20 @@ export type StoreAutomationRevision = (
revision: InsertableAutomationRevision
) => Promise<AutomationRevisionWithTriggersFunctions>
export type GetAutomations = (params: {
automationIds: string[]
projectId?: string
}) => Promise<AutomationRecord[]>
export type GetAutomation = (params: {
automationId: string
projectId?: string
}) => Promise<Nullable<AutomationRecord>>
export type UpdateAutomation = (
automation: SetRequired<Partial<AutomationRecord>, 'id'>
) => Promise<AutomationRecord>
export type CreateStoredAuthCode = (
params: Omit<AuthCodePayload, 'code'>
) => Promise<AuthCodePayload>
@@ -11,7 +11,7 @@ import {
} from '@/modules/automate/clients/executionEngine'
import {
GetProjectAutomationsParams,
getAutomation,
getAutomationFactory,
getAutomationRunsItems,
getAutomationRunsTotalCount,
getAutomationTriggerDefinitions,
@@ -24,8 +24,8 @@ import {
storeAutomationFactory,
storeAutomationRevisionFactory,
storeAutomationTokenFactory,
updateAutomationFactory,
updateAutomationRun,
updateAutomation as updateDbAutomation,
upsertAutomationFunctionRun
} from '@/modules/automate/repositories/automations'
import {
@@ -33,7 +33,7 @@ import {
createAutomationRevision,
createTestAutomationFactory,
getAutomationsStatus,
updateAutomation
validateAndUpdateAutomationFactory
} from '@/modules/automate/services/automationManagement'
import {
AuthCodePayloadAction,
@@ -111,6 +111,8 @@ const { FF_AUTOMATE_MODULE_ENABLED } = getFeatureFlags()
const storeAutomation = storeAutomationFactory({ db })
const storeAutomationToken = storeAutomationTokenFactory({ db })
const storeAutomationRevision = storeAutomationRevisionFactory({ db })
const getAutomation = getAutomationFactory({ db })
const updateDbAutomation = updateAutomationFactory({ db })
export = (FF_AUTOMATE_MODULE_ENABLED
? {
@@ -481,7 +483,7 @@ export = (FF_AUTOMATE_MODULE_ENABLED
).automation
},
async update(parent, { input }, ctx) {
const update = updateAutomation({
const update = validateAndUpdateAutomationFactory({
getAutomation,
updateAutomation: updateDbAutomation
})
+3 -2
View File
@@ -9,9 +9,9 @@ import {
getActiveTriggerDefinitions,
getAutomationRunFullTriggers,
getFullAutomationRevisionMetadata,
getAutomation,
getAutomationRevision,
getFullAutomationRunById
getFullAutomationRunById,
getAutomationFactory
} from '@/modules/automate/repositories/automations'
import { Scopes } from '@speckle/shared'
import { registerOrUpdateScopeFactory } from '@/modules/shared/repositories/scopes'
@@ -80,6 +80,7 @@ const initializeEventListeners = () => {
getCommit,
getFullAutomationRunById
})
const getAutomation = getAutomationFactory({ db })
const quitters = [
VersionsEmitter.listen(
@@ -1,7 +1,10 @@
import {
GetAutomation,
GetAutomations,
StoreAutomation,
StoreAutomationRevision,
StoreAutomationToken
StoreAutomationToken,
UpdateAutomation
} from '@/modules/automate/domain/operations'
import {
AutomationRecord,
@@ -409,47 +412,49 @@ export async function getAutomationToken(
return token || null
}
export async function getAutomations(params: {
automationIds: string[]
projectId?: string
}) {
const { automationIds, projectId } = params
if (!automationIds.length) return []
export const getAutomationsFactory =
(deps: { db: Knex }): GetAutomations =>
async (params: { automationIds: string[]; projectId?: string }) => {
const { automationIds, projectId } = params
if (!automationIds.length) return []
const q = Automations.knex<AutomationRecord[]>()
.select()
.whereIn(Automations.col.id, automationIds)
const q = tables
.automations(deps.db)
.select()
.whereIn(Automations.col.id, automationIds)
if (projectId?.length) {
q.andWhere(Automations.col.projectId, projectId)
if (projectId?.length) {
q.andWhere(Automations.col.projectId, projectId)
}
return await q
}
return await q
}
export const getAutomationFactory =
(deps: { db: Knex }): GetAutomation =>
async (params: { automationId: string; projectId?: string }) => {
const { automationId, projectId } = params
return (
(
await getAutomationsFactory(deps)({ automationIds: [automationId], projectId })
)?.[0] || null
)
}
export async function getAutomation(params: {
automationId: string
projectId?: string
}): Promise<Nullable<AutomationRecord>> {
const { automationId, projectId } = params
return (
(await getAutomations({ automationIds: [automationId], projectId }))?.[0] || null
)
}
export const updateAutomationFactory =
(deps: { db: Knex }): UpdateAutomation =>
async (automation: SetRequired<Partial<AutomationRecord>, 'id'>) => {
const [ret] = await tables
.automations(deps.db)
.where(Automations.col.id, automation.id)
.update({
...pick(automation, Automations.withoutTablePrefix.cols),
[Automations.withoutTablePrefix.col.updatedAt]: new Date()
})
.returning('*')
export async function updateAutomation(
automation: SetRequired<Partial<AutomationRecord>, 'id'>
) {
const [ret] = await Automations.knex()
.where(Automations.col.id, automation.id)
.update({
...pick(automation, Automations.withoutTablePrefix.cols),
[Automations.withoutTablePrefix.col.updatedAt]: new Date()
})
.returning<AutomationRecord[]>('*')
return ret
}
return ret
}
export async function getAutomationTriggerDefinitions<
T extends AutomationTriggerType = AutomationTriggerType
@@ -2,9 +2,7 @@ import {
InsertableAutomationRevision,
InsertableAutomationRevisionFunction,
InsertableAutomationRevisionTrigger,
getAutomation,
getLatestVersionAutomationRuns,
updateAutomation as updateDbAutomation
getLatestVersionAutomationRuns
} from '@/modules/automate/repositories/automations'
import { getServerOrigin } from '@/modules/shared/helpers/envHelper'
import cryptoRandomString from 'crypto-random-string'
@@ -51,10 +49,12 @@ import { validateAutomationName } from '@/modules/automate/utils/automationConfi
import {
CreateAutomation,
CreateStoredAuthCode,
GetAutomation,
GetEncryptionKeyPair,
StoreAutomation,
StoreAutomationRevision,
StoreAutomationToken
StoreAutomationToken,
UpdateAutomation
} from '@/modules/automate/domain/operations'
export type CreateAutomationDeps = {
@@ -243,13 +243,13 @@ export const createTestAutomationFactory =
return automationRecord
}
export type UpdateAutomationDeps = {
getAutomation: typeof getAutomation
updateAutomation: typeof updateDbAutomation
export type ValidateAndUpdateAutomationDeps = {
getAutomation: GetAutomation
updateAutomation: UpdateAutomation
}
export const updateAutomation =
(deps: UpdateAutomationDeps) =>
export const validateAndUpdateAutomationFactory =
(deps: ValidateAndUpdateAutomationDeps) =>
async (params: {
input: ProjectAutomationUpdateInput
userId: string
@@ -383,7 +383,7 @@ const validateNewRevisionFunctions =
}
export type CreateAutomationRevisionDeps = {
getAutomation: typeof getAutomation
getAutomation: GetAutomation
storeAutomationRevision: StoreAutomationRevision
getEncryptionKeyPair: GetEncryptionKeyPair
getFunctionInputDecryptor: ReturnType<typeof getFunctionInputDecryptor>
@@ -1,7 +1,6 @@
import {
InsertableAutomationRun,
getActiveTriggerDefinitions,
getAutomation,
getFullAutomationRevisionMetadata,
getAutomationToken,
getAutomationTriggerDefinitions,
@@ -43,10 +42,13 @@ import { automateLogger } from '@/logging/logging'
import { getFunctionInputDecryptor } from '@/modules/automate/services/encryption'
import { LibsodiumEncryptionError } from '@/modules/shared/errors/encryption'
import { AutomateRunsEmitter } from '@/modules/automate/events/runs'
import { GetEncryptionKeyPairFor } from '@/modules/automate/domain/operations'
import {
GetAutomation,
GetEncryptionKeyPairFor
} from '@/modules/automate/domain/operations'
export type OnModelVersionCreateDeps = {
getAutomation: typeof getAutomation
getAutomation: GetAutomation
getAutomationRevision: typeof getAutomationRevision
getTriggers: typeof getActiveTriggerDefinitions
triggerFunction: ReturnType<typeof triggerAutomationRevisionRun>
@@ -440,7 +442,7 @@ async function composeTriggerData(params: {
export type ManuallyTriggerAutomationDeps = {
getAutomationTriggerDefinitions: typeof getAutomationTriggerDefinitions
getAutomation: typeof getAutomation
getAutomation: GetAutomation
getBranchLatestCommits: typeof getBranchLatestCommits
triggerFunction: ReturnType<typeof triggerAutomationRevisionRun>
}
@@ -512,7 +514,7 @@ export const manuallyTriggerAutomation =
}
export type CreateTestAutomationRunDeps = {
getAutomation: typeof getAutomation
getAutomation: GetAutomation
getLatestAutomationRevision: typeof getLatestAutomationRevision
getFullAutomationRevisionMetadata: typeof getFullAutomationRevisionMetadata
} & CreateAutomationRunDataDeps
@@ -3,10 +3,10 @@ import {
AutomationUpdateError
} from '@/modules/automate/errors/management'
import {
getAutomation,
updateAutomation as updateDbAutomation
getAutomationFactory,
updateAutomationFactory
} from '@/modules/automate/repositories/automations'
import { updateAutomation } from '@/modules/automate/services/automationManagement'
import { validateAndUpdateAutomationFactory } from '@/modules/automate/services/automationManagement'
import {
AuthCodePayloadAction,
createStoredAuthCodeFactory
@@ -42,6 +42,7 @@ import { Automate, Roles } from '@speckle/shared'
import { expect } from 'chai'
import { times } from 'lodash'
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
import { db } from '@/db/knex'
/**
* TODO: Extra test ideas
@@ -52,7 +53,9 @@ import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
const { FF_AUTOMATE_MODULE_ENABLED } = getFeatureFlags()
const buildAutomationUpdate = () => {
const update = updateAutomation({
const getAutomation = getAutomationFactory({ db })
const updateDbAutomation = updateAutomationFactory({ db })
const update = validateAndUpdateAutomationFactory({
getAutomation,
updateAutomation: updateDbAutomation
})
@@ -33,18 +33,18 @@ import {
import { createTestCommit } from '@/test/speckle-helpers/commitHelper'
import {
InsertableAutomationRun,
getAutomation,
getFullAutomationRunById,
getAutomationTriggerDefinitions,
getFunctionRun,
updateAutomation,
updateAutomationRevision,
updateAutomationRun,
upsertAutomationRun,
upsertAutomationFunctionRun,
storeAutomationFactory,
storeAutomationTokenFactory,
storeAutomationRevisionFactory
storeAutomationRevisionFactory,
getAutomationFactory,
updateAutomationFactory
} from '@/modules/automate/repositories/automations'
import { beforeEachContext, truncateTables } from '@/test/hooks'
import { Automate } from '@speckle/shared'
@@ -78,6 +78,8 @@ const { FF_AUTOMATE_MODULE_ENABLED } = getFeatureFlags()
const storeAutomation = storeAutomationFactory({ db })
const storeAutomationToken = storeAutomationTokenFactory({ db })
const storeAutomationRevision = storeAutomationRevisionFactory({ db })
const getAutomation = getAutomationFactory({ db })
const updateAutomation = updateAutomationFactory({ db })
;(FF_AUTOMATE_MODULE_ENABLED ? describe : describe.skip)(
'Automate triggers @automate',
+2 -1
View File
@@ -63,7 +63,7 @@ import {
import {
getAutomationRevisions,
getAutomationRunsTriggers,
getAutomations,
getAutomationsFactory,
getFunctionAutomationCounts,
getLatestAutomationRevisions,
getRevisionsFunctions,
@@ -90,6 +90,7 @@ const simpleTupleCacheKey = (key: [string, string]) => `${key[0]}:${key[1]}`
const getStreamPendingModels = getStreamPendingModelsFactory({ db })
const getAppScopes = getAppScopesFactory({ db })
const getAutomations = getAutomationsFactory({ db })
/**
* TODO: Lazy load DataLoaders to reduce memory usage